@teaui/core 1.1.4

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 (203) hide show
  1. package/.dist/Buffer.d.ts +21 -0
  2. package/.dist/Buffer.js +140 -0
  3. package/.dist/Buffer.js.map +1 -0
  4. package/.dist/Color.d.ts +7 -0
  5. package/.dist/Color.js +39 -0
  6. package/.dist/Color.js.map +1 -0
  7. package/.dist/Container.d.ts +21 -0
  8. package/.dist/Container.js +138 -0
  9. package/.dist/Container.js.map +1 -0
  10. package/.dist/Screen.d.ts +54 -0
  11. package/.dist/Screen.js +278 -0
  12. package/.dist/Screen.js.map +1 -0
  13. package/.dist/Style.d.ts +46 -0
  14. package/.dist/Style.js +433 -0
  15. package/.dist/Style.js.map +1 -0
  16. package/.dist/System.d.ts +13 -0
  17. package/.dist/System.js +26 -0
  18. package/.dist/System.js.map +1 -0
  19. package/.dist/Theme.d.ts +56 -0
  20. package/.dist/Theme.js +157 -0
  21. package/.dist/Theme.js.map +1 -0
  22. package/.dist/UI.d.ts +2 -0
  23. package/.dist/UI.js +28 -0
  24. package/.dist/UI.js.map +1 -0
  25. package/.dist/View.d.ts +99 -0
  26. package/.dist/View.js +374 -0
  27. package/.dist/View.js.map +1 -0
  28. package/.dist/Viewport.d.ts +89 -0
  29. package/.dist/Viewport.js +295 -0
  30. package/.dist/Viewport.js.map +1 -0
  31. package/.dist/ansi.d.ts +31 -0
  32. package/.dist/ansi.js +139 -0
  33. package/.dist/ansi.js.map +1 -0
  34. package/.dist/components/Accordion.d.ts +47 -0
  35. package/.dist/components/Accordion.js +294 -0
  36. package/.dist/components/Accordion.js.map +1 -0
  37. package/.dist/components/Box.d.ts +67 -0
  38. package/.dist/components/Box.js +211 -0
  39. package/.dist/components/Box.js.map +1 -0
  40. package/.dist/components/Button.d.ts +28 -0
  41. package/.dist/components/Button.js +118 -0
  42. package/.dist/components/Button.js.map +1 -0
  43. package/.dist/components/Checkbox.d.ts +31 -0
  44. package/.dist/components/Checkbox.js +106 -0
  45. package/.dist/components/Checkbox.js.map +1 -0
  46. package/.dist/components/Collapsible.d.ts +32 -0
  47. package/.dist/components/Collapsible.js +109 -0
  48. package/.dist/components/Collapsible.js.map +1 -0
  49. package/.dist/components/CollapsibleText.d.ts +21 -0
  50. package/.dist/components/CollapsibleText.js +113 -0
  51. package/.dist/components/CollapsibleText.js.map +1 -0
  52. package/.dist/components/Digits.d.ts +20 -0
  53. package/.dist/components/Digits.js +843 -0
  54. package/.dist/components/Digits.js.map +1 -0
  55. package/.dist/components/Drawer.d.ts +44 -0
  56. package/.dist/components/Drawer.js +473 -0
  57. package/.dist/components/Drawer.js.map +1 -0
  58. package/.dist/components/Dropdown.d.ts +61 -0
  59. package/.dist/components/Dropdown.js +367 -0
  60. package/.dist/components/Dropdown.js.map +1 -0
  61. package/.dist/components/Header.d.ts +25 -0
  62. package/.dist/components/Header.js +106 -0
  63. package/.dist/components/Header.js.map +1 -0
  64. package/.dist/components/HotKey.d.ts +14 -0
  65. package/.dist/components/HotKey.js +31 -0
  66. package/.dist/components/HotKey.js.map +1 -0
  67. package/.dist/components/Input.d.ts +45 -0
  68. package/.dist/components/Input.js +1109 -0
  69. package/.dist/components/Input.js.map +1 -0
  70. package/.dist/components/Log.d.ts +16 -0
  71. package/.dist/components/Log.js +122 -0
  72. package/.dist/components/Log.js.map +1 -0
  73. package/.dist/components/Progress.d.ts +21 -0
  74. package/.dist/components/Progress.js +200 -0
  75. package/.dist/components/Progress.js.map +1 -0
  76. package/.dist/components/Scrollable.d.ts +50 -0
  77. package/.dist/components/Scrollable.js +226 -0
  78. package/.dist/components/Scrollable.js.map +1 -0
  79. package/.dist/components/ScrollableList.d.ts +70 -0
  80. package/.dist/components/ScrollableList.js +354 -0
  81. package/.dist/components/ScrollableList.js.map +1 -0
  82. package/.dist/components/Separator.d.ts +21 -0
  83. package/.dist/components/Separator.js +67 -0
  84. package/.dist/components/Separator.js.map +1 -0
  85. package/.dist/components/Slider.d.ts +60 -0
  86. package/.dist/components/Slider.js +341 -0
  87. package/.dist/components/Slider.js.map +1 -0
  88. package/.dist/components/Space.d.ts +19 -0
  89. package/.dist/components/Space.js +45 -0
  90. package/.dist/components/Space.js.map +1 -0
  91. package/.dist/components/Spinner.d.ts +16 -0
  92. package/.dist/components/Spinner.js +48 -0
  93. package/.dist/components/Spinner.js.map +1 -0
  94. package/.dist/components/Stack.d.ts +33 -0
  95. package/.dist/components/Stack.js +285 -0
  96. package/.dist/components/Stack.js.map +1 -0
  97. package/.dist/components/Tabs.d.ts +52 -0
  98. package/.dist/components/Tabs.js +312 -0
  99. package/.dist/components/Tabs.js.map +1 -0
  100. package/.dist/components/Text.d.ts +35 -0
  101. package/.dist/components/Text.js +242 -0
  102. package/.dist/components/Text.js.map +1 -0
  103. package/.dist/components/ToggleGroup.d.ts +26 -0
  104. package/.dist/components/ToggleGroup.js +279 -0
  105. package/.dist/components/ToggleGroup.js.map +1 -0
  106. package/.dist/components/Tree.d.ts +21 -0
  107. package/.dist/components/Tree.js +233 -0
  108. package/.dist/components/Tree.js.map +1 -0
  109. package/.dist/components/Window.d.ts +6 -0
  110. package/.dist/components/Window.js +17 -0
  111. package/.dist/components/Window.js.map +1 -0
  112. package/.dist/components/fonts.d.ts +2 -0
  113. package/.dist/components/fonts.js +39 -0
  114. package/.dist/components/fonts.js.map +1 -0
  115. package/.dist/components/index.d.ts +27 -0
  116. package/.dist/components/index.js +48 -0
  117. package/.dist/components/index.js.map +1 -0
  118. package/.dist/components/types.d.ts +6 -0
  119. package/.dist/components/types.js +20 -0
  120. package/.dist/components/types.js.map +1 -0
  121. package/.dist/components/utility/TrackMouse.d.ts +16 -0
  122. package/.dist/components/utility/TrackMouse.js +53 -0
  123. package/.dist/components/utility/TrackMouse.js.map +1 -0
  124. package/.dist/components/utility/index.d.ts +1 -0
  125. package/.dist/components/utility/index.js +6 -0
  126. package/.dist/components/utility/index.js.map +1 -0
  127. package/.dist/events/index.d.ts +12 -0
  128. package/.dist/events/index.js +20 -0
  129. package/.dist/events/index.js.map +1 -0
  130. package/.dist/events/key.d.ts +15 -0
  131. package/.dist/events/key.js +105 -0
  132. package/.dist/events/key.js.map +1 -0
  133. package/.dist/events/mouse.d.ts +65 -0
  134. package/.dist/events/mouse.js +68 -0
  135. package/.dist/events/mouse.js.map +1 -0
  136. package/.dist/events/window.d.ts +6 -0
  137. package/.dist/events/window.js +3 -0
  138. package/.dist/events/window.js.map +1 -0
  139. package/.dist/geometry.d.ts +178 -0
  140. package/.dist/geometry.js +315 -0
  141. package/.dist/geometry.js.map +1 -0
  142. package/.dist/iTerm2.d.ts +20 -0
  143. package/.dist/iTerm2.js +60 -0
  144. package/.dist/iTerm2.js.map +1 -0
  145. package/.dist/index.d.ts +18 -0
  146. package/.dist/index.js +37 -0
  147. package/.dist/index.js.map +1 -0
  148. package/.dist/inspect.d.ts +2 -0
  149. package/.dist/inspect.js +118 -0
  150. package/.dist/inspect.js.map +1 -0
  151. package/.dist/log.d.ts +12 -0
  152. package/.dist/log.js +56 -0
  153. package/.dist/log.js.map +1 -0
  154. package/.dist/managers/FocusManager.d.ts +28 -0
  155. package/.dist/managers/FocusManager.js +143 -0
  156. package/.dist/managers/FocusManager.js.map +1 -0
  157. package/.dist/managers/ModalManager.d.ts +10 -0
  158. package/.dist/managers/ModalManager.js +67 -0
  159. package/.dist/managers/ModalManager.js.map +1 -0
  160. package/.dist/managers/MouseManager.d.ts +21 -0
  161. package/.dist/managers/MouseManager.js +313 -0
  162. package/.dist/managers/MouseManager.js.map +1 -0
  163. package/.dist/managers/TickManager.d.ts +11 -0
  164. package/.dist/managers/TickManager.js +63 -0
  165. package/.dist/managers/TickManager.js.map +1 -0
  166. package/.dist/sys/alias.d.ts +470 -0
  167. package/.dist/sys/alias.js +487 -0
  168. package/.dist/sys/alias.js.map +1 -0
  169. package/.dist/sys/colors.d.ts +10 -0
  170. package/.dist/sys/colors.js +285 -0
  171. package/.dist/sys/colors.js.map +1 -0
  172. package/.dist/sys/gpmclient.d.ts +11 -0
  173. package/.dist/sys/gpmclient.js +193 -0
  174. package/.dist/sys/gpmclient.js.map +1 -0
  175. package/.dist/sys/index.d.ts +4 -0
  176. package/.dist/sys/index.js +41 -0
  177. package/.dist/sys/index.js.map +1 -0
  178. package/.dist/sys/keys.d.ts +4 -0
  179. package/.dist/sys/keys.js +531 -0
  180. package/.dist/sys/keys.js.map +1 -0
  181. package/.dist/sys/program.d.ts +356 -0
  182. package/.dist/sys/program.js +3739 -0
  183. package/.dist/sys/program.js.map +1 -0
  184. package/.dist/sys/tput.d.ts +297 -0
  185. package/.dist/sys/tput.js +2708 -0
  186. package/.dist/sys/tput.js.map +1 -0
  187. package/.dist/sys/unicode.d.ts +11 -0
  188. package/.dist/sys/unicode.js +619 -0
  189. package/.dist/sys/unicode.js.map +1 -0
  190. package/.dist/sys/usr/linux +0 -0
  191. package/.dist/sys/usr/windows-ansi +0 -0
  192. package/.dist/sys/usr/xterm +0 -0
  193. package/.dist/sys/usr/xterm-256color +0 -0
  194. package/.dist/sys/usr/xterm.termcap +243 -0
  195. package/.dist/sys/usr/xterm.terminfo +1977 -0
  196. package/.dist/terminal.d.ts +7 -0
  197. package/.dist/terminal.js +3 -0
  198. package/.dist/terminal.js.map +1 -0
  199. package/.dist/util.d.ts +22 -0
  200. package/.dist/util.js +79 -0
  201. package/.dist/util.js.map +1 -0
  202. package/LICENSE +24 -0
  203. package/package.json +49 -0
@@ -0,0 +1,1109 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Input = void 0;
4
+ const sys_1 = require("../sys");
5
+ const events_1 = require("../events");
6
+ const View_1 = require("../View");
7
+ const Style_1 = require("../Style");
8
+ const geometry_1 = require("../geometry");
9
+ const fonts_1 = require("./fonts");
10
+ const NL_SIGIL = '⤦';
11
+ /**
12
+ * Text input. Supports selection, word movement via alt+←→, single and multiline
13
+ * input, and wrapped lines.
14
+ */
15
+ class Input extends View_1.View {
16
+ /**
17
+ * Array of graphemes, with pre-calculated length
18
+ */
19
+ #placeholder = [];
20
+ #printableLines = [];
21
+ /**
22
+ * Cached after assignment - this is converted to #chars and #lines
23
+ */
24
+ #value = '';
25
+ /**
26
+ * For easy edit operations. Gets converted to #lines for printing.
27
+ */
28
+ #chars = [];
29
+ #wrappedLines = [];
30
+ // formatting options
31
+ #wrap = false;
32
+ #multiline = false;
33
+ #font = 'default';
34
+ #onChange;
35
+ #onSubmit;
36
+ // Printable width
37
+ #maxLineWidth = 0;
38
+ #cursor = { start: 0, end: 0 };
39
+ #visibleWidth = 0;
40
+ constructor(props = {}) {
41
+ super(props);
42
+ this.#update(props);
43
+ this.#cursor = { start: this.#chars.length, end: this.#chars.length };
44
+ }
45
+ update(props) {
46
+ this.#update(props);
47
+ super.update(props);
48
+ }
49
+ #update({ value, wrap, multiline, font, placeholder, onChange, onSubmit, }) {
50
+ this.#onChange = onChange;
51
+ this.#onSubmit = onSubmit;
52
+ this.#wrap = wrap ?? false;
53
+ this.#multiline = multiline ?? false;
54
+ this.#updatePlaceholderLines(placeholder ?? '');
55
+ this.#updateLines(sys_1.unicode.printableChars(value ?? ''), font ?? 'default');
56
+ }
57
+ #updatePlaceholderLines(placeholder) {
58
+ const placeholderLines = placeholder === ''
59
+ ? []
60
+ : placeholder.split('\n').map(line => sys_1.unicode.printableChars(line));
61
+ this.#placeholder = placeholderLines.map(line => [
62
+ line,
63
+ line.reduce((w, c) => w + sys_1.unicode.charWidth(c), 0),
64
+ ]);
65
+ }
66
+ #updateLines(_chars, font) {
67
+ let chars = _chars ?? this.#chars;
68
+ if (font === undefined) {
69
+ font = this.#font;
70
+ }
71
+ else {
72
+ this.#font = font;
73
+ }
74
+ const startIsAtEnd = this.#cursor.start === this.#chars.length;
75
+ const endIsAtEnd = this.#cursor.end === this.#chars.length;
76
+ if (chars.length > 0) {
77
+ if (!this.#multiline) {
78
+ chars = chars.map(char => (char === '\n' ? ' ' : char));
79
+ }
80
+ this.#value = chars.filter(char => !isAccentChar(char)).join('');
81
+ this.#chars = chars;
82
+ const [charLines] = this.#chars.reduce(([lines, line], char, index) => {
83
+ if (char === '\n') {
84
+ lines.push(line);
85
+ if (index === this.#chars.length - 1) {
86
+ lines.push([]);
87
+ }
88
+ return [lines, []];
89
+ }
90
+ line.push(char);
91
+ if (index === this.#chars.length - 1) {
92
+ lines.push(line);
93
+ return [lines, []];
94
+ }
95
+ return [lines, line];
96
+ }, [[], []]);
97
+ this.#printableLines = charLines.map((printableLine, index, all) => {
98
+ // every line needs a ' ' or NL_SIGIL at the end, for the EOL cursor
99
+ return [
100
+ printableLine.concat(index === all.length - 1 ? ' ' : NL_SIGIL),
101
+ printableLine.reduce((width, char) => width + sys_1.unicode.charWidth(char), 0) + 1,
102
+ ];
103
+ });
104
+ }
105
+ else {
106
+ this.#value = '';
107
+ this.#printableLines = this.#placeholder.map(([line, width]) => {
108
+ return [line.concat(' '), width];
109
+ });
110
+ }
111
+ this.#visibleWidth = 0;
112
+ if (endIsAtEnd) {
113
+ this.#cursor.end = this.#chars.length;
114
+ }
115
+ else {
116
+ this.#cursor.end = Math.min(this.#cursor.end, this.#chars.length);
117
+ }
118
+ if (startIsAtEnd) {
119
+ this.#cursor.start = this.#chars.length;
120
+ }
121
+ else {
122
+ this.#cursor.start = Math.min(this.#cursor.start, this.#chars.length);
123
+ }
124
+ this.#maxLineWidth = this.#printableLines.reduce((maxWidth, [, width]) => {
125
+ // the _printable_ width, not the number of characters
126
+ return Math.max(maxWidth, width);
127
+ }, 0);
128
+ this.invalidateSize();
129
+ }
130
+ get value() {
131
+ return this.#value;
132
+ }
133
+ set value(value) {
134
+ if (value !== this.#value) {
135
+ this.#updateLines(sys_1.unicode.printableChars(value), undefined);
136
+ }
137
+ }
138
+ get placeholder() {
139
+ return this.#placeholder.map(([chars]) => chars.join('')).join('\n');
140
+ }
141
+ set placeholder(placeholder) {
142
+ this.#updatePlaceholderLines(placeholder ?? '');
143
+ }
144
+ get font() {
145
+ return this.#font;
146
+ }
147
+ set font(font) {
148
+ if (font !== this.#font) {
149
+ this.#updateLines(undefined, font);
150
+ }
151
+ }
152
+ get wrap() {
153
+ return this.#wrap;
154
+ }
155
+ set wrap(wrap) {
156
+ if (wrap !== this.#wrap) {
157
+ this.#wrap = wrap;
158
+ this.#updateLines(undefined, undefined);
159
+ }
160
+ }
161
+ get multiline() {
162
+ return this.#multiline;
163
+ }
164
+ set multiline(multiline) {
165
+ if (multiline !== this.#multiline) {
166
+ this.#multiline = multiline;
167
+ this.#updateLines(undefined, undefined);
168
+ }
169
+ }
170
+ naturalSize(available) {
171
+ let lines = this.#printableLines;
172
+ if (!lines.length || !available.width) {
173
+ return geometry_1.Size.one;
174
+ }
175
+ let height = 0;
176
+ if (this.#wrap) {
177
+ for (const [, width] of lines) {
178
+ // width + 1 because there should always be room for the cursor to be _after_
179
+ // the last character.
180
+ height += Math.ceil((width + 1) / available.width);
181
+ }
182
+ }
183
+ else {
184
+ height = lines.length;
185
+ }
186
+ return new geometry_1.Size(this.#maxLineWidth, height);
187
+ }
188
+ minSelected() {
189
+ return Math.min(this.#cursor.start, this.#cursor.end);
190
+ }
191
+ maxSelected() {
192
+ return isEmptySelection(this.#cursor)
193
+ ? this.#cursor.start + 1
194
+ : Math.max(this.#cursor.start, this.#cursor.end);
195
+ }
196
+ receiveKey(event) {
197
+ const prevChars = this.#chars;
198
+ const prevText = this.#value;
199
+ let removeAccent = true;
200
+ if (event.name === 'enter' || event.name === 'return') {
201
+ if (this.#multiline) {
202
+ this.#receiveChar('\n', true);
203
+ }
204
+ else {
205
+ this.#onSubmit?.(this.#value);
206
+ return;
207
+ }
208
+ }
209
+ else if (event.full === 'C-a') {
210
+ this.#receiveGotoStart();
211
+ }
212
+ else if (event.full === 'C-e') {
213
+ this.#receiveGotoEnd();
214
+ }
215
+ else if (event.name === 'up') {
216
+ this.#receiveKeyUpArrow(event);
217
+ }
218
+ else if (event.name === 'down') {
219
+ this.#receiveKeyDownArrow(event);
220
+ }
221
+ else if (event.name === 'home') {
222
+ this.#receiveHome(event);
223
+ }
224
+ else if (event.name === 'end') {
225
+ this.#receiveEnd(event);
226
+ }
227
+ else if (event.name === 'left') {
228
+ this.#receiveKeyLeftArrow(event);
229
+ }
230
+ else if (event.name === 'right') {
231
+ this.#receiveKeyRightArrow(event);
232
+ }
233
+ else if (event.full === 'backspace') {
234
+ this.#receiveKeyBackspace();
235
+ }
236
+ else if (event.name === 'delete') {
237
+ this.#receiveKeyDelete();
238
+ }
239
+ else if (event.full === 'M-backspace' || event.full === 'C-w') {
240
+ this.#receiveKeyDeleteWord();
241
+ }
242
+ else if (isKeyAccent(event)) {
243
+ this.#receiveKeyAccent(event);
244
+ removeAccent = false;
245
+ }
246
+ else if ((0, events_1.isKeyPrintable)(event)) {
247
+ this.#receiveKeyPrintable(event);
248
+ }
249
+ if (removeAccent) {
250
+ this.#chars = this.#chars.filter(char => !isAccentChar(char));
251
+ }
252
+ if (prevChars !== this.#chars) {
253
+ this.#updateLines(this.#chars, undefined);
254
+ }
255
+ if (prevText !== this.#value) {
256
+ this.#onChange?.(this.#value);
257
+ }
258
+ }
259
+ receiveMouse(event, system) {
260
+ if (event.name === 'mouse.button.down') {
261
+ system.requestFocus();
262
+ }
263
+ }
264
+ render(viewport) {
265
+ const hasFocus = viewport.registerFocus();
266
+ if (viewport.isEmpty) {
267
+ return;
268
+ }
269
+ const visibleSize = viewport.contentSize;
270
+ if (hasFocus) {
271
+ viewport.registerTick();
272
+ }
273
+ viewport.registerMouse('mouse.button.left');
274
+ // cursorEnd: the location of the cursor relative to the text
275
+ // (ie if the text had been drawn at 0,0, cursorEnd is the screen location of
276
+ // the cursor)
277
+ // cursorPosition: the location of the cursor relative to the viewport
278
+ const [cursorEnd, cursorPosition] = this.#cursorPosition(visibleSize);
279
+ const cursorMin = this.#toPosition(this.minSelected(), visibleSize.width);
280
+ const cursorMax = this.#toPosition(this.maxSelected(), visibleSize.width);
281
+ // cursorVisible: the text location of the first line & char to draw
282
+ const cursorVisible = new geometry_1.Point(cursorEnd.x - cursorPosition.x, cursorEnd.y - cursorPosition.y);
283
+ let lines = this.#printableLines;
284
+ if (visibleSize.width !== this.#visibleWidth ||
285
+ this.#wrappedLines.length === 0) {
286
+ if (this.#wrap) {
287
+ lines = lines.flatMap(line => {
288
+ const wrappedLines = [];
289
+ let currentLine = [];
290
+ let currentWidth = 0;
291
+ for (const char of line[0]) {
292
+ const charWidth = sys_1.unicode.charWidth(char);
293
+ currentLine.push(char);
294
+ currentWidth += charWidth;
295
+ if (currentWidth >= visibleSize.width) {
296
+ wrappedLines.push([currentLine, currentWidth]);
297
+ currentLine = [];
298
+ currentWidth = 0;
299
+ }
300
+ }
301
+ if (currentLine.length) {
302
+ wrappedLines.push([currentLine, currentWidth]);
303
+ }
304
+ return wrappedLines;
305
+ });
306
+ }
307
+ this.#wrappedLines = lines;
308
+ this.#visibleWidth = visibleSize.width;
309
+ }
310
+ else {
311
+ lines = this.#wrappedLines;
312
+ }
313
+ let isPlaceholder = !Boolean(this.#chars.length);
314
+ let currentStyle = Style_1.Style.NONE;
315
+ const plainStyle = this.theme.text({
316
+ isPlaceholder,
317
+ hasFocus,
318
+ });
319
+ const selectedStyle = this.theme.text({
320
+ isSelected: true,
321
+ hasFocus,
322
+ });
323
+ const cursorStyle = plainStyle.merge({ underline: true });
324
+ const nlStyle = this.theme.text({ isPlaceholder: true });
325
+ const fontMap = this.#font && fonts_1.FONTS[this.#font];
326
+ viewport.usingPen(pen => {
327
+ let style = plainStyle;
328
+ const visibleLines = lines.slice(cursorVisible.y);
329
+ if (visibleLines.length === 0) {
330
+ visibleLines.push([[' '], 0]);
331
+ }
332
+ // is the viewport tall/wide enough to show ellipses …
333
+ const isTallEnough = viewport.contentSize.height > 4;
334
+ const isWideEnough = viewport.contentSize.width > 9;
335
+ // do we need to show vertical ellipses
336
+ const isTooTall = visibleLines.length > visibleSize.height;
337
+ // firstPoint is top-left corner of the viewport
338
+ const firstPoint = new geometry_1.Point(0, cursorVisible.y);
339
+ // lastPoint is bottom-right corner of the viewport
340
+ const lastPoint = new geometry_1.Point(visibleSize.width + cursorVisible.x - 1, cursorVisible.y + visibleSize.height - 1);
341
+ let scanTextPosition = firstPoint.mutableCopy();
342
+ for (const [line, width] of visibleLines) {
343
+ // used to determine whether to draw a final …
344
+ const isTooWide = this.#wrap
345
+ ? false
346
+ : width - cursorVisible.x > viewport.contentSize.width;
347
+ // set to true if any character is skipped
348
+ let drawInitialEllipses = false;
349
+ scanTextPosition.x = 0;
350
+ for (let char of line) {
351
+ char = fontMap?.get(char) ?? char;
352
+ const charWidth = sys_1.unicode.charWidth(char);
353
+ if (scanTextPosition.x >= cursorVisible.x) {
354
+ const inSelection = isInSelection(cursorMin, cursorMax, scanTextPosition);
355
+ const inCursor = scanTextPosition.x === cursorEnd.x &&
356
+ scanTextPosition.y === cursorEnd.y;
357
+ const inNewline = char === NL_SIGIL && scanTextPosition.x + charWidth === width;
358
+ if (isEmptySelection(this.#cursor)) {
359
+ if (isAccentChar(char)) {
360
+ style = plainStyle.merge({ underline: true, inverse: true });
361
+ }
362
+ else if (hasFocus && inCursor) {
363
+ style = inNewline
364
+ ? nlStyle.merge({ underline: true })
365
+ : cursorStyle;
366
+ }
367
+ else if (inNewline) {
368
+ style = nlStyle;
369
+ }
370
+ else {
371
+ style = plainStyle;
372
+ }
373
+ }
374
+ else {
375
+ if (inSelection) {
376
+ style = inNewline
377
+ ? nlStyle.merge({ background: selectedStyle.foreground })
378
+ : selectedStyle.merge({ underline: inCursor });
379
+ }
380
+ else if (inNewline) {
381
+ style = nlStyle;
382
+ }
383
+ else {
384
+ style = plainStyle;
385
+ }
386
+ }
387
+ if (!currentStyle.isEqual(style)) {
388
+ pen.replacePen(style);
389
+ currentStyle = style;
390
+ }
391
+ let drawEllipses = false;
392
+ if (cursorVisible.y > 0 && scanTextPosition.isEqual(firstPoint)) {
393
+ drawEllipses = isTallEnough;
394
+ }
395
+ else if (isTooTall && scanTextPosition.isEqual(lastPoint)) {
396
+ drawEllipses = isTallEnough;
397
+ }
398
+ else if (isWideEnough) {
399
+ if (drawInitialEllipses) {
400
+ drawEllipses = true;
401
+ }
402
+ else if (isTooWide &&
403
+ scanTextPosition.x - cursorVisible.x + charWidth >=
404
+ viewport.contentSize.width) {
405
+ drawEllipses = true;
406
+ }
407
+ }
408
+ viewport.write(drawEllipses ? '…' : char, scanTextPosition.offset(-cursorVisible.x, -cursorVisible.y));
409
+ drawInitialEllipses = false;
410
+ }
411
+ else {
412
+ drawInitialEllipses = true;
413
+ }
414
+ scanTextPosition.x += charWidth;
415
+ if (scanTextPosition.x - cursorVisible.x >=
416
+ viewport.contentSize.width) {
417
+ break;
418
+ }
419
+ }
420
+ scanTextPosition.y += 1;
421
+ if (scanTextPosition.y - cursorVisible.y >=
422
+ viewport.contentSize.height) {
423
+ break;
424
+ }
425
+ }
426
+ });
427
+ }
428
+ /**
429
+ * The position of the character that is at the desired cursor offset, taking
430
+ * character widths into account, relative to the text (as if the text were drawn
431
+ * at 0,0), and 'wrap' setting.
432
+ */
433
+ #toPosition(offset, visibleWidth) {
434
+ if (this.#wrap) {
435
+ let y = 0, index = 0;
436
+ let x = 0;
437
+ // immediately after a line wrap, we don't want to also increase y by 1
438
+ let isFirst = true;
439
+ for (const [chars] of this.#printableLines) {
440
+ if (!isFirst) {
441
+ y += 1;
442
+ }
443
+ isFirst = false;
444
+ x = 0;
445
+ for (const char of chars) {
446
+ if (index === offset) {
447
+ if (x === visibleWidth) {
448
+ x = 0;
449
+ y += 1;
450
+ }
451
+ return new geometry_1.Point(x, y);
452
+ }
453
+ const charWidth = sys_1.unicode.charWidth(char);
454
+ if (x + charWidth > visibleWidth) {
455
+ x = charWidth;
456
+ y += 1;
457
+ }
458
+ else {
459
+ x += charWidth;
460
+ }
461
+ index += 1;
462
+ }
463
+ }
464
+ return new geometry_1.Point(x, y);
465
+ }
466
+ let y = 0, index = 0;
467
+ for (const [chars] of this.#printableLines) {
468
+ if (index + chars.length > offset) {
469
+ let x = 0;
470
+ for (const char of chars.slice(0, offset - index)) {
471
+ x += sys_1.unicode.charWidth(char);
472
+ }
473
+ return new geometry_1.Point({ x, y });
474
+ }
475
+ index += chars.length;
476
+ y += 1;
477
+ }
478
+ return new geometry_1.Point(0, y);
479
+ }
480
+ /**
481
+ * Returns the cursor offset that points to the character at the desired screen
482
+ * position, taking into account character widths.
483
+ */
484
+ #toOffset(position, visibleWidth) {
485
+ if (this.#wrap) {
486
+ let y = 0, index = 0;
487
+ let x = 0;
488
+ for (const [chars] of this.#printableLines) {
489
+ if (y) {
490
+ y += 1;
491
+ }
492
+ x = 0;
493
+ for (const char of chars) {
494
+ if (position.isEqual(x, y)) {
495
+ return index;
496
+ }
497
+ const charWidth = sys_1.unicode.charWidth(char);
498
+ if (x + charWidth >= visibleWidth) {
499
+ x = 0;
500
+ y += 1;
501
+ index += 1;
502
+ }
503
+ else {
504
+ x += charWidth;
505
+ index += 1;
506
+ }
507
+ }
508
+ }
509
+ return index;
510
+ }
511
+ else {
512
+ if (position.y >= this.#printableLines.length) {
513
+ return this.#chars.length;
514
+ }
515
+ let y = 0, index = 0;
516
+ for (const [chars, width] of this.#printableLines) {
517
+ if (y === position.y) {
518
+ let x = 0;
519
+ for (const char of chars) {
520
+ x += sys_1.unicode.charWidth(char);
521
+ if (x > position.x) {
522
+ return index;
523
+ }
524
+ index += 1;
525
+ }
526
+ return index;
527
+ }
528
+ y += 1;
529
+ index += chars.length + 1;
530
+ }
531
+ return this.#chars.length;
532
+ }
533
+ }
534
+ /**
535
+ * Determine the position of the cursor, relative to the viewport, based on the
536
+ * text and viewport sizes.
537
+ *
538
+ * The cursor is placed so that it will appear at the start or end of the viewport
539
+ * when it is near the start or end of the line, otherwise it tries to be centered.
540
+ */
541
+ #cursorPosition(visibleSize) {
542
+ const halfWidth = Math.floor(visibleSize.width / 2);
543
+ const halfHeight = Math.floor(visibleSize.height / 2);
544
+ // the cursor, relative to the start of text (as if all text was visible),
545
+ // ie in the "coordinate system" of the text.
546
+ let cursorEnd = this.#toPosition(this.#cursor.end, visibleSize.width);
547
+ let currentLineWidth, totalHeight;
548
+ if (!this.#printableLines.length) {
549
+ return [cursorEnd, new geometry_1.Point(0, 0)];
550
+ }
551
+ if (this.#wrap) {
552
+ // run through the lines until we get to our desired cursorEnd.y
553
+ // but also add all the heights to calculate currentHeight
554
+ let h = 0;
555
+ currentLineWidth = -1;
556
+ totalHeight = 0;
557
+ for (const [, width] of this.#printableLines) {
558
+ const dh = Math.ceil(width / visibleSize.width);
559
+ totalHeight += dh;
560
+ if (currentLineWidth === -1 && dh >= cursorEnd.y) {
561
+ if (cursorEnd.y - h === dh) {
562
+ // the cursor is on the last wrapped line, use modulo divide to calculate the
563
+ // last line width, add 1 for the EOL cursor
564
+ currentLineWidth = (visibleSize.width % width) + 1;
565
+ }
566
+ else {
567
+ currentLineWidth = visibleSize.width;
568
+ }
569
+ break;
570
+ }
571
+ }
572
+ currentLineWidth = Math.max(0, currentLineWidth);
573
+ }
574
+ else {
575
+ currentLineWidth = this.#printableLines[cursorEnd.y]?.[1] ?? 0;
576
+ totalHeight = this.#printableLines.length;
577
+ }
578
+ // Calculate the viewport location where the cursor will be drawn
579
+ // x location:
580
+ let cursorX;
581
+ if (currentLineWidth <= visibleSize.width) {
582
+ // If the viewport can accommodate the entire line
583
+ // draw the cursor at its natural location.
584
+ cursorX = cursorEnd.x;
585
+ }
586
+ else if (cursorEnd.x < halfWidth) {
587
+ // If the cursor is at the start of the line
588
+ // place the cursor at the start of the viewport
589
+ cursorX = cursorEnd.x;
590
+ }
591
+ else if (cursorEnd.x > currentLineWidth - halfWidth) {
592
+ // or if the cursor is at the end of the line
593
+ // draw it at the end of the viewport
594
+ cursorX = visibleSize.width - currentLineWidth + cursorEnd.x;
595
+ }
596
+ else {
597
+ // otherwise place it in the middle.
598
+ cursorX = halfWidth;
599
+ }
600
+ // y location:
601
+ let cursorY;
602
+ if (totalHeight <= visibleSize.height) {
603
+ // If the viewport can accommodate the entire height
604
+ // draw the cursor at its natural location.
605
+ cursorY = cursorEnd.y;
606
+ }
607
+ else if (cursorEnd.y < halfHeight) {
608
+ // If the cursor is at the start of the text
609
+ // place the cursor at the start of the viewport
610
+ cursorY = cursorEnd.y;
611
+ }
612
+ else if (cursorEnd.y >= totalHeight - halfHeight) {
613
+ // or if the cursor is at the end of the text
614
+ // draw it at the end of the viewport
615
+ cursorY = visibleSize.height - totalHeight + cursorEnd.y;
616
+ }
617
+ else {
618
+ // otherwise place it in the middle.
619
+ cursorY = halfHeight;
620
+ }
621
+ // The viewport location where the cursor will be drawn
622
+ return [cursorEnd, new geometry_1.Point(cursorX, cursorY)];
623
+ }
624
+ #receiveKeyAccent(event) {
625
+ this.#chars = this.#chars.filter(char => !isAccentChar(char));
626
+ let char = ACCENT_KEYS[event.full];
627
+ if (!char) {
628
+ return;
629
+ }
630
+ this.#receiveChar(char, false);
631
+ }
632
+ #receiveKeyPrintable({ char }) {
633
+ if (this.#cursor.start === this.#cursor.end &&
634
+ isAccentChar(this.#chars[this.#cursor.start])) {
635
+ // if character under cursor is an accent, replace it.
636
+ const accented = accentChar(this.#chars[this.#cursor.start], char);
637
+ this.#receiveChar(accented, true);
638
+ return;
639
+ }
640
+ this.#receiveChar(char, true);
641
+ }
642
+ #receiveChar(char, advance) {
643
+ if (isEmptySelection(this.#cursor)) {
644
+ this.#chars = this.#chars
645
+ .slice(0, this.#cursor.start)
646
+ .concat(char, this.#chars.slice(this.#cursor.start));
647
+ this.#cursor.start = this.#cursor.end =
648
+ this.#cursor.start + (advance ? 1 : 0);
649
+ }
650
+ else {
651
+ this.#chars = this.#chars
652
+ .slice(0, this.minSelected())
653
+ .concat(char, this.#chars.slice(this.maxSelected()));
654
+ this.#cursor.start = this.#cursor.end =
655
+ this.minSelected() + (advance ? 1 : 0);
656
+ }
657
+ }
658
+ #receiveGotoStart() {
659
+ this.#cursor = { start: 0, end: 0 };
660
+ }
661
+ #receiveGotoEnd() {
662
+ this.#cursor = { start: this.#chars.length, end: this.#chars.length };
663
+ }
664
+ #receiveHome({ shift }) {
665
+ let dest = 0;
666
+ // move the cursor to the previous line, moving the cursor until it is at the
667
+ // same X position.
668
+ let cursorPosition = this.#toPosition(this.#cursor.end, this.#visibleWidth).mutableCopy();
669
+ if (cursorPosition.y === 0) {
670
+ dest = 0;
671
+ }
672
+ else {
673
+ const [targetChars, targetWidth] = this.#wrappedLines[cursorPosition.y];
674
+ dest = this.#wrappedLines
675
+ .slice(0, cursorPosition.y)
676
+ .reduce((dest, [, width]) => {
677
+ return dest + width;
678
+ }, 0);
679
+ }
680
+ if (shift) {
681
+ this.#cursor.end = dest;
682
+ }
683
+ else {
684
+ this.#cursor = { start: dest, end: dest };
685
+ }
686
+ }
687
+ #receiveEnd({ shift }) {
688
+ let dest = 0;
689
+ // move the cursor to the next line, moving the cursor until it is at the
690
+ // same X position.
691
+ let cursorPosition = this.#toPosition(this.#cursor.end, this.#visibleWidth).mutableCopy();
692
+ if (cursorPosition.y === this.#wrappedLines.length - 1) {
693
+ dest = this.#chars.length;
694
+ }
695
+ else {
696
+ const [targetChars, targetWidth] = this.#wrappedLines[cursorPosition.y + 1];
697
+ dest =
698
+ this.#wrappedLines
699
+ .slice(0, cursorPosition.y + 1)
700
+ .reduce((dest, [, width]) => {
701
+ return dest + width;
702
+ }, 0) - 1;
703
+ }
704
+ if (shift) {
705
+ this.#cursor.end = dest;
706
+ }
707
+ else {
708
+ this.#cursor = { start: dest, end: dest };
709
+ }
710
+ }
711
+ #receiveKeyUpArrow({ shift }) {
712
+ let dest = 0;
713
+ // move the cursor to the previous line, moving the cursor until it is at the
714
+ // same X position.
715
+ let cursorPosition = this.#toPosition(this.#cursor.end, this.#visibleWidth).mutableCopy();
716
+ if (cursorPosition.y === 0) {
717
+ dest = 0;
718
+ }
719
+ else if (cursorPosition.y <= this.#wrappedLines.length) {
720
+ const [targetChars, targetWidth] = this.#wrappedLines[cursorPosition.y - 1];
721
+ dest = this.#wrappedLines
722
+ .slice(0, cursorPosition.y - 1)
723
+ .reduce((dest, [, width]) => {
724
+ return dest + width;
725
+ }, 0);
726
+ if (targetWidth <= cursorPosition.x) {
727
+ dest += targetWidth - 1;
728
+ }
729
+ else {
730
+ let destOffset = 0;
731
+ for (const char of targetChars) {
732
+ const charWidth = sys_1.unicode.charWidth(char);
733
+ if (destOffset + charWidth > cursorPosition.x) {
734
+ break;
735
+ }
736
+ destOffset += 1;
737
+ }
738
+ dest += destOffset;
739
+ }
740
+ }
741
+ if (shift) {
742
+ this.#cursor.end = dest;
743
+ }
744
+ else {
745
+ this.#cursor = { start: dest, end: dest };
746
+ }
747
+ }
748
+ #receiveKeyDownArrow({ shift }) {
749
+ let dest = 0;
750
+ // move the cursor to the next line, moving the cursor until it is at the
751
+ // same X position.
752
+ let cursorPosition = this.#toPosition(this.#cursor.end, this.#visibleWidth).mutableCopy();
753
+ if (cursorPosition.y === this.#wrappedLines.length - 1 ||
754
+ this.#wrappedLines.length === 0) {
755
+ dest = this.#chars.length;
756
+ }
757
+ else {
758
+ const [targetChars, targetWidth] = this.#wrappedLines[cursorPosition.y + 1];
759
+ dest = this.#wrappedLines
760
+ .slice(0, cursorPosition.y + 1)
761
+ .reduce((dest, [, width]) => {
762
+ return dest + width;
763
+ }, 0);
764
+ if (targetWidth <= cursorPosition.x) {
765
+ dest += targetWidth - 1;
766
+ }
767
+ else {
768
+ let destOffset = 0;
769
+ for (const char of targetChars) {
770
+ const charWidth = sys_1.unicode.charWidth(char);
771
+ if (destOffset + charWidth > cursorPosition.x) {
772
+ break;
773
+ }
774
+ destOffset += 1;
775
+ }
776
+ dest += destOffset;
777
+ }
778
+ }
779
+ if (shift) {
780
+ this.#cursor.end = dest;
781
+ }
782
+ else {
783
+ this.#cursor = { start: dest, end: dest };
784
+ }
785
+ }
786
+ #prevWordOffset(shift) {
787
+ let cursor;
788
+ if (shift) {
789
+ cursor = this.#cursor.end;
790
+ }
791
+ else if (isEmptySelection(this.#cursor)) {
792
+ cursor = this.#cursor.start;
793
+ }
794
+ else {
795
+ cursor = this.minSelected();
796
+ }
797
+ let prevWordOffset = 0;
798
+ for (const [chars, offset] of sys_1.unicode.words(this.#chars)) {
799
+ prevWordOffset = offset;
800
+ if (cursor <= offset + chars.length) {
801
+ break;
802
+ }
803
+ }
804
+ return prevWordOffset;
805
+ }
806
+ #nextWordOffset(shift) {
807
+ let cursor;
808
+ if (shift) {
809
+ cursor = this.#cursor.end;
810
+ }
811
+ else if (isEmptySelection(this.#cursor)) {
812
+ cursor = this.#cursor.start;
813
+ }
814
+ else {
815
+ cursor = this.maxSelected();
816
+ }
817
+ let nextWordOffset = 0;
818
+ for (const [chars, offset] of sys_1.unicode.words(this.#chars)) {
819
+ nextWordOffset = offset + chars.length;
820
+ if (cursor < offset + chars.length) {
821
+ break;
822
+ }
823
+ }
824
+ return nextWordOffset;
825
+ }
826
+ #receiveKeyLeftArrow({ shift, meta }) {
827
+ if (meta) {
828
+ const prevWordOffset = this.#prevWordOffset(shift);
829
+ if (shift) {
830
+ this.#cursor.end = prevWordOffset;
831
+ }
832
+ else {
833
+ this.#cursor.start = this.#cursor.end = prevWordOffset;
834
+ }
835
+ }
836
+ else if (shift) {
837
+ this.#cursor.end = Math.max(0, this.#cursor.end - 1);
838
+ }
839
+ else if (isEmptySelection(this.#cursor)) {
840
+ this.#cursor.start = this.#cursor.end = Math.max(0, this.#cursor.start - 1);
841
+ }
842
+ else {
843
+ this.#cursor.start = this.#cursor.end = this.minSelected();
844
+ }
845
+ }
846
+ #receiveKeyRightArrow({ shift, meta }) {
847
+ if (meta) {
848
+ const nextWordOffset = this.#nextWordOffset(shift);
849
+ if (shift) {
850
+ this.#cursor.end = nextWordOffset;
851
+ }
852
+ else {
853
+ this.#cursor.start = this.#cursor.end = nextWordOffset;
854
+ }
855
+ }
856
+ else if (shift) {
857
+ this.#cursor.end = Math.min(this.#chars.length, this.#cursor.end + 1);
858
+ }
859
+ else if (isEmptySelection(this.#cursor)) {
860
+ this.#cursor.start = this.#cursor.end = Math.min(this.#chars.length, this.#cursor.start + 1);
861
+ }
862
+ else {
863
+ this.#cursor.start = this.#cursor.end = this.maxSelected();
864
+ }
865
+ }
866
+ #updateWidth() {
867
+ this.#maxLineWidth = this.#chars
868
+ .map(sys_1.unicode.charWidth)
869
+ .reduce((a, b) => a + b, 0);
870
+ }
871
+ #deleteSelection() {
872
+ this.#chars = this.#chars
873
+ .slice(0, this.minSelected())
874
+ .concat(this.#chars.slice(this.maxSelected()));
875
+ this.#cursor.start = this.#cursor.end = this.minSelected();
876
+ this.#updateWidth();
877
+ }
878
+ #receiveKeyBackspace() {
879
+ if (isEmptySelection(this.#cursor)) {
880
+ if (this.#cursor.start === 0) {
881
+ return;
882
+ }
883
+ this.#chars = this.#chars
884
+ .slice(0, this.#cursor.start - 1)
885
+ .concat(this.#chars.slice(this.#cursor.start));
886
+ this.#cursor.start = this.#cursor.end = this.#cursor.start - 1;
887
+ }
888
+ else {
889
+ this.#deleteSelection();
890
+ }
891
+ }
892
+ #receiveKeyDelete() {
893
+ if (isEmptySelection(this.#cursor)) {
894
+ if (this.#cursor.start > this.#chars.length - 1) {
895
+ return;
896
+ }
897
+ this.#maxLineWidth -= sys_1.unicode.charWidth(this.#chars[this.#cursor.start]);
898
+ this.#chars = this.#chars
899
+ .slice(0, this.#cursor.start)
900
+ .concat(this.#chars.slice(this.#cursor.start + 1));
901
+ }
902
+ else {
903
+ this.#deleteSelection();
904
+ }
905
+ }
906
+ #receiveKeyDeleteWord() {
907
+ if (!isEmptySelection(this.#cursor)) {
908
+ return this.#deleteSelection();
909
+ }
910
+ if (this.#cursor.start === 0) {
911
+ return;
912
+ }
913
+ const offset = this.#prevWordOffset(false);
914
+ this.#chars = this.#chars
915
+ .slice(0, offset)
916
+ .concat(this.#chars.slice(this.#cursor.start));
917
+ this.#cursor.start = this.#cursor.end = offset;
918
+ this.#updateWidth();
919
+ }
920
+ }
921
+ exports.Input = Input;
922
+ function isEmptySelection(cursor) {
923
+ return cursor.start === cursor.end;
924
+ }
925
+ function isInSelection(cursorMin, cursorMax, scanTextPosition) {
926
+ if (scanTextPosition.y < cursorMin.y || scanTextPosition.y > cursorMax.y) {
927
+ return false;
928
+ }
929
+ if (scanTextPosition.y === cursorMin.y) {
930
+ if (scanTextPosition.x < cursorMin.x) {
931
+ return false;
932
+ }
933
+ }
934
+ if (scanTextPosition.y === cursorMax.y) {
935
+ if (scanTextPosition.x >= cursorMax.x) {
936
+ return false;
937
+ }
938
+ }
939
+ return true;
940
+ }
941
+ function isAccentChar(char) {
942
+ return ACCENTS[char] !== undefined;
943
+ }
944
+ const ACCENTS = {
945
+ '`': {
946
+ A: 'À',
947
+ E: 'È',
948
+ I: 'Ì',
949
+ O: 'Ò',
950
+ U: 'Ù',
951
+ N: 'Ǹ',
952
+ a: 'à',
953
+ e: 'è',
954
+ i: 'ì',
955
+ o: 'ò',
956
+ u: 'ù',
957
+ n: 'ǹ',
958
+ },
959
+ '¸': {
960
+ C: 'Ç',
961
+ D: 'Ḑ',
962
+ E: 'Ȩ',
963
+ G: 'Ģ',
964
+ H: 'Ḩ',
965
+ K: 'Ķ',
966
+ L: 'Ļ',
967
+ N: 'Ņ',
968
+ R: 'Ŗ',
969
+ S: 'Ş',
970
+ T: 'Ţ',
971
+ c: 'ç',
972
+ d: 'ḑ',
973
+ e: 'ȩ',
974
+ g: 'ģ',
975
+ h: 'ḩ',
976
+ k: 'ķ',
977
+ l: 'ļ',
978
+ n: 'ņ',
979
+ r: 'ŗ',
980
+ s: 'ş',
981
+ t: 'ţ',
982
+ },
983
+ '´': {
984
+ A: 'Á',
985
+ C: 'Ć',
986
+ E: 'É',
987
+ G: 'Ǵ',
988
+ I: 'Í',
989
+ K: 'Ḱ',
990
+ L: 'Ĺ',
991
+ M: 'Ḿ',
992
+ N: 'Ń',
993
+ O: 'Ó',
994
+ P: 'Ṕ',
995
+ R: 'Ŕ',
996
+ S: 'Ś',
997
+ U: 'Ú',
998
+ W: 'Ẃ',
999
+ Y: 'Ý',
1000
+ a: 'á',
1001
+ c: 'ć',
1002
+ e: 'é',
1003
+ g: 'ǵ',
1004
+ i: 'í',
1005
+ k: 'ḱ',
1006
+ l: 'ĺ',
1007
+ m: 'ḿ',
1008
+ n: 'ń',
1009
+ o: 'ó',
1010
+ p: 'ṕ',
1011
+ r: 'ŕ',
1012
+ s: 'ś',
1013
+ u: 'ú',
1014
+ w: 'ẃ',
1015
+ y: 'ý',
1016
+ },
1017
+ ˆ: {
1018
+ A: 'Â',
1019
+ C: 'Ĉ',
1020
+ E: 'Ê',
1021
+ G: 'Ĝ',
1022
+ H: 'Ĥ',
1023
+ I: 'Î',
1024
+ J: 'Ĵ',
1025
+ O: 'Ô',
1026
+ S: 'Ŝ',
1027
+ U: 'Û',
1028
+ W: 'Ŵ',
1029
+ Y: 'Ŷ',
1030
+ a: 'â',
1031
+ c: 'ĉ',
1032
+ e: 'ê',
1033
+ g: 'ĝ',
1034
+ h: 'ĥ',
1035
+ i: 'î',
1036
+ j: 'ĵ',
1037
+ o: 'ô',
1038
+ s: 'ŝ',
1039
+ u: 'û',
1040
+ w: 'ŵ',
1041
+ y: 'ŷ',
1042
+ },
1043
+ '˜': {
1044
+ A: 'Ã',
1045
+ I: 'Ĩ',
1046
+ N: 'Ñ',
1047
+ O: 'Õ',
1048
+ U: 'Ũ',
1049
+ Y: 'Ỹ',
1050
+ a: 'ã',
1051
+ i: 'ĩ',
1052
+ n: 'ñ',
1053
+ o: 'õ',
1054
+ u: 'ũ',
1055
+ y: 'ỹ',
1056
+ },
1057
+ '¯': {
1058
+ A: 'Ā',
1059
+ E: 'Ē',
1060
+ I: 'Ī',
1061
+ O: 'Ō',
1062
+ U: 'Ū',
1063
+ Y: 'Ȳ',
1064
+ a: 'ā',
1065
+ e: 'ē',
1066
+ i: 'ī',
1067
+ o: 'ō',
1068
+ u: 'ū',
1069
+ y: 'ȳ',
1070
+ },
1071
+ '¨': {
1072
+ A: 'Ä',
1073
+ E: 'Ë',
1074
+ I: 'Ï',
1075
+ O: 'Ö',
1076
+ U: 'Ü',
1077
+ W: 'Ẅ',
1078
+ X: 'Ẍ',
1079
+ Y: 'Ÿ',
1080
+ a: 'ä',
1081
+ e: 'ë',
1082
+ i: 'ï',
1083
+ o: 'ö',
1084
+ u: 'ü',
1085
+ w: 'ẅ',
1086
+ x: 'ẍ',
1087
+ y: 'ÿ',
1088
+ },
1089
+ };
1090
+ const ACCENT_KEYS = {
1091
+ 'M-a': '`',
1092
+ 'M-c': '¸',
1093
+ 'M-e': '´',
1094
+ 'M-i': 'ˆ',
1095
+ 'M-n': '˜',
1096
+ 'M-o': '¯',
1097
+ 'M-s': '¸',
1098
+ 'M-u': '¨',
1099
+ };
1100
+ function accentChar(accent, char) {
1101
+ return ACCENTS[accent]?.[char] ?? char;
1102
+ }
1103
+ function isKeyAccent(event) {
1104
+ if (!event.meta || event.ctrl) {
1105
+ return false;
1106
+ }
1107
+ return ACCENT_KEYS[event.full] !== undefined;
1108
+ }
1109
+ //# sourceMappingURL=Input.js.map