@meissa_a/meissa 0.1.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.
Files changed (65) hide show
  1. package/README.md +350 -0
  2. package/dist/apps/app-generator.d.ts +30 -0
  3. package/dist/apps/index.d.ts +25 -0
  4. package/dist/apps/postmessage.d.ts +24 -0
  5. package/dist/apps/template.d.ts +10 -0
  6. package/dist/apps/types.d.ts +107 -0
  7. package/dist/apps.cjs +687 -0
  8. package/dist/apps.js +645 -0
  9. package/dist/client/component.d.ts +17 -0
  10. package/dist/client/content.d.ts +12 -0
  11. package/dist/client/index.d.ts +7 -0
  12. package/dist/client/patch.d.ts +6 -0
  13. package/dist/client/renderer.d.ts +43 -0
  14. package/dist/client/types.d.ts +52 -0
  15. package/dist/client.cjs +3558 -0
  16. package/dist/client.js +3524 -0
  17. package/dist/renderer/ComponentRenderer.d.ts +11 -0
  18. package/dist/renderer/MeissaRenderer.d.ts +8 -0
  19. package/dist/renderer/components/Alert.d.ts +2 -0
  20. package/dist/renderer/components/Badge.d.ts +2 -0
  21. package/dist/renderer/components/Btn.d.ts +2 -0
  22. package/dist/renderer/components/Card.d.ts +2 -0
  23. package/dist/renderer/components/Chart.d.ts +2 -0
  24. package/dist/renderer/components/Code.d.ts +2 -0
  25. package/dist/renderer/components/Col.d.ts +2 -0
  26. package/dist/renderer/components/Divider.d.ts +2 -0
  27. package/dist/renderer/components/Form.d.ts +2 -0
  28. package/dist/renderer/components/Grid.d.ts +2 -0
  29. package/dist/renderer/components/Heading.d.ts +2 -0
  30. package/dist/renderer/components/Img.d.ts +2 -0
  31. package/dist/renderer/components/Input.d.ts +2 -0
  32. package/dist/renderer/components/List.d.ts +2 -0
  33. package/dist/renderer/components/Progress.d.ts +2 -0
  34. package/dist/renderer/components/Row.d.ts +2 -0
  35. package/dist/renderer/components/Select.d.ts +2 -0
  36. package/dist/renderer/components/Split.d.ts +2 -0
  37. package/dist/renderer/components/Stat.d.ts +2 -0
  38. package/dist/renderer/components/Table.d.ts +2 -0
  39. package/dist/renderer/components/Tabs.d.ts +2 -0
  40. package/dist/renderer/components/Text.d.ts +2 -0
  41. package/dist/renderer/components/index.d.ts +2 -0
  42. package/dist/renderer/context/ActionContext.d.ts +3 -0
  43. package/dist/renderer/context/DataContext.d.ts +3 -0
  44. package/dist/renderer/context/FormContext.d.ts +10 -0
  45. package/dist/renderer/core/binder.d.ts +17 -0
  46. package/dist/renderer/core/evaluator.d.ts +13 -0
  47. package/dist/renderer/core/iterator.d.ts +10 -0
  48. package/dist/renderer/core/normalizer.d.ts +5 -0
  49. package/dist/renderer/core/parser.d.ts +8 -0
  50. package/dist/renderer/core/resolver.d.ts +6 -0
  51. package/dist/renderer/core/types.d.ts +68 -0
  52. package/dist/renderer/index.d.ts +7 -0
  53. package/dist/renderer/utils/cn.d.ts +2 -0
  54. package/dist/renderer/utils/filters.d.ts +8 -0
  55. package/dist/renderer/utils/sanitize.d.ts +9 -0
  56. package/dist/renderer.cjs +3273 -0
  57. package/dist/renderer.js +3239 -0
  58. package/dist/server/index.d.ts +4 -0
  59. package/dist/server/markdown.d.ts +9 -0
  60. package/dist/server/server.d.ts +39 -0
  61. package/dist/server/types.d.ts +56 -0
  62. package/dist/server/validator.d.ts +5 -0
  63. package/dist/server.cjs +345 -0
  64. package/dist/server.js +303 -0
  65. package/package.json +84 -0
package/dist/client.js ADDED
@@ -0,0 +1,3524 @@
1
+ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
2
+ get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
3
+ }) : x)(function(x) {
4
+ if (typeof require !== "undefined")
5
+ return require.apply(this, arguments);
6
+ throw Error('Dynamic require of "' + x + '" is not supported');
7
+ });
8
+
9
+ // src/client/renderer.ts
10
+ import { createElement } from "react";
11
+ import { createRoot } from "react-dom/client";
12
+
13
+ // src/renderer/MeissaRenderer.tsx
14
+ import { useMemo as useMemo4 } from "react";
15
+
16
+ // src/renderer/core/normalizer.ts
17
+ var PRIMARY_PROPS = {
18
+ text: "content",
19
+ heading: "content",
20
+ code: "content",
21
+ btn: "label",
22
+ badge: "content",
23
+ alert: "content",
24
+ img: "src",
25
+ progress: "value",
26
+ list: "items",
27
+ stat: "value",
28
+ input: "name",
29
+ select: "options",
30
+ table: "data",
31
+ chart: "data",
32
+ card: "title",
33
+ tabs: "items",
34
+ form: "submit"
35
+ };
36
+ var DEFAULTS = {
37
+ text: { variant: "default", bold: false, align: "left" },
38
+ heading: { level: 2, align: "left" },
39
+ btn: { variant: "primary", size: "md", disabled: false },
40
+ input: { type: "text", required: false, disabled: false },
41
+ table: { sortable: true },
42
+ chart: { type: "line", legend: true, h: 256 },
43
+ stat: { variant: "default" },
44
+ alert: { variant: "info", dismissible: false },
45
+ badge: { variant: "default" },
46
+ progress: { value: 0, indeterminate: false },
47
+ card: { variant: "default", padding: 4 },
48
+ row: { gap: 4, align: "center", wrap: true },
49
+ col: { gap: 4, align: "stretch" },
50
+ grid: { cols: 2, gap: 4 },
51
+ split: { ratio: "1:1", gap: 4 }
52
+ };
53
+ var CONTAINERS = new Set(["row", "col", "grid", "split", "card", "form", "fragment"]);
54
+ function normalize(input) {
55
+ if (Array.isArray(input)) {
56
+ return normalizeTuple(input);
57
+ }
58
+ if (typeof input === "object" && input !== null) {
59
+ return normalizeObject(input);
60
+ }
61
+ return { type: "text", content: `[Invalid node]` };
62
+ }
63
+ function normalizeTuple(tuple) {
64
+ const type = tuple[0];
65
+ if (!type || typeof type !== "string") {
66
+ return { type: "text", content: "[Invalid: missing type]" };
67
+ }
68
+ if (type === "switch") {
69
+ return normalizeSwitch(tuple);
70
+ }
71
+ if (type === "each") {
72
+ return normalizeEach(tuple);
73
+ }
74
+ if (type === "ref") {
75
+ return { type: "ref", name: tuple[1] };
76
+ }
77
+ const node = { type };
78
+ const second = tuple[1];
79
+ const third = tuple[2];
80
+ if (tuple.length === 1) {} else if (tuple.length === 2) {
81
+ assignSecond(node, type, second);
82
+ } else if (tuple.length >= 3) {
83
+ assignSecond(node, type, second);
84
+ if (Array.isArray(third)) {
85
+ node.children = normalizeChildren(third);
86
+ }
87
+ }
88
+ applyDefaults(node);
89
+ return node;
90
+ }
91
+ function assignSecond(node, type, second) {
92
+ if (second === null || second === undefined) {
93
+ const primaryProp = PRIMARY_PROPS[type];
94
+ if (primaryProp) {
95
+ node[primaryProp] = null;
96
+ }
97
+ } else if (typeof second === "string" || typeof second === "number" || typeof second === "boolean") {
98
+ const primaryProp = PRIMARY_PROPS[type];
99
+ if (primaryProp) {
100
+ node[primaryProp] = second;
101
+ }
102
+ } else if (Array.isArray(second)) {
103
+ if (second.length > 0 && Array.isArray(second[0])) {
104
+ node.children = normalizeChildren(second);
105
+ } else {
106
+ const primaryProp = PRIMARY_PROPS[type];
107
+ if (primaryProp) {
108
+ node[primaryProp] = second;
109
+ }
110
+ }
111
+ } else if (typeof second === "object") {
112
+ const obj = second;
113
+ if ("type" in obj && typeof obj.type === "string") {
114
+ Object.assign(node, obj);
115
+ node.type = type;
116
+ } else {
117
+ if (type === "tabs" && !("items" in obj)) {
118
+ const hasTabContent = Object.values(obj).some((v) => Array.isArray(v));
119
+ if (hasTabContent) {
120
+ node.items = obj;
121
+ return;
122
+ }
123
+ }
124
+ Object.assign(node, obj);
125
+ }
126
+ }
127
+ }
128
+ function normalizeSwitch(tuple) {
129
+ const binding = tuple[1];
130
+ const cases = tuple[2];
131
+ const normalizedCases = {};
132
+ if (cases && typeof cases === "object") {
133
+ for (const [key, value] of Object.entries(cases)) {
134
+ normalizedCases[key] = normalize(value);
135
+ }
136
+ }
137
+ return { type: "switch", binding, cases: normalizedCases };
138
+ }
139
+ function normalizeEach(tuple) {
140
+ const binding = tuple[1];
141
+ const template = tuple[2];
142
+ return {
143
+ type: "each",
144
+ binding,
145
+ template: normalize(template)
146
+ };
147
+ }
148
+ function normalizeChildren(arr) {
149
+ const result = [];
150
+ for (const item of arr) {
151
+ if (item === null || item === undefined)
152
+ continue;
153
+ result.push(normalize(item));
154
+ }
155
+ return result;
156
+ }
157
+ function normalizeObject(obj) {
158
+ const node = { type: obj.type };
159
+ for (const [key, value] of Object.entries(obj)) {
160
+ if (key === "children" && Array.isArray(value)) {
161
+ node.children = normalizeChildren(value);
162
+ } else {
163
+ node[key] = value;
164
+ }
165
+ }
166
+ applyDefaults(node);
167
+ return node;
168
+ }
169
+ function applyDefaults(node) {
170
+ const defaults = DEFAULTS[node.type];
171
+ if (!defaults)
172
+ return;
173
+ for (const [key, value] of Object.entries(defaults)) {
174
+ if (!(key in node)) {
175
+ node[key] = value;
176
+ }
177
+ }
178
+ }
179
+
180
+ // src/renderer/core/resolver.ts
181
+ function resolveRefs(nodes, defs) {
182
+ if (Object.keys(defs).length === 0)
183
+ return nodes;
184
+ return nodes.map((node) => resolveNode(node, defs));
185
+ }
186
+ function resolveNode(node, defs) {
187
+ if (node.type === "ref") {
188
+ const name = node.name;
189
+ const def = defs[name];
190
+ if (def) {
191
+ return structuredClone(def);
192
+ }
193
+ return { type: "text", content: `[Unknown ref: ${name}]` };
194
+ }
195
+ if (node.children) {
196
+ node.children = node.children.map((child) => resolveNode(child, defs));
197
+ }
198
+ if (node.type === "each" && node.template) {
199
+ node.template = resolveNode(node.template, defs);
200
+ }
201
+ if (node.type === "switch" && node.cases) {
202
+ const cases = node.cases;
203
+ for (const key of Object.keys(cases)) {
204
+ cases[key] = resolveNode(cases[key], defs);
205
+ }
206
+ }
207
+ return node;
208
+ }
209
+
210
+ // src/renderer/core/parser.ts
211
+ function parse(input) {
212
+ if (isDocument(input)) {
213
+ const doc = input;
214
+ const defs = normalizeDefs(doc.defs);
215
+ const nodes = normalizeArray(doc.ui);
216
+ const resolved = resolveRefs(nodes, defs);
217
+ return {
218
+ nodes: resolved,
219
+ defs,
220
+ data: doc.data ?? {},
221
+ theme: doc.theme
222
+ };
223
+ }
224
+ if (Array.isArray(input) && input.length > 0) {
225
+ if (typeof input[0] === "string" && !Array.isArray(input[1]?.constructor === Array ? input[1] : null)) {
226
+ if (input.length <= 3 && isComponentType(input[0])) {
227
+ const node = normalize(input);
228
+ return { nodes: [node], defs: {}, data: {} };
229
+ }
230
+ }
231
+ const nodes = normalizeArray(input);
232
+ return { nodes, defs: {}, data: {} };
233
+ }
234
+ if (typeof input === "object" && input !== null && "type" in input) {
235
+ const node = normalize(input);
236
+ return { nodes: [node], defs: {}, data: {} };
237
+ }
238
+ return { nodes: [], defs: {}, data: {} };
239
+ }
240
+ function isDocument(input) {
241
+ return typeof input === "object" && input !== null && !Array.isArray(input) && "ui" in input && Array.isArray(input.ui);
242
+ }
243
+ function isComponentType(value) {
244
+ const types = new Set([
245
+ "text",
246
+ "heading",
247
+ "code",
248
+ "img",
249
+ "btn",
250
+ "input",
251
+ "select",
252
+ "form",
253
+ "table",
254
+ "list",
255
+ "chart",
256
+ "stat",
257
+ "card",
258
+ "tabs",
259
+ "alert",
260
+ "badge",
261
+ "progress",
262
+ "divider",
263
+ "row",
264
+ "col",
265
+ "grid",
266
+ "split",
267
+ "each",
268
+ "switch",
269
+ "ref",
270
+ "fragment"
271
+ ]);
272
+ return types.has(value);
273
+ }
274
+ function normalizeArray(arr) {
275
+ const result = [];
276
+ for (const item of arr) {
277
+ if (item === null || item === undefined)
278
+ continue;
279
+ if (Array.isArray(item)) {
280
+ if (typeof item[0] === "string") {
281
+ result.push(normalize(item));
282
+ }
283
+ } else if (typeof item === "object" && "type" in item) {
284
+ result.push(normalize(item));
285
+ }
286
+ }
287
+ return result;
288
+ }
289
+ function normalizeDefs(defs) {
290
+ if (!defs)
291
+ return {};
292
+ const result = {};
293
+ for (const [name, def] of Object.entries(defs)) {
294
+ result[name] = normalize(def);
295
+ }
296
+ return result;
297
+ }
298
+
299
+ // src/renderer/context/DataContext.tsx
300
+ import { createContext, useContext } from "react";
301
+ var DataContext = createContext({
302
+ data: {},
303
+ root: {}
304
+ });
305
+ var DataProvider = DataContext.Provider;
306
+ function useData() {
307
+ return useContext(DataContext);
308
+ }
309
+
310
+ // src/renderer/context/ActionContext.tsx
311
+ import { createContext as createContext2, useContext as useContext2 } from "react";
312
+ var noop = () => {};
313
+ var ActionContext = createContext2({
314
+ onAction: noop,
315
+ onNavigate: noop
316
+ });
317
+ var ActionProvider = ActionContext.Provider;
318
+ function useAction() {
319
+ return useContext2(ActionContext);
320
+ }
321
+
322
+ // src/renderer/ComponentRenderer.tsx
323
+ import { useMemo as useMemo3 } from "react";
324
+
325
+ // src/renderer/utils/filters.ts
326
+ var filters = {
327
+ currency(value) {
328
+ const num = Number(value);
329
+ if (isNaN(num))
330
+ return value;
331
+ return new Intl.NumberFormat("en-US", {
332
+ style: "currency",
333
+ currency: "USD"
334
+ }).format(num);
335
+ },
336
+ percent(value) {
337
+ const num = Number(value);
338
+ if (isNaN(num))
339
+ return value;
340
+ const pct = num <= 1 && num >= 0 ? num * 100 : num;
341
+ return `${Math.round(pct)}%`;
342
+ },
343
+ number(value) {
344
+ const num = Number(value);
345
+ if (isNaN(num))
346
+ return value;
347
+ return new Intl.NumberFormat("en-US").format(num);
348
+ },
349
+ relative(value) {
350
+ if (!value)
351
+ return "";
352
+ const date = new Date(value);
353
+ if (isNaN(date.getTime()))
354
+ return String(value);
355
+ const now = Date.now();
356
+ const diff = now - date.getTime();
357
+ const seconds = Math.floor(diff / 1000);
358
+ const minutes = Math.floor(seconds / 60);
359
+ const hours = Math.floor(minutes / 60);
360
+ const days = Math.floor(hours / 24);
361
+ const months = Math.floor(days / 30);
362
+ const years = Math.floor(days / 365);
363
+ if (seconds < 60)
364
+ return "just now";
365
+ if (minutes < 60)
366
+ return `${minutes} minute${minutes > 1 ? "s" : ""} ago`;
367
+ if (hours < 24)
368
+ return `${hours} hour${hours > 1 ? "s" : ""} ago`;
369
+ if (days < 30)
370
+ return `${days} day${days > 1 ? "s" : ""} ago`;
371
+ if (months < 12)
372
+ return `${months} month${months > 1 ? "s" : ""} ago`;
373
+ return `${years} year${years > 1 ? "s" : ""} ago`;
374
+ },
375
+ date(value, format) {
376
+ if (!value)
377
+ return "";
378
+ const date = new Date(value);
379
+ if (isNaN(date.getTime()))
380
+ return String(value);
381
+ switch (format) {
382
+ case "short":
383
+ return date.toLocaleDateString("en-US", { month: "short", day: "numeric", year: "numeric" });
384
+ case "long":
385
+ return date.toLocaleDateString("en-US", { month: "long", day: "numeric", year: "numeric" });
386
+ case "iso":
387
+ return date.toISOString().split("T")[0];
388
+ case "time":
389
+ return date.toLocaleTimeString("en-US", { hour: "numeric", minute: "2-digit" });
390
+ case "datetime":
391
+ return date.toLocaleDateString("en-US", { month: "short", day: "numeric", year: "numeric" }) + " " + date.toLocaleTimeString("en-US", { hour: "numeric", minute: "2-digit" });
392
+ default:
393
+ return date.toLocaleDateString("en-US", { month: "short", day: "numeric", year: "numeric" });
394
+ }
395
+ },
396
+ uppercase(value) {
397
+ return typeof value === "string" ? value.toUpperCase() : value;
398
+ },
399
+ lowercase(value) {
400
+ return typeof value === "string" ? value.toLowerCase() : value;
401
+ },
402
+ truncate(value, arg) {
403
+ if (typeof value !== "string")
404
+ return value;
405
+ const max = parseInt(arg || "50", 10);
406
+ if (value.length <= max)
407
+ return value;
408
+ return value.slice(0, max) + "...";
409
+ },
410
+ default(value, arg) {
411
+ if (value === null || value === undefined || value === "") {
412
+ if (arg && arg.startsWith('"') && arg.endsWith('"')) {
413
+ return arg.slice(1, -1);
414
+ }
415
+ if (arg && /^-?\d+(\.\d+)?$/.test(arg)) {
416
+ return Number(arg);
417
+ }
418
+ return arg ?? "";
419
+ }
420
+ return value;
421
+ }
422
+ };
423
+ function applyFilter(filterExpr, value) {
424
+ const colonIdx = filterExpr.indexOf(":");
425
+ const name = colonIdx >= 0 ? filterExpr.slice(0, colonIdx) : filterExpr;
426
+ const arg = colonIdx >= 0 ? filterExpr.slice(colonIdx + 1) : undefined;
427
+ const fn = filters[name];
428
+ if (!fn)
429
+ return value;
430
+ return fn(value, arg);
431
+ }
432
+
433
+ // src/renderer/core/binder.ts
434
+ function resolveBindings(template, data) {
435
+ if (typeof template !== "string")
436
+ return template;
437
+ if (!template.includes("{{"))
438
+ return template;
439
+ const exactMatch = template.match(/^\{\{(.+?)\}\}$/);
440
+ if (exactMatch) {
441
+ return resolveExpression(exactMatch[1], data);
442
+ }
443
+ return template.replace(/\{\{(.+?)\}\}/g, (_, expr) => {
444
+ const result = resolveExpression(expr, data);
445
+ return result == null ? "" : String(result);
446
+ });
447
+ }
448
+ function resolveExpression(expr, data) {
449
+ const parts = expr.split("|").map((s) => s.trim());
450
+ const path = parts[0];
451
+ const filters2 = parts.slice(1);
452
+ if (hasComparison(path)) {
453
+ return evaluateComparison(path, data);
454
+ }
455
+ let value = resolvePath(path, data);
456
+ for (const filter of filters2) {
457
+ value = applyFilter(filter, value);
458
+ }
459
+ return value;
460
+ }
461
+ function resolvePath(path, data) {
462
+ if (!path)
463
+ return;
464
+ if (path.startsWith("!")) {
465
+ const value = resolvePath(path.slice(1), data);
466
+ return !isTruthy(value);
467
+ }
468
+ const segments = parsePath(path);
469
+ let current = data;
470
+ for (const segment of segments) {
471
+ if (current === null || current === undefined)
472
+ return;
473
+ if (typeof current === "object") {
474
+ current = current[segment];
475
+ } else {
476
+ return;
477
+ }
478
+ }
479
+ return current;
480
+ }
481
+ function parsePath(path) {
482
+ const segments = [];
483
+ let current = "";
484
+ for (let i = 0;i < path.length; i++) {
485
+ const char = path[i];
486
+ if (char === ".") {
487
+ if (current)
488
+ segments.push(current);
489
+ current = "";
490
+ } else if (char === "[") {
491
+ if (current)
492
+ segments.push(current);
493
+ current = "";
494
+ } else if (char === "]") {
495
+ if (current)
496
+ segments.push(current);
497
+ current = "";
498
+ } else {
499
+ current += char;
500
+ }
501
+ }
502
+ if (current)
503
+ segments.push(current);
504
+ return segments;
505
+ }
506
+ function hasComparison(expr) {
507
+ return /\s*(==|!=|<=|>=|<|>)\s*/.test(expr);
508
+ }
509
+ function evaluateComparison(expr, data) {
510
+ const match = expr.match(/^(.+?)\s*(==|!=|<=|>=|<|>)\s*(.+)$/);
511
+ if (!match)
512
+ return false;
513
+ const [, leftExpr, op, rightExpr] = match;
514
+ const left = resolveOperand(leftExpr.trim(), data);
515
+ const right = resolveOperand(rightExpr.trim(), data);
516
+ switch (op) {
517
+ case "==":
518
+ return left == right;
519
+ case "!=":
520
+ return left != right;
521
+ case "<":
522
+ return Number(left) < Number(right);
523
+ case ">":
524
+ return Number(left) > Number(right);
525
+ case "<=":
526
+ return Number(left) <= Number(right);
527
+ case ">=":
528
+ return Number(left) >= Number(right);
529
+ default:
530
+ return false;
531
+ }
532
+ }
533
+ function resolveOperand(expr, data) {
534
+ if (expr.startsWith("'") && expr.endsWith("'") || expr.startsWith('"') && expr.endsWith('"')) {
535
+ return expr.slice(1, -1);
536
+ }
537
+ if (/^-?\d+(\.\d+)?$/.test(expr)) {
538
+ return Number(expr);
539
+ }
540
+ if (expr === "true")
541
+ return true;
542
+ if (expr === "false")
543
+ return false;
544
+ if (expr === "null")
545
+ return null;
546
+ return resolvePath(expr, data);
547
+ }
548
+ function isTruthy(value) {
549
+ if (value === null || value === undefined)
550
+ return false;
551
+ if (value === false)
552
+ return false;
553
+ if (value === 0)
554
+ return false;
555
+ if (value === "")
556
+ return false;
557
+ if (Array.isArray(value) && value.length === 0)
558
+ return false;
559
+ return true;
560
+ }
561
+
562
+ // src/renderer/core/evaluator.ts
563
+ function evaluate(node, data) {
564
+ if (node.type === "switch") {
565
+ return evaluateSwitch(node, data);
566
+ }
567
+ if (node.if !== undefined) {
568
+ const value = resolveBindings(node.if, data);
569
+ const negated = typeof node.if === "string" && node.if.startsWith("!{{");
570
+ const truthy = negated ? value : isTruthy(value);
571
+ if (!truthy) {
572
+ return { node: null, hidden: false };
573
+ }
574
+ }
575
+ let hidden = false;
576
+ if (node.show !== undefined) {
577
+ const value = resolveBindings(node.show, data);
578
+ if (!isTruthy(value)) {
579
+ hidden = true;
580
+ }
581
+ }
582
+ return { node, hidden };
583
+ }
584
+ function evaluateSwitch(node, data) {
585
+ const binding = node.binding;
586
+ const cases = node.cases;
587
+ if (!binding || !cases) {
588
+ return { node: null, hidden: false };
589
+ }
590
+ const value = resolveBindings(binding, data);
591
+ const key = String(value);
592
+ if (key in cases) {
593
+ return { node: cases[key], hidden: false };
594
+ }
595
+ if ("_" in cases) {
596
+ return { node: cases["_"], hidden: false };
597
+ }
598
+ return { node: null, hidden: false };
599
+ }
600
+
601
+ // src/renderer/core/iterator.ts
602
+ function expandEach(node, data) {
603
+ const binding = node.binding;
604
+ const template = node.template;
605
+ if (!binding || !template)
606
+ return [];
607
+ const items = resolveBindings(binding, data);
608
+ if (!Array.isArray(items))
609
+ return [];
610
+ return items.map((item, index) => ({
611
+ node: template,
612
+ data: {
613
+ ...data,
614
+ $: item,
615
+ $i: index,
616
+ $first: index === 0,
617
+ $last: index === items.length - 1
618
+ }
619
+ }));
620
+ }
621
+
622
+ // ../../node_modules/.bun/clsx@2.1.1/node_modules/clsx/dist/clsx.mjs
623
+ function r(e) {
624
+ var t, f, n = "";
625
+ if (typeof e == "string" || typeof e == "number")
626
+ n += e;
627
+ else if (typeof e == "object")
628
+ if (Array.isArray(e)) {
629
+ var o = e.length;
630
+ for (t = 0;t < o; t++)
631
+ e[t] && (f = r(e[t])) && (n && (n += " "), n += f);
632
+ } else
633
+ for (f in e)
634
+ e[f] && (n && (n += " "), n += f);
635
+ return n;
636
+ }
637
+ function clsx() {
638
+ for (var e, t, f = 0, n = "", o = arguments.length;f < o; f++)
639
+ (e = arguments[f]) && (t = r(e)) && (n && (n += " "), n += t);
640
+ return n;
641
+ }
642
+
643
+ // ../../node_modules/.bun/tailwind-merge@2.6.1/node_modules/tailwind-merge/dist/bundle-mjs.mjs
644
+ var CLASS_PART_SEPARATOR = "-";
645
+ var createClassGroupUtils = (config) => {
646
+ const classMap = createClassMap(config);
647
+ const {
648
+ conflictingClassGroups,
649
+ conflictingClassGroupModifiers
650
+ } = config;
651
+ const getClassGroupId = (className) => {
652
+ const classParts = className.split(CLASS_PART_SEPARATOR);
653
+ if (classParts[0] === "" && classParts.length !== 1) {
654
+ classParts.shift();
655
+ }
656
+ return getGroupRecursive(classParts, classMap) || getGroupIdForArbitraryProperty(className);
657
+ };
658
+ const getConflictingClassGroupIds = (classGroupId, hasPostfixModifier) => {
659
+ const conflicts = conflictingClassGroups[classGroupId] || [];
660
+ if (hasPostfixModifier && conflictingClassGroupModifiers[classGroupId]) {
661
+ return [...conflicts, ...conflictingClassGroupModifiers[classGroupId]];
662
+ }
663
+ return conflicts;
664
+ };
665
+ return {
666
+ getClassGroupId,
667
+ getConflictingClassGroupIds
668
+ };
669
+ };
670
+ var getGroupRecursive = (classParts, classPartObject) => {
671
+ if (classParts.length === 0) {
672
+ return classPartObject.classGroupId;
673
+ }
674
+ const currentClassPart = classParts[0];
675
+ const nextClassPartObject = classPartObject.nextPart.get(currentClassPart);
676
+ const classGroupFromNextClassPart = nextClassPartObject ? getGroupRecursive(classParts.slice(1), nextClassPartObject) : undefined;
677
+ if (classGroupFromNextClassPart) {
678
+ return classGroupFromNextClassPart;
679
+ }
680
+ if (classPartObject.validators.length === 0) {
681
+ return;
682
+ }
683
+ const classRest = classParts.join(CLASS_PART_SEPARATOR);
684
+ return classPartObject.validators.find(({
685
+ validator
686
+ }) => validator(classRest))?.classGroupId;
687
+ };
688
+ var arbitraryPropertyRegex = /^\[(.+)\]$/;
689
+ var getGroupIdForArbitraryProperty = (className) => {
690
+ if (arbitraryPropertyRegex.test(className)) {
691
+ const arbitraryPropertyClassName = arbitraryPropertyRegex.exec(className)[1];
692
+ const property = arbitraryPropertyClassName?.substring(0, arbitraryPropertyClassName.indexOf(":"));
693
+ if (property) {
694
+ return "arbitrary.." + property;
695
+ }
696
+ }
697
+ };
698
+ var createClassMap = (config) => {
699
+ const {
700
+ theme,
701
+ prefix
702
+ } = config;
703
+ const classMap = {
704
+ nextPart: new Map,
705
+ validators: []
706
+ };
707
+ const prefixedClassGroupEntries = getPrefixedClassGroupEntries(Object.entries(config.classGroups), prefix);
708
+ prefixedClassGroupEntries.forEach(([classGroupId, classGroup]) => {
709
+ processClassesRecursively(classGroup, classMap, classGroupId, theme);
710
+ });
711
+ return classMap;
712
+ };
713
+ var processClassesRecursively = (classGroup, classPartObject, classGroupId, theme) => {
714
+ classGroup.forEach((classDefinition) => {
715
+ if (typeof classDefinition === "string") {
716
+ const classPartObjectToEdit = classDefinition === "" ? classPartObject : getPart(classPartObject, classDefinition);
717
+ classPartObjectToEdit.classGroupId = classGroupId;
718
+ return;
719
+ }
720
+ if (typeof classDefinition === "function") {
721
+ if (isThemeGetter(classDefinition)) {
722
+ processClassesRecursively(classDefinition(theme), classPartObject, classGroupId, theme);
723
+ return;
724
+ }
725
+ classPartObject.validators.push({
726
+ validator: classDefinition,
727
+ classGroupId
728
+ });
729
+ return;
730
+ }
731
+ Object.entries(classDefinition).forEach(([key, classGroup2]) => {
732
+ processClassesRecursively(classGroup2, getPart(classPartObject, key), classGroupId, theme);
733
+ });
734
+ });
735
+ };
736
+ var getPart = (classPartObject, path) => {
737
+ let currentClassPartObject = classPartObject;
738
+ path.split(CLASS_PART_SEPARATOR).forEach((pathPart) => {
739
+ if (!currentClassPartObject.nextPart.has(pathPart)) {
740
+ currentClassPartObject.nextPart.set(pathPart, {
741
+ nextPart: new Map,
742
+ validators: []
743
+ });
744
+ }
745
+ currentClassPartObject = currentClassPartObject.nextPart.get(pathPart);
746
+ });
747
+ return currentClassPartObject;
748
+ };
749
+ var isThemeGetter = (func) => func.isThemeGetter;
750
+ var getPrefixedClassGroupEntries = (classGroupEntries, prefix) => {
751
+ if (!prefix) {
752
+ return classGroupEntries;
753
+ }
754
+ return classGroupEntries.map(([classGroupId, classGroup]) => {
755
+ const prefixedClassGroup = classGroup.map((classDefinition) => {
756
+ if (typeof classDefinition === "string") {
757
+ return prefix + classDefinition;
758
+ }
759
+ if (typeof classDefinition === "object") {
760
+ return Object.fromEntries(Object.entries(classDefinition).map(([key, value]) => [prefix + key, value]));
761
+ }
762
+ return classDefinition;
763
+ });
764
+ return [classGroupId, prefixedClassGroup];
765
+ });
766
+ };
767
+ var createLruCache = (maxCacheSize) => {
768
+ if (maxCacheSize < 1) {
769
+ return {
770
+ get: () => {
771
+ return;
772
+ },
773
+ set: () => {}
774
+ };
775
+ }
776
+ let cacheSize = 0;
777
+ let cache = new Map;
778
+ let previousCache = new Map;
779
+ const update = (key, value) => {
780
+ cache.set(key, value);
781
+ cacheSize++;
782
+ if (cacheSize > maxCacheSize) {
783
+ cacheSize = 0;
784
+ previousCache = cache;
785
+ cache = new Map;
786
+ }
787
+ };
788
+ return {
789
+ get(key) {
790
+ let value = cache.get(key);
791
+ if (value !== undefined) {
792
+ return value;
793
+ }
794
+ if ((value = previousCache.get(key)) !== undefined) {
795
+ update(key, value);
796
+ return value;
797
+ }
798
+ },
799
+ set(key, value) {
800
+ if (cache.has(key)) {
801
+ cache.set(key, value);
802
+ } else {
803
+ update(key, value);
804
+ }
805
+ }
806
+ };
807
+ };
808
+ var IMPORTANT_MODIFIER = "!";
809
+ var createParseClassName = (config) => {
810
+ const {
811
+ separator,
812
+ experimentalParseClassName
813
+ } = config;
814
+ const isSeparatorSingleCharacter = separator.length === 1;
815
+ const firstSeparatorCharacter = separator[0];
816
+ const separatorLength = separator.length;
817
+ const parseClassName = (className) => {
818
+ const modifiers = [];
819
+ let bracketDepth = 0;
820
+ let modifierStart = 0;
821
+ let postfixModifierPosition;
822
+ for (let index = 0;index < className.length; index++) {
823
+ let currentCharacter = className[index];
824
+ if (bracketDepth === 0) {
825
+ if (currentCharacter === firstSeparatorCharacter && (isSeparatorSingleCharacter || className.slice(index, index + separatorLength) === separator)) {
826
+ modifiers.push(className.slice(modifierStart, index));
827
+ modifierStart = index + separatorLength;
828
+ continue;
829
+ }
830
+ if (currentCharacter === "/") {
831
+ postfixModifierPosition = index;
832
+ continue;
833
+ }
834
+ }
835
+ if (currentCharacter === "[") {
836
+ bracketDepth++;
837
+ } else if (currentCharacter === "]") {
838
+ bracketDepth--;
839
+ }
840
+ }
841
+ const baseClassNameWithImportantModifier = modifiers.length === 0 ? className : className.substring(modifierStart);
842
+ const hasImportantModifier = baseClassNameWithImportantModifier.startsWith(IMPORTANT_MODIFIER);
843
+ const baseClassName = hasImportantModifier ? baseClassNameWithImportantModifier.substring(1) : baseClassNameWithImportantModifier;
844
+ const maybePostfixModifierPosition = postfixModifierPosition && postfixModifierPosition > modifierStart ? postfixModifierPosition - modifierStart : undefined;
845
+ return {
846
+ modifiers,
847
+ hasImportantModifier,
848
+ baseClassName,
849
+ maybePostfixModifierPosition
850
+ };
851
+ };
852
+ if (experimentalParseClassName) {
853
+ return (className) => experimentalParseClassName({
854
+ className,
855
+ parseClassName
856
+ });
857
+ }
858
+ return parseClassName;
859
+ };
860
+ var sortModifiers = (modifiers) => {
861
+ if (modifiers.length <= 1) {
862
+ return modifiers;
863
+ }
864
+ const sortedModifiers = [];
865
+ let unsortedModifiers = [];
866
+ modifiers.forEach((modifier) => {
867
+ const isArbitraryVariant = modifier[0] === "[";
868
+ if (isArbitraryVariant) {
869
+ sortedModifiers.push(...unsortedModifiers.sort(), modifier);
870
+ unsortedModifiers = [];
871
+ } else {
872
+ unsortedModifiers.push(modifier);
873
+ }
874
+ });
875
+ sortedModifiers.push(...unsortedModifiers.sort());
876
+ return sortedModifiers;
877
+ };
878
+ var createConfigUtils = (config) => ({
879
+ cache: createLruCache(config.cacheSize),
880
+ parseClassName: createParseClassName(config),
881
+ ...createClassGroupUtils(config)
882
+ });
883
+ var SPLIT_CLASSES_REGEX = /\s+/;
884
+ var mergeClassList = (classList, configUtils) => {
885
+ const {
886
+ parseClassName,
887
+ getClassGroupId,
888
+ getConflictingClassGroupIds
889
+ } = configUtils;
890
+ const classGroupsInConflict = [];
891
+ const classNames = classList.trim().split(SPLIT_CLASSES_REGEX);
892
+ let result = "";
893
+ for (let index = classNames.length - 1;index >= 0; index -= 1) {
894
+ const originalClassName = classNames[index];
895
+ const {
896
+ modifiers,
897
+ hasImportantModifier,
898
+ baseClassName,
899
+ maybePostfixModifierPosition
900
+ } = parseClassName(originalClassName);
901
+ let hasPostfixModifier = Boolean(maybePostfixModifierPosition);
902
+ let classGroupId = getClassGroupId(hasPostfixModifier ? baseClassName.substring(0, maybePostfixModifierPosition) : baseClassName);
903
+ if (!classGroupId) {
904
+ if (!hasPostfixModifier) {
905
+ result = originalClassName + (result.length > 0 ? " " + result : result);
906
+ continue;
907
+ }
908
+ classGroupId = getClassGroupId(baseClassName);
909
+ if (!classGroupId) {
910
+ result = originalClassName + (result.length > 0 ? " " + result : result);
911
+ continue;
912
+ }
913
+ hasPostfixModifier = false;
914
+ }
915
+ const variantModifier = sortModifiers(modifiers).join(":");
916
+ const modifierId = hasImportantModifier ? variantModifier + IMPORTANT_MODIFIER : variantModifier;
917
+ const classId = modifierId + classGroupId;
918
+ if (classGroupsInConflict.includes(classId)) {
919
+ continue;
920
+ }
921
+ classGroupsInConflict.push(classId);
922
+ const conflictGroups = getConflictingClassGroupIds(classGroupId, hasPostfixModifier);
923
+ for (let i = 0;i < conflictGroups.length; ++i) {
924
+ const group = conflictGroups[i];
925
+ classGroupsInConflict.push(modifierId + group);
926
+ }
927
+ result = originalClassName + (result.length > 0 ? " " + result : result);
928
+ }
929
+ return result;
930
+ };
931
+ function twJoin() {
932
+ let index = 0;
933
+ let argument;
934
+ let resolvedValue;
935
+ let string = "";
936
+ while (index < arguments.length) {
937
+ if (argument = arguments[index++]) {
938
+ if (resolvedValue = toValue(argument)) {
939
+ string && (string += " ");
940
+ string += resolvedValue;
941
+ }
942
+ }
943
+ }
944
+ return string;
945
+ }
946
+ var toValue = (mix) => {
947
+ if (typeof mix === "string") {
948
+ return mix;
949
+ }
950
+ let resolvedValue;
951
+ let string = "";
952
+ for (let k = 0;k < mix.length; k++) {
953
+ if (mix[k]) {
954
+ if (resolvedValue = toValue(mix[k])) {
955
+ string && (string += " ");
956
+ string += resolvedValue;
957
+ }
958
+ }
959
+ }
960
+ return string;
961
+ };
962
+ function createTailwindMerge(createConfigFirst, ...createConfigRest) {
963
+ let configUtils;
964
+ let cacheGet;
965
+ let cacheSet;
966
+ let functionToCall = initTailwindMerge;
967
+ function initTailwindMerge(classList) {
968
+ const config = createConfigRest.reduce((previousConfig, createConfigCurrent) => createConfigCurrent(previousConfig), createConfigFirst());
969
+ configUtils = createConfigUtils(config);
970
+ cacheGet = configUtils.cache.get;
971
+ cacheSet = configUtils.cache.set;
972
+ functionToCall = tailwindMerge;
973
+ return tailwindMerge(classList);
974
+ }
975
+ function tailwindMerge(classList) {
976
+ const cachedResult = cacheGet(classList);
977
+ if (cachedResult) {
978
+ return cachedResult;
979
+ }
980
+ const result = mergeClassList(classList, configUtils);
981
+ cacheSet(classList, result);
982
+ return result;
983
+ }
984
+ return function callTailwindMerge() {
985
+ return functionToCall(twJoin.apply(null, arguments));
986
+ };
987
+ }
988
+ var fromTheme = (key) => {
989
+ const themeGetter = (theme) => theme[key] || [];
990
+ themeGetter.isThemeGetter = true;
991
+ return themeGetter;
992
+ };
993
+ var arbitraryValueRegex = /^\[(?:([a-z-]+):)?(.+)\]$/i;
994
+ var fractionRegex = /^\d+\/\d+$/;
995
+ var stringLengths = /* @__PURE__ */ new Set(["px", "full", "screen"]);
996
+ var tshirtUnitRegex = /^(\d+(\.\d+)?)?(xs|sm|md|lg|xl)$/;
997
+ var lengthUnitRegex = /\d+(%|px|r?em|[sdl]?v([hwib]|min|max)|pt|pc|in|cm|mm|cap|ch|ex|r?lh|cq(w|h|i|b|min|max))|\b(calc|min|max|clamp)\(.+\)|^0$/;
998
+ var colorFunctionRegex = /^(rgba?|hsla?|hwb|(ok)?(lab|lch)|color-mix)\(.+\)$/;
999
+ var shadowRegex = /^(inset_)?-?((\d+)?\.?(\d+)[a-z]+|0)_-?((\d+)?\.?(\d+)[a-z]+|0)/;
1000
+ var imageRegex = /^(url|image|image-set|cross-fade|element|(repeating-)?(linear|radial|conic)-gradient)\(.+\)$/;
1001
+ var isLength = (value) => isNumber(value) || stringLengths.has(value) || fractionRegex.test(value);
1002
+ var isArbitraryLength = (value) => getIsArbitraryValue(value, "length", isLengthOnly);
1003
+ var isNumber = (value) => Boolean(value) && !Number.isNaN(Number(value));
1004
+ var isArbitraryNumber = (value) => getIsArbitraryValue(value, "number", isNumber);
1005
+ var isInteger = (value) => Boolean(value) && Number.isInteger(Number(value));
1006
+ var isPercent = (value) => value.endsWith("%") && isNumber(value.slice(0, -1));
1007
+ var isArbitraryValue = (value) => arbitraryValueRegex.test(value);
1008
+ var isTshirtSize = (value) => tshirtUnitRegex.test(value);
1009
+ var sizeLabels = /* @__PURE__ */ new Set(["length", "size", "percentage"]);
1010
+ var isArbitrarySize = (value) => getIsArbitraryValue(value, sizeLabels, isNever);
1011
+ var isArbitraryPosition = (value) => getIsArbitraryValue(value, "position", isNever);
1012
+ var imageLabels = /* @__PURE__ */ new Set(["image", "url"]);
1013
+ var isArbitraryImage = (value) => getIsArbitraryValue(value, imageLabels, isImage);
1014
+ var isArbitraryShadow = (value) => getIsArbitraryValue(value, "", isShadow);
1015
+ var isAny = () => true;
1016
+ var getIsArbitraryValue = (value, label, testValue) => {
1017
+ const result = arbitraryValueRegex.exec(value);
1018
+ if (result) {
1019
+ if (result[1]) {
1020
+ return typeof label === "string" ? result[1] === label : label.has(result[1]);
1021
+ }
1022
+ return testValue(result[2]);
1023
+ }
1024
+ return false;
1025
+ };
1026
+ var isLengthOnly = (value) => lengthUnitRegex.test(value) && !colorFunctionRegex.test(value);
1027
+ var isNever = () => false;
1028
+ var isShadow = (value) => shadowRegex.test(value);
1029
+ var isImage = (value) => imageRegex.test(value);
1030
+ var getDefaultConfig = () => {
1031
+ const colors = fromTheme("colors");
1032
+ const spacing = fromTheme("spacing");
1033
+ const blur = fromTheme("blur");
1034
+ const brightness = fromTheme("brightness");
1035
+ const borderColor = fromTheme("borderColor");
1036
+ const borderRadius = fromTheme("borderRadius");
1037
+ const borderSpacing = fromTheme("borderSpacing");
1038
+ const borderWidth = fromTheme("borderWidth");
1039
+ const contrast = fromTheme("contrast");
1040
+ const grayscale = fromTheme("grayscale");
1041
+ const hueRotate = fromTheme("hueRotate");
1042
+ const invert = fromTheme("invert");
1043
+ const gap = fromTheme("gap");
1044
+ const gradientColorStops = fromTheme("gradientColorStops");
1045
+ const gradientColorStopPositions = fromTheme("gradientColorStopPositions");
1046
+ const inset = fromTheme("inset");
1047
+ const margin = fromTheme("margin");
1048
+ const opacity = fromTheme("opacity");
1049
+ const padding = fromTheme("padding");
1050
+ const saturate = fromTheme("saturate");
1051
+ const scale = fromTheme("scale");
1052
+ const sepia = fromTheme("sepia");
1053
+ const skew = fromTheme("skew");
1054
+ const space = fromTheme("space");
1055
+ const translate = fromTheme("translate");
1056
+ const getOverscroll = () => ["auto", "contain", "none"];
1057
+ const getOverflow = () => ["auto", "hidden", "clip", "visible", "scroll"];
1058
+ const getSpacingWithAutoAndArbitrary = () => ["auto", isArbitraryValue, spacing];
1059
+ const getSpacingWithArbitrary = () => [isArbitraryValue, spacing];
1060
+ const getLengthWithEmptyAndArbitrary = () => ["", isLength, isArbitraryLength];
1061
+ const getNumberWithAutoAndArbitrary = () => ["auto", isNumber, isArbitraryValue];
1062
+ const getPositions = () => ["bottom", "center", "left", "left-bottom", "left-top", "right", "right-bottom", "right-top", "top"];
1063
+ const getLineStyles = () => ["solid", "dashed", "dotted", "double", "none"];
1064
+ const getBlendModes = () => ["normal", "multiply", "screen", "overlay", "darken", "lighten", "color-dodge", "color-burn", "hard-light", "soft-light", "difference", "exclusion", "hue", "saturation", "color", "luminosity"];
1065
+ const getAlign = () => ["start", "end", "center", "between", "around", "evenly", "stretch"];
1066
+ const getZeroAndEmpty = () => ["", "0", isArbitraryValue];
1067
+ const getBreaks = () => ["auto", "avoid", "all", "avoid-page", "page", "left", "right", "column"];
1068
+ const getNumberAndArbitrary = () => [isNumber, isArbitraryValue];
1069
+ return {
1070
+ cacheSize: 500,
1071
+ separator: ":",
1072
+ theme: {
1073
+ colors: [isAny],
1074
+ spacing: [isLength, isArbitraryLength],
1075
+ blur: ["none", "", isTshirtSize, isArbitraryValue],
1076
+ brightness: getNumberAndArbitrary(),
1077
+ borderColor: [colors],
1078
+ borderRadius: ["none", "", "full", isTshirtSize, isArbitraryValue],
1079
+ borderSpacing: getSpacingWithArbitrary(),
1080
+ borderWidth: getLengthWithEmptyAndArbitrary(),
1081
+ contrast: getNumberAndArbitrary(),
1082
+ grayscale: getZeroAndEmpty(),
1083
+ hueRotate: getNumberAndArbitrary(),
1084
+ invert: getZeroAndEmpty(),
1085
+ gap: getSpacingWithArbitrary(),
1086
+ gradientColorStops: [colors],
1087
+ gradientColorStopPositions: [isPercent, isArbitraryLength],
1088
+ inset: getSpacingWithAutoAndArbitrary(),
1089
+ margin: getSpacingWithAutoAndArbitrary(),
1090
+ opacity: getNumberAndArbitrary(),
1091
+ padding: getSpacingWithArbitrary(),
1092
+ saturate: getNumberAndArbitrary(),
1093
+ scale: getNumberAndArbitrary(),
1094
+ sepia: getZeroAndEmpty(),
1095
+ skew: getNumberAndArbitrary(),
1096
+ space: getSpacingWithArbitrary(),
1097
+ translate: getSpacingWithArbitrary()
1098
+ },
1099
+ classGroups: {
1100
+ aspect: [{
1101
+ aspect: ["auto", "square", "video", isArbitraryValue]
1102
+ }],
1103
+ container: ["container"],
1104
+ columns: [{
1105
+ columns: [isTshirtSize]
1106
+ }],
1107
+ "break-after": [{
1108
+ "break-after": getBreaks()
1109
+ }],
1110
+ "break-before": [{
1111
+ "break-before": getBreaks()
1112
+ }],
1113
+ "break-inside": [{
1114
+ "break-inside": ["auto", "avoid", "avoid-page", "avoid-column"]
1115
+ }],
1116
+ "box-decoration": [{
1117
+ "box-decoration": ["slice", "clone"]
1118
+ }],
1119
+ box: [{
1120
+ box: ["border", "content"]
1121
+ }],
1122
+ display: ["block", "inline-block", "inline", "flex", "inline-flex", "table", "inline-table", "table-caption", "table-cell", "table-column", "table-column-group", "table-footer-group", "table-header-group", "table-row-group", "table-row", "flow-root", "grid", "inline-grid", "contents", "list-item", "hidden"],
1123
+ float: [{
1124
+ float: ["right", "left", "none", "start", "end"]
1125
+ }],
1126
+ clear: [{
1127
+ clear: ["left", "right", "both", "none", "start", "end"]
1128
+ }],
1129
+ isolation: ["isolate", "isolation-auto"],
1130
+ "object-fit": [{
1131
+ object: ["contain", "cover", "fill", "none", "scale-down"]
1132
+ }],
1133
+ "object-position": [{
1134
+ object: [...getPositions(), isArbitraryValue]
1135
+ }],
1136
+ overflow: [{
1137
+ overflow: getOverflow()
1138
+ }],
1139
+ "overflow-x": [{
1140
+ "overflow-x": getOverflow()
1141
+ }],
1142
+ "overflow-y": [{
1143
+ "overflow-y": getOverflow()
1144
+ }],
1145
+ overscroll: [{
1146
+ overscroll: getOverscroll()
1147
+ }],
1148
+ "overscroll-x": [{
1149
+ "overscroll-x": getOverscroll()
1150
+ }],
1151
+ "overscroll-y": [{
1152
+ "overscroll-y": getOverscroll()
1153
+ }],
1154
+ position: ["static", "fixed", "absolute", "relative", "sticky"],
1155
+ inset: [{
1156
+ inset: [inset]
1157
+ }],
1158
+ "inset-x": [{
1159
+ "inset-x": [inset]
1160
+ }],
1161
+ "inset-y": [{
1162
+ "inset-y": [inset]
1163
+ }],
1164
+ start: [{
1165
+ start: [inset]
1166
+ }],
1167
+ end: [{
1168
+ end: [inset]
1169
+ }],
1170
+ top: [{
1171
+ top: [inset]
1172
+ }],
1173
+ right: [{
1174
+ right: [inset]
1175
+ }],
1176
+ bottom: [{
1177
+ bottom: [inset]
1178
+ }],
1179
+ left: [{
1180
+ left: [inset]
1181
+ }],
1182
+ visibility: ["visible", "invisible", "collapse"],
1183
+ z: [{
1184
+ z: ["auto", isInteger, isArbitraryValue]
1185
+ }],
1186
+ basis: [{
1187
+ basis: getSpacingWithAutoAndArbitrary()
1188
+ }],
1189
+ "flex-direction": [{
1190
+ flex: ["row", "row-reverse", "col", "col-reverse"]
1191
+ }],
1192
+ "flex-wrap": [{
1193
+ flex: ["wrap", "wrap-reverse", "nowrap"]
1194
+ }],
1195
+ flex: [{
1196
+ flex: ["1", "auto", "initial", "none", isArbitraryValue]
1197
+ }],
1198
+ grow: [{
1199
+ grow: getZeroAndEmpty()
1200
+ }],
1201
+ shrink: [{
1202
+ shrink: getZeroAndEmpty()
1203
+ }],
1204
+ order: [{
1205
+ order: ["first", "last", "none", isInteger, isArbitraryValue]
1206
+ }],
1207
+ "grid-cols": [{
1208
+ "grid-cols": [isAny]
1209
+ }],
1210
+ "col-start-end": [{
1211
+ col: ["auto", {
1212
+ span: ["full", isInteger, isArbitraryValue]
1213
+ }, isArbitraryValue]
1214
+ }],
1215
+ "col-start": [{
1216
+ "col-start": getNumberWithAutoAndArbitrary()
1217
+ }],
1218
+ "col-end": [{
1219
+ "col-end": getNumberWithAutoAndArbitrary()
1220
+ }],
1221
+ "grid-rows": [{
1222
+ "grid-rows": [isAny]
1223
+ }],
1224
+ "row-start-end": [{
1225
+ row: ["auto", {
1226
+ span: [isInteger, isArbitraryValue]
1227
+ }, isArbitraryValue]
1228
+ }],
1229
+ "row-start": [{
1230
+ "row-start": getNumberWithAutoAndArbitrary()
1231
+ }],
1232
+ "row-end": [{
1233
+ "row-end": getNumberWithAutoAndArbitrary()
1234
+ }],
1235
+ "grid-flow": [{
1236
+ "grid-flow": ["row", "col", "dense", "row-dense", "col-dense"]
1237
+ }],
1238
+ "auto-cols": [{
1239
+ "auto-cols": ["auto", "min", "max", "fr", isArbitraryValue]
1240
+ }],
1241
+ "auto-rows": [{
1242
+ "auto-rows": ["auto", "min", "max", "fr", isArbitraryValue]
1243
+ }],
1244
+ gap: [{
1245
+ gap: [gap]
1246
+ }],
1247
+ "gap-x": [{
1248
+ "gap-x": [gap]
1249
+ }],
1250
+ "gap-y": [{
1251
+ "gap-y": [gap]
1252
+ }],
1253
+ "justify-content": [{
1254
+ justify: ["normal", ...getAlign()]
1255
+ }],
1256
+ "justify-items": [{
1257
+ "justify-items": ["start", "end", "center", "stretch"]
1258
+ }],
1259
+ "justify-self": [{
1260
+ "justify-self": ["auto", "start", "end", "center", "stretch"]
1261
+ }],
1262
+ "align-content": [{
1263
+ content: ["normal", ...getAlign(), "baseline"]
1264
+ }],
1265
+ "align-items": [{
1266
+ items: ["start", "end", "center", "baseline", "stretch"]
1267
+ }],
1268
+ "align-self": [{
1269
+ self: ["auto", "start", "end", "center", "stretch", "baseline"]
1270
+ }],
1271
+ "place-content": [{
1272
+ "place-content": [...getAlign(), "baseline"]
1273
+ }],
1274
+ "place-items": [{
1275
+ "place-items": ["start", "end", "center", "baseline", "stretch"]
1276
+ }],
1277
+ "place-self": [{
1278
+ "place-self": ["auto", "start", "end", "center", "stretch"]
1279
+ }],
1280
+ p: [{
1281
+ p: [padding]
1282
+ }],
1283
+ px: [{
1284
+ px: [padding]
1285
+ }],
1286
+ py: [{
1287
+ py: [padding]
1288
+ }],
1289
+ ps: [{
1290
+ ps: [padding]
1291
+ }],
1292
+ pe: [{
1293
+ pe: [padding]
1294
+ }],
1295
+ pt: [{
1296
+ pt: [padding]
1297
+ }],
1298
+ pr: [{
1299
+ pr: [padding]
1300
+ }],
1301
+ pb: [{
1302
+ pb: [padding]
1303
+ }],
1304
+ pl: [{
1305
+ pl: [padding]
1306
+ }],
1307
+ m: [{
1308
+ m: [margin]
1309
+ }],
1310
+ mx: [{
1311
+ mx: [margin]
1312
+ }],
1313
+ my: [{
1314
+ my: [margin]
1315
+ }],
1316
+ ms: [{
1317
+ ms: [margin]
1318
+ }],
1319
+ me: [{
1320
+ me: [margin]
1321
+ }],
1322
+ mt: [{
1323
+ mt: [margin]
1324
+ }],
1325
+ mr: [{
1326
+ mr: [margin]
1327
+ }],
1328
+ mb: [{
1329
+ mb: [margin]
1330
+ }],
1331
+ ml: [{
1332
+ ml: [margin]
1333
+ }],
1334
+ "space-x": [{
1335
+ "space-x": [space]
1336
+ }],
1337
+ "space-x-reverse": ["space-x-reverse"],
1338
+ "space-y": [{
1339
+ "space-y": [space]
1340
+ }],
1341
+ "space-y-reverse": ["space-y-reverse"],
1342
+ w: [{
1343
+ w: ["auto", "min", "max", "fit", "svw", "lvw", "dvw", isArbitraryValue, spacing]
1344
+ }],
1345
+ "min-w": [{
1346
+ "min-w": [isArbitraryValue, spacing, "min", "max", "fit"]
1347
+ }],
1348
+ "max-w": [{
1349
+ "max-w": [isArbitraryValue, spacing, "none", "full", "min", "max", "fit", "prose", {
1350
+ screen: [isTshirtSize]
1351
+ }, isTshirtSize]
1352
+ }],
1353
+ h: [{
1354
+ h: [isArbitraryValue, spacing, "auto", "min", "max", "fit", "svh", "lvh", "dvh"]
1355
+ }],
1356
+ "min-h": [{
1357
+ "min-h": [isArbitraryValue, spacing, "min", "max", "fit", "svh", "lvh", "dvh"]
1358
+ }],
1359
+ "max-h": [{
1360
+ "max-h": [isArbitraryValue, spacing, "min", "max", "fit", "svh", "lvh", "dvh"]
1361
+ }],
1362
+ size: [{
1363
+ size: [isArbitraryValue, spacing, "auto", "min", "max", "fit"]
1364
+ }],
1365
+ "font-size": [{
1366
+ text: ["base", isTshirtSize, isArbitraryLength]
1367
+ }],
1368
+ "font-smoothing": ["antialiased", "subpixel-antialiased"],
1369
+ "font-style": ["italic", "not-italic"],
1370
+ "font-weight": [{
1371
+ font: ["thin", "extralight", "light", "normal", "medium", "semibold", "bold", "extrabold", "black", isArbitraryNumber]
1372
+ }],
1373
+ "font-family": [{
1374
+ font: [isAny]
1375
+ }],
1376
+ "fvn-normal": ["normal-nums"],
1377
+ "fvn-ordinal": ["ordinal"],
1378
+ "fvn-slashed-zero": ["slashed-zero"],
1379
+ "fvn-figure": ["lining-nums", "oldstyle-nums"],
1380
+ "fvn-spacing": ["proportional-nums", "tabular-nums"],
1381
+ "fvn-fraction": ["diagonal-fractions", "stacked-fractions"],
1382
+ tracking: [{
1383
+ tracking: ["tighter", "tight", "normal", "wide", "wider", "widest", isArbitraryValue]
1384
+ }],
1385
+ "line-clamp": [{
1386
+ "line-clamp": ["none", isNumber, isArbitraryNumber]
1387
+ }],
1388
+ leading: [{
1389
+ leading: ["none", "tight", "snug", "normal", "relaxed", "loose", isLength, isArbitraryValue]
1390
+ }],
1391
+ "list-image": [{
1392
+ "list-image": ["none", isArbitraryValue]
1393
+ }],
1394
+ "list-style-type": [{
1395
+ list: ["none", "disc", "decimal", isArbitraryValue]
1396
+ }],
1397
+ "list-style-position": [{
1398
+ list: ["inside", "outside"]
1399
+ }],
1400
+ "placeholder-color": [{
1401
+ placeholder: [colors]
1402
+ }],
1403
+ "placeholder-opacity": [{
1404
+ "placeholder-opacity": [opacity]
1405
+ }],
1406
+ "text-alignment": [{
1407
+ text: ["left", "center", "right", "justify", "start", "end"]
1408
+ }],
1409
+ "text-color": [{
1410
+ text: [colors]
1411
+ }],
1412
+ "text-opacity": [{
1413
+ "text-opacity": [opacity]
1414
+ }],
1415
+ "text-decoration": ["underline", "overline", "line-through", "no-underline"],
1416
+ "text-decoration-style": [{
1417
+ decoration: [...getLineStyles(), "wavy"]
1418
+ }],
1419
+ "text-decoration-thickness": [{
1420
+ decoration: ["auto", "from-font", isLength, isArbitraryLength]
1421
+ }],
1422
+ "underline-offset": [{
1423
+ "underline-offset": ["auto", isLength, isArbitraryValue]
1424
+ }],
1425
+ "text-decoration-color": [{
1426
+ decoration: [colors]
1427
+ }],
1428
+ "text-transform": ["uppercase", "lowercase", "capitalize", "normal-case"],
1429
+ "text-overflow": ["truncate", "text-ellipsis", "text-clip"],
1430
+ "text-wrap": [{
1431
+ text: ["wrap", "nowrap", "balance", "pretty"]
1432
+ }],
1433
+ indent: [{
1434
+ indent: getSpacingWithArbitrary()
1435
+ }],
1436
+ "vertical-align": [{
1437
+ align: ["baseline", "top", "middle", "bottom", "text-top", "text-bottom", "sub", "super", isArbitraryValue]
1438
+ }],
1439
+ whitespace: [{
1440
+ whitespace: ["normal", "nowrap", "pre", "pre-line", "pre-wrap", "break-spaces"]
1441
+ }],
1442
+ break: [{
1443
+ break: ["normal", "words", "all", "keep"]
1444
+ }],
1445
+ hyphens: [{
1446
+ hyphens: ["none", "manual", "auto"]
1447
+ }],
1448
+ content: [{
1449
+ content: ["none", isArbitraryValue]
1450
+ }],
1451
+ "bg-attachment": [{
1452
+ bg: ["fixed", "local", "scroll"]
1453
+ }],
1454
+ "bg-clip": [{
1455
+ "bg-clip": ["border", "padding", "content", "text"]
1456
+ }],
1457
+ "bg-opacity": [{
1458
+ "bg-opacity": [opacity]
1459
+ }],
1460
+ "bg-origin": [{
1461
+ "bg-origin": ["border", "padding", "content"]
1462
+ }],
1463
+ "bg-position": [{
1464
+ bg: [...getPositions(), isArbitraryPosition]
1465
+ }],
1466
+ "bg-repeat": [{
1467
+ bg: ["no-repeat", {
1468
+ repeat: ["", "x", "y", "round", "space"]
1469
+ }]
1470
+ }],
1471
+ "bg-size": [{
1472
+ bg: ["auto", "cover", "contain", isArbitrarySize]
1473
+ }],
1474
+ "bg-image": [{
1475
+ bg: ["none", {
1476
+ "gradient-to": ["t", "tr", "r", "br", "b", "bl", "l", "tl"]
1477
+ }, isArbitraryImage]
1478
+ }],
1479
+ "bg-color": [{
1480
+ bg: [colors]
1481
+ }],
1482
+ "gradient-from-pos": [{
1483
+ from: [gradientColorStopPositions]
1484
+ }],
1485
+ "gradient-via-pos": [{
1486
+ via: [gradientColorStopPositions]
1487
+ }],
1488
+ "gradient-to-pos": [{
1489
+ to: [gradientColorStopPositions]
1490
+ }],
1491
+ "gradient-from": [{
1492
+ from: [gradientColorStops]
1493
+ }],
1494
+ "gradient-via": [{
1495
+ via: [gradientColorStops]
1496
+ }],
1497
+ "gradient-to": [{
1498
+ to: [gradientColorStops]
1499
+ }],
1500
+ rounded: [{
1501
+ rounded: [borderRadius]
1502
+ }],
1503
+ "rounded-s": [{
1504
+ "rounded-s": [borderRadius]
1505
+ }],
1506
+ "rounded-e": [{
1507
+ "rounded-e": [borderRadius]
1508
+ }],
1509
+ "rounded-t": [{
1510
+ "rounded-t": [borderRadius]
1511
+ }],
1512
+ "rounded-r": [{
1513
+ "rounded-r": [borderRadius]
1514
+ }],
1515
+ "rounded-b": [{
1516
+ "rounded-b": [borderRadius]
1517
+ }],
1518
+ "rounded-l": [{
1519
+ "rounded-l": [borderRadius]
1520
+ }],
1521
+ "rounded-ss": [{
1522
+ "rounded-ss": [borderRadius]
1523
+ }],
1524
+ "rounded-se": [{
1525
+ "rounded-se": [borderRadius]
1526
+ }],
1527
+ "rounded-ee": [{
1528
+ "rounded-ee": [borderRadius]
1529
+ }],
1530
+ "rounded-es": [{
1531
+ "rounded-es": [borderRadius]
1532
+ }],
1533
+ "rounded-tl": [{
1534
+ "rounded-tl": [borderRadius]
1535
+ }],
1536
+ "rounded-tr": [{
1537
+ "rounded-tr": [borderRadius]
1538
+ }],
1539
+ "rounded-br": [{
1540
+ "rounded-br": [borderRadius]
1541
+ }],
1542
+ "rounded-bl": [{
1543
+ "rounded-bl": [borderRadius]
1544
+ }],
1545
+ "border-w": [{
1546
+ border: [borderWidth]
1547
+ }],
1548
+ "border-w-x": [{
1549
+ "border-x": [borderWidth]
1550
+ }],
1551
+ "border-w-y": [{
1552
+ "border-y": [borderWidth]
1553
+ }],
1554
+ "border-w-s": [{
1555
+ "border-s": [borderWidth]
1556
+ }],
1557
+ "border-w-e": [{
1558
+ "border-e": [borderWidth]
1559
+ }],
1560
+ "border-w-t": [{
1561
+ "border-t": [borderWidth]
1562
+ }],
1563
+ "border-w-r": [{
1564
+ "border-r": [borderWidth]
1565
+ }],
1566
+ "border-w-b": [{
1567
+ "border-b": [borderWidth]
1568
+ }],
1569
+ "border-w-l": [{
1570
+ "border-l": [borderWidth]
1571
+ }],
1572
+ "border-opacity": [{
1573
+ "border-opacity": [opacity]
1574
+ }],
1575
+ "border-style": [{
1576
+ border: [...getLineStyles(), "hidden"]
1577
+ }],
1578
+ "divide-x": [{
1579
+ "divide-x": [borderWidth]
1580
+ }],
1581
+ "divide-x-reverse": ["divide-x-reverse"],
1582
+ "divide-y": [{
1583
+ "divide-y": [borderWidth]
1584
+ }],
1585
+ "divide-y-reverse": ["divide-y-reverse"],
1586
+ "divide-opacity": [{
1587
+ "divide-opacity": [opacity]
1588
+ }],
1589
+ "divide-style": [{
1590
+ divide: getLineStyles()
1591
+ }],
1592
+ "border-color": [{
1593
+ border: [borderColor]
1594
+ }],
1595
+ "border-color-x": [{
1596
+ "border-x": [borderColor]
1597
+ }],
1598
+ "border-color-y": [{
1599
+ "border-y": [borderColor]
1600
+ }],
1601
+ "border-color-s": [{
1602
+ "border-s": [borderColor]
1603
+ }],
1604
+ "border-color-e": [{
1605
+ "border-e": [borderColor]
1606
+ }],
1607
+ "border-color-t": [{
1608
+ "border-t": [borderColor]
1609
+ }],
1610
+ "border-color-r": [{
1611
+ "border-r": [borderColor]
1612
+ }],
1613
+ "border-color-b": [{
1614
+ "border-b": [borderColor]
1615
+ }],
1616
+ "border-color-l": [{
1617
+ "border-l": [borderColor]
1618
+ }],
1619
+ "divide-color": [{
1620
+ divide: [borderColor]
1621
+ }],
1622
+ "outline-style": [{
1623
+ outline: ["", ...getLineStyles()]
1624
+ }],
1625
+ "outline-offset": [{
1626
+ "outline-offset": [isLength, isArbitraryValue]
1627
+ }],
1628
+ "outline-w": [{
1629
+ outline: [isLength, isArbitraryLength]
1630
+ }],
1631
+ "outline-color": [{
1632
+ outline: [colors]
1633
+ }],
1634
+ "ring-w": [{
1635
+ ring: getLengthWithEmptyAndArbitrary()
1636
+ }],
1637
+ "ring-w-inset": ["ring-inset"],
1638
+ "ring-color": [{
1639
+ ring: [colors]
1640
+ }],
1641
+ "ring-opacity": [{
1642
+ "ring-opacity": [opacity]
1643
+ }],
1644
+ "ring-offset-w": [{
1645
+ "ring-offset": [isLength, isArbitraryLength]
1646
+ }],
1647
+ "ring-offset-color": [{
1648
+ "ring-offset": [colors]
1649
+ }],
1650
+ shadow: [{
1651
+ shadow: ["", "inner", "none", isTshirtSize, isArbitraryShadow]
1652
+ }],
1653
+ "shadow-color": [{
1654
+ shadow: [isAny]
1655
+ }],
1656
+ opacity: [{
1657
+ opacity: [opacity]
1658
+ }],
1659
+ "mix-blend": [{
1660
+ "mix-blend": [...getBlendModes(), "plus-lighter", "plus-darker"]
1661
+ }],
1662
+ "bg-blend": [{
1663
+ "bg-blend": getBlendModes()
1664
+ }],
1665
+ filter: [{
1666
+ filter: ["", "none"]
1667
+ }],
1668
+ blur: [{
1669
+ blur: [blur]
1670
+ }],
1671
+ brightness: [{
1672
+ brightness: [brightness]
1673
+ }],
1674
+ contrast: [{
1675
+ contrast: [contrast]
1676
+ }],
1677
+ "drop-shadow": [{
1678
+ "drop-shadow": ["", "none", isTshirtSize, isArbitraryValue]
1679
+ }],
1680
+ grayscale: [{
1681
+ grayscale: [grayscale]
1682
+ }],
1683
+ "hue-rotate": [{
1684
+ "hue-rotate": [hueRotate]
1685
+ }],
1686
+ invert: [{
1687
+ invert: [invert]
1688
+ }],
1689
+ saturate: [{
1690
+ saturate: [saturate]
1691
+ }],
1692
+ sepia: [{
1693
+ sepia: [sepia]
1694
+ }],
1695
+ "backdrop-filter": [{
1696
+ "backdrop-filter": ["", "none"]
1697
+ }],
1698
+ "backdrop-blur": [{
1699
+ "backdrop-blur": [blur]
1700
+ }],
1701
+ "backdrop-brightness": [{
1702
+ "backdrop-brightness": [brightness]
1703
+ }],
1704
+ "backdrop-contrast": [{
1705
+ "backdrop-contrast": [contrast]
1706
+ }],
1707
+ "backdrop-grayscale": [{
1708
+ "backdrop-grayscale": [grayscale]
1709
+ }],
1710
+ "backdrop-hue-rotate": [{
1711
+ "backdrop-hue-rotate": [hueRotate]
1712
+ }],
1713
+ "backdrop-invert": [{
1714
+ "backdrop-invert": [invert]
1715
+ }],
1716
+ "backdrop-opacity": [{
1717
+ "backdrop-opacity": [opacity]
1718
+ }],
1719
+ "backdrop-saturate": [{
1720
+ "backdrop-saturate": [saturate]
1721
+ }],
1722
+ "backdrop-sepia": [{
1723
+ "backdrop-sepia": [sepia]
1724
+ }],
1725
+ "border-collapse": [{
1726
+ border: ["collapse", "separate"]
1727
+ }],
1728
+ "border-spacing": [{
1729
+ "border-spacing": [borderSpacing]
1730
+ }],
1731
+ "border-spacing-x": [{
1732
+ "border-spacing-x": [borderSpacing]
1733
+ }],
1734
+ "border-spacing-y": [{
1735
+ "border-spacing-y": [borderSpacing]
1736
+ }],
1737
+ "table-layout": [{
1738
+ table: ["auto", "fixed"]
1739
+ }],
1740
+ caption: [{
1741
+ caption: ["top", "bottom"]
1742
+ }],
1743
+ transition: [{
1744
+ transition: ["none", "all", "", "colors", "opacity", "shadow", "transform", isArbitraryValue]
1745
+ }],
1746
+ duration: [{
1747
+ duration: getNumberAndArbitrary()
1748
+ }],
1749
+ ease: [{
1750
+ ease: ["linear", "in", "out", "in-out", isArbitraryValue]
1751
+ }],
1752
+ delay: [{
1753
+ delay: getNumberAndArbitrary()
1754
+ }],
1755
+ animate: [{
1756
+ animate: ["none", "spin", "ping", "pulse", "bounce", isArbitraryValue]
1757
+ }],
1758
+ transform: [{
1759
+ transform: ["", "gpu", "none"]
1760
+ }],
1761
+ scale: [{
1762
+ scale: [scale]
1763
+ }],
1764
+ "scale-x": [{
1765
+ "scale-x": [scale]
1766
+ }],
1767
+ "scale-y": [{
1768
+ "scale-y": [scale]
1769
+ }],
1770
+ rotate: [{
1771
+ rotate: [isInteger, isArbitraryValue]
1772
+ }],
1773
+ "translate-x": [{
1774
+ "translate-x": [translate]
1775
+ }],
1776
+ "translate-y": [{
1777
+ "translate-y": [translate]
1778
+ }],
1779
+ "skew-x": [{
1780
+ "skew-x": [skew]
1781
+ }],
1782
+ "skew-y": [{
1783
+ "skew-y": [skew]
1784
+ }],
1785
+ "transform-origin": [{
1786
+ origin: ["center", "top", "top-right", "right", "bottom-right", "bottom", "bottom-left", "left", "top-left", isArbitraryValue]
1787
+ }],
1788
+ accent: [{
1789
+ accent: ["auto", colors]
1790
+ }],
1791
+ appearance: [{
1792
+ appearance: ["none", "auto"]
1793
+ }],
1794
+ cursor: [{
1795
+ cursor: ["auto", "default", "pointer", "wait", "text", "move", "help", "not-allowed", "none", "context-menu", "progress", "cell", "crosshair", "vertical-text", "alias", "copy", "no-drop", "grab", "grabbing", "all-scroll", "col-resize", "row-resize", "n-resize", "e-resize", "s-resize", "w-resize", "ne-resize", "nw-resize", "se-resize", "sw-resize", "ew-resize", "ns-resize", "nesw-resize", "nwse-resize", "zoom-in", "zoom-out", isArbitraryValue]
1796
+ }],
1797
+ "caret-color": [{
1798
+ caret: [colors]
1799
+ }],
1800
+ "pointer-events": [{
1801
+ "pointer-events": ["none", "auto"]
1802
+ }],
1803
+ resize: [{
1804
+ resize: ["none", "y", "x", ""]
1805
+ }],
1806
+ "scroll-behavior": [{
1807
+ scroll: ["auto", "smooth"]
1808
+ }],
1809
+ "scroll-m": [{
1810
+ "scroll-m": getSpacingWithArbitrary()
1811
+ }],
1812
+ "scroll-mx": [{
1813
+ "scroll-mx": getSpacingWithArbitrary()
1814
+ }],
1815
+ "scroll-my": [{
1816
+ "scroll-my": getSpacingWithArbitrary()
1817
+ }],
1818
+ "scroll-ms": [{
1819
+ "scroll-ms": getSpacingWithArbitrary()
1820
+ }],
1821
+ "scroll-me": [{
1822
+ "scroll-me": getSpacingWithArbitrary()
1823
+ }],
1824
+ "scroll-mt": [{
1825
+ "scroll-mt": getSpacingWithArbitrary()
1826
+ }],
1827
+ "scroll-mr": [{
1828
+ "scroll-mr": getSpacingWithArbitrary()
1829
+ }],
1830
+ "scroll-mb": [{
1831
+ "scroll-mb": getSpacingWithArbitrary()
1832
+ }],
1833
+ "scroll-ml": [{
1834
+ "scroll-ml": getSpacingWithArbitrary()
1835
+ }],
1836
+ "scroll-p": [{
1837
+ "scroll-p": getSpacingWithArbitrary()
1838
+ }],
1839
+ "scroll-px": [{
1840
+ "scroll-px": getSpacingWithArbitrary()
1841
+ }],
1842
+ "scroll-py": [{
1843
+ "scroll-py": getSpacingWithArbitrary()
1844
+ }],
1845
+ "scroll-ps": [{
1846
+ "scroll-ps": getSpacingWithArbitrary()
1847
+ }],
1848
+ "scroll-pe": [{
1849
+ "scroll-pe": getSpacingWithArbitrary()
1850
+ }],
1851
+ "scroll-pt": [{
1852
+ "scroll-pt": getSpacingWithArbitrary()
1853
+ }],
1854
+ "scroll-pr": [{
1855
+ "scroll-pr": getSpacingWithArbitrary()
1856
+ }],
1857
+ "scroll-pb": [{
1858
+ "scroll-pb": getSpacingWithArbitrary()
1859
+ }],
1860
+ "scroll-pl": [{
1861
+ "scroll-pl": getSpacingWithArbitrary()
1862
+ }],
1863
+ "snap-align": [{
1864
+ snap: ["start", "end", "center", "align-none"]
1865
+ }],
1866
+ "snap-stop": [{
1867
+ snap: ["normal", "always"]
1868
+ }],
1869
+ "snap-type": [{
1870
+ snap: ["none", "x", "y", "both"]
1871
+ }],
1872
+ "snap-strictness": [{
1873
+ snap: ["mandatory", "proximity"]
1874
+ }],
1875
+ touch: [{
1876
+ touch: ["auto", "none", "manipulation"]
1877
+ }],
1878
+ "touch-x": [{
1879
+ "touch-pan": ["x", "left", "right"]
1880
+ }],
1881
+ "touch-y": [{
1882
+ "touch-pan": ["y", "up", "down"]
1883
+ }],
1884
+ "touch-pz": ["touch-pinch-zoom"],
1885
+ select: [{
1886
+ select: ["none", "text", "all", "auto"]
1887
+ }],
1888
+ "will-change": [{
1889
+ "will-change": ["auto", "scroll", "contents", "transform", isArbitraryValue]
1890
+ }],
1891
+ fill: [{
1892
+ fill: [colors, "none"]
1893
+ }],
1894
+ "stroke-w": [{
1895
+ stroke: [isLength, isArbitraryLength, isArbitraryNumber]
1896
+ }],
1897
+ stroke: [{
1898
+ stroke: [colors, "none"]
1899
+ }],
1900
+ sr: ["sr-only", "not-sr-only"],
1901
+ "forced-color-adjust": [{
1902
+ "forced-color-adjust": ["auto", "none"]
1903
+ }]
1904
+ },
1905
+ conflictingClassGroups: {
1906
+ overflow: ["overflow-x", "overflow-y"],
1907
+ overscroll: ["overscroll-x", "overscroll-y"],
1908
+ inset: ["inset-x", "inset-y", "start", "end", "top", "right", "bottom", "left"],
1909
+ "inset-x": ["right", "left"],
1910
+ "inset-y": ["top", "bottom"],
1911
+ flex: ["basis", "grow", "shrink"],
1912
+ gap: ["gap-x", "gap-y"],
1913
+ p: ["px", "py", "ps", "pe", "pt", "pr", "pb", "pl"],
1914
+ px: ["pr", "pl"],
1915
+ py: ["pt", "pb"],
1916
+ m: ["mx", "my", "ms", "me", "mt", "mr", "mb", "ml"],
1917
+ mx: ["mr", "ml"],
1918
+ my: ["mt", "mb"],
1919
+ size: ["w", "h"],
1920
+ "font-size": ["leading"],
1921
+ "fvn-normal": ["fvn-ordinal", "fvn-slashed-zero", "fvn-figure", "fvn-spacing", "fvn-fraction"],
1922
+ "fvn-ordinal": ["fvn-normal"],
1923
+ "fvn-slashed-zero": ["fvn-normal"],
1924
+ "fvn-figure": ["fvn-normal"],
1925
+ "fvn-spacing": ["fvn-normal"],
1926
+ "fvn-fraction": ["fvn-normal"],
1927
+ "line-clamp": ["display", "overflow"],
1928
+ rounded: ["rounded-s", "rounded-e", "rounded-t", "rounded-r", "rounded-b", "rounded-l", "rounded-ss", "rounded-se", "rounded-ee", "rounded-es", "rounded-tl", "rounded-tr", "rounded-br", "rounded-bl"],
1929
+ "rounded-s": ["rounded-ss", "rounded-es"],
1930
+ "rounded-e": ["rounded-se", "rounded-ee"],
1931
+ "rounded-t": ["rounded-tl", "rounded-tr"],
1932
+ "rounded-r": ["rounded-tr", "rounded-br"],
1933
+ "rounded-b": ["rounded-br", "rounded-bl"],
1934
+ "rounded-l": ["rounded-tl", "rounded-bl"],
1935
+ "border-spacing": ["border-spacing-x", "border-spacing-y"],
1936
+ "border-w": ["border-w-s", "border-w-e", "border-w-t", "border-w-r", "border-w-b", "border-w-l"],
1937
+ "border-w-x": ["border-w-r", "border-w-l"],
1938
+ "border-w-y": ["border-w-t", "border-w-b"],
1939
+ "border-color": ["border-color-s", "border-color-e", "border-color-t", "border-color-r", "border-color-b", "border-color-l"],
1940
+ "border-color-x": ["border-color-r", "border-color-l"],
1941
+ "border-color-y": ["border-color-t", "border-color-b"],
1942
+ "scroll-m": ["scroll-mx", "scroll-my", "scroll-ms", "scroll-me", "scroll-mt", "scroll-mr", "scroll-mb", "scroll-ml"],
1943
+ "scroll-mx": ["scroll-mr", "scroll-ml"],
1944
+ "scroll-my": ["scroll-mt", "scroll-mb"],
1945
+ "scroll-p": ["scroll-px", "scroll-py", "scroll-ps", "scroll-pe", "scroll-pt", "scroll-pr", "scroll-pb", "scroll-pl"],
1946
+ "scroll-px": ["scroll-pr", "scroll-pl"],
1947
+ "scroll-py": ["scroll-pt", "scroll-pb"],
1948
+ touch: ["touch-x", "touch-y", "touch-pz"],
1949
+ "touch-x": ["touch"],
1950
+ "touch-y": ["touch"],
1951
+ "touch-pz": ["touch"]
1952
+ },
1953
+ conflictingClassGroupModifiers: {
1954
+ "font-size": ["leading"]
1955
+ }
1956
+ };
1957
+ };
1958
+ var twMerge = /* @__PURE__ */ createTailwindMerge(getDefaultConfig);
1959
+
1960
+ // src/renderer/utils/cn.ts
1961
+ function cn(...inputs) {
1962
+ return twMerge(clsx(inputs));
1963
+ }
1964
+
1965
+ // src/renderer/components/Text.tsx
1966
+ import { jsxDEV } from "react/jsx-dev-runtime";
1967
+ var variantClasses = {
1968
+ default: "text-meissa-fg",
1969
+ muted: "text-meissa-muted",
1970
+ success: "text-meissa-success",
1971
+ warning: "text-meissa-warning",
1972
+ error: "text-meissa-destructive"
1973
+ };
1974
+ var alignClasses = {
1975
+ left: "text-left",
1976
+ center: "text-center",
1977
+ right: "text-right"
1978
+ };
1979
+ function Text({ node }) {
1980
+ const variant = node.variant || "default";
1981
+ const bold = node.bold;
1982
+ const align = node.align || "left";
1983
+ const content = node.content;
1984
+ return /* @__PURE__ */ jsxDEV("p", {
1985
+ className: cn(variantClasses[variant], alignClasses[align], bold && "font-semibold", node.class),
1986
+ children: content
1987
+ }, undefined, false, undefined, this);
1988
+ }
1989
+
1990
+ // src/renderer/components/Heading.tsx
1991
+ import { jsxDEV as jsxDEV2 } from "react/jsx-dev-runtime";
1992
+ var levelClasses = {
1993
+ 1: "text-3xl font-bold",
1994
+ 2: "text-2xl font-semibold",
1995
+ 3: "text-xl font-semibold",
1996
+ 4: "text-lg font-medium",
1997
+ 5: "text-base font-medium",
1998
+ 6: "text-sm font-medium"
1999
+ };
2000
+ var alignClasses2 = {
2001
+ left: "text-left",
2002
+ center: "text-center",
2003
+ right: "text-right"
2004
+ };
2005
+ function Heading({ node }) {
2006
+ const level = node.level || 2;
2007
+ const align = node.align || "left";
2008
+ const content = node.content;
2009
+ const Tag = `h${level}`;
2010
+ return /* @__PURE__ */ jsxDEV2(Tag, {
2011
+ className: cn(levelClasses[level], alignClasses2[align], "text-meissa-fg", node.class),
2012
+ children: content
2013
+ }, undefined, false, undefined, this);
2014
+ }
2015
+
2016
+ // src/renderer/components/Code.tsx
2017
+ import { jsxDEV as jsxDEV3 } from "react/jsx-dev-runtime";
2018
+ function Code({ node }) {
2019
+ const content = node.content;
2020
+ const lang = node.lang;
2021
+ const inline = node.inline;
2022
+ if (inline) {
2023
+ return /* @__PURE__ */ jsxDEV3("code", {
2024
+ className: cn("bg-meissa-fg/10 rounded px-1.5 py-0.5 text-sm font-mono text-meissa-fg", node.class),
2025
+ children: content
2026
+ }, undefined, false, undefined, this);
2027
+ }
2028
+ return /* @__PURE__ */ jsxDEV3("pre", {
2029
+ className: cn("bg-meissa-fg/10 rounded-lg p-4 overflow-x-auto", node.class),
2030
+ children: /* @__PURE__ */ jsxDEV3("code", {
2031
+ className: "text-sm font-mono text-meissa-fg",
2032
+ "data-lang": lang,
2033
+ children: content
2034
+ }, undefined, false, undefined, this)
2035
+ }, undefined, false, undefined, this);
2036
+ }
2037
+
2038
+ // src/renderer/utils/sanitize.ts
2039
+ function sanitizeUrl(url) {
2040
+ const trimmed = url.trim().toLowerCase();
2041
+ if (trimmed.startsWith("javascript:") || trimmed.startsWith("data:text/html")) {
2042
+ return "about:blank";
2043
+ }
2044
+ return url;
2045
+ }
2046
+
2047
+ // src/renderer/components/Img.tsx
2048
+ import { jsxDEV as jsxDEV4 } from "react/jsx-dev-runtime";
2049
+ var fitClasses = {
2050
+ cover: "object-cover",
2051
+ contain: "object-contain",
2052
+ fill: "object-fill"
2053
+ };
2054
+ function Img({ node }) {
2055
+ const src = sanitizeUrl(node.src);
2056
+ const alt = node.alt || "";
2057
+ const w = node.w;
2058
+ const h = node.h;
2059
+ const fit = node.fit || "cover";
2060
+ return /* @__PURE__ */ jsxDEV4("img", {
2061
+ src,
2062
+ alt,
2063
+ width: w,
2064
+ height: h,
2065
+ className: cn("rounded", fitClasses[fit], node.class)
2066
+ }, undefined, false, undefined, this);
2067
+ }
2068
+
2069
+ // src/renderer/components/Btn.tsx
2070
+ import { useCallback as useCallback2 } from "react";
2071
+
2072
+ // src/renderer/context/FormContext.tsx
2073
+ import { createContext as createContext3, useContext as useContext3, useState, useCallback } from "react";
2074
+ import { jsxDEV as jsxDEV5 } from "react/jsx-dev-runtime";
2075
+ var FormContext = createContext3(null);
2076
+ function useForm() {
2077
+ return useContext3(FormContext);
2078
+ }
2079
+ function FormProvider({ submitAction, onSubmit, children }) {
2080
+ const [values, setValues] = useState({});
2081
+ const setValue = useCallback((name, value) => {
2082
+ setValues((prev) => ({ ...prev, [name]: value }));
2083
+ }, []);
2084
+ const submit = useCallback((action, extraArgs) => {
2085
+ onSubmit(action || submitAction, { ...values, ...extraArgs });
2086
+ }, [submitAction, onSubmit, values]);
2087
+ return /* @__PURE__ */ jsxDEV5(FormContext.Provider, {
2088
+ value: { values, setValue, submit },
2089
+ children
2090
+ }, undefined, false, undefined, this);
2091
+ }
2092
+
2093
+ // src/renderer/components/Btn.tsx
2094
+ import { jsxDEV as jsxDEV6 } from "react/jsx-dev-runtime";
2095
+ var variantClasses2 = {
2096
+ primary: "bg-meissa-primary text-white hover:opacity-90",
2097
+ secondary: "bg-meissa-fg/10 text-meissa-fg hover:bg-meissa-fg/15",
2098
+ destructive: "bg-meissa-destructive text-white hover:opacity-90",
2099
+ ghost: "hover:bg-meissa-fg/10 text-meissa-fg",
2100
+ outline: "border border-meissa-border text-meissa-fg hover:bg-meissa-fg/5"
2101
+ };
2102
+ var sizeClasses = {
2103
+ sm: "px-2.5 py-1 text-xs",
2104
+ md: "px-4 py-2 text-sm",
2105
+ lg: "px-6 py-3 text-base"
2106
+ };
2107
+ function Btn({ node }) {
2108
+ const { onAction, onNavigate } = useAction();
2109
+ const form = useForm();
2110
+ const label = node.label;
2111
+ const variant = node.variant || "primary";
2112
+ const size = node.size || "md";
2113
+ const disabled = node.disabled;
2114
+ const action = node.action;
2115
+ const args = node.args;
2116
+ const confirm = node.confirm;
2117
+ const navigate = node.navigate;
2118
+ const handleClick = useCallback2(() => {
2119
+ if (disabled)
2120
+ return;
2121
+ if (confirm) {
2122
+ if (!window.confirm(confirm))
2123
+ return;
2124
+ }
2125
+ if (navigate) {
2126
+ onNavigate(navigate);
2127
+ } else if (action) {
2128
+ onAction(action, args);
2129
+ } else if (form) {
2130
+ form.submit(undefined, args);
2131
+ }
2132
+ }, [disabled, confirm, navigate, action, args, form, onAction, onNavigate]);
2133
+ return /* @__PURE__ */ jsxDEV6("button", {
2134
+ type: "button",
2135
+ disabled,
2136
+ onClick: handleClick,
2137
+ className: cn("inline-flex items-center justify-center rounded-md font-medium transition-colors", "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-meissa-primary", "disabled:opacity-50 disabled:pointer-events-none", variantClasses2[variant], sizeClasses[size], node.class),
2138
+ children: label
2139
+ }, undefined, false, undefined, this);
2140
+ }
2141
+
2142
+ // src/renderer/components/Input.tsx
2143
+ import { useCallback as useCallback3 } from "react";
2144
+ import { jsxDEV as jsxDEV7 } from "react/jsx-dev-runtime";
2145
+ function Input({ node }) {
2146
+ const form = useForm();
2147
+ const name = node.name;
2148
+ const type = node.type || "text";
2149
+ const label = node.label;
2150
+ const placeholder = node.placeholder;
2151
+ const required = node.required;
2152
+ const disabled = node.disabled;
2153
+ const value = form?.values[name] ?? node.value ?? "";
2154
+ const handleChange = useCallback3((e) => {
2155
+ form?.setValue(name, e.target.value);
2156
+ }, [form, name]);
2157
+ const inputClasses = cn("w-full rounded-md border border-meissa-border bg-meissa-bg px-3 py-2 text-sm", "placeholder:text-meissa-muted", "focus:outline-none focus:ring-2 focus:ring-meissa-primary focus:border-transparent", "disabled:opacity-50 disabled:cursor-not-allowed", node.class);
2158
+ return /* @__PURE__ */ jsxDEV7("div", {
2159
+ className: "flex flex-col gap-1.5",
2160
+ children: [
2161
+ label && /* @__PURE__ */ jsxDEV7("label", {
2162
+ className: "text-sm font-medium text-meissa-fg",
2163
+ children: [
2164
+ label,
2165
+ required && /* @__PURE__ */ jsxDEV7("span", {
2166
+ className: "text-meissa-destructive ml-1",
2167
+ children: "*"
2168
+ }, undefined, false, undefined, this)
2169
+ ]
2170
+ }, undefined, true, undefined, this),
2171
+ type === "textarea" ? /* @__PURE__ */ jsxDEV7("textarea", {
2172
+ name,
2173
+ placeholder,
2174
+ required,
2175
+ disabled,
2176
+ value,
2177
+ onChange: handleChange,
2178
+ className: cn(inputClasses, "min-h-[80px] resize-y"),
2179
+ rows: 4
2180
+ }, undefined, false, undefined, this) : /* @__PURE__ */ jsxDEV7("input", {
2181
+ name,
2182
+ type,
2183
+ placeholder,
2184
+ required,
2185
+ disabled,
2186
+ value,
2187
+ onChange: handleChange,
2188
+ className: inputClasses
2189
+ }, undefined, false, undefined, this)
2190
+ ]
2191
+ }, undefined, true, undefined, this);
2192
+ }
2193
+
2194
+ // src/renderer/components/Select.tsx
2195
+ import { useCallback as useCallback4 } from "react";
2196
+ import { jsxDEV as jsxDEV8 } from "react/jsx-dev-runtime";
2197
+ function normalizeOptions(raw) {
2198
+ return raw.map((item) => {
2199
+ if (typeof item === "string")
2200
+ return { label: item, value: item };
2201
+ const obj = item;
2202
+ return { label: obj.label || obj.value, value: obj.value || obj.label };
2203
+ });
2204
+ }
2205
+ function Select({ node }) {
2206
+ const form = useForm();
2207
+ const name = node.name;
2208
+ const label = node.label;
2209
+ const placeholder = node.placeholder || "Select...";
2210
+ const required = node.required;
2211
+ const multiple = node.multiple;
2212
+ const rawOptions = node.options || [];
2213
+ const options = normalizeOptions(rawOptions);
2214
+ const value = form?.values[name] ?? node.value ?? "";
2215
+ const handleChange = useCallback4((e) => {
2216
+ form?.setValue(name, e.target.value);
2217
+ }, [form, name]);
2218
+ return /* @__PURE__ */ jsxDEV8("div", {
2219
+ className: "flex flex-col gap-1.5",
2220
+ children: [
2221
+ label && /* @__PURE__ */ jsxDEV8("label", {
2222
+ className: "text-sm font-medium text-meissa-fg",
2223
+ children: [
2224
+ label,
2225
+ required && /* @__PURE__ */ jsxDEV8("span", {
2226
+ className: "text-meissa-destructive ml-1",
2227
+ children: "*"
2228
+ }, undefined, false, undefined, this)
2229
+ ]
2230
+ }, undefined, true, undefined, this),
2231
+ /* @__PURE__ */ jsxDEV8("select", {
2232
+ name,
2233
+ required,
2234
+ multiple,
2235
+ value,
2236
+ onChange: handleChange,
2237
+ className: cn("w-full rounded-md border border-meissa-border bg-meissa-bg px-3 py-2 text-sm", "focus:outline-none focus:ring-2 focus:ring-meissa-primary focus:border-transparent", "disabled:opacity-50 disabled:cursor-not-allowed", node.class),
2238
+ children: [
2239
+ !multiple && /* @__PURE__ */ jsxDEV8("option", {
2240
+ value: "",
2241
+ children: placeholder
2242
+ }, undefined, false, undefined, this),
2243
+ options.map((opt) => /* @__PURE__ */ jsxDEV8("option", {
2244
+ value: opt.value,
2245
+ children: opt.label
2246
+ }, opt.value, false, undefined, this))
2247
+ ]
2248
+ }, undefined, true, undefined, this)
2249
+ ]
2250
+ }, undefined, true, undefined, this);
2251
+ }
2252
+
2253
+ // src/renderer/components/Form.tsx
2254
+ import { useCallback as useCallback5 } from "react";
2255
+ import { jsxDEV as jsxDEV9 } from "react/jsx-dev-runtime";
2256
+ function Form({ node, children }) {
2257
+ const { onAction } = useAction();
2258
+ const submit = node.submit;
2259
+ const args = node.args || {};
2260
+ const handleSubmit = useCallback5((action, formValues) => {
2261
+ onAction(action || submit, { ...args, ...formValues });
2262
+ }, [onAction, submit, args]);
2263
+ const onFormSubmit = useCallback5((e) => {
2264
+ e.preventDefault();
2265
+ }, []);
2266
+ return /* @__PURE__ */ jsxDEV9(FormProvider, {
2267
+ submitAction: submit,
2268
+ onSubmit: handleSubmit,
2269
+ children: /* @__PURE__ */ jsxDEV9("form", {
2270
+ onSubmit: onFormSubmit,
2271
+ className: cn("flex flex-col gap-4", node.class),
2272
+ children
2273
+ }, undefined, false, undefined, this)
2274
+ }, undefined, false, undefined, this);
2275
+ }
2276
+
2277
+ // src/renderer/components/Table.tsx
2278
+ import { useState as useState2, useMemo, useCallback as useCallback6 } from "react";
2279
+ import { jsxDEV as jsxDEV10 } from "react/jsx-dev-runtime";
2280
+ function toTitleCase(key) {
2281
+ return key.replace(/([A-Z])/g, " $1").replace(/[_-]/g, " ").replace(/\b\w/g, (c) => c.toUpperCase()).trim();
2282
+ }
2283
+ function isNumeric(val) {
2284
+ return typeof val === "number" || typeof val === "string" && !isNaN(Number(val)) && val.trim() !== "";
2285
+ }
2286
+ function Table({ node }) {
2287
+ const { onAction } = useAction();
2288
+ const data = node.data || [];
2289
+ const customColumns = node.columns;
2290
+ const headers = node.headers || {};
2291
+ const sortable = node.sortable !== false;
2292
+ const paginate = node.paginate;
2293
+ const actions = node.actions;
2294
+ const [sortKey, setSortKey] = useState2(null);
2295
+ const [sortDir, setSortDir] = useState2("asc");
2296
+ const [page, setPage] = useState2(0);
2297
+ const columns = useMemo(() => {
2298
+ if (customColumns)
2299
+ return customColumns;
2300
+ if (data.length === 0)
2301
+ return [];
2302
+ return Object.keys(data[0]);
2303
+ }, [customColumns, data]);
2304
+ const numericCols = useMemo(() => {
2305
+ if (data.length === 0)
2306
+ return new Set;
2307
+ const set = new Set;
2308
+ for (const col of columns) {
2309
+ if (data.every((row) => row[col] == null || isNumeric(row[col]))) {
2310
+ set.add(col);
2311
+ }
2312
+ }
2313
+ return set;
2314
+ }, [columns, data]);
2315
+ const sortedData = useMemo(() => {
2316
+ if (!sortKey)
2317
+ return data;
2318
+ return [...data].sort((a, b) => {
2319
+ const av = a[sortKey];
2320
+ const bv = b[sortKey];
2321
+ if (av == null && bv == null)
2322
+ return 0;
2323
+ if (av == null)
2324
+ return 1;
2325
+ if (bv == null)
2326
+ return -1;
2327
+ const cmp = numericCols.has(sortKey) ? Number(av) - Number(bv) : String(av).localeCompare(String(bv));
2328
+ return sortDir === "asc" ? cmp : -cmp;
2329
+ });
2330
+ }, [data, sortKey, sortDir, numericCols]);
2331
+ const paginatedData = useMemo(() => {
2332
+ if (!paginate)
2333
+ return sortedData;
2334
+ const start = page * paginate;
2335
+ return sortedData.slice(start, start + paginate);
2336
+ }, [sortedData, page, paginate]);
2337
+ const totalPages = paginate ? Math.ceil(data.length / paginate) : 1;
2338
+ const handleSort = useCallback6((col) => {
2339
+ if (!sortable)
2340
+ return;
2341
+ if (sortKey === col) {
2342
+ setSortDir((d) => d === "asc" ? "desc" : "asc");
2343
+ } else {
2344
+ setSortKey(col);
2345
+ setSortDir("asc");
2346
+ }
2347
+ }, [sortable, sortKey]);
2348
+ const handleAction = useCallback6((action, row) => {
2349
+ const resolvedArgs = {};
2350
+ if (action.args) {
2351
+ for (const [k, v] of Object.entries(action.args)) {
2352
+ if (typeof v === "string" && v.startsWith("{{$.") && v.endsWith("}}")) {
2353
+ const path = v.slice(4, -2);
2354
+ resolvedArgs[k] = row[path];
2355
+ } else {
2356
+ resolvedArgs[k] = v;
2357
+ }
2358
+ }
2359
+ }
2360
+ onAction(action.action, resolvedArgs);
2361
+ }, [onAction]);
2362
+ return /* @__PURE__ */ jsxDEV10("div", {
2363
+ className: cn("w-full overflow-x-auto", node.class),
2364
+ children: [
2365
+ /* @__PURE__ */ jsxDEV10("table", {
2366
+ className: "w-full text-sm",
2367
+ children: [
2368
+ /* @__PURE__ */ jsxDEV10("thead", {
2369
+ children: /* @__PURE__ */ jsxDEV10("tr", {
2370
+ className: "border-b border-meissa-border",
2371
+ children: [
2372
+ columns.map((col) => /* @__PURE__ */ jsxDEV10("th", {
2373
+ onClick: () => handleSort(col),
2374
+ className: cn("px-3 py-2 font-medium text-meissa-muted", numericCols.has(col) ? "text-right" : "text-left", sortable && "cursor-pointer select-none hover:text-meissa-fg"),
2375
+ children: [
2376
+ headers[col] || toTitleCase(col),
2377
+ sortKey === col && /* @__PURE__ */ jsxDEV10("span", {
2378
+ className: "ml-1",
2379
+ children: sortDir === "asc" ? "↑" : "↓"
2380
+ }, undefined, false, undefined, this)
2381
+ ]
2382
+ }, col, true, undefined, this)),
2383
+ actions && /* @__PURE__ */ jsxDEV10("th", {
2384
+ className: "px-3 py-2"
2385
+ }, undefined, false, undefined, this)
2386
+ ]
2387
+ }, undefined, true, undefined, this)
2388
+ }, undefined, false, undefined, this),
2389
+ /* @__PURE__ */ jsxDEV10("tbody", {
2390
+ children: paginatedData.map((row, i) => /* @__PURE__ */ jsxDEV10("tr", {
2391
+ className: cn("border-b border-meissa-border last:border-0", i % 2 === 1 && "bg-meissa-fg/[0.03]"),
2392
+ children: [
2393
+ columns.map((col) => /* @__PURE__ */ jsxDEV10("td", {
2394
+ className: cn("px-3 py-2 text-meissa-fg", numericCols.has(col) ? "text-right" : "text-left"),
2395
+ children: row[col] != null ? String(row[col]) : ""
2396
+ }, col, false, undefined, this)),
2397
+ actions && /* @__PURE__ */ jsxDEV10("td", {
2398
+ className: "px-3 py-2 text-right",
2399
+ children: /* @__PURE__ */ jsxDEV10("div", {
2400
+ className: "flex justify-end gap-1",
2401
+ children: actions.map((action, ai) => /* @__PURE__ */ jsxDEV10("button", {
2402
+ type: "button",
2403
+ onClick: () => handleAction(action, row),
2404
+ className: cn("px-2 py-1 text-xs rounded font-medium", action.variant === "destructive" ? "text-meissa-destructive hover:bg-meissa-destructive/10" : "text-meissa-primary hover:bg-meissa-primary/10"),
2405
+ children: action.label
2406
+ }, ai, false, undefined, this))
2407
+ }, undefined, false, undefined, this)
2408
+ }, undefined, false, undefined, this)
2409
+ ]
2410
+ }, i, true, undefined, this))
2411
+ }, undefined, false, undefined, this)
2412
+ ]
2413
+ }, undefined, true, undefined, this),
2414
+ paginate && totalPages > 1 && /* @__PURE__ */ jsxDEV10("div", {
2415
+ className: "flex items-center justify-between px-3 py-2 border-t border-meissa-border",
2416
+ children: [
2417
+ /* @__PURE__ */ jsxDEV10("span", {
2418
+ className: "text-xs text-meissa-muted",
2419
+ children: [
2420
+ "Page ",
2421
+ page + 1,
2422
+ " of ",
2423
+ totalPages
2424
+ ]
2425
+ }, undefined, true, undefined, this),
2426
+ /* @__PURE__ */ jsxDEV10("div", {
2427
+ className: "flex gap-1",
2428
+ children: [
2429
+ /* @__PURE__ */ jsxDEV10("button", {
2430
+ type: "button",
2431
+ disabled: page === 0,
2432
+ onClick: () => setPage((p) => p - 1),
2433
+ className: "px-2 py-1 text-xs rounded border border-meissa-border disabled:opacity-50",
2434
+ children: "Prev"
2435
+ }, undefined, false, undefined, this),
2436
+ /* @__PURE__ */ jsxDEV10("button", {
2437
+ type: "button",
2438
+ disabled: page >= totalPages - 1,
2439
+ onClick: () => setPage((p) => p + 1),
2440
+ className: "px-2 py-1 text-xs rounded border border-meissa-border disabled:opacity-50",
2441
+ children: "Next"
2442
+ }, undefined, false, undefined, this)
2443
+ ]
2444
+ }, undefined, true, undefined, this)
2445
+ ]
2446
+ }, undefined, true, undefined, this)
2447
+ ]
2448
+ }, undefined, true, undefined, this);
2449
+ }
2450
+
2451
+ // src/renderer/components/List.tsx
2452
+ import { jsxDEV as jsxDEV11 } from "react/jsx-dev-runtime";
2453
+ var variantClasses3 = {
2454
+ default: "space-y-1",
2455
+ compact: "space-y-0.5",
2456
+ spaced: "space-y-3"
2457
+ };
2458
+ function List({ node }) {
2459
+ const items = node.items || [];
2460
+ const ordered = node.ordered;
2461
+ const variant = node.variant || "default";
2462
+ const Tag = ordered ? "ol" : "ul";
2463
+ return /* @__PURE__ */ jsxDEV11(Tag, {
2464
+ className: cn(ordered ? "list-decimal" : "list-disc", "pl-5 text-sm text-meissa-fg", variantClasses3[variant], node.class),
2465
+ children: items.map((item, i) => /* @__PURE__ */ jsxDEV11("li", {
2466
+ children: String(item)
2467
+ }, i, false, undefined, this))
2468
+ }, undefined, false, undefined, this);
2469
+ }
2470
+
2471
+ // src/renderer/components/Chart.tsx
2472
+ import { Suspense, useMemo as useMemo2, use } from "react";
2473
+ import { jsxDEV as jsxDEV12 } from "react/jsx-dev-runtime";
2474
+ var rechartsPromise = import("recharts");
2475
+ var COLORS = ["#6366f1", "#10b981", "#f59e0b", "#ef4444", "#8b5cf6", "#06b6d4"];
2476
+ function ChartInner({ node }) {
2477
+ const data = node.data || [];
2478
+ const type = node.type || "line";
2479
+ const x = node.x;
2480
+ const y = node.y;
2481
+ const title = node.title;
2482
+ const legend = node.legend !== false;
2483
+ const h = node.h || 256;
2484
+ const colors = node.colors || COLORS;
2485
+ const { xKey, yKeys } = useMemo2(() => {
2486
+ if (data.length === 0)
2487
+ return { xKey: "", yKeys: [] };
2488
+ const keys = Object.keys(data[0]);
2489
+ const resolvedX = x || keys[0];
2490
+ const resolvedY = y ? Array.isArray(y) ? y : [y] : keys.filter((k) => k !== resolvedX);
2491
+ return { xKey: resolvedX, yKeys: resolvedY };
2492
+ }, [data, x, y]);
2493
+ if (data.length === 0) {
2494
+ return /* @__PURE__ */ jsxDEV12("div", {
2495
+ className: "text-sm text-meissa-muted italic",
2496
+ children: "No data"
2497
+ }, undefined, false, undefined, this);
2498
+ }
2499
+ return /* @__PURE__ */ jsxDEV12("div", {
2500
+ className: cn("w-full", node.class),
2501
+ style: { height: h },
2502
+ children: [
2503
+ title && /* @__PURE__ */ jsxDEV12("p", {
2504
+ className: "text-sm font-medium text-meissa-fg mb-2",
2505
+ children: title
2506
+ }, undefined, false, undefined, this),
2507
+ /* @__PURE__ */ jsxDEV12(Suspense, {
2508
+ fallback: /* @__PURE__ */ jsxDEV12("div", {
2509
+ className: "animate-pulse bg-meissa-fg/10 rounded w-full h-full"
2510
+ }, undefined, false, undefined, this),
2511
+ children: /* @__PURE__ */ jsxDEV12(RechartsChart, {
2512
+ data,
2513
+ type,
2514
+ xKey,
2515
+ yKeys,
2516
+ colors,
2517
+ legend,
2518
+ h: h - (title ? 28 : 0)
2519
+ }, undefined, false, undefined, this)
2520
+ }, undefined, false, undefined, this)
2521
+ ]
2522
+ }, undefined, true, undefined, this);
2523
+ }
2524
+ function RechartsChart({ data, type, xKey, yKeys, colors, legend, h }) {
2525
+ const recharts = use(rechartsPromise);
2526
+ const {
2527
+ ResponsiveContainer,
2528
+ LineChart,
2529
+ Line,
2530
+ BarChart,
2531
+ Bar,
2532
+ AreaChart,
2533
+ Area,
2534
+ PieChart,
2535
+ Pie,
2536
+ Cell,
2537
+ XAxis,
2538
+ YAxis,
2539
+ CartesianGrid,
2540
+ Tooltip,
2541
+ Legend
2542
+ } = recharts;
2543
+ if (type === "sparkline") {
2544
+ return /* @__PURE__ */ jsxDEV12(ResponsiveContainer, {
2545
+ width: "100%",
2546
+ height: h,
2547
+ children: /* @__PURE__ */ jsxDEV12(LineChart, {
2548
+ data,
2549
+ children: /* @__PURE__ */ jsxDEV12(Line, {
2550
+ type: "monotone",
2551
+ dataKey: yKeys[0],
2552
+ stroke: colors[0],
2553
+ strokeWidth: 2,
2554
+ dot: false
2555
+ }, undefined, false, undefined, this)
2556
+ }, undefined, false, undefined, this)
2557
+ }, undefined, false, undefined, this);
2558
+ }
2559
+ if (type === "pie" || type === "donut") {
2560
+ return /* @__PURE__ */ jsxDEV12(ResponsiveContainer, {
2561
+ width: "100%",
2562
+ height: h,
2563
+ children: /* @__PURE__ */ jsxDEV12(PieChart, {
2564
+ children: [
2565
+ /* @__PURE__ */ jsxDEV12(Pie, {
2566
+ data,
2567
+ dataKey: yKeys[0],
2568
+ nameKey: xKey,
2569
+ innerRadius: type === "donut" ? "60%" : 0,
2570
+ outerRadius: "80%",
2571
+ children: data.map((_, i) => /* @__PURE__ */ jsxDEV12(Cell, {
2572
+ fill: colors[i % colors.length]
2573
+ }, i, false, undefined, this))
2574
+ }, undefined, false, undefined, this),
2575
+ /* @__PURE__ */ jsxDEV12(Tooltip, {}, undefined, false, undefined, this),
2576
+ legend && /* @__PURE__ */ jsxDEV12(Legend, {}, undefined, false, undefined, this)
2577
+ ]
2578
+ }, undefined, true, undefined, this)
2579
+ }, undefined, false, undefined, this);
2580
+ }
2581
+ const ChartComponent = type === "bar" ? BarChart : type === "area" ? AreaChart : LineChart;
2582
+ const SeriesComponent = type === "bar" ? Bar : type === "area" ? Area : Line;
2583
+ return /* @__PURE__ */ jsxDEV12(ResponsiveContainer, {
2584
+ width: "100%",
2585
+ height: h,
2586
+ children: /* @__PURE__ */ jsxDEV12(ChartComponent, {
2587
+ data,
2588
+ children: [
2589
+ /* @__PURE__ */ jsxDEV12(CartesianGrid, {
2590
+ strokeDasharray: "3 3"
2591
+ }, undefined, false, undefined, this),
2592
+ /* @__PURE__ */ jsxDEV12(XAxis, {
2593
+ dataKey: xKey,
2594
+ tick: { fontSize: 12 }
2595
+ }, undefined, false, undefined, this),
2596
+ /* @__PURE__ */ jsxDEV12(YAxis, {
2597
+ tick: { fontSize: 12 }
2598
+ }, undefined, false, undefined, this),
2599
+ /* @__PURE__ */ jsxDEV12(Tooltip, {}, undefined, false, undefined, this),
2600
+ legend && yKeys.length > 1 && /* @__PURE__ */ jsxDEV12(Legend, {}, undefined, false, undefined, this),
2601
+ yKeys.map((key, i) => /* @__PURE__ */ jsxDEV12(SeriesComponent, {
2602
+ type: "monotone",
2603
+ dataKey: key,
2604
+ stroke: colors[i % colors.length],
2605
+ fill: colors[i % colors.length],
2606
+ ...type === "area" ? { fillOpacity: 0.3 } : {}
2607
+ }, key, false, undefined, this))
2608
+ ]
2609
+ }, undefined, true, undefined, this)
2610
+ }, undefined, false, undefined, this);
2611
+ }
2612
+ function Chart({ node }) {
2613
+ return /* @__PURE__ */ jsxDEV12(ChartInner, {
2614
+ node
2615
+ }, undefined, false, undefined, this);
2616
+ }
2617
+
2618
+ // src/renderer/components/Stat.tsx
2619
+ import { jsxDEV as jsxDEV13 } from "react/jsx-dev-runtime";
2620
+ var variantClasses4 = {
2621
+ default: "",
2622
+ success: "text-green-600",
2623
+ warning: "text-yellow-600",
2624
+ destructive: "text-red-600"
2625
+ };
2626
+ function Stat({ node }) {
2627
+ const value = node.value;
2628
+ const label = node.label;
2629
+ const trend = node.trend;
2630
+ const variant = node.variant || "default";
2631
+ const trendPositive = trend?.startsWith("+");
2632
+ const trendNegative = trend?.startsWith("-");
2633
+ return /* @__PURE__ */ jsxDEV13("div", {
2634
+ className: cn("flex flex-col gap-1", node.class),
2635
+ children: [
2636
+ label && /* @__PURE__ */ jsxDEV13("span", {
2637
+ className: "text-sm text-meissa-muted",
2638
+ children: label
2639
+ }, undefined, false, undefined, this),
2640
+ /* @__PURE__ */ jsxDEV13("div", {
2641
+ className: "flex items-baseline gap-2",
2642
+ children: [
2643
+ /* @__PURE__ */ jsxDEV13("span", {
2644
+ className: cn("text-2xl font-semibold", variantClasses4[variant] || "text-meissa-fg"),
2645
+ children: value
2646
+ }, undefined, false, undefined, this),
2647
+ trend && /* @__PURE__ */ jsxDEV13("span", {
2648
+ className: cn("text-sm font-medium", trendPositive && "text-green-600", trendNegative && "text-red-600", !trendPositive && !trendNegative && "text-meissa-muted"),
2649
+ children: [
2650
+ trendPositive && "↑",
2651
+ trendNegative && "↓",
2652
+ trend
2653
+ ]
2654
+ }, undefined, true, undefined, this)
2655
+ ]
2656
+ }, undefined, true, undefined, this)
2657
+ ]
2658
+ }, undefined, true, undefined, this);
2659
+ }
2660
+
2661
+ // src/renderer/components/Card.tsx
2662
+ import { jsxDEV as jsxDEV14 } from "react/jsx-dev-runtime";
2663
+ var variantClasses5 = {
2664
+ default: "border border-meissa-border bg-meissa-bg",
2665
+ outline: "border-2 border-meissa-border bg-transparent",
2666
+ elevated: "border border-meissa-border bg-meissa-bg shadow-md"
2667
+ };
2668
+ var paddingClasses = {
2669
+ 0: "p-0",
2670
+ 1: "p-1",
2671
+ 2: "p-2",
2672
+ 3: "p-3",
2673
+ 4: "p-4",
2674
+ 6: "p-6",
2675
+ 8: "p-8"
2676
+ };
2677
+ function Card({ node, children }) {
2678
+ const title = node.title;
2679
+ const subtitle = node.subtitle;
2680
+ const variant = node.variant || "default";
2681
+ const padding = node.padding ?? 4;
2682
+ return /* @__PURE__ */ jsxDEV14("div", {
2683
+ className: cn("rounded-lg", variantClasses5[variant], node.class),
2684
+ children: [
2685
+ (title || subtitle) && /* @__PURE__ */ jsxDEV14("div", {
2686
+ className: cn("border-b border-meissa-border", paddingClasses[padding] || "p-4"),
2687
+ children: [
2688
+ title && /* @__PURE__ */ jsxDEV14("h3", {
2689
+ className: "font-semibold text-meissa-fg",
2690
+ children: title
2691
+ }, undefined, false, undefined, this),
2692
+ subtitle && /* @__PURE__ */ jsxDEV14("p", {
2693
+ className: "text-sm text-meissa-muted mt-0.5",
2694
+ children: subtitle
2695
+ }, undefined, false, undefined, this)
2696
+ ]
2697
+ }, undefined, true, undefined, this),
2698
+ /* @__PURE__ */ jsxDEV14("div", {
2699
+ className: cn("flex flex-col gap-4", paddingClasses[padding] || "p-4"),
2700
+ children
2701
+ }, undefined, false, undefined, this)
2702
+ ]
2703
+ }, undefined, true, undefined, this);
2704
+ }
2705
+
2706
+ // src/renderer/components/Tabs.tsx
2707
+ import { useState as useState3 } from "react";
2708
+ import { jsxDEV as jsxDEV15 } from "react/jsx-dev-runtime";
2709
+ var tabVariantClasses = {
2710
+ default: "border-b-2 border-transparent data-[active=true]:border-meissa-primary data-[active=true]:text-meissa-primary",
2711
+ pills: "rounded-md data-[active=true]:bg-meissa-primary data-[active=true]:text-white",
2712
+ underline: "border-b-2 border-transparent data-[active=true]:border-meissa-fg data-[active=true]:text-meissa-fg"
2713
+ };
2714
+ function Tabs({ node, children }) {
2715
+ const items = node.items || {};
2716
+ const defaultTab = node.default || Object.keys(items)[0];
2717
+ const variant = node.variant || "default";
2718
+ const [activeTab, setActiveTab] = useState3(defaultTab);
2719
+ const tabKeys = Object.keys(items);
2720
+ return /* @__PURE__ */ jsxDEV15("div", {
2721
+ className: cn("w-full", node.class),
2722
+ children: [
2723
+ /* @__PURE__ */ jsxDEV15("div", {
2724
+ className: cn("flex", variant === "default" || variant === "underline" ? "border-b border-meissa-border" : "gap-1"),
2725
+ role: "tablist",
2726
+ children: tabKeys.map((key) => /* @__PURE__ */ jsxDEV15("button", {
2727
+ type: "button",
2728
+ role: "tab",
2729
+ "aria-selected": activeTab === key,
2730
+ "data-active": activeTab === key,
2731
+ onClick: () => setActiveTab(key),
2732
+ className: cn("px-4 py-2 text-sm font-medium text-meissa-muted transition-colors", "hover:text-meissa-fg", tabVariantClasses[variant]),
2733
+ children: key
2734
+ }, key, false, undefined, this))
2735
+ }, undefined, false, undefined, this),
2736
+ /* @__PURE__ */ jsxDEV15("div", {
2737
+ className: "pt-4",
2738
+ role: "tabpanel",
2739
+ children
2740
+ }, undefined, false, undefined, this)
2741
+ ]
2742
+ }, undefined, true, undefined, this);
2743
+ }
2744
+
2745
+ // src/renderer/components/Alert.tsx
2746
+ import { useState as useState4, useCallback as useCallback7 } from "react";
2747
+ import { jsxDEV as jsxDEV16 } from "react/jsx-dev-runtime";
2748
+ var variantClasses6 = {
2749
+ info: "bg-meissa-primary/10 border-meissa-primary/20 text-meissa-primary",
2750
+ success: "bg-meissa-success/10 border-meissa-success/20 text-meissa-success",
2751
+ warning: "bg-meissa-warning/10 border-meissa-warning/20 text-meissa-warning",
2752
+ error: "bg-meissa-destructive/10 border-meissa-destructive/20 text-meissa-destructive"
2753
+ };
2754
+ function Alert({ node }) {
2755
+ const [dismissed, setDismissed] = useState4(false);
2756
+ const content = node.content;
2757
+ const variant = node.variant || "info";
2758
+ const title = node.title;
2759
+ const dismissible = node.dismissible;
2760
+ const handleDismiss = useCallback7(() => setDismissed(true), []);
2761
+ if (dismissed)
2762
+ return null;
2763
+ return /* @__PURE__ */ jsxDEV16("div", {
2764
+ role: "alert",
2765
+ className: cn("rounded-md border p-4", variantClasses6[variant], node.class),
2766
+ children: /* @__PURE__ */ jsxDEV16("div", {
2767
+ className: "flex items-start justify-between",
2768
+ children: [
2769
+ /* @__PURE__ */ jsxDEV16("div", {
2770
+ className: "flex-1",
2771
+ children: [
2772
+ title && /* @__PURE__ */ jsxDEV16("p", {
2773
+ className: "font-medium mb-1",
2774
+ children: title
2775
+ }, undefined, false, undefined, this),
2776
+ /* @__PURE__ */ jsxDEV16("p", {
2777
+ className: "text-sm",
2778
+ children: content
2779
+ }, undefined, false, undefined, this)
2780
+ ]
2781
+ }, undefined, true, undefined, this),
2782
+ dismissible && /* @__PURE__ */ jsxDEV16("button", {
2783
+ type: "button",
2784
+ onClick: handleDismiss,
2785
+ className: "ml-3 inline-flex shrink-0 rounded p-1 opacity-70 hover:opacity-100",
2786
+ "aria-label": "Dismiss",
2787
+ children: /* @__PURE__ */ jsxDEV16("svg", {
2788
+ className: "h-4 w-4",
2789
+ fill: "none",
2790
+ viewBox: "0 0 24 24",
2791
+ stroke: "currentColor",
2792
+ children: /* @__PURE__ */ jsxDEV16("path", {
2793
+ strokeLinecap: "round",
2794
+ strokeLinejoin: "round",
2795
+ strokeWidth: 2,
2796
+ d: "M6 18L18 6M6 6l12 12"
2797
+ }, undefined, false, undefined, this)
2798
+ }, undefined, false, undefined, this)
2799
+ }, undefined, false, undefined, this)
2800
+ ]
2801
+ }, undefined, true, undefined, this)
2802
+ }, undefined, false, undefined, this);
2803
+ }
2804
+
2805
+ // src/renderer/components/Badge.tsx
2806
+ import { jsxDEV as jsxDEV17 } from "react/jsx-dev-runtime";
2807
+ var variantClasses7 = {
2808
+ default: "bg-meissa-fg/10 text-meissa-fg",
2809
+ primary: "bg-meissa-primary/10 text-meissa-primary",
2810
+ success: "bg-meissa-success/10 text-meissa-success",
2811
+ warning: "bg-meissa-warning/10 text-meissa-warning",
2812
+ error: "bg-meissa-destructive/10 text-meissa-destructive",
2813
+ outline: "border border-meissa-border text-meissa-fg"
2814
+ };
2815
+ function Badge({ node }) {
2816
+ const content = node.content;
2817
+ const variant = node.variant || "default";
2818
+ return /* @__PURE__ */ jsxDEV17("span", {
2819
+ className: cn("inline-flex items-center rounded-full px-2.5 py-0.5 text-xs font-medium", variantClasses7[variant], node.class),
2820
+ children: content
2821
+ }, undefined, false, undefined, this);
2822
+ }
2823
+
2824
+ // src/renderer/components/Progress.tsx
2825
+ import { jsxDEV as jsxDEV18 } from "react/jsx-dev-runtime";
2826
+ var variantClasses8 = {
2827
+ default: "bg-meissa-primary",
2828
+ success: "bg-green-500",
2829
+ warning: "bg-yellow-500",
2830
+ error: "bg-red-500"
2831
+ };
2832
+ function Progress({ node }) {
2833
+ const value = node.value ?? 0;
2834
+ const label = node.label;
2835
+ const showValue = node.showValue;
2836
+ const variant = node.variant || "default";
2837
+ const indeterminate = node.indeterminate;
2838
+ return /* @__PURE__ */ jsxDEV18("div", {
2839
+ className: cn("w-full", node.class),
2840
+ children: [
2841
+ (label || showValue) && /* @__PURE__ */ jsxDEV18("div", {
2842
+ className: "flex justify-between mb-1",
2843
+ children: [
2844
+ label && /* @__PURE__ */ jsxDEV18("span", {
2845
+ className: "text-sm text-meissa-fg",
2846
+ children: label
2847
+ }, undefined, false, undefined, this),
2848
+ showValue && !indeterminate && /* @__PURE__ */ jsxDEV18("span", {
2849
+ className: "text-sm text-meissa-muted",
2850
+ children: [
2851
+ Math.round(value),
2852
+ "%"
2853
+ ]
2854
+ }, undefined, true, undefined, this)
2855
+ ]
2856
+ }, undefined, true, undefined, this),
2857
+ /* @__PURE__ */ jsxDEV18("div", {
2858
+ className: "w-full h-2 bg-meissa-fg/10 rounded-full overflow-hidden",
2859
+ children: /* @__PURE__ */ jsxDEV18("div", {
2860
+ className: cn("h-full rounded-full transition-all duration-300", variantClasses8[variant], indeterminate && "animate-pulse w-full"),
2861
+ style: !indeterminate ? { width: `${Math.min(100, Math.max(0, value))}%` } : undefined,
2862
+ role: "progressbar",
2863
+ "aria-valuenow": indeterminate ? undefined : value,
2864
+ "aria-valuemin": 0,
2865
+ "aria-valuemax": 100
2866
+ }, undefined, false, undefined, this)
2867
+ }, undefined, false, undefined, this)
2868
+ ]
2869
+ }, undefined, true, undefined, this);
2870
+ }
2871
+
2872
+ // src/renderer/components/Divider.tsx
2873
+ import { jsxDEV as jsxDEV19 } from "react/jsx-dev-runtime";
2874
+ var spacingClasses = {
2875
+ 0: "my-0",
2876
+ 1: "my-1",
2877
+ 2: "my-2",
2878
+ 3: "my-3",
2879
+ 4: "my-4",
2880
+ 6: "my-6",
2881
+ 8: "my-8",
2882
+ 10: "my-10",
2883
+ 12: "my-12",
2884
+ 16: "my-16"
2885
+ };
2886
+ function Divider({ node }) {
2887
+ const label = node.label;
2888
+ const spacing = node.spacing ?? 4;
2889
+ if (label) {
2890
+ return /* @__PURE__ */ jsxDEV19("div", {
2891
+ className: cn("flex items-center", spacingClasses[spacing] || "my-4", node.class),
2892
+ children: [
2893
+ /* @__PURE__ */ jsxDEV19("div", {
2894
+ className: "flex-1 border-t border-meissa-border"
2895
+ }, undefined, false, undefined, this),
2896
+ /* @__PURE__ */ jsxDEV19("span", {
2897
+ className: "px-3 text-sm text-meissa-muted",
2898
+ children: label
2899
+ }, undefined, false, undefined, this),
2900
+ /* @__PURE__ */ jsxDEV19("div", {
2901
+ className: "flex-1 border-t border-meissa-border"
2902
+ }, undefined, false, undefined, this)
2903
+ ]
2904
+ }, undefined, true, undefined, this);
2905
+ }
2906
+ return /* @__PURE__ */ jsxDEV19("hr", {
2907
+ className: cn("border-t border-meissa-border", spacingClasses[spacing] || "my-4", node.class)
2908
+ }, undefined, false, undefined, this);
2909
+ }
2910
+
2911
+ // src/renderer/components/Row.tsx
2912
+ import { jsxDEV as jsxDEV20 } from "react/jsx-dev-runtime";
2913
+ var alignClasses3 = {
2914
+ start: "items-start",
2915
+ center: "items-center",
2916
+ end: "items-end",
2917
+ stretch: "items-stretch"
2918
+ };
2919
+ var justifyClasses = {
2920
+ start: "justify-start",
2921
+ center: "justify-center",
2922
+ end: "justify-end",
2923
+ between: "justify-between",
2924
+ around: "justify-around"
2925
+ };
2926
+ var gapClasses = {
2927
+ 0: "gap-0",
2928
+ 1: "gap-1",
2929
+ 2: "gap-2",
2930
+ 3: "gap-3",
2931
+ 4: "gap-4",
2932
+ 6: "gap-6",
2933
+ 8: "gap-8",
2934
+ 10: "gap-10",
2935
+ 12: "gap-12",
2936
+ 16: "gap-16"
2937
+ };
2938
+ function Row({ node, children }) {
2939
+ const gap = node.gap ?? 4;
2940
+ const align = node.align || "center";
2941
+ const justify = node.justify || "start";
2942
+ const wrap = node.wrap;
2943
+ return /* @__PURE__ */ jsxDEV20("div", {
2944
+ className: cn("flex flex-row", gapClasses[gap] || "gap-4", alignClasses3[align], justifyClasses[justify], wrap && "flex-wrap", "max-sm:flex-wrap", node.class),
2945
+ children
2946
+ }, undefined, false, undefined, this);
2947
+ }
2948
+
2949
+ // src/renderer/components/Col.tsx
2950
+ import { jsxDEV as jsxDEV21 } from "react/jsx-dev-runtime";
2951
+ var alignClasses4 = {
2952
+ start: "items-start",
2953
+ center: "items-center",
2954
+ end: "items-end",
2955
+ stretch: "items-stretch"
2956
+ };
2957
+ var justifyClasses2 = {
2958
+ start: "justify-start",
2959
+ center: "justify-center",
2960
+ end: "justify-end",
2961
+ between: "justify-between",
2962
+ around: "justify-around"
2963
+ };
2964
+ var gapClasses2 = {
2965
+ 0: "gap-0",
2966
+ 1: "gap-1",
2967
+ 2: "gap-2",
2968
+ 3: "gap-3",
2969
+ 4: "gap-4",
2970
+ 6: "gap-6",
2971
+ 8: "gap-8",
2972
+ 10: "gap-10",
2973
+ 12: "gap-12",
2974
+ 16: "gap-16"
2975
+ };
2976
+ function Col({ node, children }) {
2977
+ const gap = node.gap ?? 4;
2978
+ const align = node.align || "stretch";
2979
+ const justify = node.justify || "start";
2980
+ return /* @__PURE__ */ jsxDEV21("div", {
2981
+ className: cn("flex flex-col", gapClasses2[gap] || "gap-4", alignClasses4[align], justifyClasses2[justify], node.class),
2982
+ children
2983
+ }, undefined, false, undefined, this);
2984
+ }
2985
+
2986
+ // src/renderer/components/Grid.tsx
2987
+ import { jsxDEV as jsxDEV22 } from "react/jsx-dev-runtime";
2988
+ var colsClasses = {
2989
+ 1: "grid-cols-1",
2990
+ 2: "grid-cols-2",
2991
+ 3: "grid-cols-3",
2992
+ 4: "grid-cols-4",
2993
+ 5: "grid-cols-5",
2994
+ 6: "grid-cols-6"
2995
+ };
2996
+ var gapClasses3 = {
2997
+ 0: "gap-0",
2998
+ 1: "gap-1",
2999
+ 2: "gap-2",
3000
+ 3: "gap-3",
3001
+ 4: "gap-4",
3002
+ 6: "gap-6",
3003
+ 8: "gap-8",
3004
+ 10: "gap-10",
3005
+ 12: "gap-12",
3006
+ 16: "gap-16"
3007
+ };
3008
+ var alignClasses5 = {
3009
+ start: "items-start",
3010
+ center: "items-center",
3011
+ end: "items-end",
3012
+ stretch: "items-stretch"
3013
+ };
3014
+ function Grid({ node, children }) {
3015
+ const cols = node.cols ?? 3;
3016
+ const gap = node.gap ?? 4;
3017
+ const align = node.align || "stretch";
3018
+ return /* @__PURE__ */ jsxDEV22("div", {
3019
+ className: cn("grid", colsClasses[cols] || `grid-cols-${cols}`, gapClasses3[gap] || "gap-4", alignClasses5[align], "max-sm:grid-cols-1 max-md:grid-cols-2", node.class),
3020
+ children
3021
+ }, undefined, false, undefined, this);
3022
+ }
3023
+
3024
+ // src/renderer/components/Split.tsx
3025
+ import { jsxDEV as jsxDEV23 } from "react/jsx-dev-runtime";
3026
+ var ratioMap = {
3027
+ "1/4": ["w-1/4", "w-3/4"],
3028
+ "1/3": ["w-1/3", "w-2/3"],
3029
+ "1/2": ["w-1/2", "w-1/2"],
3030
+ "2/3": ["w-2/3", "w-1/3"],
3031
+ "3/4": ["w-3/4", "w-1/4"]
3032
+ };
3033
+ var gapClasses4 = {
3034
+ 0: "gap-0",
3035
+ 1: "gap-1",
3036
+ 2: "gap-2",
3037
+ 3: "gap-3",
3038
+ 4: "gap-4",
3039
+ 6: "gap-6",
3040
+ 8: "gap-8",
3041
+ 10: "gap-10",
3042
+ 12: "gap-12",
3043
+ 16: "gap-16"
3044
+ };
3045
+ function Split({ node, children }) {
3046
+ const ratio = node.ratio || "1/3";
3047
+ const gap = node.gap ?? 4;
3048
+ const dir = node.dir || "row";
3049
+ const isCol = dir === "col";
3050
+ const [firstSize, secondSize] = ratioMap[ratio] || ["w-1/3", "w-2/3"];
3051
+ const childArray = Array.isArray(children) ? children : [children];
3052
+ return /* @__PURE__ */ jsxDEV23("div", {
3053
+ className: cn("flex", isCol ? "flex-col" : "flex-row", gapClasses4[gap] || "gap-4", "max-sm:flex-col", node.class),
3054
+ children: [
3055
+ childArray[0] && /* @__PURE__ */ jsxDEV23("div", {
3056
+ className: cn(!isCol && firstSize, "max-sm:w-full"),
3057
+ children: childArray[0]
3058
+ }, undefined, false, undefined, this),
3059
+ childArray[1] && /* @__PURE__ */ jsxDEV23("div", {
3060
+ className: cn(!isCol && secondSize, "max-sm:w-full"),
3061
+ children: childArray[1]
3062
+ }, undefined, false, undefined, this)
3063
+ ]
3064
+ }, undefined, true, undefined, this);
3065
+ }
3066
+
3067
+ // src/renderer/components/index.ts
3068
+ var COMPONENT_REGISTRY = {
3069
+ text: Text,
3070
+ heading: Heading,
3071
+ code: Code,
3072
+ img: Img,
3073
+ btn: Btn,
3074
+ input: Input,
3075
+ select: Select,
3076
+ form: Form,
3077
+ table: Table,
3078
+ list: List,
3079
+ chart: Chart,
3080
+ stat: Stat,
3081
+ card: Card,
3082
+ tabs: Tabs,
3083
+ alert: Alert,
3084
+ badge: Badge,
3085
+ progress: Progress,
3086
+ divider: Divider,
3087
+ row: Row,
3088
+ col: Col,
3089
+ grid: Grid,
3090
+ split: Split
3091
+ };
3092
+
3093
+ // src/renderer/ComponentRenderer.tsx
3094
+ import { jsxDEV as jsxDEV24, Fragment } from "react/jsx-dev-runtime";
3095
+ function ComponentRenderer({ node }) {
3096
+ const { data } = useData();
3097
+ const evalResult = useMemo3(() => evaluate(node, data), [node, data]);
3098
+ if (!evalResult.node)
3099
+ return null;
3100
+ const evaluatedNode = evalResult.node;
3101
+ if (evaluatedNode.type === "each") {
3102
+ return /* @__PURE__ */ jsxDEV24(EachRenderer, {
3103
+ node: evaluatedNode
3104
+ }, undefined, false, undefined, this);
3105
+ }
3106
+ if (evaluatedNode.type === "fragment") {
3107
+ return /* @__PURE__ */ jsxDEV24(FragmentRenderer, {
3108
+ node: evaluatedNode
3109
+ }, undefined, false, undefined, this);
3110
+ }
3111
+ const boundNode = useMemo3(() => bindNode(evaluatedNode, data), [evaluatedNode, data]);
3112
+ const Component = COMPONENT_REGISTRY[boundNode.type];
3113
+ if (!Component) {
3114
+ if (typeof globalThis !== "undefined" && globalThis.process?.env?.NODE_ENV !== "production") {
3115
+ console.warn(`[Meissa] Unknown component type: "${boundNode.type}"`);
3116
+ }
3117
+ return null;
3118
+ }
3119
+ const children = boundNode.children?.map((child, i) => /* @__PURE__ */ jsxDEV24(ComponentRenderer, {
3120
+ node: child
3121
+ }, child.id || i, false, undefined, this));
3122
+ const element = /* @__PURE__ */ jsxDEV24(Component, {
3123
+ node: boundNode,
3124
+ children
3125
+ }, undefined, false, undefined, this);
3126
+ if (evalResult.hidden) {
3127
+ return /* @__PURE__ */ jsxDEV24("div", {
3128
+ style: { display: "none" },
3129
+ children: element
3130
+ }, undefined, false, undefined, this);
3131
+ }
3132
+ return element;
3133
+ }
3134
+ function EachRenderer({ node }) {
3135
+ const { data, root } = useData();
3136
+ const items = useMemo3(() => expandEach(node, data), [node, data]);
3137
+ return /* @__PURE__ */ jsxDEV24(Fragment, {
3138
+ children: items.map((item, i) => /* @__PURE__ */ jsxDEV24(DataProvider, {
3139
+ value: { data: item.data, root },
3140
+ children: /* @__PURE__ */ jsxDEV24(ComponentRenderer, {
3141
+ node: item.node
3142
+ }, undefined, false, undefined, this)
3143
+ }, i, false, undefined, this))
3144
+ }, undefined, false, undefined, this);
3145
+ }
3146
+ function FragmentRenderer({ node }) {
3147
+ if (!node.children)
3148
+ return null;
3149
+ return /* @__PURE__ */ jsxDEV24(Fragment, {
3150
+ children: node.children.map((child, i) => /* @__PURE__ */ jsxDEV24(ComponentRenderer, {
3151
+ node: child
3152
+ }, child.id || i, false, undefined, this))
3153
+ }, undefined, false, undefined, this);
3154
+ }
3155
+ function bindNode(node, data) {
3156
+ const bound = { type: node.type };
3157
+ for (const [key, value] of Object.entries(node)) {
3158
+ if (key === "type")
3159
+ continue;
3160
+ if (key === "children") {
3161
+ bound.children = node.children;
3162
+ continue;
3163
+ }
3164
+ bound[key] = bindValue(value, data);
3165
+ }
3166
+ return bound;
3167
+ }
3168
+ function bindValue(value, data) {
3169
+ if (typeof value === "string") {
3170
+ return resolveBindings(value, data);
3171
+ }
3172
+ if (Array.isArray(value)) {
3173
+ return value.map((item) => bindValue(item, data));
3174
+ }
3175
+ if (value !== null && typeof value === "object") {
3176
+ const result = {};
3177
+ for (const [k, v] of Object.entries(value)) {
3178
+ result[k] = bindValue(v, data);
3179
+ }
3180
+ return result;
3181
+ }
3182
+ return value;
3183
+ }
3184
+
3185
+ // src/renderer/MeissaRenderer.tsx
3186
+ import { jsxDEV as jsxDEV25 } from "react/jsx-dev-runtime";
3187
+ var noop2 = () => {};
3188
+ function MeissaRenderer({
3189
+ schema,
3190
+ data: externalData,
3191
+ theme,
3192
+ onAction = noop2,
3193
+ onNavigate = noop2,
3194
+ className
3195
+ }) {
3196
+ const parsed = useMemo4(() => parse(schema), [schema]);
3197
+ const mergedData = useMemo4(() => ({ ...parsed.data, ...externalData }), [parsed.data, externalData]);
3198
+ const themeStyles = useMemo4(() => {
3199
+ const mergedTheme = { ...parsed.theme, ...theme };
3200
+ if (!mergedTheme?.colors)
3201
+ return;
3202
+ const vars = {};
3203
+ const { colors } = mergedTheme;
3204
+ if (colors.primary)
3205
+ vars["--meissa-primary"] = colors.primary;
3206
+ if (colors.destructive)
3207
+ vars["--meissa-destructive"] = colors.destructive;
3208
+ if (colors.success)
3209
+ vars["--meissa-success"] = colors.success;
3210
+ if (colors.warning)
3211
+ vars["--meissa-warning"] = colors.warning;
3212
+ if (colors.bg)
3213
+ vars["--meissa-bg"] = colors.bg;
3214
+ if (colors.fg)
3215
+ vars["--meissa-fg"] = colors.fg;
3216
+ if (colors.muted)
3217
+ vars["--meissa-muted"] = colors.muted;
3218
+ if (colors.border)
3219
+ vars["--meissa-border"] = colors.border;
3220
+ return vars;
3221
+ }, [parsed.theme, theme]);
3222
+ return /* @__PURE__ */ jsxDEV25("div", {
3223
+ className: cn("flex flex-col gap-4", className),
3224
+ style: themeStyles,
3225
+ children: /* @__PURE__ */ jsxDEV25(ActionProvider, {
3226
+ value: { onAction, onNavigate },
3227
+ children: /* @__PURE__ */ jsxDEV25(DataProvider, {
3228
+ value: { data: mergedData, root: mergedData },
3229
+ children: parsed.nodes.map((node, i) => /* @__PURE__ */ jsxDEV25(ComponentRenderer, {
3230
+ node
3231
+ }, node.id || i, false, undefined, this))
3232
+ }, undefined, false, undefined, this)
3233
+ }, undefined, false, undefined, this)
3234
+ }, undefined, false, undefined, this);
3235
+ }
3236
+ // src/client/patch.ts
3237
+ function parsePointer(pointer) {
3238
+ if (pointer === "" || pointer === "/")
3239
+ return [];
3240
+ if (!pointer.startsWith("/")) {
3241
+ throw new Error(`Invalid JSON Pointer: "${pointer}" — must start with "/"`);
3242
+ }
3243
+ return pointer.slice(1).split("/").map((seg) => seg.replace(/~1/g, "/").replace(/~0/g, "~"));
3244
+ }
3245
+ function traverse(obj, segments) {
3246
+ if (segments.length === 0) {
3247
+ throw new Error("Cannot operate on root with empty path");
3248
+ }
3249
+ let current = obj;
3250
+ for (let i = 0;i < segments.length - 1; i++) {
3251
+ const seg = segments[i];
3252
+ if (Array.isArray(current)) {
3253
+ const idx = parseInt(seg, 10);
3254
+ if (isNaN(idx))
3255
+ throw new Error(`Invalid array index: "${seg}"`);
3256
+ current = current[idx];
3257
+ } else if (current !== null && typeof current === "object") {
3258
+ current = current[seg];
3259
+ } else {
3260
+ throw new Error(`Cannot traverse into ${typeof current} at segment "${seg}"`);
3261
+ }
3262
+ }
3263
+ return [current, segments[segments.length - 1]];
3264
+ }
3265
+ function applyOp(data, op) {
3266
+ const segments = parsePointer(op.path);
3267
+ if (segments.length === 0) {
3268
+ if (op.op === "replace") {
3269
+ throw new Error("Cannot replace root — use update() instead");
3270
+ }
3271
+ throw new Error(`Cannot ${op.op} at root path`);
3272
+ }
3273
+ const [parent, lastKey] = traverse(data, segments);
3274
+ if (Array.isArray(parent)) {
3275
+ const isAppend = lastKey === "-";
3276
+ const idx = isAppend ? parent.length : parseInt(lastKey, 10);
3277
+ switch (op.op) {
3278
+ case "add":
3279
+ if (isAppend) {
3280
+ parent.push(op.value);
3281
+ } else {
3282
+ if (isNaN(idx))
3283
+ throw new Error(`Invalid array index: "${lastKey}"`);
3284
+ parent.splice(idx, 0, op.value);
3285
+ }
3286
+ break;
3287
+ case "replace":
3288
+ if (isNaN(idx))
3289
+ throw new Error(`Invalid array index: "${lastKey}"`);
3290
+ parent[idx] = op.value;
3291
+ break;
3292
+ case "remove":
3293
+ if (isNaN(idx))
3294
+ throw new Error(`Invalid array index: "${lastKey}"`);
3295
+ parent.splice(idx, 1);
3296
+ break;
3297
+ }
3298
+ } else if (parent !== null && typeof parent === "object") {
3299
+ const obj = parent;
3300
+ switch (op.op) {
3301
+ case "add":
3302
+ case "replace":
3303
+ obj[lastKey] = op.value;
3304
+ break;
3305
+ case "remove":
3306
+ delete obj[lastKey];
3307
+ break;
3308
+ }
3309
+ } else {
3310
+ throw new Error(`Cannot apply patch at "${op.path}" — parent is not an object or array`);
3311
+ }
3312
+ }
3313
+ function applyPatches(data, patches) {
3314
+ const cloned = structuredClone(data);
3315
+ for (const patch of patches) {
3316
+ applyOp(cloned, patch);
3317
+ }
3318
+ return cloned;
3319
+ }
3320
+
3321
+ // src/client/renderer.ts
3322
+ class MeissaClientRenderer {
3323
+ root;
3324
+ container;
3325
+ theme;
3326
+ onAction;
3327
+ onNavigate;
3328
+ currentSchema = null;
3329
+ currentData = {};
3330
+ destroyed = false;
3331
+ constructor(options) {
3332
+ this.container = options.container;
3333
+ this.theme = options.theme;
3334
+ this.onAction = options.onAction;
3335
+ this.onNavigate = options.onNavigate;
3336
+ this.root = createRoot(this.container);
3337
+ }
3338
+ render(schema, data) {
3339
+ if (this.destroyed) {
3340
+ throw new Error("MeissaClientRenderer has been destroyed");
3341
+ }
3342
+ this.currentSchema = schema;
3343
+ if (data !== undefined) {
3344
+ this.currentData = data;
3345
+ }
3346
+ this.commitRender();
3347
+ }
3348
+ patch(patches) {
3349
+ if (this.destroyed) {
3350
+ throw new Error("MeissaClientRenderer has been destroyed");
3351
+ }
3352
+ if (!this.currentSchema) {
3353
+ throw new Error("Cannot patch before initial render");
3354
+ }
3355
+ this.currentData = applyPatches(this.currentData, patches);
3356
+ this.commitRender();
3357
+ }
3358
+ update(data) {
3359
+ if (this.destroyed) {
3360
+ throw new Error("MeissaClientRenderer has been destroyed");
3361
+ }
3362
+ if (!this.currentSchema) {
3363
+ throw new Error("Cannot update before initial render");
3364
+ }
3365
+ this.currentData = data;
3366
+ this.commitRender();
3367
+ }
3368
+ destroy() {
3369
+ if (this.destroyed)
3370
+ return;
3371
+ this.destroyed = true;
3372
+ this.root.unmount();
3373
+ this.currentSchema = null;
3374
+ this.currentData = {};
3375
+ }
3376
+ commitRender() {
3377
+ if (!this.currentSchema)
3378
+ return;
3379
+ const handleAction = (name, args) => {
3380
+ if (this.onAction) {
3381
+ this.onAction(name, args ?? {});
3382
+ }
3383
+ };
3384
+ const handleNavigate = (uri) => {
3385
+ if (this.onNavigate) {
3386
+ this.onNavigate(uri);
3387
+ }
3388
+ };
3389
+ this.root.render(createElement(MeissaRenderer, {
3390
+ schema: this.currentSchema,
3391
+ data: this.currentData,
3392
+ theme: this.theme,
3393
+ onAction: handleAction,
3394
+ onNavigate: handleNavigate
3395
+ }));
3396
+ }
3397
+ }
3398
+ // src/client/component.tsx
3399
+ import { useState as useState5, useCallback as useCallback8, useRef } from "react";
3400
+ import { forwardRef, useImperativeHandle } from "react";
3401
+ import { jsxDEV as jsxDEV26 } from "react/jsx-dev-runtime";
3402
+ function MeissaContent({
3403
+ schema,
3404
+ data: externalData,
3405
+ theme,
3406
+ onAction,
3407
+ onNavigate,
3408
+ className
3409
+ }) {
3410
+ const [patchedData, setPatchedData] = useState5(externalData);
3411
+ const dataRef = useRef(patchedData);
3412
+ dataRef.current = patchedData;
3413
+ const prevExternalRef = useRef(externalData);
3414
+ if (externalData !== prevExternalRef.current) {
3415
+ prevExternalRef.current = externalData;
3416
+ setPatchedData(externalData);
3417
+ dataRef.current = externalData;
3418
+ }
3419
+ const applyPatch = useCallback8((patches) => {
3420
+ setPatchedData((current) => {
3421
+ const base = current ?? {};
3422
+ return applyPatches(base, patches);
3423
+ });
3424
+ }, []);
3425
+ const handleAction = useCallback8((name, args) => {
3426
+ if (onAction) {
3427
+ onAction(name, args ?? {});
3428
+ }
3429
+ }, [onAction]);
3430
+ const handleNavigate = useCallback8((uri) => {
3431
+ if (onNavigate) {
3432
+ onNavigate(uri);
3433
+ }
3434
+ }, [onNavigate]);
3435
+ return /* @__PURE__ */ jsxDEV26(MeissaRenderer, {
3436
+ schema,
3437
+ data: patchedData,
3438
+ theme,
3439
+ onAction: handleAction,
3440
+ onNavigate: handleNavigate,
3441
+ className
3442
+ }, undefined, false, undefined, this);
3443
+ }
3444
+ var MeissaContentWithRef = forwardRef(function MeissaContentWithRef2(props, ref) {
3445
+ const [patchedData, setPatchedData] = useState5(props.data);
3446
+ const dataRef = useRef(patchedData);
3447
+ dataRef.current = patchedData;
3448
+ const prevExternalRef = useRef(props.data);
3449
+ if (props.data !== prevExternalRef.current) {
3450
+ prevExternalRef.current = props.data;
3451
+ setPatchedData(props.data);
3452
+ dataRef.current = props.data;
3453
+ }
3454
+ const applyPatchFn = useCallback8((patches) => {
3455
+ setPatchedData((current) => {
3456
+ const base = current ?? {};
3457
+ return applyPatches(base, patches);
3458
+ });
3459
+ }, []);
3460
+ useImperativeHandle(ref, () => ({
3461
+ applyPatch: applyPatchFn
3462
+ }), [applyPatchFn]);
3463
+ const handleAction = useCallback8((name, args) => {
3464
+ if (props.onAction) {
3465
+ props.onAction(name, args ?? {});
3466
+ }
3467
+ }, [props.onAction]);
3468
+ const handleNavigate = useCallback8((uri) => {
3469
+ if (props.onNavigate) {
3470
+ props.onNavigate(uri);
3471
+ }
3472
+ }, [props.onNavigate]);
3473
+ return /* @__PURE__ */ jsxDEV26(MeissaRenderer, {
3474
+ schema: props.schema,
3475
+ data: patchedData,
3476
+ theme: props.theme,
3477
+ onAction: handleAction,
3478
+ onNavigate: handleNavigate,
3479
+ className: props.className
3480
+ }, undefined, false, undefined, this);
3481
+ });
3482
+ // src/client/content.ts
3483
+ function handleMcpContent(contentBlocks) {
3484
+ for (const block of contentBlocks) {
3485
+ if (block.type === "meissa/patch") {
3486
+ const patchBlock = block;
3487
+ return {
3488
+ type: "meissa/patch",
3489
+ target: patchBlock.target,
3490
+ patches: patchBlock.patches
3491
+ };
3492
+ }
3493
+ }
3494
+ for (const block of contentBlocks) {
3495
+ if (block.type === "meissa") {
3496
+ const meissaBlock = block;
3497
+ return {
3498
+ type: "meissa",
3499
+ schema: meissaBlock.schema,
3500
+ data: meissaBlock.data,
3501
+ theme: meissaBlock.theme,
3502
+ fallback: meissaBlock.fallback
3503
+ };
3504
+ }
3505
+ }
3506
+ const textParts = [];
3507
+ for (const block of contentBlocks) {
3508
+ if (block.type === "text") {
3509
+ textParts.push(block.text);
3510
+ }
3511
+ }
3512
+ return {
3513
+ type: "text",
3514
+ text: textParts.join(`
3515
+ `)
3516
+ };
3517
+ }
3518
+ export {
3519
+ handleMcpContent,
3520
+ applyPatches,
3521
+ MeissaContentWithRef,
3522
+ MeissaContent,
3523
+ MeissaClientRenderer
3524
+ };