@silvery/examples 0.17.3 → 0.17.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 (112) hide show
  1. package/dist/UPNG-Cy7ViL8f.mjs +5074 -0
  2. package/dist/__vite-browser-external-2447137e-BML7CYau.mjs +4 -0
  3. package/dist/_banner-DLPxCqVy.mjs +44 -0
  4. package/dist/ansi-CCE2pVS0.mjs +16397 -0
  5. package/dist/apng-HhhBjRGt.mjs +68 -0
  6. package/dist/apng-mwUQbTTF.mjs +3 -0
  7. package/dist/apps/aichat/index.mjs +1299 -0
  8. package/dist/apps/app-todo.mjs +139 -0
  9. package/dist/apps/async-data.mjs +204 -0
  10. package/dist/apps/cli-wizard.mjs +339 -0
  11. package/dist/apps/clipboard.mjs +198 -0
  12. package/dist/apps/components.mjs +864 -0
  13. package/dist/apps/data-explorer.mjs +483 -0
  14. package/dist/apps/dev-tools.mjs +397 -0
  15. package/dist/apps/explorer.mjs +698 -0
  16. package/dist/apps/gallery.mjs +766 -0
  17. package/dist/apps/inline-bench.mjs +115 -0
  18. package/dist/apps/kanban.mjs +280 -0
  19. package/dist/apps/layout-ref.mjs +187 -0
  20. package/dist/apps/outline.mjs +203 -0
  21. package/dist/apps/paste-demo.mjs +189 -0
  22. package/dist/apps/scroll.mjs +86 -0
  23. package/dist/apps/search-filter.mjs +287 -0
  24. package/dist/apps/selection.mjs +355 -0
  25. package/dist/apps/spatial-focus-demo.mjs +388 -0
  26. package/dist/apps/task-list.mjs +258 -0
  27. package/dist/apps/terminal-caps-demo.mjs +315 -0
  28. package/dist/apps/terminal.mjs +872 -0
  29. package/dist/apps/text-selection-demo.mjs +254 -0
  30. package/dist/apps/textarea.mjs +178 -0
  31. package/dist/apps/theme.mjs +661 -0
  32. package/dist/apps/transform.mjs +215 -0
  33. package/dist/apps/virtual-10k.mjs +422 -0
  34. package/dist/assets/resvgjs.darwin-arm64-BtufyGW1.node +0 -0
  35. package/dist/backends-Bahh9mKN.mjs +1179 -0
  36. package/dist/backends-CCtCDQ94.mjs +3 -0
  37. package/dist/{cli.mjs → bin/cli.mjs} +15 -19
  38. package/dist/chunk-BSw8zbkd.mjs +37 -0
  39. package/dist/components/counter.mjs +48 -0
  40. package/dist/components/hello.mjs +31 -0
  41. package/dist/components/progress-bar.mjs +59 -0
  42. package/dist/components/select-list.mjs +85 -0
  43. package/dist/components/spinner.mjs +57 -0
  44. package/dist/components/text-input.mjs +62 -0
  45. package/dist/components/virtual-list.mjs +51 -0
  46. package/dist/flexily-zero-adapter-UB-ra8fR.mjs +3374 -0
  47. package/dist/gif-BZaqPPVX.mjs +3 -0
  48. package/dist/gif-BtnXuxLF.mjs +71 -0
  49. package/dist/gifenc-CLRW41dk.mjs +728 -0
  50. package/dist/jsx-runtime-dMs_8fNu.mjs +241 -0
  51. package/dist/key-mapping-5oYQdAQE.mjs +3 -0
  52. package/dist/key-mapping-D4LR1go6.mjs +130 -0
  53. package/dist/layout/dashboard.mjs +1204 -0
  54. package/dist/layout/live-resize.mjs +303 -0
  55. package/dist/layout/overflow.mjs +70 -0
  56. package/dist/layout/text-layout.mjs +335 -0
  57. package/dist/node-NuJ94BWl.mjs +1083 -0
  58. package/dist/plugins-D1KtkT4a.mjs +3057 -0
  59. package/dist/resvg-js-C_8Wps1F.mjs +201 -0
  60. package/dist/src-BTEVGpd9.mjs +23538 -0
  61. package/dist/src-CUUOuRH6.mjs +5322 -0
  62. package/dist/src-CzfRafCQ.mjs +814 -0
  63. package/dist/usingCtx-CsEf0xO3.mjs +57 -0
  64. package/dist/yoga-adapter-BVtQ5OJR.mjs +237 -0
  65. package/package.json +18 -13
  66. package/_banner.tsx +0 -60
  67. package/apps/aichat/components.tsx +0 -469
  68. package/apps/aichat/index.tsx +0 -220
  69. package/apps/aichat/script.ts +0 -460
  70. package/apps/aichat/state.ts +0 -325
  71. package/apps/aichat/types.ts +0 -19
  72. package/apps/app-todo.tsx +0 -201
  73. package/apps/async-data.tsx +0 -196
  74. package/apps/cli-wizard.tsx +0 -332
  75. package/apps/clipboard.tsx +0 -183
  76. package/apps/components.tsx +0 -658
  77. package/apps/data-explorer.tsx +0 -490
  78. package/apps/dev-tools.tsx +0 -395
  79. package/apps/explorer.tsx +0 -731
  80. package/apps/gallery.tsx +0 -653
  81. package/apps/inline-bench.tsx +0 -138
  82. package/apps/kanban.tsx +0 -265
  83. package/apps/layout-ref.tsx +0 -173
  84. package/apps/outline.tsx +0 -160
  85. package/apps/panes/index.tsx +0 -203
  86. package/apps/paste-demo.tsx +0 -185
  87. package/apps/scroll.tsx +0 -80
  88. package/apps/search-filter.tsx +0 -240
  89. package/apps/selection.tsx +0 -346
  90. package/apps/spatial-focus-demo.tsx +0 -372
  91. package/apps/task-list.tsx +0 -271
  92. package/apps/terminal-caps-demo.tsx +0 -317
  93. package/apps/terminal.tsx +0 -784
  94. package/apps/text-selection-demo.tsx +0 -193
  95. package/apps/textarea.tsx +0 -155
  96. package/apps/theme.tsx +0 -515
  97. package/apps/transform.tsx +0 -229
  98. package/apps/virtual-10k.tsx +0 -405
  99. package/apps/vterm-demo/index.tsx +0 -216
  100. package/components/counter.tsx +0 -49
  101. package/components/hello.tsx +0 -38
  102. package/components/progress-bar.tsx +0 -52
  103. package/components/select-list.tsx +0 -54
  104. package/components/spinner.tsx +0 -44
  105. package/components/text-input.tsx +0 -61
  106. package/components/virtual-list.tsx +0 -56
  107. package/dist/cli.d.mts +0 -1
  108. package/dist/cli.mjs.map +0 -1
  109. package/layout/dashboard.tsx +0 -953
  110. package/layout/live-resize.tsx +0 -282
  111. package/layout/overflow.tsx +0 -51
  112. package/layout/text-layout.tsx +0 -283
@@ -0,0 +1,766 @@
1
+ import { t as _usingCtx } from "../usingCtx-CsEf0xO3.mjs";
2
+ import { t as require_jsx_runtime } from "../jsx-runtime-dMs_8fNu.mjs";
3
+ import { t as ExampleBanner } from "../_banner-DLPxCqVy.mjs";
4
+ import { useMemo, useState } from "react";
5
+ import { Box, H2, Image, Kbd, Muted, Tab, TabList, TabPanel, Tabs, Text, createTerm, render, useApp, useBoxRect, useInput } from "silvery";
6
+ import { deflateSync } from "node:zlib";
7
+ //#region apps/gallery.tsx
8
+ var import_jsx_runtime = require_jsx_runtime();
9
+ const meta = {
10
+ name: "Gallery",
11
+ description: "Kitty images, pixel art, and truecolor rendering",
12
+ demo: true,
13
+ features: [
14
+ "Image",
15
+ "Kitty graphics",
16
+ "half-block",
17
+ "truecolor",
18
+ "mouse input"
19
+ ]
20
+ };
21
+ /** HSV to RGB (h: 0-360, s/v: 0-1) */
22
+ function hsvToRgb(h, s, v) {
23
+ const c = v * s;
24
+ const x = c * (1 - Math.abs(h / 60 % 2 - 1));
25
+ const m = v - c;
26
+ let r = 0, g = 0, b = 0;
27
+ if (h < 60) {
28
+ r = c;
29
+ g = x;
30
+ } else if (h < 120) {
31
+ r = x;
32
+ g = c;
33
+ } else if (h < 180) {
34
+ g = c;
35
+ b = x;
36
+ } else if (h < 240) {
37
+ g = x;
38
+ b = c;
39
+ } else if (h < 300) {
40
+ r = x;
41
+ b = c;
42
+ } else {
43
+ r = c;
44
+ b = x;
45
+ }
46
+ return [
47
+ Math.round((r + m) * 255),
48
+ Math.round((g + m) * 255),
49
+ Math.round((b + m) * 255)
50
+ ];
51
+ }
52
+ /** HSL to RGB (h: 0-360, s/l: 0-1) */
53
+ function hslToRgb(h, s, l) {
54
+ const c = (1 - Math.abs(2 * l - 1)) * s;
55
+ const x = c * (1 - Math.abs(h / 60 % 2 - 1));
56
+ const m = l - c / 2;
57
+ let r1, g1, b1;
58
+ if (h < 60) [r1, g1, b1] = [
59
+ c,
60
+ x,
61
+ 0
62
+ ];
63
+ else if (h < 120) [r1, g1, b1] = [
64
+ x,
65
+ c,
66
+ 0
67
+ ];
68
+ else if (h < 180) [r1, g1, b1] = [
69
+ 0,
70
+ c,
71
+ x
72
+ ];
73
+ else if (h < 240) [r1, g1, b1] = [
74
+ 0,
75
+ x,
76
+ c
77
+ ];
78
+ else if (h < 300) [r1, g1, b1] = [
79
+ x,
80
+ 0,
81
+ c
82
+ ];
83
+ else [r1, g1, b1] = [
84
+ c,
85
+ 0,
86
+ x
87
+ ];
88
+ return [
89
+ Math.round((r1 + m) * 255),
90
+ Math.round((g1 + m) * 255),
91
+ Math.round((b1 + m) * 255)
92
+ ];
93
+ }
94
+ function crc32(data) {
95
+ let crc = 4294967295;
96
+ for (let i = 0; i < data.length; i++) {
97
+ crc ^= data[i];
98
+ for (let j = 0; j < 8; j++) crc = crc & 1 ? crc >>> 1 ^ 3988292384 : crc >>> 1;
99
+ }
100
+ return (crc ^ 4294967295) >>> 0;
101
+ }
102
+ function makeChunk(type, data) {
103
+ const len = Buffer.alloc(4);
104
+ len.writeUInt32BE(data.length);
105
+ const typeBytes = Buffer.from(type, "ascii");
106
+ const payload = Buffer.concat([typeBytes, data]);
107
+ const crc = crc32(payload);
108
+ const crcBuf = Buffer.alloc(4);
109
+ crcBuf.writeUInt32BE(crc >>> 0);
110
+ return Buffer.concat([
111
+ len,
112
+ payload,
113
+ crcBuf
114
+ ]);
115
+ }
116
+ function encodePng(width, height, pixelFn) {
117
+ const rawData = Buffer.alloc(height * (1 + width * 4));
118
+ for (let y = 0; y < height; y++) {
119
+ const rowOffset = y * (1 + width * 4);
120
+ rawData[rowOffset] = 0;
121
+ for (let x = 0; x < width; x++) {
122
+ const [r, g, b] = pixelFn(x, y);
123
+ const off = rowOffset + 1 + x * 4;
124
+ rawData[off] = r;
125
+ rawData[off + 1] = g;
126
+ rawData[off + 2] = b;
127
+ rawData[off + 3] = 255;
128
+ }
129
+ }
130
+ const compressed = deflateSync(rawData);
131
+ const signature = Buffer.from([
132
+ 137,
133
+ 80,
134
+ 78,
135
+ 71,
136
+ 13,
137
+ 10,
138
+ 26,
139
+ 10
140
+ ]);
141
+ const ihdr = Buffer.alloc(13);
142
+ ihdr.writeUInt32BE(width, 0);
143
+ ihdr.writeUInt32BE(height, 4);
144
+ ihdr[8] = 8;
145
+ ihdr[9] = 6;
146
+ return Buffer.concat([
147
+ signature,
148
+ makeChunk("IHDR", ihdr),
149
+ makeChunk("IDAT", compressed),
150
+ makeChunk("IEND", Buffer.alloc(0))
151
+ ]);
152
+ }
153
+ function generateRainbow(w, h) {
154
+ return encodePng(w, h, (x, y) => {
155
+ return hsvToRgb(x / w * 360, .7 + .3 * Math.sin(y / h * Math.PI), .5 + .5 * Math.cos(y / h * Math.PI * 2));
156
+ });
157
+ }
158
+ function generatePlasma(w, h) {
159
+ return encodePng(w, h, (x, y) => {
160
+ const nx = x / w;
161
+ const ny = y / h;
162
+ const v1 = Math.sin(nx * 10 + ny * 3);
163
+ const v2 = Math.sin(nx * 5 - ny * 8 + 2);
164
+ const v3 = Math.sin(Math.sqrt((nx - .5) ** 2 + (ny - .5) ** 2) * 15);
165
+ return hslToRgb(((v1 + v2 + v3) / 3 + 1) / 2 * 360, .9, .55);
166
+ });
167
+ }
168
+ function generateMandelbrot(w, h) {
169
+ return encodePng(w, h, (x, y) => {
170
+ const cx = x / w * 3.5 - 2.5;
171
+ const cy = y / h * 2 - 1;
172
+ let zx = 0, zy = 0;
173
+ let i = 0;
174
+ const maxIter = 80;
175
+ while (zx * zx + zy * zy < 4 && i < maxIter) {
176
+ const tmp = zx * zx - zy * zy + cx;
177
+ zy = 2 * zx * zy + cy;
178
+ zx = tmp;
179
+ i++;
180
+ }
181
+ if (i === maxIter) return [
182
+ 0,
183
+ 0,
184
+ 0
185
+ ];
186
+ return hslToRgb(i / maxIter * 360, 1, .5);
187
+ });
188
+ }
189
+ function generateGradientGrid(w, h) {
190
+ return encodePng(w, h, (x, y) => {
191
+ return [
192
+ Math.round(x / w * 255),
193
+ Math.round(y / h * 255),
194
+ Math.round(255 - (x + y) / (w + h) * 255)
195
+ ];
196
+ });
197
+ }
198
+ function generateCheckerPattern(w, h) {
199
+ const size = 16;
200
+ return encodePng(w, h, (x, y) => {
201
+ const cx = Math.floor(x / size);
202
+ const cy = Math.floor(y / size);
203
+ return hslToRgb((cx + cy) * 30 % 360, .8, (cx + cy) % 2 === 0 ? .6 : .35);
204
+ });
205
+ }
206
+ function ImagesTab() {
207
+ const rect = useBoxRect();
208
+ const w = Math.max(20, rect.width - 4);
209
+ const imgH = Math.max(5, rect.height - 6);
210
+ const images = useMemo(() => {
211
+ const pw = 256;
212
+ const ph = 192;
213
+ return [
214
+ {
215
+ name: "Rainbow",
216
+ description: "HSV color wheel gradient",
217
+ png: generateRainbow(pw, ph)
218
+ },
219
+ {
220
+ name: "Plasma",
221
+ description: "Sine-wave plasma interference",
222
+ png: generatePlasma(pw, ph)
223
+ },
224
+ {
225
+ name: "Mandelbrot",
226
+ description: "Fractal escape-time coloring",
227
+ png: generateMandelbrot(pw, ph)
228
+ },
229
+ {
230
+ name: "RGB Cube",
231
+ description: "Red-Green-Blue gradient grid",
232
+ png: generateGradientGrid(pw, ph)
233
+ },
234
+ {
235
+ name: "Checker",
236
+ description: "Hue-shifted checkerboard",
237
+ png: generateCheckerPattern(pw, ph)
238
+ }
239
+ ];
240
+ }, []);
241
+ const [index, setIndex] = useState(0);
242
+ const img = images[index];
243
+ useInput((input, key) => {
244
+ if (input === "j" || key.downArrow || input === "n") setIndex((i) => (i + 1) % images.length);
245
+ if (input === "k" || key.upArrow || input === "p") setIndex((i) => (i - 1 + images.length) % images.length);
246
+ });
247
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Box, {
248
+ flexDirection: "column",
249
+ flexGrow: 1,
250
+ gap: 1,
251
+ children: [
252
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Box, {
253
+ paddingX: 1,
254
+ gap: 2,
255
+ children: [
256
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, {
257
+ bold: true,
258
+ color: "$primary",
259
+ children: img.name
260
+ }),
261
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Muted, { children: img.description }),
262
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Muted, { children: [
263
+ "(",
264
+ index + 1,
265
+ "/",
266
+ images.length,
267
+ ")"
268
+ ] })
269
+ ]
270
+ }),
271
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Box, {
272
+ flexGrow: 1,
273
+ justifyContent: "center",
274
+ paddingX: 1,
275
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Image, {
276
+ src: img.png,
277
+ width: w,
278
+ height: imgH,
279
+ fallback: `[${img.name} — graphics protocol not available. Run in Kitty/WezTerm/Ghostty for images.]`
280
+ })
281
+ }),
282
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Muted, { children: [
283
+ " ",
284
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Kbd, { children: "j/k" }),
285
+ " navigate images"
286
+ ] })
287
+ ]
288
+ });
289
+ }
290
+ const UPPER_HALF = "▀";
291
+ const LOWER_HALF = "▄";
292
+ const FULL_BLOCK = "█";
293
+ const PAINT_PRESETS = [
294
+ {
295
+ name: "white",
296
+ color: [
297
+ 255,
298
+ 255,
299
+ 255
300
+ ]
301
+ },
302
+ {
303
+ name: "red",
304
+ color: [
305
+ 255,
306
+ 0,
307
+ 0
308
+ ]
309
+ },
310
+ {
311
+ name: "orange",
312
+ color: [
313
+ 255,
314
+ 165,
315
+ 0
316
+ ]
317
+ },
318
+ {
319
+ name: "yellow",
320
+ color: [
321
+ 255,
322
+ 255,
323
+ 0
324
+ ]
325
+ },
326
+ {
327
+ name: "green",
328
+ color: [
329
+ 0,
330
+ 200,
331
+ 0
332
+ ]
333
+ },
334
+ {
335
+ name: "cyan",
336
+ color: [
337
+ 0,
338
+ 255,
339
+ 255
340
+ ]
341
+ },
342
+ {
343
+ name: "blue",
344
+ color: [
345
+ 0,
346
+ 100,
347
+ 255
348
+ ]
349
+ },
350
+ {
351
+ name: "magenta",
352
+ color: [
353
+ 200,
354
+ 0,
355
+ 200
356
+ ]
357
+ },
358
+ {
359
+ name: "pink",
360
+ color: [
361
+ 255,
362
+ 128,
363
+ 200
364
+ ]
365
+ },
366
+ {
367
+ name: "black",
368
+ color: [
369
+ 30,
370
+ 30,
371
+ 30
372
+ ]
373
+ }
374
+ ];
375
+ function PaintTab() {
376
+ const rect = useBoxRect();
377
+ const canvasW = Math.max(10, rect.width - 2);
378
+ const canvasTermH = Math.max(4, rect.height - 7);
379
+ const canvasPixH = canvasTermH * 2;
380
+ const [pixels, setPixels] = useState(() => {
381
+ const rows = [];
382
+ for (let y = 0; y < canvasPixH; y++) rows.push(new Array(canvasW).fill(null));
383
+ const cx = Math.floor(canvasW / 2);
384
+ const cy = Math.floor(canvasPixH / 2);
385
+ const radius = Math.min(cx, cy) - 2;
386
+ for (let angle = 0; angle < 720; angle += 2) {
387
+ const r = angle / 720 * radius;
388
+ const rad = angle * Math.PI / 180;
389
+ const px = Math.round(cx + r * Math.cos(rad));
390
+ const py = Math.round(cy + r * Math.sin(rad));
391
+ const color = hslToRgb(angle % 360, .9, .55);
392
+ for (let dy = -1; dy <= 1; dy++) for (let dx = -1; dx <= 1; dx++) {
393
+ const x = px + dx;
394
+ const y = py + dy;
395
+ if (x >= 0 && x < canvasW && y >= 0 && y < canvasPixH) rows[y][x] = color;
396
+ }
397
+ }
398
+ return rows;
399
+ });
400
+ const [colorIndex, setColorIndex] = useState(1);
401
+ const [tool, setTool] = useState("pen");
402
+ const currentColor = PAINT_PRESETS[colorIndex].color;
403
+ useInput((input) => {
404
+ if (input >= "1" && input <= "9") {
405
+ setColorIndex(Number(input) - 1);
406
+ setTool("pen");
407
+ } else if (input === "0") {
408
+ setColorIndex(9);
409
+ setTool("pen");
410
+ } else if (input === "e") setTool((t) => t === "eraser" ? "pen" : "eraser");
411
+ else if (input === "c") setPixels((prev) => prev.map((row) => row.map(() => null)));
412
+ });
413
+ const canvasLines = [];
414
+ for (let row = 0; row < canvasTermH; row++) {
415
+ const cells = [];
416
+ for (let col = 0; col < canvasW; col++) {
417
+ const top = row * 2 < pixels.length ? pixels[row * 2]?.[col] ?? null : null;
418
+ const bot = row * 2 + 1 < pixels.length ? pixels[row * 2 + 1]?.[col] ?? null : null;
419
+ if (top === null && bot === null) cells.push(/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, { children: " " }, col));
420
+ else if (top !== null && bot === null) cells.push(/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, {
421
+ color: `rgb(${top[0]},${top[1]},${top[2]})`,
422
+ children: UPPER_HALF
423
+ }, col));
424
+ else if (top === null && bot !== null) cells.push(/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, {
425
+ color: `rgb(${bot[0]},${bot[1]},${bot[2]})`,
426
+ children: LOWER_HALF
427
+ }, col));
428
+ else if (top !== null && top[0] === bot?.[0] && top[1] === bot[1] && top[2] === bot[2]) cells.push(/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, {
429
+ color: `rgb(${top[0]},${top[1]},${top[2]})`,
430
+ children: FULL_BLOCK
431
+ }, col));
432
+ else cells.push(/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, {
433
+ color: `rgb(${top[0]},${top[1]},${top[2]})`,
434
+ backgroundColor: `rgb(${bot[0]},${bot[1]},${bot[2]})`,
435
+ children: UPPER_HALF
436
+ }, col));
437
+ }
438
+ canvasLines.push(/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Box, { children: cells }, row));
439
+ }
440
+ const paletteItems = PAINT_PRESETS.map((p, i) => {
441
+ const selected = i === colorIndex;
442
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, {
443
+ backgroundColor: `rgb(${p.color[0]},${p.color[1]},${p.color[2]})`,
444
+ color: p.color[0] + p.color[1] + p.color[2] > 384 ? "black" : "white",
445
+ bold: selected,
446
+ children: selected ? `[${(i + 1) % 10}]` : ` ${(i + 1) % 10} `
447
+ }, i);
448
+ });
449
+ const toolLabel = tool === "pen" ? "Pen" : "Eraser";
450
+ const [cr, cg, cb] = currentColor;
451
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Box, {
452
+ flexDirection: "column",
453
+ flexGrow: 1,
454
+ children: [
455
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Box, {
456
+ paddingX: 1,
457
+ gap: 2,
458
+ children: [
459
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, {
460
+ bold: true,
461
+ color: `rgb(${cr},${cg},${cb})`,
462
+ children: toolLabel
463
+ }),
464
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, {
465
+ backgroundColor: `rgb(${cr},${cg},${cb})`,
466
+ children: " "
467
+ }),
468
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Muted, { children: [
469
+ "rgb(",
470
+ cr,
471
+ ",",
472
+ cg,
473
+ ",",
474
+ cb,
475
+ ")"
476
+ ] })
477
+ ]
478
+ }),
479
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Box, {
480
+ flexDirection: "column",
481
+ flexGrow: 1,
482
+ borderStyle: "round",
483
+ marginX: 1,
484
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Box, {
485
+ flexDirection: "column",
486
+ children: canvasLines
487
+ })
488
+ }),
489
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Box, {
490
+ paddingX: 1,
491
+ gap: 0,
492
+ children: paletteItems
493
+ }),
494
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Muted, { children: [
495
+ " ",
496
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Kbd, { children: "1-0" }),
497
+ " color ",
498
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Kbd, { children: "e" }),
499
+ " eraser ",
500
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Kbd, { children: "c" }),
501
+ " clear (click canvas in Kitty/Ghostty for mouse paint)"
502
+ ] })
503
+ ]
504
+ });
505
+ }
506
+ function TruecolorTab() {
507
+ const rect = useBoxRect();
508
+ const w = Math.max(20, rect.width - 4);
509
+ const availH = Math.max(10, rect.height - 3);
510
+ const hueBarH = Math.min(3, Math.max(1, Math.floor(availH * .15)));
511
+ const gradientH = Math.min(8, Math.max(2, Math.floor(availH * .35)));
512
+ const paletteH = Math.min(4, Math.max(2, Math.floor(availH * .2)));
513
+ const hueBar = [];
514
+ for (let row = 0; row < hueBarH; row++) {
515
+ const cells = [];
516
+ for (let col = 0; col < w; col++) {
517
+ const [r, g, b] = hslToRgb(col / w * 360, 1, .35 + row / Math.max(1, hueBarH - 1) * .3);
518
+ cells.push(/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, {
519
+ backgroundColor: `rgb(${r},${g},${b})`,
520
+ children: " "
521
+ }, col));
522
+ }
523
+ hueBar.push(/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Box, { children: cells }, row));
524
+ }
525
+ const gradient = [];
526
+ for (let row = 0; row < gradientH; row++) {
527
+ const cells = [];
528
+ const sat = 1 - row / Math.max(1, gradientH - 1) * .8;
529
+ for (let col = 0; col < w; col++) {
530
+ const [r, g, b] = hsvToRgb(col / w * 360, sat, .95);
531
+ cells.push(/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, {
532
+ backgroundColor: `rgb(${r},${g},${b})`,
533
+ children: " "
534
+ }, col));
535
+ }
536
+ gradient.push(/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Box, { children: cells }, row));
537
+ }
538
+ const paletteCols = 16;
539
+ const paletteRows = Math.min(paletteH, Math.ceil(256 / paletteCols));
540
+ const palette = [];
541
+ for (let row = 0; row < paletteRows; row++) {
542
+ const cells = [];
543
+ const cellW = Math.max(1, Math.floor(w / paletteCols));
544
+ for (let col = 0; col < paletteCols; col++) {
545
+ const idx = row * paletteCols + col;
546
+ if (idx >= 256) break;
547
+ const [r, g, b] = ansi256toRgb(idx);
548
+ const label = idx.toString().padStart(3);
549
+ const textColor = r + g + b > 384 ? "black" : "white";
550
+ cells.push(/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Box, {
551
+ width: cellW,
552
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, {
553
+ backgroundColor: `rgb(${r},${g},${b})`,
554
+ color: textColor,
555
+ children: label.slice(0, cellW)
556
+ })
557
+ }, col));
558
+ }
559
+ palette.push(/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Box, { children: cells }, row));
560
+ }
561
+ const grayCells = [];
562
+ for (let col = 0; col < w; col++) {
563
+ const v = Math.round(col / Math.max(1, w - 1) * 255);
564
+ grayCells.push(/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, {
565
+ backgroundColor: `rgb(${v},${v},${v})`,
566
+ children: " "
567
+ }, col));
568
+ }
569
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Box, {
570
+ flexDirection: "column",
571
+ flexGrow: 1,
572
+ gap: 1,
573
+ paddingX: 1,
574
+ children: [
575
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Box, {
576
+ flexDirection: "column",
577
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(H2, { children: "HSL Rainbow" }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Box, {
578
+ flexDirection: "column",
579
+ children: hueBar
580
+ })]
581
+ }),
582
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Box, {
583
+ flexDirection: "column",
584
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(H2, { children: "Saturation Gradient" }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Box, {
585
+ flexDirection: "column",
586
+ children: gradient
587
+ })]
588
+ }),
589
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Box, {
590
+ flexDirection: "column",
591
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(H2, { children: "256-Color Palette" }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Box, {
592
+ flexDirection: "column",
593
+ children: palette
594
+ })]
595
+ }),
596
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Box, {
597
+ flexDirection: "column",
598
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(H2, { children: "Grayscale Ramp" }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Box, { children: grayCells })]
599
+ })
600
+ ]
601
+ });
602
+ }
603
+ /** Convert ANSI 256-color index to RGB */
604
+ function ansi256toRgb(idx) {
605
+ if (idx < 16) return [
606
+ [
607
+ 0,
608
+ 0,
609
+ 0
610
+ ],
611
+ [
612
+ 128,
613
+ 0,
614
+ 0
615
+ ],
616
+ [
617
+ 0,
618
+ 128,
619
+ 0
620
+ ],
621
+ [
622
+ 128,
623
+ 128,
624
+ 0
625
+ ],
626
+ [
627
+ 0,
628
+ 0,
629
+ 128
630
+ ],
631
+ [
632
+ 128,
633
+ 0,
634
+ 128
635
+ ],
636
+ [
637
+ 0,
638
+ 128,
639
+ 128
640
+ ],
641
+ [
642
+ 192,
643
+ 192,
644
+ 192
645
+ ],
646
+ [
647
+ 128,
648
+ 128,
649
+ 128
650
+ ],
651
+ [
652
+ 255,
653
+ 0,
654
+ 0
655
+ ],
656
+ [
657
+ 0,
658
+ 255,
659
+ 0
660
+ ],
661
+ [
662
+ 255,
663
+ 255,
664
+ 0
665
+ ],
666
+ [
667
+ 0,
668
+ 0,
669
+ 255
670
+ ],
671
+ [
672
+ 255,
673
+ 0,
674
+ 255
675
+ ],
676
+ [
677
+ 0,
678
+ 255,
679
+ 255
680
+ ],
681
+ [
682
+ 255,
683
+ 255,
684
+ 255
685
+ ]
686
+ ][idx];
687
+ if (idx < 232) {
688
+ const i = idx - 16;
689
+ const r = Math.floor(i / 36);
690
+ const g = Math.floor(i % 36 / 6);
691
+ const b = i % 6;
692
+ return [
693
+ r ? r * 40 + 55 : 0,
694
+ g ? g * 40 + 55 : 0,
695
+ b ? b * 40 + 55 : 0
696
+ ];
697
+ }
698
+ const v = (idx - 232) * 10 + 8;
699
+ return [
700
+ v,
701
+ v,
702
+ v
703
+ ];
704
+ }
705
+ function Gallery() {
706
+ const { exit } = useApp();
707
+ const [activeTab, setActiveTab] = useState("images");
708
+ useInput((input, key) => {
709
+ if (input === "q" || key.escape) exit();
710
+ });
711
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Box, {
712
+ flexDirection: "column",
713
+ flexGrow: 1,
714
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Tabs, {
715
+ value: activeTab,
716
+ onChange: setActiveTab,
717
+ children: [
718
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(TabList, { children: [
719
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Tab, {
720
+ value: "images",
721
+ children: "Images"
722
+ }),
723
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Tab, {
724
+ value: "paint",
725
+ children: "Paint"
726
+ }),
727
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Tab, {
728
+ value: "truecolor",
729
+ children: "Truecolor"
730
+ })
731
+ ] }),
732
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TabPanel, {
733
+ value: "images",
734
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ImagesTab, {})
735
+ }),
736
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TabPanel, {
737
+ value: "paint",
738
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(PaintTab, {})
739
+ }),
740
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TabPanel, {
741
+ value: "truecolor",
742
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TruecolorTab, {})
743
+ })
744
+ ]
745
+ })
746
+ });
747
+ }
748
+ async function main() {
749
+ try {
750
+ var _usingCtx$1 = _usingCtx();
751
+ const term = _usingCtx$1.u(createTerm());
752
+ const { waitUntilExit } = await render(/* @__PURE__ */ (0, import_jsx_runtime.jsx)(ExampleBanner, {
753
+ meta,
754
+ controls: "h/l tab j/k navigate Esc/q quit",
755
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Gallery, {})
756
+ }), term);
757
+ await waitUntilExit();
758
+ } catch (_) {
759
+ _usingCtx$1.e = _;
760
+ } finally {
761
+ _usingCtx$1.d();
762
+ }
763
+ }
764
+ if (import.meta.main) await main();
765
+ //#endregion
766
+ export { Gallery, main, meta };