@flyingrobots/bijou 1.1.0 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +35 -5
- package/dist/adapters/test/io.d.ts +2 -0
- package/dist/adapters/test/io.d.ts.map +1 -1
- package/dist/adapters/test/io.js +9 -0
- package/dist/adapters/test/io.js.map +1 -1
- package/dist/core/components/dag-edges.d.ts +78 -0
- package/dist/core/components/dag-edges.d.ts.map +1 -0
- package/dist/core/components/dag-edges.js +127 -0
- package/dist/core/components/dag-edges.js.map +1 -0
- package/dist/core/components/dag-layout.d.ts +37 -0
- package/dist/core/components/dag-layout.d.ts.map +1 -0
- package/dist/core/components/dag-layout.js +172 -0
- package/dist/core/components/dag-layout.js.map +1 -0
- package/dist/core/components/dag-render.d.ts +51 -0
- package/dist/core/components/dag-render.d.ts.map +1 -0
- package/dist/core/components/dag-render.js +440 -0
- package/dist/core/components/dag-render.js.map +1 -0
- package/dist/core/components/dag.d.ts +4 -4
- package/dist/core/components/dag.d.ts.map +1 -1
- package/dist/core/components/dag.js +6 -651
- package/dist/core/components/dag.js.map +1 -1
- package/dist/core/components/markdown-parse.d.ts +69 -0
- package/dist/core/components/markdown-parse.d.ts.map +1 -0
- package/dist/core/components/markdown-parse.js +272 -0
- package/dist/core/components/markdown-parse.js.map +1 -0
- package/dist/core/components/markdown-render.d.ts +20 -0
- package/dist/core/components/markdown-render.d.ts.map +1 -0
- package/dist/core/components/markdown-render.js +135 -0
- package/dist/core/components/markdown-render.js.map +1 -0
- package/dist/core/components/markdown.d.ts.map +1 -1
- package/dist/core/components/markdown.js +6 -371
- package/dist/core/components/markdown.js.map +1 -1
- package/dist/core/detect/tty.d.ts +2 -3
- package/dist/core/detect/tty.d.ts.map +1 -1
- package/dist/core/detect/tty.js +3 -4
- package/dist/core/detect/tty.js.map +1 -1
- package/dist/core/forms/filter-interactive.d.ts +66 -0
- package/dist/core/forms/filter-interactive.d.ts.map +1 -0
- package/dist/core/forms/filter-interactive.js +241 -0
- package/dist/core/forms/filter-interactive.js.map +1 -0
- package/dist/core/forms/filter.d.ts +2 -32
- package/dist/core/forms/filter.d.ts.map +1 -1
- package/dist/core/forms/filter.js +2 -167
- package/dist/core/forms/filter.js.map +1 -1
- package/dist/core/forms/select.js +29 -5
- package/dist/core/forms/select.js.map +1 -1
- package/dist/core/forms/textarea-editor.d.ts +39 -0
- package/dist/core/forms/textarea-editor.d.ts.map +1 -0
- package/dist/core/forms/textarea-editor.js +210 -0
- package/dist/core/forms/textarea-editor.js.map +1 -0
- package/dist/core/forms/textarea.d.ts +2 -19
- package/dist/core/forms/textarea.d.ts.map +1 -1
- package/dist/core/forms/textarea.js +2 -195
- package/dist/core/forms/textarea.js.map +1 -1
- package/dist/core/forms/types.d.ts +2 -0
- package/dist/core/forms/types.d.ts.map +1 -1
- package/dist/core/theme/resolve.d.ts +7 -0
- package/dist/core/theme/resolve.d.ts.map +1 -1
- package/dist/core/theme/resolve.js +6 -2
- package/dist/core/theme/resolve.js.map +1 -1
- package/dist/ports/io.d.ts +2 -0
- package/dist/ports/io.d.ts.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Interactive textarea editor state machine.
|
|
3
|
+
*
|
|
4
|
+
* Renders a scrollable multi-line editor with cursor navigation,
|
|
5
|
+
* optional line numbers, placeholder text, and max-length guard.
|
|
6
|
+
* Ctrl+D submits; Ctrl+C or Escape cancels.
|
|
7
|
+
*/
|
|
8
|
+
import { formatFormTitle, terminalRenderer, createStyledFn } from './form-utils.js';
|
|
9
|
+
/**
|
|
10
|
+
* Render a full interactive textarea editor using raw terminal input.
|
|
11
|
+
*
|
|
12
|
+
* Supports arrow-key cursor movement, scrolling, line wrapping,
|
|
13
|
+
* optional line numbers, placeholder text, and a max-length guard.
|
|
14
|
+
* Ctrl+D submits; Ctrl+C or Escape cancels.
|
|
15
|
+
*
|
|
16
|
+
* @param options - Textarea field configuration.
|
|
17
|
+
* @param ctx - Bijou context.
|
|
18
|
+
* @returns The entered text (newline-joined), or the default value on cancel.
|
|
19
|
+
*/
|
|
20
|
+
export async function interactiveTextarea(options, ctx) {
|
|
21
|
+
const t = ctx.theme;
|
|
22
|
+
const styledFn = createStyledFn(ctx);
|
|
23
|
+
const height = options.height ?? 6;
|
|
24
|
+
const renderWidth = options.width ?? 80;
|
|
25
|
+
const showLineNumbers = options.showLineNumbers ?? false;
|
|
26
|
+
const term = terminalRenderer(ctx);
|
|
27
|
+
let lines = [''];
|
|
28
|
+
let cursorRow = 0;
|
|
29
|
+
let cursorCol = 0;
|
|
30
|
+
let scrollY = 0;
|
|
31
|
+
let totalLength = 0; // running counter for lines.join('\n').length
|
|
32
|
+
function visibleLines() {
|
|
33
|
+
return lines.slice(scrollY, scrollY + height);
|
|
34
|
+
}
|
|
35
|
+
function ensureCursorVisible() {
|
|
36
|
+
if (cursorRow < scrollY)
|
|
37
|
+
scrollY = cursorRow;
|
|
38
|
+
if (cursorRow >= scrollY + height)
|
|
39
|
+
scrollY = cursorRow - height + 1;
|
|
40
|
+
}
|
|
41
|
+
function render() {
|
|
42
|
+
const label = formatFormTitle(options.title, ctx);
|
|
43
|
+
const hint = styledFn(t.theme.semantic.muted, ' (Ctrl+D to submit, Ctrl+C/Esc to cancel)');
|
|
44
|
+
term.writeLine(`${label}${hint}`);
|
|
45
|
+
const vis = visibleLines();
|
|
46
|
+
const numWidth = showLineNumbers ? String(lines.length).length : 0;
|
|
47
|
+
const prefixWidth = showLineNumbers ? numWidth + 3 : 2; // " N │ " or " "
|
|
48
|
+
const contentWidth = Math.max(1, renderWidth - prefixWidth);
|
|
49
|
+
for (let i = 0; i < height; i++) {
|
|
50
|
+
const lineIdx = scrollY + i;
|
|
51
|
+
const rawLine = vis[i] ?? '';
|
|
52
|
+
const line = rawLine.length > contentWidth ? rawLine.slice(0, contentWidth) : rawLine;
|
|
53
|
+
const prefix = showLineNumbers
|
|
54
|
+
? styledFn(t.theme.semantic.muted, `${String(lineIdx + 1).padStart(numWidth)} │ `)
|
|
55
|
+
: ' ';
|
|
56
|
+
if (lineIdx === 0 && options.placeholder && lines.length === 1 && lines[0] === '') {
|
|
57
|
+
ctx.io.write(`\x1b[K${prefix}${styledFn(t.theme.semantic.muted, options.placeholder)}\n`);
|
|
58
|
+
}
|
|
59
|
+
else {
|
|
60
|
+
ctx.io.write(`\x1b[K${prefix}${line}\n`);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
// Status line
|
|
64
|
+
const pos = `Ln ${cursorRow + 1}, Col ${cursorCol + 1}`;
|
|
65
|
+
const lenInfo = options.maxLength != null ? ` | ${totalLength}/${options.maxLength}` : '';
|
|
66
|
+
ctx.io.write(`\x1b[K${styledFn(t.theme.semantic.muted, pos + lenInfo)}\n`);
|
|
67
|
+
}
|
|
68
|
+
function clearRender() {
|
|
69
|
+
const totalLines = height + 2; // header + visible lines + status
|
|
70
|
+
term.moveUp(totalLines);
|
|
71
|
+
}
|
|
72
|
+
function cleanup(value, cancelled) {
|
|
73
|
+
clearRender();
|
|
74
|
+
const totalLines = height + 2;
|
|
75
|
+
term.clearBlock(totalLines);
|
|
76
|
+
const summary = cancelled
|
|
77
|
+
? '(cancelled)'
|
|
78
|
+
: (value
|
|
79
|
+
? (value.includes('\n') ? `${value.split('\n').length} lines` : value)
|
|
80
|
+
: '(empty)');
|
|
81
|
+
const label = formatFormTitle(options.title, ctx) + ' ' + styledFn(t.theme.semantic.info, summary);
|
|
82
|
+
ctx.io.write(`\x1b[K${label}\n`);
|
|
83
|
+
term.showCursor();
|
|
84
|
+
}
|
|
85
|
+
term.hideCursor();
|
|
86
|
+
render();
|
|
87
|
+
return new Promise((resolve) => {
|
|
88
|
+
const handle = ctx.io.rawInput((key) => {
|
|
89
|
+
if (key === '\x04') {
|
|
90
|
+
// Ctrl+D — submit
|
|
91
|
+
handle.dispose();
|
|
92
|
+
const text = lines.join('\n');
|
|
93
|
+
const value = text || (options.defaultValue ?? '');
|
|
94
|
+
cleanup(value, false);
|
|
95
|
+
resolve(value);
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
if (key === '\x03' || key === '\x1b') {
|
|
99
|
+
// Ctrl+C or Escape — cancel
|
|
100
|
+
// TODO: bare \x1b may false-trigger on slow connections where escape
|
|
101
|
+
// sequences arrive as separate bytes. Timer-based disambiguation is a
|
|
102
|
+
// shared debt with filter-interactive.ts — unify in a future PR.
|
|
103
|
+
handle.dispose();
|
|
104
|
+
const value = options.defaultValue ?? '';
|
|
105
|
+
cleanup(value, true);
|
|
106
|
+
resolve(value);
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
if (key === '\r' || key === '\n') {
|
|
110
|
+
// Enter — newline (counts as 1 character for maxLength)
|
|
111
|
+
if (options.maxLength != null && totalLength >= options.maxLength)
|
|
112
|
+
return;
|
|
113
|
+
const currentLine = lines[cursorRow];
|
|
114
|
+
const before = currentLine.slice(0, cursorCol);
|
|
115
|
+
const after = currentLine.slice(cursorCol);
|
|
116
|
+
lines[cursorRow] = before;
|
|
117
|
+
lines.splice(cursorRow + 1, 0, after);
|
|
118
|
+
totalLength++; // newline character
|
|
119
|
+
cursorRow++;
|
|
120
|
+
cursorCol = 0;
|
|
121
|
+
ensureCursorVisible();
|
|
122
|
+
clearRender();
|
|
123
|
+
render();
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
126
|
+
if (key === '\x7f' || key === '\b') {
|
|
127
|
+
// Backspace
|
|
128
|
+
if (cursorCol > 0) {
|
|
129
|
+
const line = lines[cursorRow];
|
|
130
|
+
lines[cursorRow] = line.slice(0, cursorCol - 1) + line.slice(cursorCol);
|
|
131
|
+
cursorCol--;
|
|
132
|
+
totalLength--; // removed one character
|
|
133
|
+
}
|
|
134
|
+
else if (cursorRow > 0) {
|
|
135
|
+
// Merge with previous line
|
|
136
|
+
const prevLine = lines[cursorRow - 1];
|
|
137
|
+
const currentLine = lines[cursorRow];
|
|
138
|
+
cursorCol = prevLine.length;
|
|
139
|
+
lines[cursorRow - 1] = prevLine + currentLine;
|
|
140
|
+
lines.splice(cursorRow, 1);
|
|
141
|
+
cursorRow--;
|
|
142
|
+
totalLength--; // removed newline character
|
|
143
|
+
ensureCursorVisible();
|
|
144
|
+
}
|
|
145
|
+
clearRender();
|
|
146
|
+
render();
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
149
|
+
// Arrow keys
|
|
150
|
+
if (key === '\x1b[A') { // Up
|
|
151
|
+
if (cursorRow > 0) {
|
|
152
|
+
cursorRow--;
|
|
153
|
+
cursorCol = Math.min(cursorCol, lines[cursorRow].length);
|
|
154
|
+
ensureCursorVisible();
|
|
155
|
+
}
|
|
156
|
+
clearRender();
|
|
157
|
+
render();
|
|
158
|
+
return;
|
|
159
|
+
}
|
|
160
|
+
if (key === '\x1b[B') { // Down
|
|
161
|
+
if (cursorRow < lines.length - 1) {
|
|
162
|
+
cursorRow++;
|
|
163
|
+
cursorCol = Math.min(cursorCol, lines[cursorRow].length);
|
|
164
|
+
ensureCursorVisible();
|
|
165
|
+
}
|
|
166
|
+
clearRender();
|
|
167
|
+
render();
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
170
|
+
if (key === '\x1b[C') { // Right
|
|
171
|
+
if (cursorCol < lines[cursorRow].length) {
|
|
172
|
+
cursorCol++;
|
|
173
|
+
}
|
|
174
|
+
else if (cursorRow < lines.length - 1) {
|
|
175
|
+
cursorRow++;
|
|
176
|
+
cursorCol = 0;
|
|
177
|
+
ensureCursorVisible();
|
|
178
|
+
}
|
|
179
|
+
clearRender();
|
|
180
|
+
render();
|
|
181
|
+
return;
|
|
182
|
+
}
|
|
183
|
+
if (key === '\x1b[D') { // Left
|
|
184
|
+
if (cursorCol > 0) {
|
|
185
|
+
cursorCol--;
|
|
186
|
+
}
|
|
187
|
+
else if (cursorRow > 0) {
|
|
188
|
+
cursorRow--;
|
|
189
|
+
cursorCol = lines[cursorRow].length;
|
|
190
|
+
ensureCursorVisible();
|
|
191
|
+
}
|
|
192
|
+
clearRender();
|
|
193
|
+
render();
|
|
194
|
+
return;
|
|
195
|
+
}
|
|
196
|
+
// Printable character
|
|
197
|
+
if (key.length === 1 && key >= ' ') {
|
|
198
|
+
if (options.maxLength != null && totalLength >= options.maxLength)
|
|
199
|
+
return;
|
|
200
|
+
const line = lines[cursorRow];
|
|
201
|
+
lines[cursorRow] = line.slice(0, cursorCol) + key + line.slice(cursorCol);
|
|
202
|
+
cursorCol++;
|
|
203
|
+
totalLength++; // added one character
|
|
204
|
+
clearRender();
|
|
205
|
+
render();
|
|
206
|
+
}
|
|
207
|
+
});
|
|
208
|
+
});
|
|
209
|
+
}
|
|
210
|
+
//# sourceMappingURL=textarea-editor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"textarea-editor.js","sourceRoot":"","sources":["../../../src/core/forms/textarea-editor.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,22 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
import type {
|
|
3
|
-
/**
|
|
4
|
-
* Options for the multi-line textarea field.
|
|
5
|
-
*/
|
|
6
|
-
export interface TextareaOptions extends FieldOptions<string> {
|
|
7
|
-
/** Placeholder text shown when the textarea is empty. */
|
|
8
|
-
placeholder?: string;
|
|
9
|
-
/** Maximum character count (including newlines). */
|
|
10
|
-
maxLength?: number;
|
|
11
|
-
/** Display line numbers in the gutter. Default: false. */
|
|
12
|
-
showLineNumbers?: boolean;
|
|
13
|
-
/** Visible editor height in lines. Default: 6. */
|
|
14
|
-
height?: number;
|
|
15
|
-
/** Render width in columns. Default: 80. */
|
|
16
|
-
width?: number;
|
|
17
|
-
/** Bijou context for IO, styling, and mode detection. */
|
|
18
|
-
ctx?: BijouContext;
|
|
19
|
-
}
|
|
1
|
+
export type { TextareaOptions } from './textarea-editor.js';
|
|
2
|
+
import type { TextareaOptions } from './textarea-editor.js';
|
|
20
3
|
/**
|
|
21
4
|
* Prompt the user for multi-line text input.
|
|
22
5
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"textarea.d.ts","sourceRoot":"","sources":["../../../src/core/forms/textarea.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"textarea.d.ts","sourceRoot":"","sources":["../../../src/core/forms/textarea.ts"],"names":[],"mappings":"AAIA,YAAY,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAC5D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAE5D;;;;;;;;;GASG;AACH,wBAAsB,QAAQ,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,MAAM,CAAC,CAQxE"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { resolveCtx } from '../resolve-ctx.js';
|
|
2
|
-
import { formatFormTitle, writeValidationError,
|
|
2
|
+
import { formatFormTitle, writeValidationError, formDispatch } from './form-utils.js';
|
|
3
|
+
import { interactiveTextarea } from './textarea-editor.js';
|
|
3
4
|
/**
|
|
4
5
|
* Prompt the user for multi-line text input.
|
|
5
6
|
*
|
|
@@ -42,198 +43,4 @@ async function fallbackTextarea(options, ctx) {
|
|
|
42
43
|
}
|
|
43
44
|
return value;
|
|
44
45
|
}
|
|
45
|
-
/**
|
|
46
|
-
* Render a full interactive textarea editor using raw terminal input.
|
|
47
|
-
*
|
|
48
|
-
* Supports arrow-key cursor movement, scrolling, line wrapping,
|
|
49
|
-
* optional line numbers, placeholder text, and a max-length guard.
|
|
50
|
-
* Ctrl+D submits; Ctrl+C or Escape cancels.
|
|
51
|
-
*
|
|
52
|
-
* @param options - Textarea field configuration.
|
|
53
|
-
* @param ctx - Bijou context.
|
|
54
|
-
* @returns The entered text (newline-joined), or the default value on cancel.
|
|
55
|
-
*/
|
|
56
|
-
async function interactiveTextarea(options, ctx) {
|
|
57
|
-
const t = ctx.theme;
|
|
58
|
-
const styledFn = createStyledFn(ctx);
|
|
59
|
-
const height = options.height ?? 6;
|
|
60
|
-
const renderWidth = options.width ?? 80;
|
|
61
|
-
const showLineNumbers = options.showLineNumbers ?? false;
|
|
62
|
-
const term = terminalRenderer(ctx);
|
|
63
|
-
let lines = [''];
|
|
64
|
-
let cursorRow = 0;
|
|
65
|
-
let cursorCol = 0;
|
|
66
|
-
let scrollY = 0;
|
|
67
|
-
function visibleLines() {
|
|
68
|
-
return lines.slice(scrollY, scrollY + height);
|
|
69
|
-
}
|
|
70
|
-
function ensureCursorVisible() {
|
|
71
|
-
if (cursorRow < scrollY)
|
|
72
|
-
scrollY = cursorRow;
|
|
73
|
-
if (cursorRow >= scrollY + height)
|
|
74
|
-
scrollY = cursorRow - height + 1;
|
|
75
|
-
}
|
|
76
|
-
function render() {
|
|
77
|
-
const label = formatFormTitle(options.title, ctx);
|
|
78
|
-
const hint = styledFn(t.theme.semantic.muted, ' (Ctrl+D to submit, Ctrl+C/Esc to cancel)');
|
|
79
|
-
term.hideCursor();
|
|
80
|
-
term.writeLine(`${label}${hint}`);
|
|
81
|
-
const vis = visibleLines();
|
|
82
|
-
const prefixWidth = showLineNumbers ? 6 : 2; // " 1 │ " or " "
|
|
83
|
-
const contentWidth = Math.max(1, renderWidth - prefixWidth);
|
|
84
|
-
for (let i = 0; i < height; i++) {
|
|
85
|
-
const lineIdx = scrollY + i;
|
|
86
|
-
const rawLine = vis[i] ?? '';
|
|
87
|
-
const line = rawLine.length > contentWidth ? rawLine.slice(0, contentWidth) : rawLine;
|
|
88
|
-
const prefix = showLineNumbers
|
|
89
|
-
? styledFn(t.theme.semantic.muted, `${String(lineIdx + 1).padStart(3)} │ `)
|
|
90
|
-
: ' ';
|
|
91
|
-
if (lineIdx === 0 && options.placeholder && lines.length === 1 && lines[0] === '') {
|
|
92
|
-
ctx.io.write(`\x1b[K${prefix}${styledFn(t.theme.semantic.muted, options.placeholder)}\n`);
|
|
93
|
-
}
|
|
94
|
-
else {
|
|
95
|
-
ctx.io.write(`\x1b[K${prefix}${line}\n`);
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
// Status line
|
|
99
|
-
const pos = `Ln ${cursorRow + 1}, Col ${cursorCol + 1}`;
|
|
100
|
-
const lenInfo = options.maxLength ? ` | ${currentLength()}/${options.maxLength}` : '';
|
|
101
|
-
ctx.io.write(`\x1b[K${styledFn(t.theme.semantic.muted, pos + lenInfo)}\n`);
|
|
102
|
-
}
|
|
103
|
-
function currentLength() {
|
|
104
|
-
return lines.join('\n').length;
|
|
105
|
-
}
|
|
106
|
-
function clearRender() {
|
|
107
|
-
const totalLines = height + 2; // header + visible lines + status
|
|
108
|
-
term.moveUp(totalLines);
|
|
109
|
-
}
|
|
110
|
-
function cleanup(submitted) {
|
|
111
|
-
clearRender();
|
|
112
|
-
const totalLines = height + 2;
|
|
113
|
-
term.clearBlock(totalLines);
|
|
114
|
-
const value = submitted ? lines.join('\n') : '';
|
|
115
|
-
const summary = value
|
|
116
|
-
? (value.includes('\n') ? `${value.split('\n').length} lines` : value)
|
|
117
|
-
: '(cancelled)';
|
|
118
|
-
const label = formatFormTitle(options.title, ctx) + ' ' + styledFn(t.theme.semantic.info, summary);
|
|
119
|
-
ctx.io.write(`\x1b[K${label}\n`);
|
|
120
|
-
term.showCursor();
|
|
121
|
-
}
|
|
122
|
-
render();
|
|
123
|
-
return new Promise((resolve) => {
|
|
124
|
-
const handle = ctx.io.rawInput((key) => {
|
|
125
|
-
if (key === '\x04') {
|
|
126
|
-
// Ctrl+D — submit
|
|
127
|
-
handle.dispose();
|
|
128
|
-
cleanup(true);
|
|
129
|
-
resolve(lines.join('\n'));
|
|
130
|
-
return;
|
|
131
|
-
}
|
|
132
|
-
if (key === '\x03' || key === '\x1b') {
|
|
133
|
-
// Ctrl+C or Escape — cancel
|
|
134
|
-
// Note: bare \x1b may false-trigger on slow connections where escape
|
|
135
|
-
// sequences arrive as separate bytes. Timer-based disambiguation is a
|
|
136
|
-
// separate future improvement.
|
|
137
|
-
handle.dispose();
|
|
138
|
-
cleanup(false);
|
|
139
|
-
resolve(options.defaultValue ?? '');
|
|
140
|
-
return;
|
|
141
|
-
}
|
|
142
|
-
if (key === '\r' || key === '\n') {
|
|
143
|
-
// Enter — newline (counts as 1 character for maxLength)
|
|
144
|
-
if (options.maxLength && currentLength() >= options.maxLength)
|
|
145
|
-
return;
|
|
146
|
-
const currentLine = lines[cursorRow];
|
|
147
|
-
const before = currentLine.slice(0, cursorCol);
|
|
148
|
-
const after = currentLine.slice(cursorCol);
|
|
149
|
-
lines[cursorRow] = before;
|
|
150
|
-
lines.splice(cursorRow + 1, 0, after);
|
|
151
|
-
cursorRow++;
|
|
152
|
-
cursorCol = 0;
|
|
153
|
-
ensureCursorVisible();
|
|
154
|
-
clearRender();
|
|
155
|
-
render();
|
|
156
|
-
return;
|
|
157
|
-
}
|
|
158
|
-
if (key === '\x7f' || key === '\b') {
|
|
159
|
-
// Backspace
|
|
160
|
-
if (cursorCol > 0) {
|
|
161
|
-
const line = lines[cursorRow];
|
|
162
|
-
lines[cursorRow] = line.slice(0, cursorCol - 1) + line.slice(cursorCol);
|
|
163
|
-
cursorCol--;
|
|
164
|
-
}
|
|
165
|
-
else if (cursorRow > 0) {
|
|
166
|
-
// Merge with previous line
|
|
167
|
-
const prevLine = lines[cursorRow - 1];
|
|
168
|
-
const currentLine = lines[cursorRow];
|
|
169
|
-
cursorCol = prevLine.length;
|
|
170
|
-
lines[cursorRow - 1] = prevLine + currentLine;
|
|
171
|
-
lines.splice(cursorRow, 1);
|
|
172
|
-
cursorRow--;
|
|
173
|
-
ensureCursorVisible();
|
|
174
|
-
}
|
|
175
|
-
clearRender();
|
|
176
|
-
render();
|
|
177
|
-
return;
|
|
178
|
-
}
|
|
179
|
-
// Arrow keys
|
|
180
|
-
if (key === '\x1b[A') { // Up
|
|
181
|
-
if (cursorRow > 0) {
|
|
182
|
-
cursorRow--;
|
|
183
|
-
cursorCol = Math.min(cursorCol, lines[cursorRow].length);
|
|
184
|
-
ensureCursorVisible();
|
|
185
|
-
}
|
|
186
|
-
clearRender();
|
|
187
|
-
render();
|
|
188
|
-
return;
|
|
189
|
-
}
|
|
190
|
-
if (key === '\x1b[B') { // Down
|
|
191
|
-
if (cursorRow < lines.length - 1) {
|
|
192
|
-
cursorRow++;
|
|
193
|
-
cursorCol = Math.min(cursorCol, lines[cursorRow].length);
|
|
194
|
-
ensureCursorVisible();
|
|
195
|
-
}
|
|
196
|
-
clearRender();
|
|
197
|
-
render();
|
|
198
|
-
return;
|
|
199
|
-
}
|
|
200
|
-
if (key === '\x1b[C') { // Right
|
|
201
|
-
if (cursorCol < lines[cursorRow].length) {
|
|
202
|
-
cursorCol++;
|
|
203
|
-
}
|
|
204
|
-
else if (cursorRow < lines.length - 1) {
|
|
205
|
-
cursorRow++;
|
|
206
|
-
cursorCol = 0;
|
|
207
|
-
ensureCursorVisible();
|
|
208
|
-
}
|
|
209
|
-
clearRender();
|
|
210
|
-
render();
|
|
211
|
-
return;
|
|
212
|
-
}
|
|
213
|
-
if (key === '\x1b[D') { // Left
|
|
214
|
-
if (cursorCol > 0) {
|
|
215
|
-
cursorCol--;
|
|
216
|
-
}
|
|
217
|
-
else if (cursorRow > 0) {
|
|
218
|
-
cursorRow--;
|
|
219
|
-
cursorCol = lines[cursorRow].length;
|
|
220
|
-
ensureCursorVisible();
|
|
221
|
-
}
|
|
222
|
-
clearRender();
|
|
223
|
-
render();
|
|
224
|
-
return;
|
|
225
|
-
}
|
|
226
|
-
// Printable character
|
|
227
|
-
if (key.length === 1 && key >= ' ') {
|
|
228
|
-
if (options.maxLength && currentLength() >= options.maxLength)
|
|
229
|
-
return;
|
|
230
|
-
const line = lines[cursorRow];
|
|
231
|
-
lines[cursorRow] = line.slice(0, cursorCol) + key + line.slice(cursorCol);
|
|
232
|
-
cursorCol++;
|
|
233
|
-
clearRender();
|
|
234
|
-
render();
|
|
235
|
-
}
|
|
236
|
-
});
|
|
237
|
-
});
|
|
238
|
-
}
|
|
239
46
|
//# sourceMappingURL=textarea.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"textarea.js","sourceRoot":"","sources":["../../../src/core/forms/textarea.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"textarea.js","sourceRoot":"","sources":["../../../src/core/forms/textarea.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,eAAe,EAAE,oBAAoB,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AACtF,OAAO,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAI3D;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,QAAQ,CAAC,OAAwB;IACrD,MAAM,GAAG,GAAG,UAAU,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IAEpC,OAAO,YAAY,CACjB,GAAG,EACH,CAAC,CAAC,EAAE,EAAE,CAAC,mBAAmB,CAAC,OAAO,EAAE,CAAC,CAAC,EACtC,CAAC,CAAC,EAAE,EAAE,CAAC,gBAAgB,CAAC,OAAO,EAAE,CAAC,CAAC,CACpC,CAAC;AACJ,CAAC;AAED;;;;;;;;;GASG;AACH,KAAK,UAAU,gBAAgB,CAAC,OAAwB,EAAE,GAAiB;IACzE,GAAG,CAAC,EAAE,CAAC,KAAK,CAAC,eAAe,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,GAAG,IAAI,CAAC,CAAC;IAEzD,MAAM,MAAM,GAAG,GAAG,CAAC,IAAI,KAAK,YAAY;QACtC,CAAC,CAAC,cAAc;QAChB,CAAC,CAAC,IAAI,CAAC;IACT,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;IAC7C,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,EAAE,IAAI,OAAO,CAAC,YAAY,IAAI,EAAE,CAAC;IAE1D,IAAI,OAAO,CAAC,QAAQ,IAAI,KAAK,KAAK,EAAE,EAAE,CAAC;QACrC,oBAAoB,CAAC,yBAAyB,EAAE,GAAG,CAAC,CAAC;IACvD,CAAC;IAED,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC;QACrB,MAAM,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;QACvC,IAAI,CAAC,MAAM,CAAC,KAAK,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;YACpC,oBAAoB,CAAC,MAAM,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;QAC5C,CAAC;IACH,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC"}
|
|
@@ -49,6 +49,8 @@ export interface SelectOption<T = string> {
|
|
|
49
49
|
export interface SelectFieldOptions<T = string> extends FieldOptions<T> {
|
|
50
50
|
/** List of selectable options. */
|
|
51
51
|
options: SelectOption<T>[];
|
|
52
|
+
/** Maximum number of options visible at once in interactive mode. Default: 7. */
|
|
53
|
+
maxVisible?: number;
|
|
52
54
|
}
|
|
53
55
|
/**
|
|
54
56
|
* Options for a yes/no confirmation field.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/core/forms/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,2CAA2C;IAC3C,KAAK,EAAE,OAAO,CAAC;IACf,0DAA0D;IAC1D,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;;GAIG;AACH,MAAM,MAAM,SAAS,CAAC,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,KAAK,gBAAgB,CAAC;AAE1D;;;;GAIG;AACH,MAAM,WAAW,YAAY,CAAC,CAAC;IAC7B,sCAAsC;IACtC,KAAK,EAAE,MAAM,CAAC;IACd,8DAA8D;IAC9D,YAAY,CAAC,EAAE,CAAC,CAAC;IACjB,qDAAqD;IACrD,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,kEAAkE;IAClE,QAAQ,CAAC,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC;CACzB;AAED;;;;GAIG;AACH,MAAM,WAAW,YAAY,CAAC,CAAC,GAAG,MAAM;IACtC,8CAA8C;IAC9C,KAAK,EAAE,MAAM,CAAC;IACd,mDAAmD;IACnD,KAAK,EAAE,CAAC,CAAC;IACT,uDAAuD;IACvD,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED;;;;GAIG;AACH,MAAM,WAAW,kBAAkB,CAAC,CAAC,GAAG,MAAM,CAAE,SAAQ,YAAY,CAAC,CAAC,CAAC;IACrE,kCAAkC;IAClC,OAAO,EAAE,YAAY,CAAC,CAAC,CAAC,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/core/forms/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,2CAA2C;IAC3C,KAAK,EAAE,OAAO,CAAC;IACf,0DAA0D;IAC1D,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;;GAIG;AACH,MAAM,MAAM,SAAS,CAAC,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,KAAK,gBAAgB,CAAC;AAE1D;;;;GAIG;AACH,MAAM,WAAW,YAAY,CAAC,CAAC;IAC7B,sCAAsC;IACtC,KAAK,EAAE,MAAM,CAAC;IACd,8DAA8D;IAC9D,YAAY,CAAC,EAAE,CAAC,CAAC;IACjB,qDAAqD;IACrD,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,kEAAkE;IAClE,QAAQ,CAAC,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC;CACzB;AAED;;;;GAIG;AACH,MAAM,WAAW,YAAY,CAAC,CAAC,GAAG,MAAM;IACtC,8CAA8C;IAC9C,KAAK,EAAE,MAAM,CAAC;IACd,mDAAmD;IACnD,KAAK,EAAE,CAAC,CAAC;IACT,uDAAuD;IACvD,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED;;;;GAIG;AACH,MAAM,WAAW,kBAAkB,CAAC,CAAC,GAAG,MAAM,CAAE,SAAQ,YAAY,CAAC,CAAC,CAAC;IACrE,kCAAkC;IAClC,OAAO,EAAE,YAAY,CAAC,CAAC,CAAC,EAAE,CAAC;IAC3B,iFAAiF;IACjF,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;GAEG;AACH,MAAM,WAAW,mBAAoB,SAAQ,YAAY,CAAC,OAAO,CAAC;IAChE,wDAAwD;IACxD,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAED;;;;GAIG;AACH,MAAM,WAAW,gBAAgB,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IACjE,4CAA4C;IAC5C,MAAM,EAAE,CAAC,CAAC;IACV,6DAA6D;IAC7D,SAAS,EAAE,OAAO,CAAC;CACpB"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { Theme, TokenValue, InkColor } from './tokens.js';
|
|
2
2
|
import type { RuntimePort } from '../../ports/runtime.js';
|
|
3
|
+
import type { WritePort } from '../../ports/io.js';
|
|
3
4
|
import type { ColorScheme } from '../detect/tty.js';
|
|
4
5
|
/**
|
|
5
6
|
* Check the no-color.org spec: `NO_COLOR` defined (any value) means no color.
|
|
@@ -52,6 +53,12 @@ export interface ThemeResolverOptions {
|
|
|
52
53
|
fallback?: Theme;
|
|
53
54
|
/** Optional RuntimePort for reading env vars. Falls back to `process.env`. */
|
|
54
55
|
runtime?: RuntimePort;
|
|
56
|
+
/**
|
|
57
|
+
* Optional output port for resolver warnings (unknown env/configured theme names).
|
|
58
|
+
*
|
|
59
|
+
* When omitted, resolver fallbacks remain silent.
|
|
60
|
+
*/
|
|
61
|
+
warningPort?: Pick<WritePort, 'writeError'>;
|
|
55
62
|
}
|
|
56
63
|
/** A stateful theme resolver that caches the resolved theme and reads env vars. */
|
|
57
64
|
export interface ThemeResolver {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resolve.d.ts","sourceRoot":"","sources":["../../../src/core/theme/resolve.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAC/D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAIpD;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,OAAO,CAAC,EAAE,WAAW,GAAG,OAAO,CAGxD;AAED,8EAA8E;AAC9E,MAAM,WAAW,aAAa;IAC5B,mCAAmC;IACnC,KAAK,EAAE,KAAK,CAAC;IACb,yDAAyD;IACzD,OAAO,EAAE,OAAO,CAAC;IACjB,iEAAiE;IACjE,WAAW,EAAE,WAAW,CAAC;IAEzB;;;;OAIG;IACH,GAAG,CAAC,KAAK,EAAE,UAAU,GAAG,QAAQ,CAAC;IAEjC;;;;OAIG;IACH,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,QAAQ,CAAC;IAEpC;;;;OAIG;IACH,GAAG,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM,CAAC;CAChC;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,WAAW,GAAE,WAAoB,GAAG,aAAa,CAqB/G;AAED,0DAA0D;AAC1D,MAAM,WAAW,oBAAoB;IACnC,8EAA8E;IAC9E,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,uFAAuF;IACvF,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;IAChC,+EAA+E;IAC/E,QAAQ,CAAC,EAAE,KAAK,CAAC;IACjB,8EAA8E;IAC9E,OAAO,CAAC,EAAE,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"resolve.d.ts","sourceRoot":"","sources":["../../../src/core/theme/resolve.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAC/D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAIpD;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,OAAO,CAAC,EAAE,WAAW,GAAG,OAAO,CAGxD;AAED,8EAA8E;AAC9E,MAAM,WAAW,aAAa;IAC5B,mCAAmC;IACnC,KAAK,EAAE,KAAK,CAAC;IACb,yDAAyD;IACzD,OAAO,EAAE,OAAO,CAAC;IACjB,iEAAiE;IACjE,WAAW,EAAE,WAAW,CAAC;IAEzB;;;;OAIG;IACH,GAAG,CAAC,KAAK,EAAE,UAAU,GAAG,QAAQ,CAAC;IAEjC;;;;OAIG;IACH,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,QAAQ,CAAC;IAEpC;;;;OAIG;IACH,GAAG,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM,CAAC;CAChC;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,WAAW,GAAE,WAAoB,GAAG,aAAa,CAqB/G;AAED,0DAA0D;AAC1D,MAAM,WAAW,oBAAoB;IACnC,8EAA8E;IAC9E,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,uFAAuF;IACvF,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;IAChC,+EAA+E;IAC/E,QAAQ,CAAC,EAAE,KAAK,CAAC;IACjB,8EAA8E;IAC9E,OAAO,CAAC,EAAE,WAAW,CAAC;IACtB;;;;OAIG;IACH,WAAW,CAAC,EAAE,IAAI,CAAC,SAAS,EAAE,YAAY,CAAC,CAAC;CAC7C;AAED,mFAAmF;AACnF,MAAM,WAAW,aAAa;IAC5B,4DAA4D;IAC5D,QAAQ,IAAI,aAAa,CAAC;IAC1B;;;OAGG;IACH,YAAY,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,aAAa,CAAC;IAC3C,kDAAkD;IAClD,gBAAgB,IAAI,IAAI,CAAC;CAC1B;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,GAAE,oBAAyB,GAAG,aAAa,CAsDrF;AAKD;;;GAGG;AACH,wBAAgB,QAAQ,IAAI,aAAa,CAExC;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,aAAa,CAEzD;AAED,sEAAsE;AACtE,wBAAgB,qBAAqB,IAAI,IAAI,CAE5C"}
|
|
@@ -47,9 +47,13 @@ export function createThemeResolver(options = {}) {
|
|
|
47
47
|
const presets = options.presets ?? PRESETS;
|
|
48
48
|
const fallback = options.fallback ?? CYAN_MAGENTA;
|
|
49
49
|
const runtime = options.runtime;
|
|
50
|
+
const warningPort = options.warningPort;
|
|
50
51
|
const readEnv = runtime
|
|
51
52
|
? (key) => runtime.env(key)
|
|
52
53
|
: (key) => process.env[key];
|
|
54
|
+
const warn = (message) => {
|
|
55
|
+
warningPort?.writeError?.(`${message}\n`);
|
|
56
|
+
};
|
|
53
57
|
let cached = null;
|
|
54
58
|
function getTheme() {
|
|
55
59
|
if (cached !== null)
|
|
@@ -59,7 +63,7 @@ export function createThemeResolver(options = {}) {
|
|
|
59
63
|
const themeName = readEnv(envVar) ?? fallback.name;
|
|
60
64
|
const theme = presets[themeName];
|
|
61
65
|
if (theme === undefined) {
|
|
62
|
-
|
|
66
|
+
warn(`[bijou] Unknown ${envVar}="${themeName}", falling back to "${fallback.name}".`);
|
|
63
67
|
cached = createResolved(fallback, noColor, colorScheme);
|
|
64
68
|
}
|
|
65
69
|
else {
|
|
@@ -73,7 +77,7 @@ export function createThemeResolver(options = {}) {
|
|
|
73
77
|
const themeName = name ?? readEnv(envVar) ?? fallback.name;
|
|
74
78
|
const theme = presets[themeName];
|
|
75
79
|
if (theme === undefined) {
|
|
76
|
-
|
|
80
|
+
warn(`[bijou] Unknown theme "${themeName}", falling back to "${fallback.name}".`);
|
|
77
81
|
return createResolved(fallback, noColor, colorScheme);
|
|
78
82
|
}
|
|
79
83
|
return createResolved(theme, noColor, colorScheme);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resolve.js","sourceRoot":"","sources":["../../../src/core/theme/resolve.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"resolve.js","sourceRoot":"","sources":["../../../src/core/theme/resolve.ts"],"names":[],"mappings":"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"}
|
package/dist/ports/io.d.ts
CHANGED
|
@@ -17,6 +17,8 @@ export interface TimerHandle {
|
|
|
17
17
|
export interface WritePort {
|
|
18
18
|
/** Write a string to the output stream (typically stdout). */
|
|
19
19
|
write(data: string): void;
|
|
20
|
+
/** Write a string to the error stream (typically stderr). */
|
|
21
|
+
writeError?: (data: string) => void;
|
|
20
22
|
}
|
|
21
23
|
/**
|
|
22
24
|
* Output + line-oriented input port.
|
package/dist/ports/io.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"io.d.ts","sourceRoot":"","sources":["../../src/ports/io.ts"],"names":[],"mappings":"AAAA,mEAAmE;AACnE,MAAM,WAAW,cAAc;IAC7B,iDAAiD;IACjD,OAAO,IAAI,IAAI,CAAC;CACjB;AAED,qDAAqD;AACrD,MAAM,WAAW,WAAW;IAC1B,wBAAwB;IACxB,OAAO,IAAI,IAAI,CAAC;CACjB;AAED;;;;;GAKG;AACH,MAAM,WAAW,SAAS;IACxB,8DAA8D;IAC9D,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"io.d.ts","sourceRoot":"","sources":["../../src/ports/io.ts"],"names":[],"mappings":"AAAA,mEAAmE;AACnE,MAAM,WAAW,cAAc;IAC7B,iDAAiD;IACjD,OAAO,IAAI,IAAI,CAAC;CACjB;AAED,qDAAqD;AACrD,MAAM,WAAW,WAAW;IAC1B,wBAAwB;IACxB,OAAO,IAAI,IAAI,CAAC;CACjB;AAED;;;;;GAKG;AACH,MAAM,WAAW,SAAS;IACxB,8DAA8D;IAC9D,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,6DAA6D;IAC7D,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CACrC;AAED;;;;;GAKG;AACH,MAAM,WAAW,SAAU,SAAQ,SAAS;IAC1C,uDAAuD;IACvD,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;CAC3C;AAED;;;;;GAKG;AACH,MAAM,WAAW,eAAgB,SAAQ,SAAS;IAChD;;;OAGG;IACH,QAAQ,CAAC,KAAK,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,GAAG,cAAc,CAAC;IAEvD;;;OAGG;IACH,WAAW,CAAC,QAAQ,EAAE,MAAM,IAAI,EAAE,EAAE,EAAE,MAAM,GAAG,WAAW,CAAC;CAC5D;AAED;;;;;GAKG;AACH,MAAM,WAAW,QAAQ;IACvB,6CAA6C;IAC7C,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC;IAE/B;;;OAGG;IACH,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAEhC,uDAAuD;IACvD,QAAQ,CAAC,GAAG,QAAQ,EAAE,MAAM,EAAE,GAAG,MAAM,CAAC;CACzC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,MAAO,SAAQ,eAAe,EAAE,QAAQ;IACvD;;;OAGG;IACH,QAAQ,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,IAAI,GAAG,cAAc,CAAC;CAC1E"}
|