@draht/tui 2026.5.12 → 2026.7.7-1

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 (97) hide show
  1. package/dist/autocomplete.d.ts +5 -1
  2. package/dist/autocomplete.d.ts.map +1 -1
  3. package/dist/autocomplete.js +16 -7
  4. package/dist/autocomplete.js.map +1 -1
  5. package/dist/components/box.d.ts +1 -1
  6. package/dist/components/box.d.ts.map +1 -1
  7. package/dist/components/box.js.map +1 -1
  8. package/dist/components/cancellable-loader.d.ts +1 -1
  9. package/dist/components/cancellable-loader.d.ts.map +1 -1
  10. package/dist/components/cancellable-loader.js.map +1 -1
  11. package/dist/components/editor.d.ts +14 -3
  12. package/dist/components/editor.d.ts.map +1 -1
  13. package/dist/components/editor.js +234 -175
  14. package/dist/components/editor.js.map +1 -1
  15. package/dist/components/image.d.ts +2 -2
  16. package/dist/components/image.d.ts.map +1 -1
  17. package/dist/components/image.js +31 -11
  18. package/dist/components/image.js.map +1 -1
  19. package/dist/components/input.d.ts +1 -1
  20. package/dist/components/input.d.ts.map +1 -1
  21. package/dist/components/input.js +7 -55
  22. package/dist/components/input.js.map +1 -1
  23. package/dist/components/loader.d.ts +17 -7
  24. package/dist/components/loader.d.ts.map +1 -1
  25. package/dist/components/loader.js +34 -14
  26. package/dist/components/loader.js.map +1 -1
  27. package/dist/components/markdown.d.ts +11 -7
  28. package/dist/components/markdown.d.ts.map +1 -1
  29. package/dist/components/markdown.js +119 -102
  30. package/dist/components/markdown.js.map +1 -1
  31. package/dist/components/select-list.d.ts +1 -1
  32. package/dist/components/select-list.d.ts.map +1 -1
  33. package/dist/components/select-list.js.map +1 -1
  34. package/dist/components/settings-list.d.ts +1 -1
  35. package/dist/components/settings-list.d.ts.map +1 -1
  36. package/dist/components/settings-list.js.map +1 -1
  37. package/dist/components/spacer.d.ts +1 -1
  38. package/dist/components/spacer.d.ts.map +1 -1
  39. package/dist/components/spacer.js.map +1 -1
  40. package/dist/components/text.d.ts +1 -1
  41. package/dist/components/text.d.ts.map +1 -1
  42. package/dist/components/text.js.map +1 -1
  43. package/dist/components/truncated-text.d.ts +1 -1
  44. package/dist/components/truncated-text.d.ts.map +1 -1
  45. package/dist/components/truncated-text.js.map +1 -1
  46. package/dist/editor-component.d.ts +2 -2
  47. package/dist/editor-component.d.ts.map +1 -1
  48. package/dist/editor-component.js.map +1 -1
  49. package/dist/fuzzy.d.ts +1 -1
  50. package/dist/fuzzy.d.ts.map +1 -1
  51. package/dist/fuzzy.js +5 -2
  52. package/dist/fuzzy.js.map +1 -1
  53. package/dist/index.d.ts +23 -22
  54. package/dist/index.d.ts.map +1 -1
  55. package/dist/index.js +4 -2
  56. package/dist/index.js.map +1 -1
  57. package/dist/keybindings.d.ts +2 -2
  58. package/dist/keybindings.d.ts.map +1 -1
  59. package/dist/keybindings.js +1 -1
  60. package/dist/keybindings.js.map +1 -1
  61. package/dist/keys.d.ts +19 -5
  62. package/dist/keys.d.ts.map +1 -1
  63. package/dist/keys.js +82 -33
  64. package/dist/keys.js.map +1 -1
  65. package/dist/native-modifiers.d.ts +3 -0
  66. package/dist/native-modifiers.d.ts.map +1 -0
  67. package/dist/native-modifiers.js +53 -0
  68. package/dist/native-modifiers.js.map +1 -0
  69. package/dist/stdin-buffer.d.ts +2 -0
  70. package/dist/stdin-buffer.d.ts.map +1 -1
  71. package/dist/stdin-buffer.js +48 -4
  72. package/dist/stdin-buffer.js.map +1 -1
  73. package/dist/terminal-colors.d.ts +10 -0
  74. package/dist/terminal-colors.d.ts.map +1 -0
  75. package/dist/terminal-colors.js +59 -0
  76. package/dist/terminal-colors.js.map +1 -0
  77. package/dist/terminal-image.d.ts +23 -1
  78. package/dist/terminal-image.d.ts.map +1 -1
  79. package/dist/terminal-image.js +98 -16
  80. package/dist/terminal-image.js.map +1 -1
  81. package/dist/terminal.d.ts +36 -10
  82. package/dist/terminal.d.ts.map +1 -1
  83. package/dist/terminal.js +212 -64
  84. package/dist/terminal.js.map +1 -1
  85. package/dist/tui.d.ts +51 -5
  86. package/dist/tui.d.ts.map +1 -1
  87. package/dist/tui.js +431 -32
  88. package/dist/tui.js.map +1 -1
  89. package/dist/utils.d.ts +8 -1
  90. package/dist/utils.d.ts.map +1 -1
  91. package/dist/utils.js +143 -43
  92. package/dist/utils.js.map +1 -1
  93. package/dist/word-navigation.d.ts +25 -0
  94. package/dist/word-navigation.d.ts.map +1 -0
  95. package/dist/word-navigation.js +96 -0
  96. package/dist/word-navigation.js.map +1 -0
  97. package/package.json +1 -1
package/dist/keys.js CHANGED
@@ -40,8 +40,8 @@ export function isKittyProtocolActive() {
40
40
  * Usage:
41
41
  * - Key.escape, Key.enter, Key.tab, etc. for special keys
42
42
  * - Key.backtick, Key.comma, Key.period, etc. for symbol keys
43
- * - Key.ctrl("c"), Key.alt("x") for single modifier
44
- * - Key.ctrlShift("p"), Key.ctrlAlt("x") for combined modifiers
43
+ * - Key.ctrl("c"), Key.alt("x"), Key.super("k") for single modifiers
44
+ * - Key.ctrlShift("p"), Key.ctrlAlt("x"), Key.ctrlSuper("k") for combined modifiers
45
45
  */
46
46
  export const Key = {
47
47
  // Special keys
@@ -111,6 +111,7 @@ export const Key = {
111
111
  ctrl: (key) => `ctrl+${key}`,
112
112
  shift: (key) => `shift+${key}`,
113
113
  alt: (key) => `alt+${key}`,
114
+ super: (key) => `super+${key}`,
114
115
  // Combined modifiers
115
116
  ctrlShift: (key) => `ctrl+shift+${key}`,
116
117
  shiftCtrl: (key) => `shift+ctrl+${key}`,
@@ -118,8 +119,15 @@ export const Key = {
118
119
  altCtrl: (key) => `alt+ctrl+${key}`,
119
120
  shiftAlt: (key) => `shift+alt+${key}`,
120
121
  altShift: (key) => `alt+shift+${key}`,
122
+ ctrlSuper: (key) => `ctrl+super+${key}`,
123
+ superCtrl: (key) => `super+ctrl+${key}`,
124
+ shiftSuper: (key) => `shift+super+${key}`,
125
+ superShift: (key) => `super+shift+${key}`,
126
+ altSuper: (key) => `alt+super+${key}`,
127
+ superAlt: (key) => `super+alt+${key}`,
121
128
  // Triple modifiers
122
129
  ctrlShiftAlt: (key) => `ctrl+shift+alt+${key}`,
130
+ ctrlShiftSuper: (key) => `ctrl+shift+super+${key}`,
123
131
  };
124
132
  // =============================================================================
125
133
  // Constants
@@ -161,6 +169,7 @@ const MODIFIERS = {
161
169
  shift: 1,
162
170
  alt: 2,
163
171
  ctrl: 4,
172
+ super: 8,
164
173
  };
165
174
  const LOCK_MASK = 64 + 128; // Caps Lock + Num Lock
166
175
  const CODEPOINTS = {
@@ -217,6 +226,13 @@ const KITTY_FUNCTIONAL_KEY_EQUIVALENTS = new Map([
217
226
  function normalizeKittyFunctionalCodepoint(codepoint) {
218
227
  return KITTY_FUNCTIONAL_KEY_EQUIVALENTS.get(codepoint) ?? codepoint;
219
228
  }
229
+ function normalizeShiftedLetterIdentityCodepoint(codepoint, modifier) {
230
+ const effectiveModifier = modifier & ~LOCK_MASK;
231
+ if ((effectiveModifier & MODIFIERS.shift) !== 0 && codepoint >= 65 && codepoint <= 90) {
232
+ return codepoint + 32;
233
+ }
234
+ return codepoint;
235
+ }
220
236
  const LEGACY_KEY_SEQUENCES = {
221
237
  up: ["\x1b[A", "\x1bOA"],
222
238
  down: ["\x1b[B", "\x1bOB"],
@@ -468,8 +484,8 @@ function matchesKittySequence(data, expectedCodepoint, expectedModifier) {
468
484
  // Check if modifiers match
469
485
  if (actualMod !== expectedMod)
470
486
  return false;
471
- const normalizedCodepoint = normalizeKittyFunctionalCodepoint(parsed.codepoint);
472
- const normalizedExpectedCodepoint = normalizeKittyFunctionalCodepoint(expectedCodepoint);
487
+ const normalizedCodepoint = normalizeShiftedLetterIdentityCodepoint(normalizeKittyFunctionalCodepoint(parsed.codepoint), parsed.modifier);
488
+ const normalizedExpectedCodepoint = normalizeShiftedLetterIdentityCodepoint(normalizeKittyFunctionalCodepoint(expectedCodepoint), expectedModifier);
473
489
  // Primary match: codepoint matches directly after normalizing functional keys
474
490
  if (normalizedCodepoint === normalizedExpectedCodepoint)
475
491
  return true;
@@ -562,12 +578,16 @@ function isDigitKey(key) {
562
578
  function matchesPrintableModifyOtherKeys(data, expectedKeycode, expectedModifier) {
563
579
  if (expectedModifier === 0)
564
580
  return false;
565
- return matchesModifyOtherKeys(data, expectedKeycode, expectedModifier);
581
+ const parsed = parseModifyOtherKeysSequence(data);
582
+ if (!parsed || parsed.modifier !== expectedModifier)
583
+ return false;
584
+ return (normalizeShiftedLetterIdentityCodepoint(parsed.codepoint, parsed.modifier) ===
585
+ normalizeShiftedLetterIdentityCodepoint(expectedKeycode, expectedModifier));
566
586
  }
567
587
  function formatKeyNameWithModifiers(keyName, modifier) {
568
588
  const mods = [];
569
589
  const effectiveMod = modifier & ~LOCK_MASK;
570
- const supportedModifierMask = MODIFIERS.shift | MODIFIERS.ctrl | MODIFIERS.alt;
590
+ const supportedModifierMask = MODIFIERS.shift | MODIFIERS.ctrl | MODIFIERS.alt | MODIFIERS.super;
571
591
  if ((effectiveMod & ~supportedModifierMask) !== 0)
572
592
  return undefined;
573
593
  if (effectiveMod & MODIFIERS.shift)
@@ -576,6 +596,8 @@ function formatKeyNameWithModifiers(keyName, modifier) {
576
596
  mods.push("ctrl");
577
597
  if (effectiveMod & MODIFIERS.alt)
578
598
  mods.push("alt");
599
+ if (effectiveMod & MODIFIERS.super)
600
+ mods.push("super");
579
601
  return mods.length > 0 ? `${mods.join("+")}+${keyName}` : keyName;
580
602
  }
581
603
  function parseKeyId(keyId) {
@@ -588,6 +610,7 @@ function parseKeyId(keyId) {
588
610
  ctrl: parts.includes("ctrl"),
589
611
  shift: parts.includes("shift"),
590
612
  alt: parts.includes("alt"),
613
+ super: parts.includes("super"),
591
614
  };
592
615
  }
593
616
  /**
@@ -599,9 +622,10 @@ function parseKeyId(keyId) {
599
622
  * - Ctrl combinations: "ctrl+c", "ctrl+z", etc.
600
623
  * - Shift combinations: "shift+tab", "shift+enter"
601
624
  * - Alt combinations: "alt+enter", "alt+backspace"
602
- * - Combined modifiers: "shift+ctrl+p", "ctrl+alt+x"
625
+ * - Super combinations: "super+k", "super+enter"
626
+ * - Combined modifiers: "shift+ctrl+p", "ctrl+alt+x", "ctrl+super+k"
603
627
  *
604
- * Use the Key helper for autocomplete: Key.ctrl("c"), Key.escape, Key.ctrlShift("p")
628
+ * Use the Key helper for autocomplete: Key.ctrl("c"), Key.escape, Key.ctrlShift("p"), Key.super("k")
605
629
  *
606
630
  * @param data - Raw input data from terminal
607
631
  * @param keyId - Key identifier (e.g., "ctrl+c", "escape", Key.ctrl("c"))
@@ -610,7 +634,7 @@ export function matchesKey(data, keyId) {
610
634
  const parsed = parseKeyId(keyId);
611
635
  if (!parsed)
612
636
  return false;
613
- const { key, ctrl, shift, alt } = parsed;
637
+ const { key, ctrl, shift, alt, super: superModifier } = parsed;
614
638
  let modifier = 0;
615
639
  if (shift)
616
640
  modifier |= MODIFIERS.shift;
@@ -618,6 +642,8 @@ export function matchesKey(data, keyId) {
618
642
  modifier |= MODIFIERS.alt;
619
643
  if (ctrl)
620
644
  modifier |= MODIFIERS.ctrl;
645
+ if (superModifier)
646
+ modifier |= MODIFIERS.super;
621
647
  switch (key) {
622
648
  case "escape":
623
649
  case "esc":
@@ -628,10 +654,10 @@ export function matchesKey(data, keyId) {
628
654
  matchesModifyOtherKeys(data, CODEPOINTS.escape, 0));
629
655
  case "space":
630
656
  if (!_kittyProtocolActive) {
631
- if (ctrl && !alt && !shift && data === "\x00") {
657
+ if (modifier === MODIFIERS.ctrl && data === "\x00") {
632
658
  return true;
633
659
  }
634
- if (alt && !ctrl && !shift && data === "\x1b ") {
660
+ if (modifier === MODIFIERS.alt && data === "\x1b ") {
635
661
  return true;
636
662
  }
637
663
  }
@@ -643,7 +669,7 @@ export function matchesKey(data, keyId) {
643
669
  return (matchesKittySequence(data, CODEPOINTS.space, modifier) ||
644
670
  matchesModifyOtherKeys(data, CODEPOINTS.space, modifier));
645
671
  case "tab":
646
- if (shift && !ctrl && !alt) {
672
+ if (modifier === MODIFIERS.shift) {
647
673
  return (data === "\x1b[Z" ||
648
674
  matchesKittySequence(data, CODEPOINTS.tab, MODIFIERS.shift) ||
649
675
  matchesModifyOtherKeys(data, CODEPOINTS.tab, MODIFIERS.shift));
@@ -655,7 +681,7 @@ export function matchesKey(data, keyId) {
655
681
  matchesModifyOtherKeys(data, CODEPOINTS.tab, modifier));
656
682
  case "enter":
657
683
  case "return":
658
- if (shift && !ctrl && !alt) {
684
+ if (modifier === MODIFIERS.shift) {
659
685
  // CSI u sequences (standard Kitty protocol)
660
686
  if (matchesKittySequence(data, CODEPOINTS.enter, MODIFIERS.shift) ||
661
687
  matchesKittySequence(data, CODEPOINTS.kpEnter, MODIFIERS.shift)) {
@@ -673,7 +699,7 @@ export function matchesKey(data, keyId) {
673
699
  }
674
700
  return false;
675
701
  }
676
- if (alt && !ctrl && !shift) {
702
+ if (modifier === MODIFIERS.alt) {
677
703
  // CSI u sequences (standard Kitty protocol)
678
704
  if (matchesKittySequence(data, CODEPOINTS.enter, MODIFIERS.alt) ||
679
705
  matchesKittySequence(data, CODEPOINTS.kpEnter, MODIFIERS.alt)) {
@@ -701,14 +727,14 @@ export function matchesKey(data, keyId) {
701
727
  matchesKittySequence(data, CODEPOINTS.kpEnter, modifier) ||
702
728
  matchesModifyOtherKeys(data, CODEPOINTS.enter, modifier));
703
729
  case "backspace":
704
- if (alt && !ctrl && !shift) {
730
+ if (modifier === MODIFIERS.alt) {
705
731
  if (data === "\x1b\x7f" || data === "\x1b\b") {
706
732
  return true;
707
733
  }
708
734
  return (matchesKittySequence(data, CODEPOINTS.backspace, MODIFIERS.alt) ||
709
735
  matchesModifyOtherKeys(data, CODEPOINTS.backspace, MODIFIERS.alt));
710
736
  }
711
- if (ctrl && !alt && !shift) {
737
+ if (modifier === MODIFIERS.ctrl) {
712
738
  // Legacy raw 0x08 is ambiguous: it can be Ctrl+Backspace on Windows
713
739
  // Terminal or plain Backspace on other terminals, while also
714
740
  // overlapping with Ctrl+H.
@@ -784,7 +810,7 @@ export function matchesKey(data, keyId) {
784
810
  }
785
811
  return matchesKittySequence(data, FUNCTIONAL_CODEPOINTS.pageDown, modifier);
786
812
  case "up":
787
- if (alt && !ctrl && !shift) {
813
+ if (modifier === MODIFIERS.alt) {
788
814
  return data === "\x1bp" || matchesKittySequence(data, ARROW_CODEPOINTS.up, MODIFIERS.alt);
789
815
  }
790
816
  if (modifier === 0) {
@@ -796,7 +822,7 @@ export function matchesKey(data, keyId) {
796
822
  }
797
823
  return matchesKittySequence(data, ARROW_CODEPOINTS.up, modifier);
798
824
  case "down":
799
- if (alt && !ctrl && !shift) {
825
+ if (modifier === MODIFIERS.alt) {
800
826
  return data === "\x1bn" || matchesKittySequence(data, ARROW_CODEPOINTS.down, MODIFIERS.alt);
801
827
  }
802
828
  if (modifier === 0) {
@@ -808,13 +834,13 @@ export function matchesKey(data, keyId) {
808
834
  }
809
835
  return matchesKittySequence(data, ARROW_CODEPOINTS.down, modifier);
810
836
  case "left":
811
- if (alt && !ctrl && !shift) {
837
+ if (modifier === MODIFIERS.alt) {
812
838
  return (data === "\x1b[1;3D" ||
813
839
  (!_kittyProtocolActive && data === "\x1bB") ||
814
840
  data === "\x1bb" ||
815
841
  matchesKittySequence(data, ARROW_CODEPOINTS.left, MODIFIERS.alt));
816
842
  }
817
- if (ctrl && !alt && !shift) {
843
+ if (modifier === MODIFIERS.ctrl) {
818
844
  return (data === "\x1b[1;5D" ||
819
845
  matchesLegacyModifierSequence(data, "left", MODIFIERS.ctrl) ||
820
846
  matchesKittySequence(data, ARROW_CODEPOINTS.left, MODIFIERS.ctrl));
@@ -828,13 +854,13 @@ export function matchesKey(data, keyId) {
828
854
  }
829
855
  return matchesKittySequence(data, ARROW_CODEPOINTS.left, modifier);
830
856
  case "right":
831
- if (alt && !ctrl && !shift) {
857
+ if (modifier === MODIFIERS.alt) {
832
858
  return (data === "\x1b[1;3C" ||
833
859
  (!_kittyProtocolActive && data === "\x1bF") ||
834
860
  data === "\x1bf" ||
835
861
  matchesKittySequence(data, ARROW_CODEPOINTS.right, MODIFIERS.alt));
836
862
  }
837
- if (ctrl && !alt && !shift) {
863
+ if (modifier === MODIFIERS.ctrl) {
838
864
  return (data === "\x1b[1;5C" ||
839
865
  matchesLegacyModifierSequence(data, "right", MODIFIERS.ctrl) ||
840
866
  matchesKittySequence(data, ARROW_CODEPOINTS.right, MODIFIERS.ctrl));
@@ -872,27 +898,30 @@ export function matchesKey(data, keyId) {
872
898
  const rawCtrl = rawCtrlChar(key);
873
899
  const isLetter = key >= "a" && key <= "z";
874
900
  const isDigit = isDigitKey(key);
875
- if (ctrl && alt && !shift && !_kittyProtocolActive && rawCtrl) {
876
- // Legacy: ctrl+alt+key is ESC followed by the control character
877
- return data === `\x1b${rawCtrl}`;
901
+ if (modifier === MODIFIERS.ctrl + MODIFIERS.alt && !_kittyProtocolActive && rawCtrl) {
902
+ // Legacy: ctrl+alt+key is ESC followed by the control character.
903
+ // If that legacy form does not match, continue so CSI-u and
904
+ // modifyOtherKeys sequences from tmux can still be recognized.
905
+ if (data === `\x1b${rawCtrl}`)
906
+ return true;
878
907
  }
879
- if (alt && !ctrl && !shift && !_kittyProtocolActive && (isLetter || isDigit)) {
908
+ if (modifier === MODIFIERS.alt && !_kittyProtocolActive && (isLetter || isDigit)) {
880
909
  // Legacy: alt+letter/digit is ESC followed by the key
881
910
  if (data === `\x1b${key}`)
882
911
  return true;
883
912
  }
884
- if (ctrl && !shift && !alt) {
913
+ if (modifier === MODIFIERS.ctrl) {
885
914
  // Legacy: ctrl+key sends the control character
886
915
  if (rawCtrl && data === rawCtrl)
887
916
  return true;
888
917
  return (matchesKittySequence(data, codepoint, MODIFIERS.ctrl) ||
889
918
  matchesPrintableModifyOtherKeys(data, codepoint, MODIFIERS.ctrl));
890
919
  }
891
- if (ctrl && shift && !alt) {
920
+ if (modifier === MODIFIERS.shift + MODIFIERS.ctrl) {
892
921
  return (matchesKittySequence(data, codepoint, MODIFIERS.shift + MODIFIERS.ctrl) ||
893
922
  matchesPrintableModifyOtherKeys(data, codepoint, MODIFIERS.shift + MODIFIERS.ctrl));
894
923
  }
895
- if (shift && !ctrl && !alt) {
924
+ if (modifier === MODIFIERS.shift) {
896
925
  // Legacy: shift+letter produces uppercase
897
926
  if (isLetter && data === key.toUpperCase())
898
927
  return true;
@@ -916,15 +945,16 @@ export function matchesKey(data, keyId) {
916
945
  */
917
946
  function formatParsedKey(codepoint, modifier, baseLayoutKey) {
918
947
  const normalizedCodepoint = normalizeKittyFunctionalCodepoint(codepoint);
948
+ const identityCodepoint = normalizeShiftedLetterIdentityCodepoint(normalizedCodepoint, modifier);
919
949
  // Use base layout key only when codepoint is not a recognized Latin
920
950
  // letter (a-z), digit (0-9), or symbol (/, -, [, ;, etc.). For those,
921
951
  // the codepoint is authoritative regardless of physical key position.
922
952
  // This prevents remapped layouts (Dvorak, Colemak, xremap, etc.) from
923
953
  // reporting the wrong key name based on the QWERTY physical position.
924
- const isLatinLetter = normalizedCodepoint >= 97 && normalizedCodepoint <= 122; // a-z
925
- const isDigit = normalizedCodepoint >= 48 && normalizedCodepoint <= 57; // 0-9
926
- const isKnownSymbol = SYMBOL_KEYS.has(String.fromCharCode(normalizedCodepoint));
927
- const effectiveCodepoint = isLatinLetter || isDigit || isKnownSymbol ? normalizedCodepoint : (baseLayoutKey ?? normalizedCodepoint);
954
+ const isLatinLetter = identityCodepoint >= 97 && identityCodepoint <= 122; // a-z
955
+ const isDigit = identityCodepoint >= 48 && identityCodepoint <= 57; // 0-9
956
+ const isKnownSymbol = SYMBOL_KEYS.has(String.fromCharCode(identityCodepoint));
957
+ const effectiveCodepoint = isLatinLetter || isDigit || isKnownSymbol ? identityCodepoint : (baseLayoutKey ?? identityCodepoint);
928
958
  let keyName;
929
959
  if (effectiveCodepoint === CODEPOINTS.escape)
930
960
  keyName = "escape";
@@ -1121,4 +1151,23 @@ export function decodeKittyPrintable(data) {
1121
1151
  return undefined;
1122
1152
  }
1123
1153
  }
1154
+ function decodeModifyOtherKeysPrintable(data) {
1155
+ const parsed = parseModifyOtherKeysSequence(data);
1156
+ if (!parsed)
1157
+ return undefined;
1158
+ const modifier = parsed.modifier & ~LOCK_MASK;
1159
+ if ((modifier & ~MODIFIERS.shift) !== 0)
1160
+ return undefined;
1161
+ if (!Number.isFinite(parsed.codepoint) || parsed.codepoint < 32)
1162
+ return undefined;
1163
+ try {
1164
+ return String.fromCodePoint(parsed.codepoint);
1165
+ }
1166
+ catch {
1167
+ return undefined;
1168
+ }
1169
+ }
1170
+ export function decodePrintableKey(data) {
1171
+ return decodeKittyPrintable(data) ?? decodeModifyOtherKeysPrintable(data);
1172
+ }
1124
1173
  //# sourceMappingURL=keys.js.map