@silvery/examples 0.17.3 → 0.17.5

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