buninu-linux 0.14.57 → 0.16.59

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 (299) hide show
  1. package/LICENSES/linux-firmware/LICENCE.nvidia +131 -0
  2. package/LICENSES/linux-firmware/LICENSE.amdgpu +51 -0
  3. package/LICENSES/linux-firmware/LICENSE.amdisp +31 -0
  4. package/LICENSES/linux-firmware/LICENSE.i915 +39 -0
  5. package/LICENSES/linux-firmware/LICENSE.radeon +51 -0
  6. package/LICENSES/linux-firmware/LICENSE.xe +39 -0
  7. package/LICENSES/linux-firmware/WHENCE +10280 -0
  8. package/NOTICE.md +64 -46
  9. package/README.md +378 -87
  10. package/README.zh.md +2041 -0
  11. package/build-image.sh +10 -1
  12. package/build-uki.sh +3 -1
  13. package/fetch-alpine.sh +14 -0
  14. package/graphics.md +31 -0
  15. package/index.js +28 -11
  16. package/initramfs/bin/buninu-browser +4 -1
  17. package/initramfs/bin/buninu-land +1 -1
  18. package/initramfs/bin/bunterm +3 -3
  19. package/initramfs/bin/chroot +13 -0
  20. package/initramfs/bin/chvt +11 -0
  21. package/initramfs/bin/mount +4 -0
  22. package/initramfs/bin/umount +6 -0
  23. package/initramfs/bin/xdg-open +33 -0
  24. package/initramfs/buninu/CHANGELOG.md +66 -0
  25. package/initramfs/buninu/apps/bunmsh/CHANGELOG.md +4 -0
  26. package/initramfs/buninu/apps/bunmsh/package.json +1 -1
  27. package/initramfs/buninu/apps/bunmsh/src/main.js +1 -1
  28. package/initramfs/buninu/apps/jsgotty/LICENSES/MIT-jsmdcui.txt +22 -0
  29. package/initramfs/buninu/apps/jsgotty/NOTICE +5 -0
  30. package/initramfs/buninu/apps/jsgotty/README.en.md +61 -0
  31. package/initramfs/buninu/apps/jsgotty/README.md +61 -0
  32. package/initramfs/buninu/apps/jsgotty/client-modes.mjs +117 -0
  33. package/initramfs/buninu/apps/jsgotty/client.mjs +100 -10
  34. package/initramfs/buninu/apps/jsgotty/clipboard-powershell.js +18 -0
  35. package/initramfs/buninu/apps/jsgotty/clipboard.js +148 -0
  36. package/initramfs/buninu/apps/jsgotty/gotty.js +13 -0
  37. package/initramfs/buninu/apps/jsgotty/package-lock.json +2 -2
  38. package/initramfs/buninu/apps/jsgotty/package.json +1 -1
  39. package/initramfs/buninu/apps/jsgotty/static/css/index.css +14 -1
  40. package/initramfs/buninu/apps/jsgotty/static/index.html +1 -0
  41. package/initramfs/buninu/apps/jsgotty/static/js/gotty.js +187 -23
  42. package/initramfs/buninu/apps/jsgotty/static/js/kitty-keyboard.js +193 -0
  43. package/initramfs/buninu/apps/jsgotty/static/js/kitty.js +115 -7
  44. package/initramfs/buninu/apps/jsgotty/terminal-modes.js +332 -0
  45. package/initramfs/buninu/apps/jsgotty/tests/android-alt.test.js +115 -0
  46. package/initramfs/buninu/apps/jsgotty/tests/arrow-modifiers.test.js +80 -0
  47. package/initramfs/buninu/apps/jsgotty/tests/client-exit.test.mjs +45 -0
  48. package/initramfs/buninu/apps/jsgotty/tests/client-modes.test.mjs +105 -0
  49. package/initramfs/buninu/apps/jsgotty/tests/clipboard-browser.test.js +81 -0
  50. package/initramfs/buninu/apps/jsgotty/tests/clipboard.test.js +75 -0
  51. package/initramfs/buninu/apps/jsgotty/tests/kitty-keyboard-browser.test.js +53 -0
  52. package/initramfs/buninu/apps/jsgotty/tests/kitty-keyboard.test.js +102 -0
  53. package/initramfs/buninu/apps/jsgotty/tests/manual/README.md +20 -0
  54. package/initramfs/buninu/apps/jsgotty/tests/manual/keyboard-collector.cjs +55 -0
  55. package/initramfs/buninu/apps/jsgotty/tests/manual/keyboard-debug.js +74 -0
  56. package/initramfs/buninu/apps/jsgotty/tests/manual/kitty-keyboard.js +80 -0
  57. package/initramfs/buninu/apps/jsgotty/tests/manual/zoom-collector.cjs +55 -0
  58. package/initramfs/buninu/apps/jsgotty/tests/manual/zoom-debug.js +39 -0
  59. package/initramfs/buninu/apps/jsgotty/tests/manual-touch-diagnostics.js +33 -0
  60. package/initramfs/buninu/apps/jsgotty/tests/manual-touch-diagnostics.mjs +22 -0
  61. package/initramfs/buninu/apps/jsgotty/tests/nested-cli-pty.test.mjs +116 -0
  62. package/initramfs/buninu/apps/jsgotty/tests/reconnect-modes-browser.test.js +144 -0
  63. package/initramfs/buninu/apps/jsgotty/tests/reconnect-modes.md +44 -0
  64. package/initramfs/buninu/apps/jsgotty/tests/reconnect-modes.test.js +166 -0
  65. package/initramfs/buninu/apps/jsgotty/tests/touch-drag-browser.test.js +106 -0
  66. package/initramfs/buninu/apps/jsgotty/tests/wheel-browser.test.js +60 -0
  67. package/initramfs/buninu/apps/jsmdcui/CHANGELOG.md +44 -0
  68. package/initramfs/buninu/apps/jsmdcui/package.json +1 -1
  69. package/initramfs/buninu/apps/jsmdcui/src/highlight/go-regexp.js +83 -0
  70. package/initramfs/buninu/apps/jsmdcui/src/highlight/highlighter.js +49 -62
  71. package/initramfs/buninu/apps/jsmdcui/src/highlight/parser.js +8 -5
  72. package/initramfs/buninu/apps/jsmdcui/tests/go-regexp.test.js +98 -0
  73. package/initramfs/buninu/apps/jsmdcui/tests/heading-ids.test.js +21 -16
  74. package/initramfs/buninu/apps/jsmdcui/tests/highlight-regions.test.js +73 -0
  75. package/initramfs/buninu/apps/jsmdcui/tests/id-collision.test.js +32 -9
  76. package/initramfs/buninu/apps/jsmdcui/tests/markdown-behavior.mjs +9 -0
  77. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/NORMAL-HTML.md +46 -0
  78. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/README.md +85 -0
  79. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/REPORT.md +328 -0
  80. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/compare.mjs +75 -0
  81. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/go.mod +5 -0
  82. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/normal-html-report.json +619 -0
  83. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/normal-html.html +9 -0
  84. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/oracle.go +49 -0
  85. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/report.json +2174 -0
  86. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/PowerShell.txt +39 -0
  87. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/ada.txt +25 -0
  88. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/apacheconf.txt +49 -0
  89. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/arduino.txt +38 -0
  90. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/asciidoc.txt +33 -0
  91. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/asm.txt +77 -0
  92. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/ats.txt +48 -0
  93. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/awk.txt +28 -0
  94. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/b.txt +27 -0
  95. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/bat.txt +39 -0
  96. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/c.txt +34 -0
  97. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/caddyfile.txt +14 -0
  98. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/cake.txt +7 -0
  99. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/clojure.txt +18 -0
  100. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/cmake.txt +20 -0
  101. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/coffeescript.txt +32 -0
  102. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/colortest.txt +19 -0
  103. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/conky.txt +12 -0
  104. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/cpp.txt +46 -0
  105. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/crontab.txt +16 -0
  106. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/crystal.txt +28 -0
  107. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/csharp.txt +28 -0
  108. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/css.txt +19 -0
  109. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/csx.txt +7 -0
  110. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/cuda.txt +37 -0
  111. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/cython.txt +22 -0
  112. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/d.txt +52 -0
  113. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/dart.txt +27 -0
  114. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/default.txt +8 -0
  115. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/dockerfile.txt +10 -0
  116. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/dot.txt +15 -0
  117. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/elixir.txt +23 -0
  118. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/elm.txt +20 -0
  119. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/erb.txt +32 -0
  120. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/erlang.txt +23 -0
  121. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/fish.txt +20 -0
  122. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/forth.txt +17 -0
  123. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/fortran.txt +40 -0
  124. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/freebsd-kernel.txt +10 -0
  125. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/fsharp.txt +27 -0
  126. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/gdscript.txt +26 -0
  127. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/gemini.txt +11 -0
  128. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/gentoo-ebuild.txt +28 -0
  129. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/gentoo-etc-portage.txt +14 -0
  130. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/git-commit.txt +19 -0
  131. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/git-config.txt +11 -0
  132. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/git-rebase-todo.txt +10 -0
  133. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/gleam.txt +44 -0
  134. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/glsl.txt +18 -0
  135. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/gnuplot.txt +11 -0
  136. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/go.txt +33 -0
  137. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/godoc.txt +9 -0
  138. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/golo.txt +50 -0
  139. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/gomod.txt +16 -0
  140. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/graphql.txt +20 -0
  141. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/groff.txt +18 -0
  142. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/groovy.txt +42 -0
  143. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/haml.txt +16 -0
  144. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/hare.txt +31 -0
  145. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/haskell.txt +26 -0
  146. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/hc.txt +28 -0
  147. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/html.txt +26 -0
  148. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/html4.txt +20 -0
  149. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/html5.txt +20 -0
  150. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/ini.txt +16 -0
  151. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/inputrc.txt +14 -0
  152. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/java.txt +18 -0
  153. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/javascript.txt +41 -0
  154. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/jinja2.txt +13 -0
  155. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/json.txt +21 -0
  156. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/jsonnet.txt +28 -0
  157. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/julia.txt +24 -0
  158. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/justfile.txt +26 -0
  159. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/keymap.txt +15 -0
  160. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/kickstart.txt +16 -0
  161. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/kotlin.txt +30 -0
  162. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/kvlang.txt +37 -0
  163. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/ledger.txt +13 -0
  164. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/lfe.txt +17 -0
  165. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/lilypond.txt +15 -0
  166. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/lisp.txt +17 -0
  167. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/log.txt +45 -0
  168. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/lua.txt +48 -0
  169. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/mail.txt +17 -0
  170. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/makefile.txt +25 -0
  171. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/man.txt +12 -0
  172. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/markdown.txt +21 -0
  173. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/mc.txt +11 -0
  174. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/meson.txt +29 -0
  175. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/micro.txt +25 -0
  176. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/mpdconf.txt +13 -0
  177. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/msbuild.txt +7 -0
  178. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/nanorc.txt +16 -0
  179. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/nftables.txt +22 -0
  180. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/nginx.txt +17 -0
  181. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/nim.txt +23 -0
  182. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/nix.txt +15 -0
  183. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/nu.txt +92 -0
  184. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/objc.txt +36 -0
  185. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/ocaml.txt +25 -0
  186. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/octave.txt +35 -0
  187. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/odin.txt +35 -0
  188. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/pascal.txt +22 -0
  189. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/patch.txt +13 -0
  190. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/peg.txt +16 -0
  191. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/perl.txt +27 -0
  192. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/php.txt +44 -0
  193. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/pkg-config.txt +12 -0
  194. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/po.txt +12 -0
  195. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/pony.txt +29 -0
  196. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/pov.txt +17 -0
  197. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/privoxy-action.txt +14 -0
  198. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/privoxy-config.txt +10 -0
  199. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/privoxy-filter.txt +12 -0
  200. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/proto.txt +22 -0
  201. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/prql.txt +42 -0
  202. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/puppet.txt +22 -0
  203. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/python2.txt +24 -0
  204. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/python3.txt +28 -0
  205. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/r.txt +16 -0
  206. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/raku.txt +19 -0
  207. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/reST.txt +18 -0
  208. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/renpy.txt +11 -0
  209. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/rpmspec.txt +31 -0
  210. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/ruby.txt +34 -0
  211. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/rust.txt +27 -0
  212. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/sage.txt +24 -0
  213. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/scad.txt +23 -0
  214. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/scala.txt +16 -0
  215. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/sed.txt +12 -0
  216. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/sh.txt +20 -0
  217. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/sls.txt +15 -0
  218. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/smalltalk.txt +28 -0
  219. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/solidity.txt +26 -0
  220. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/sql.txt +35 -0
  221. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/stata.txt +32 -0
  222. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/svelte.txt +10 -0
  223. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/swift.txt +53 -0
  224. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/systemd.txt +15 -0
  225. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/tcl.txt +17 -0
  226. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/terraform.txt +28 -0
  227. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/tex.txt +15 -0
  228. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/toml.txt +31 -0
  229. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/twig.txt +29 -0
  230. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/typescript.txt +32 -0
  231. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/v.txt +47 -0
  232. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/vala.txt +22 -0
  233. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/verilog.txt +37 -0
  234. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/vhdl.txt +37 -0
  235. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/vi.txt +17 -0
  236. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/vue.txt +29 -0
  237. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/xml.txt +14 -0
  238. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/xresources.txt +14 -0
  239. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/yaml.txt +19 -0
  240. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/yum.txt +12 -0
  241. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/zig.txt +24 -0
  242. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/zscript.txt +31 -0
  243. package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/zsh.txt +21 -0
  244. package/initramfs/buninu/package.json +1 -1
  245. package/initramfs/init.js +19 -3
  246. package/initramfs/lib/bunterm/clipboard.js +14 -0
  247. package/initramfs/lib/bunterm/commands.js +37 -0
  248. package/initramfs/lib/bunterm/fps.js +38 -0
  249. package/initramfs/lib/bunterm/images.js +14 -6
  250. package/initramfs/lib/bunterm/input.js +58 -15
  251. package/initramfs/lib/bunterm/keyboard.js +62 -0
  252. package/initramfs/lib/bunterm/keycodes.js +104 -0
  253. package/initramfs/lib/bunterm/kitty-keyboard.cjs +195 -0
  254. package/initramfs/lib/bunterm/raw-protocol.js +111 -0
  255. package/initramfs/lib/bunterm/renderer.js +116 -28
  256. package/initramfs/lib/bunterm/selection.js +60 -0
  257. package/initramfs/lib/bunterm/terminal.js +157 -12
  258. package/initramfs/lib/bunterm/vt-menu.js +181 -0
  259. package/initramfs/lib/bunterm/vt.js +27 -1
  260. package/initramfs/lib/canvas.js +99 -0
  261. package/initramfs/lib/chvt.js +31 -0
  262. package/initramfs/lib/fbdev.js +32 -8
  263. package/initramfs/lib/gpu.js +77 -0
  264. package/initramfs/lib/mapped-frame.js +28 -0
  265. package/initramfs/lib/raw-image.js +71 -0
  266. package/initramfs/lib/xdg-open.js +42 -0
  267. package/initramfs/usr/share/doc/buninu-linux/bunterm.md +85 -11
  268. package/initramfs/usr/share/doc/buninu-linux/chvt.md +34 -0
  269. package/initramfs/usr/share/doc/buninu-linux/xdg-open.md +43 -0
  270. package/package.json +1 -1
  271. package/scripts/arch.js +7 -5
  272. package/scripts/arch.sh +5 -5
  273. package/scripts/build.js +16 -3
  274. package/scripts/fetch-gpu.js +105 -0
  275. package/scripts/fetch.js +11 -1
  276. package/scripts/gpu-firmware.json +22 -0
  277. package/scripts/modules.js +4 -1
  278. package/scripts/npm-packages.md +18 -17
  279. package/test/bunterm-fps.test.js +17 -0
  280. package/test/bunterm-image-bytes.test.js +15 -0
  281. package/test/bunterm-keyboard.test.js +116 -0
  282. package/test/bunterm-mapped-lifetime.test.js +147 -0
  283. package/test/bunterm-next-vt.test.js +9 -0
  284. package/test/bunterm-raw-protocol.test.js +39 -0
  285. package/test/bunterm-renderer.test.js +167 -0
  286. package/test/bunterm-selection.test.js +38 -0
  287. package/test/bunterm-vt-menu.test.js +178 -0
  288. package/test/chroot-bind.test.js +40 -2
  289. package/test/chvt.test.js +46 -0
  290. package/test/fbdev-sync.test.js +42 -0
  291. package/test/fetch-npm.test.js +2 -2
  292. package/test/gpu.test.js +155 -0
  293. package/test/image-size.test.js +17 -0
  294. package/test/manual-bunterm-image-paths.js +31 -0
  295. package/test/mount-libc-lifetime.test.js +50 -0
  296. package/test/no-gpu.test.js +43 -0
  297. package/test/readme-cli.test.js +29 -0
  298. package/test/stage-npm.test.js +11 -4
  299. package/test/xdg-open.test.js +55 -0
@@ -30,6 +30,7 @@
30
30
  <script src="./js/windows_bridge.js"></script>
31
31
  <script src="./js/zmodem.js"></script>
32
32
  <script src="./js/xterm-addon-unicode11.js"></script>
33
+ <script src="./js/kitty-keyboard.js"></script>
33
34
  <script src="./js/gotty.js"></script>
34
35
 
35
36
 
@@ -12168,7 +12168,8 @@
12168
12168
  (t.msgSetWindowTitle = "3"),
12169
12169
  (t.msgSetPreferences = "4"),
12170
12170
  (t.msgSetReconnect = "5"),
12171
- (t.msgSetBufferSize = "6"));
12171
+ (t.msgSetBufferSize = "6"),
12172
+ (t.msgRestoreModes = "m"));
12172
12173
  t.WebTTY = class {
12173
12174
  term;
12174
12175
  connectionFactory;
@@ -12193,6 +12194,9 @@
12193
12194
  this.reconnectDeadline = 0;
12194
12195
  this.reconnectAttempts = 0;
12195
12196
  this.zmodemExpectedSeq = 0;
12197
+ this.term.onClipboard?.(data => {
12198
+ if (!this.disconnected) this.connection.send("C" + data);
12199
+ });
12196
12200
  }
12197
12201
  open() {
12198
12202
  let e;
@@ -12330,6 +12334,9 @@
12330
12334
  const e = JSON.parse(i);
12331
12335
  this.term.setPreferences(e);
12332
12336
  break;
12337
+ case t.msgRestoreModes:
12338
+ this.term.applySessionModes(JSON.parse(i));
12339
+ break;
12333
12340
  case t.msgSetReconnect:
12334
12341
  const r = JSON.parse(i);
12335
12342
  "number" == typeof r
@@ -12540,9 +12547,33 @@
12540
12547
  })),
12541
12548
  (this.fitAddOn = new s.FitAddon()),
12542
12549
  (this.zmodemAddon = new a.ZModemAddon({
12543
- toTerminal: (e) => this.term.write(e),
12550
+ toTerminal: (e) => this.writeTerminal(e),
12544
12551
  toServer: (e) => this.sendInput(e),
12545
12552
  })),
12553
+ (this.kittyKeyboard = new globalThis.GoTTYKittyKeyboard.KittyKeyboard(this.term, {
12554
+ android: /Android/i.test(navigator.userAgent),
12555
+ })),
12556
+ this.term.parser.registerOscHandler(52, data => {
12557
+ if (!this.disconnected && data.length <= 1048576) this.clipboardHandler?.(data);
12558
+ return true;
12559
+ }),
12560
+ this.term.parser.registerOscHandler(777, data => {
12561
+ const match = /^jsgotty-modes;([a-f0-9]{32})$/.exec(data);
12562
+ if (!match) {
12563
+ const restore = /^jsgotty-kitty-v1;(normal|alternate);(\d{1,2});(\d{1,2}(?:,\d{1,2})*)?$/.exec(data);
12564
+ if (!restore) return false;
12565
+ const flags = +restore[2], stack = restore[3] ? restore[3].split(',').map(Number) : [];
12566
+ if (flags > 31 || stack.length > 32 || stack.some(n => n > 31)) return true;
12567
+ this.kittyKeyboard.states[restore[1]] = {flags: flags & 11, stack: stack.map(n => n & 11)};
12568
+ return true;
12569
+ }
12570
+ this.term.input("\x1b]777;jsgotty-modes;" + match[1] + ";" +
12571
+ btoa(JSON.stringify({...this.sessionModes(), kittyRestore: 1})) + "\x07", false);
12572
+ return true;
12573
+ }),
12574
+ this.term.attachCustomKeyEventHandler((event) =>
12575
+ this.kittyKeyboard.handle(event) && this.handleAndroidAltKey(event),
12576
+ ),
12546
12577
  this.setPreferences(t),
12547
12578
  (() => {
12548
12579
  try {
@@ -12594,12 +12625,73 @@
12594
12625
  ));
12595
12626
  }),
12596
12627
  this.term.open(e),
12628
+ this.kittyKeyboard.attach(this.term.textarea),
12629
+ this.term.textarea?.addEventListener("blur", () => {
12630
+ this.androidAltDownKeys?.clear();
12631
+ }),
12597
12632
  this.term.focus(),
12598
12633
  this.resizeListener(),
12599
12634
  window.addEventListener("resize", () => {
12600
12635
  this.resizeListener();
12601
12636
  }));
12602
12637
  }
12638
+ // Android can translate physical Alt shortcuts into accent dead keys.
12639
+ // Resolve printable physical keys before xterm's composition handling.
12640
+ handleAndroidAltKey(event) {
12641
+ if (!/Android/i.test(navigator.userAgent)) return true;
12642
+ let code = event.code;
12643
+ // Some Android IMEs omit code and swallow the dead-key keydown,
12644
+ // but still deliver keyup with a usable legacy keyCode.
12645
+ if (!code) {
12646
+ if (event.keyCode >= 65 && event.keyCode <= 90)
12647
+ code = "Key" + String.fromCharCode(event.keyCode);
12648
+ else if (event.keyCode >= 48 && event.keyCode <= 57)
12649
+ code = "Digit" + String.fromCharCode(event.keyCode);
12650
+ else code = {
12651
+ 32: "Space", 186: "Semicolon", 187: "Equal", 188: "Comma",
12652
+ 189: "Minus", 190: "Period", 191: "Slash", 192: "Backquote",
12653
+ 219: "BracketLeft", 220: "Backslash", 221: "BracketRight", 222: "Quote",
12654
+ }[event.keyCode];
12655
+ }
12656
+ this.androidAltDownKeys ??= new Set();
12657
+ const alreadySent = event.type === "keyup" && this.androidAltDownKeys.delete(code);
12658
+ if (
12659
+ !["keydown", "keypress", "keyup"].includes(event.type) ||
12660
+ !event.altKey || event.ctrlKey || event.metaKey ||
12661
+ event.isComposing || event.getModifierState?.("AltGraph") ||
12662
+ (event.type === "keyup" && event.key !== "Dead")
12663
+ ) return true;
12664
+
12665
+ let character;
12666
+ if (/^Key[A-Z]$/.test(code)) {
12667
+ const letter = code.slice(3);
12668
+ character = event.shiftKey ? letter : letter.toLowerCase();
12669
+ } else if (/^Digit[0-9]$/.test(code)) {
12670
+ const digit = code.slice(5);
12671
+ character = event.shiftKey ? ")!@#$%^&*("[Number(digit)] : digit;
12672
+ } else {
12673
+ const punctuation = {
12674
+ Backquote: ["`", "~"], Minus: ["-", "_"], Equal: ["=", "+"],
12675
+ BracketLeft: ["[", "{"], BracketRight: ["]", "}"],
12676
+ Backslash: ["\\", "|"], Semicolon: [";", ":"], Quote: ["'", '"'],
12677
+ Comma: [",", "<"], Period: [".", ">"], Slash: ["/", "?"],
12678
+ Space: [" ", " "],
12679
+ };
12680
+ character = Object.hasOwn(punctuation, code)
12681
+ ? punctuation[code][event.shiftKey ? 1 : 0]
12682
+ : undefined;
12683
+ }
12684
+ if (character === undefined) return true;
12685
+ event.preventDefault();
12686
+ event.stopPropagation();
12687
+ if (event.type === "keydown") {
12688
+ this.androidAltDownKeys.add(code);
12689
+ this.term.input("\x1b" + character, true);
12690
+ } else if (event.type === "keyup" && !alreadySent) {
12691
+ this.term.input("\x1b" + character, true);
12692
+ }
12693
+ return false;
12694
+ }
12603
12695
  info() {
12604
12696
  return { columns: this.term.cols, rows: this.term.rows };
12605
12697
  }
@@ -12609,7 +12701,73 @@
12609
12701
  getMessage() {
12610
12702
  return this.message;
12611
12703
  }
12704
+ enqueueTerminal(task) {
12705
+ this.terminalTasks ||= [];
12706
+ this.terminalTasks.push(task);
12707
+ if (this.terminalBusy) return;
12708
+ this.terminalBusy = true;
12709
+ const next = () => {
12710
+ const task = this.terminalTasks.shift();
12711
+ if (!task) { this.terminalBusy = false; return; }
12712
+ task(next);
12713
+ };
12714
+ next();
12715
+ }
12716
+ writeTerminal(data) {
12717
+ this.enqueueTerminal(done => this.term.write(data, done));
12718
+ }
12719
+ onClipboard(handler) {
12720
+ this.clipboardHandler = handler;
12721
+ }
12722
+ sessionModes() {
12723
+ const core = this.term._core;
12724
+ return {dec: {...core.coreService.decPrivateModes},
12725
+ mouse: core.coreMouseService.activeProtocol,
12726
+ encoding: core.coreMouseService.activeEncoding,
12727
+ cursorHidden: !!core.coreService.isCursorHidden,
12728
+ alternate: this.term.buffer.active.type === "alternate",
12729
+ kitty: JSON.parse(JSON.stringify(this.kittyKeyboard.states))};
12730
+ }
12731
+ applySessionModes(state) {
12732
+ this.enqueueTerminal(done => this.term.write("", () => this.restoreSessionModes(state, done)));
12733
+ }
12734
+ restoreSessionModes(state, done) {
12735
+ if (!state || !state.dec) { done(); return; }
12736
+ const core = this.term._core;
12737
+ const dec = core.coreService.decPrivateModes;
12738
+ const mouse = core.coreMouseService;
12739
+ // A socket-only reconnect keeps xterm's modes, so send only differences:
12740
+ // DECOM homes the cursor and 1049 overwrites the saved cursor.
12741
+ let sequence = "";
12742
+ const alternate = this.term.buffer.active.type === "alternate";
12743
+ if (!!state.alternate !== alternate) sequence += `\x1b[?1049${state.alternate ? "h" : "l"}`;
12744
+ const flags = {1:"applicationCursorKeys", 6:"origin", 7:"wraparound", 45:"reverseWraparound",
12745
+ 66:"applicationKeypad", 1004:"sendFocus", 2004:"bracketedPasteMode"};
12746
+ for (const [mode, name] of Object.entries(flags))
12747
+ if (!!state.dec[name] !== !!dec[name]) sequence += `\x1b[?${mode}${state.dec[name] ? "h" : "l"}`;
12748
+ if (!!state.cursorHidden !== !!core.coreService.isCursorHidden)
12749
+ sequence += `\x1b[?25${state.cursorHidden ? "l" : "h"}`;
12750
+ if (state.mouse !== mouse.activeProtocol) {
12751
+ const modes = {X10:9, VT200:1000, DRAG:1002, ANY:1003};
12752
+ sequence += modes[state.mouse] ? `\x1b[?${modes[state.mouse]}h` : "\x1b[?1000l";
12753
+ }
12754
+ if (state.encoding !== mouse.activeEncoding) {
12755
+ const modes = {SGR:1006, SGR_PIXELS:1016};
12756
+ sequence += modes[state.encoding] ? `\x1b[?${modes[state.encoding]}h` : "\x1b[?1006l";
12757
+ }
12758
+ const complete = () => {
12759
+ // Assigned rather than replayed so the push stack never doubles; the server
12760
+ // keeps every flag, so mask to the ones kitty-keyboard.js implements.
12761
+ const supported = (s) => ({flags: s.flags & 11, stack: s.stack.map((f) => f & 11)});
12762
+ if (state.kitty?.normal && state.kitty?.alternate)
12763
+ this.kittyKeyboard.states = {normal: supported(state.kitty.normal), alternate: supported(state.kitty.alternate)};
12764
+ done();
12765
+ };
12766
+ if (sequence) this.term.write(sequence, complete);
12767
+ else complete();
12768
+ }
12612
12769
  setDisconnected(e) {
12770
+ if (e) this.kittyKeyboard.clearHeld(false);
12613
12771
  this.disconnected = !!e;
12614
12772
  }
12615
12773
  setReconnectAction(e) {
@@ -12721,9 +12879,12 @@
12721
12879
  this.term.blur();
12722
12880
  }
12723
12881
  reset() {
12882
+ // Reconnecting the transport does not reset the running PTY's modes.
12883
+ this.kittyKeyboard.clearHeld(false);
12724
12884
  (this.removeMessage(), this.term.clear());
12725
12885
  }
12726
12886
  close() {
12887
+ this.kittyKeyboard.dispose();
12727
12888
  (window.removeEventListener("resize", this.resizeListener),
12728
12889
  this.term.dispose());
12729
12890
  }
@@ -15836,8 +15997,15 @@
15836
15997
  !1 === e._customWheelEventHandler(t)
15837
15998
  )
15838
15999
  return !1;
15839
- if (0 === e.viewport.getLinesScrolled(t))
15840
- return !1;
16000
+ // Preserve both axes of diagonal wheel/touch gestures.
16001
+ // CoreMouseService already encodes wheel actions 2/3 as 66/67.
16002
+ if (t.deltaX) e.coreMouseService.triggerMouseEvent({
16003
+ col: i.col, row: i.row, x: i.x, y: i.y,
16004
+ button: 4, action: t.deltaX < 0 ? 2 : 3,
16005
+ ctrl: t.ctrlKey, alt: t.altKey, shift: t.shiftKey,
16006
+ });
16007
+ if (0 === e.viewport.getLinesScrolled(t, true))
16008
+ return !!t.deltaX;
15841
16009
  ((s = t.deltaY < 0 ? 0 : 1), (r = 4));
15842
16010
  break;
15843
16011
  default:
@@ -16811,8 +16979,9 @@
16811
16979
  }
16812
16980
  return { bufferElements: s, cursorElement: i };
16813
16981
  }
16814
- getLinesScrolled(e) {
16815
- if (0 === e.deltaY || e.shiftKey) return 0;
16982
+ getLinesScrolled(e, mouseReporting = false) {
16983
+ // Shift belongs to the remote application while mouse reporting is active.
16984
+ if (0 === e.deltaY || (e.shiftKey && !mouseReporting)) return 0;
16816
16985
  let t = this._applyScrollModifier(e.deltaY, e);
16817
16986
  return (
16818
16987
  e.deltaMode === WheelEvent.DOM_DELTA_PIXEL
@@ -26746,39 +26915,32 @@
26746
26915
  case 37:
26747
26916
  if (e.metaKey) break;
26748
26917
  a
26749
- ? ((o.key = r.C0.ESC + "[1;" + (a + 1) + "D"),
26750
- o.key === r.C0.ESC + "[1;3D" &&
26751
- (o.key = r.C0.ESC + (i ? "b" : "[1;5D")))
26918
+ ? (o.key = r.C0.ESC + "[1;" + (a + 1) + "D")
26752
26919
  : (o.key = t ? r.C0.ESC + "OD" : r.C0.ESC + "[D");
26753
26920
  break;
26754
26921
  case 39:
26755
26922
  if (e.metaKey) break;
26756
26923
  a
26757
- ? ((o.key = r.C0.ESC + "[1;" + (a + 1) + "C"),
26758
- o.key === r.C0.ESC + "[1;3C" &&
26759
- (o.key = r.C0.ESC + (i ? "f" : "[1;5C")))
26924
+ ? (o.key = r.C0.ESC + "[1;" + (a + 1) + "C")
26760
26925
  : (o.key = t ? r.C0.ESC + "OC" : r.C0.ESC + "[C");
26761
26926
  break;
26762
26927
  case 38:
26763
26928
  if (e.metaKey) break;
26764
26929
  a
26765
- ? ((o.key = r.C0.ESC + "[1;" + (a + 1) + "A"),
26766
- i ||
26767
- o.key !== r.C0.ESC + "[1;3A" ||
26768
- (o.key = r.C0.ESC + "[1;5A"))
26930
+ ? (o.key = r.C0.ESC + "[1;" + (a + 1) + "A")
26769
26931
  : (o.key = t ? r.C0.ESC + "OA" : r.C0.ESC + "[A");
26770
26932
  break;
26771
26933
  case 40:
26772
26934
  if (e.metaKey) break;
26773
26935
  a
26774
- ? ((o.key = r.C0.ESC + "[1;" + (a + 1) + "B"),
26775
- i ||
26776
- o.key !== r.C0.ESC + "[1;3B" ||
26777
- (o.key = r.C0.ESC + "[1;5B"))
26936
+ ? (o.key = r.C0.ESC + "[1;" + (a + 1) + "B")
26778
26937
  : (o.key = t ? r.C0.ESC + "OB" : r.C0.ESC + "[B");
26779
26938
  break;
26780
26939
  case 45:
26781
- e.shiftKey || e.ctrlKey || (o.key = r.C0.ESC + "[2~");
26940
+ e.shiftKey || e.ctrlKey ||
26941
+ (o.key = e.altKey
26942
+ ? r.C0.ESC + "[2;" + (a + 1) + "~"
26943
+ : r.C0.ESC + "[2~");
26782
26944
  break;
26783
26945
  case 46:
26784
26946
  o.key = a
@@ -26802,14 +26964,14 @@
26802
26964
  case 33:
26803
26965
  e.shiftKey
26804
26966
  ? (o.type = 2)
26805
- : e.ctrlKey
26967
+ : e.ctrlKey || e.altKey
26806
26968
  ? (o.key = r.C0.ESC + "[5;" + (a + 1) + "~")
26807
26969
  : (o.key = r.C0.ESC + "[5~");
26808
26970
  break;
26809
26971
  case 34:
26810
26972
  e.shiftKey
26811
26973
  ? (o.type = 3)
26812
- : e.ctrlKey
26974
+ : e.ctrlKey || e.altKey
26813
26975
  ? (o.key = r.C0.ESC + "[6;" + (a + 1) + "~")
26814
26976
  : (o.key = r.C0.ESC + "[6~");
26815
26977
  break;
@@ -26927,6 +27089,8 @@
26927
27089
  ))
26928
27090
  : 56 === e.keyCode
26929
27091
  ? (o.key = r.C0.DEL)
27092
+ : "/" === e.key
27093
+ ? (o.key = r.C0.US)
26930
27094
  : 219 === e.keyCode
26931
27095
  ? (o.key = r.C0.ESC)
26932
27096
  : 220 === e.keyCode
@@ -0,0 +1,193 @@
1
+ // Kitty keyboard transport for the shipped xterm wrapper (no build step).
2
+ // Spec: https://sw.kovidgoyal.net/kitty/keyboard-protocol/
3
+ (function (root) {
4
+ 'use strict';
5
+ // Supported progressive enhancements: disambiguation, event types, all keys.
6
+ // Do not advertise alternate-layout/text reporting until those are implemented.
7
+ const SUPPORTED = 1 | 2 | 8;
8
+ const functional = {
9
+ Escape:[27,'u'], Enter:[13,'u'], Tab:[9,'u'], Backspace:[127,'u'],
10
+ Insert:[2,'~'], Delete:[3,'~'], ArrowLeft:[1,'D'], ArrowRight:[1,'C'],
11
+ ArrowUp:[1,'A'], ArrowDown:[1,'B'], PageUp:[5,'~'], PageDown:[6,'~'],
12
+ Home:[1,'H'], End:[1,'F'], CapsLock:[57358,'u'], ScrollLock:[57359,'u'],
13
+ NumLock:[57360,'u'], PrintScreen:[57361,'u'], Pause:[57362,'u'], ContextMenu:[57363,'u'],
14
+ MediaPlay:[57428,'u'], MediaPause:[57429,'u'], MediaPlayPause:[57430,'u'],
15
+ MediaStop:[57432,'u'], MediaFastForward:[57433,'u'], MediaRewind:[57434,'u'],
16
+ MediaTrackNext:[57435,'u'], MediaTrackPrevious:[57436,'u'], MediaRecord:[57437,'u'],
17
+ AudioVolumeDown:[57438,'u'], AudioVolumeUp:[57439,'u'], AudioVolumeMute:[57440,'u'],
18
+ };
19
+ [11,12,13,14,15,17,18,19,20,21,23,24].forEach((n,i) => functional['F'+(i+1)] = [n,'~']);
20
+ for (let i=13;i<=35;i++) functional['F'+i] = [57376+i-13,'u'];
21
+ const punctuation = {
22
+ Backquote:['`','~'], Minus:['-','_'], Equal:['=','+'], BracketLeft:['[','{'],
23
+ BracketRight:[']','}'], Backslash:['\\','|'], Semicolon:[';',':'], Quote:["'",'"'],
24
+ Comma:[',','<'], Period:['.','>'], Slash:['/','?'], Space:[' ',' '],
25
+ };
26
+ const modifiers = {Shift:[1,57441], Control:[4,57442], Alt:[2,57443], Meta:[8,57444],
27
+ OS:[8,57444], Super:[8,57444], Hyper:[16,57445], AltGraph:[0,57453]};
28
+ const has = (object,key) => Object.prototype.hasOwnProperty.call(object,key);
29
+ const lock = (e,name) => Boolean(e.getModifierState?.(name));
30
+ function physicalCode(e) {
31
+ if (e.code && e.code !== 'Unidentified') return e.code;
32
+ if (e.keyCode>=65 && e.keyCode<=90) return 'Key'+String.fromCharCode(e.keyCode);
33
+ if (e.keyCode>=48 && e.keyCode<=57) return 'Digit'+String.fromCharCode(e.keyCode);
34
+ return ({32:'Space',186:'Semicolon',187:'Equal',188:'Comma',189:'Minus',190:'Period',
35
+ 191:'Slash',192:'Backquote',219:'BracketLeft',220:'Backslash',221:'BracketRight',222:'Quote'})[e.keyCode] || '';
36
+ }
37
+ function baseCharacter(e, android) {
38
+ const code=physicalCode(e);
39
+ // Android's Alt accent conversion must not turn an E/I/N/U shortcut into a dead key.
40
+ const recover=android && e.altKey && !lock(e,'AltGraph');
41
+ if (recover || ([...e.key || ''].length===1 && e.key.codePointAt(0)<32)) {
42
+ if (/^Key[A-Z]$/.test(code)) return code.slice(3).toLowerCase();
43
+ if (/^Digit[0-9]$/.test(code)) return code.slice(5);
44
+ if (has(punctuation,code)) return punctuation[code][0];
45
+ }
46
+ if ([...e.key || ''].length!==1) return null;
47
+ if (e.shiftKey) {
48
+ if (has(punctuation,code) && punctuation[code][1]===e.key) return punctuation[code][0];
49
+ if (/^Digit[0-9]$/.test(code) && ')!@#$%^&*('[Number(code.slice(5))]===e.key) return code.slice(5);
50
+ }
51
+ const lower=e.key.toLowerCase();
52
+ return [...lower].length===1 ? lower : e.key;
53
+ }
54
+ function keyDefinition(e, flags, android) {
55
+ if (has(modifiers,e.key)) {
56
+ const [bit,left]=modifiers[e.key];
57
+ const right=e.location===2 || /Right$/.test(e.code || '');
58
+ return {number:left+(right && e.key!=='AltGraph'?6:0),suffix:'u',modifier:bit};
59
+ }
60
+ if ((flags & 9) && (e.location===3 || /^Numpad/.test(e.code || ''))) {
61
+ const numpad={NumpadDecimal:57409,NumpadDivide:57410,NumpadMultiply:57411,
62
+ NumpadSubtract:57412,NumpadAdd:57413,NumpadEnter:57414,NumpadEqual:57415,
63
+ NumpadComma:57416};
64
+ const nav={ArrowLeft:57417,ArrowRight:57418,ArrowUp:57419,ArrowDown:57420,
65
+ PageUp:57421,PageDown:57422,Home:57423,End:57424,Insert:57425,Delete:57426,Clear:57427};
66
+ const number=has(nav,e.key)?nav[e.key]:/^Numpad[0-9]$/.test(e.code || '')
67
+ ?57399+Number(e.code.slice(6)):numpad[e.code];
68
+ if (number) return {number,suffix:'u'};
69
+ }
70
+ if (has(functional,e.key)) {
71
+ const [number,suffix]=functional[e.key];
72
+ return {number,suffix,recovery:['Enter','Tab','Backspace'].includes(e.key)};
73
+ }
74
+ const ch=baseCharacter(e,android);
75
+ return ch===null?null:{number:ch.codePointAt(0),suffix:'u',text:true};
76
+ }
77
+ class KittyKeyboard {
78
+ constructor(term, {android=false}={}) {
79
+ this.term=term; this.android=android; this.disposables=[];
80
+ this.metaKeys=new Set(); this.down=new Map(); this.suppressed=new Set(); this.reset();
81
+ const register=(prefix,fn) => this.disposables.push(term.parser.registerCsiHandler({prefix,final:'u'},p=>{fn(p);return true;}));
82
+ const value=(p,i,fallback=0) => Number.isInteger(p[i])?p[i]:fallback;
83
+ register('?',()=>term.input(`\x1b[?${this.flags}u`,false));
84
+ register('>',p=>{const s=this.state;s.stack.push(s.flags);if(s.stack.length>32)s.stack.shift();s.flags=value(p,0)&SUPPORTED;});
85
+ register('<',p=>{const s=this.state;let count=Math.min(value(p,0)||1,33);while(count--)s.flags=s.stack.pop()??0;});
86
+ register('=',p=>{const s=this.state,f=value(p,0)&SUPPORTED,m=value(p,1)||1;if(m===1)s.flags=f;else if(m===2)s.flags|=f;else if(m===3)s.flags&=~f;});
87
+ this.disposables.push(term.parser.registerEscHandler({final:'c'},()=>{this.reset();return false;}));
88
+ this.disposables.push(term.parser.registerCsiHandler({intermediates:'!',final:'p'},()=>{this.reset();return false;}));
89
+ }
90
+ get state() { return this.states[this.term.buffer.active.type==='alternate'?'alternate':'normal']; }
91
+ get flags() { return this.state.flags; }
92
+ reset() {
93
+ this.states={normal:{flags:0,stack:[]},alternate:{flags:0,stack:[]}};
94
+ this.clearHeld(false);
95
+ }
96
+ clearHeld(report=true) {
97
+ // Release keys reported to the client before losing focus, avoiding stuck remote keys.
98
+ if (report && (this.flags & 2)) for (const key of this.down.values()) {
99
+ if(key.reported) this.term.input(this.sequence(key.def,0,3),true);
100
+ }
101
+ this.metaKeys.clear();this.down.clear();this.suppressed.clear();this.suppressKeypress=false;
102
+ }
103
+ attach(element) {
104
+ const doc=element.ownerDocument, win=doc.defaultView;
105
+ const blur=()=>this.clearHeld();
106
+ const visibility=()=>{if(doc.hidden)this.clearHeld();};
107
+ element.addEventListener('blur',blur);win.addEventListener('blur',blur);
108
+ doc.addEventListener('visibilitychange',visibility);
109
+ this.disposables.push({dispose:()=>{element.removeEventListener('blur',blur);win.removeEventListener('blur',blur);doc.removeEventListener('visibilitychange',visibility);}});
110
+ }
111
+ dispose() {this.clearHeld(false);for(const d of this.disposables)d.dispose();}
112
+ sequence(def,bits,type) {
113
+ const event=(this.flags&2) && type!==1?':'+type:'';
114
+ const mods=bits+1;
115
+ if(def.suffix!=='u' && mods===1 && !event)
116
+ return '\x1b['+(def.number===1?'':def.number)+def.suffix;
117
+ return `\x1b[${def.number}${mods!==1||event?';'+mods+event:''}${def.suffix}`;
118
+ }
119
+ handle(event) {
120
+ if (!['keydown','keyup','keypress'].includes(event.type)) return true;
121
+ const identity=physicalCode(event)||event.key;
122
+ const metaKey=['Meta','OS','Super'].includes(event.key);
123
+ if(this.android && metaKey) {
124
+ if(event.type==='keydown')this.metaKeys.add(event.code||String(event.location||0));
125
+ if(event.type==='keyup')this.metaKeys.delete(event.code||String(event.location||0));
126
+ }
127
+ // Patch only this terminal's Android event, preserving the native DOM event.
128
+ if(this.android && this.metaKeys.size && !event.metaKey) {
129
+ const original=event.getModifierState?.bind(event);
130
+ Object.defineProperties(event,{
131
+ metaKey:{configurable:true,value:true},
132
+ getModifierState:{configurable:true,value:name=>name==='Meta'||Boolean(original?.(name))},
133
+ });
134
+ }
135
+ if(!this.flags || this.term.options.disableStdin) return true;
136
+ const consume=()=>{event.preventDefault();event.stopPropagation();return false;};
137
+ if(event.type==='keypress')return this.suppressKeypress?consume():true;
138
+ let previous=this.down.get(identity);
139
+ if(event.type==='keyup') {
140
+ // Some Android IMEs emit only the release of an Alt dead key. Recover
141
+ // that chord here too, never falling back to legacy ESC text in Kitty mode.
142
+ if(!previous && this.android && event.altKey && event.key==='Dead' &&
143
+ !event.isComposing && !lock(event,'AltGraph') && (this.flags&9)) {
144
+ const def=keyDefinition(event,this.flags,this.android);
145
+ if(def) {
146
+ this.term.input(this.sequence(def,this.bits(event),1),true);
147
+ previous={def,reported:true};this.suppressed.add(identity);
148
+ }
149
+ }
150
+ this.down.delete(identity);
151
+ const suppressed=this.suppressed.delete(identity);
152
+ this.suppressKeypress=false;
153
+ if(previous?.reported && (this.flags&2)) {
154
+ let bits=this.bits(event);
155
+ if(previous.def.modifier && ![...this.down.values()].some(k=>k.def.modifier===previous.def.modifier)) bits &= ~previous.def.modifier;
156
+ if(metaKey && this.metaKeys.size) bits|=8;
157
+ this.term.input(this.sequence(previous.def,bits,3),true);
158
+ }
159
+ return suppressed?consume():true;
160
+ }
161
+ this.suppressKeypress=false;
162
+ if(event.isComposing || event.keyCode===229 && event.key==='Unidentified')return true;
163
+ if(event.key==='Dead' && !(this.android && event.altKey && !lock(event,'AltGraph')))return true;
164
+ const def=keyDefinition(event,this.flags,this.android);
165
+ if(!def)return true;
166
+ let bits=this.bits(event);
167
+ if(def.modifier!==undefined) {
168
+ if(!(this.flags&8))return true;
169
+ bits|=def.modifier;
170
+ }
171
+ const all=Boolean(this.flags&8);
172
+ // Enter/Tab/Backspace remain recovery keys unless modified or report-all is requested.
173
+ if(!all && def.recovery && !(bits&~192))return true;
174
+ const shortcut=Boolean(bits&62);
175
+ if(def.text && !all && !(this.flags&1 && shortcut))return true;
176
+ // With only event reporting requested, leave legacy printable shortcuts untouched.
177
+ if(def.text && !all && !(this.flags&1))return true;
178
+ const type=event.repeat?2:1;
179
+ this.down.set(identity,{def,reported:!(def.recovery && !all)});this.suppressed.add(identity);this.suppressKeypress=true;
180
+ this.term.input(this.sequence(def,bits,type),true);
181
+ return consume();
182
+ }
183
+ bits(e) {
184
+ const altgr=lock(e,'AltGraph');
185
+ return (e.shiftKey?1:0)|(!altgr&&e.altKey?2:0)|(!altgr&&e.ctrlKey?4:0)|
186
+ (e.metaKey || this.android&&this.metaKeys.size?8:0)|
187
+ (lock(e,'Hyper')?16:0)|(lock(e,'CapsLock')?64:0)|(lock(e,'NumLock')?128:0);
188
+ }
189
+ }
190
+ const api={KittyKeyboard,SUPPORTED};
191
+ if(typeof module==='object' && module.exports)module.exports=api;
192
+ else root.GoTTYKittyKeyboard=api;
193
+ })(globalThis);