@shapesos/clay 0.16.0 → 0.18.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 (83) hide show
  1. package/dist/ai-elements.cjs +3 -1
  2. package/dist/ai-elements.cjs.map +1 -1
  3. package/dist/ai-elements.js +4 -4
  4. package/dist/artifacts.cjs +976 -69
  5. package/dist/artifacts.cjs.map +1 -1
  6. package/dist/artifacts.d.cts +20 -3
  7. package/dist/artifacts.d.ts +20 -3
  8. package/dist/artifacts.js +13 -5
  9. package/dist/blocks.cjs +690 -85
  10. package/dist/blocks.cjs.map +1 -1
  11. package/dist/blocks.css +1 -1
  12. package/dist/blocks.d.cts +3 -3
  13. package/dist/blocks.d.ts +3 -3
  14. package/dist/blocks.js +5 -5
  15. package/dist/button.cjs +3 -1
  16. package/dist/button.cjs.map +1 -1
  17. package/dist/button.js +2 -2
  18. package/dist/capture.cjs +3 -1
  19. package/dist/capture.cjs.map +1 -1
  20. package/dist/capture.js +2 -2
  21. package/dist/chart.cjs +16 -36
  22. package/dist/chart.cjs.map +1 -1
  23. package/dist/chart.d.cts +3 -11
  24. package/dist/chart.d.ts +3 -11
  25. package/dist/chart.js +2 -2
  26. package/dist/chat.cjs +714 -109
  27. package/dist/chat.cjs.map +1 -1
  28. package/dist/chat.d.cts +2 -2
  29. package/dist/chat.d.ts +2 -2
  30. package/dist/chat.js +6 -6
  31. package/dist/{chunk-UZKNSAAD.js → chunk-7MY4X4YL.js} +3 -3
  32. package/dist/chunk-BHHJOG5X.js +1 -0
  33. package/dist/{chunk-GAZRZZRF.js → chunk-CATIRDZP.js} +5 -5
  34. package/dist/{chunk-B4U37WIH.js → chunk-CFCLVJIO.js} +2 -2
  35. package/dist/{chunk-PYDVANWI.js → chunk-E36VI2HA.js} +2 -2
  36. package/dist/{chunk-U3IXCSV6.js → chunk-G4NXVFXU.js} +18 -40
  37. package/dist/chunk-G4NXVFXU.js.map +1 -0
  38. package/dist/{chunk-JAGNXEWK.js → chunk-GK4XW4BC.js} +2 -2
  39. package/dist/{chunk-4VE6ZXXW.js → chunk-MQP57DOP.js} +3 -3
  40. package/dist/{chunk-2YCBDSPK.js → chunk-QR4VBGK4.js} +673 -42
  41. package/dist/chunk-QR4VBGK4.js.map +1 -0
  42. package/dist/{chunk-JF3P66JF.js → chunk-SN3ORQSJ.js} +4 -2
  43. package/dist/{chunk-JF3P66JF.js.map → chunk-SN3ORQSJ.js.map} +1 -1
  44. package/dist/{chunk-PGR2MDDU.js → chunk-W66OJM55.js} +2 -2
  45. package/dist/{chunk-7OYIDM42.js → chunk-XKURJ72I.js} +2 -2
  46. package/dist/{dom-to-image-NATF3446.js → dom-to-image-QB7KMTAE.js} +3 -3
  47. package/dist/icon.cjs +3 -1
  48. package/dist/icon.cjs.map +1 -1
  49. package/dist/icon.js +2 -2
  50. package/dist/index.cjs +780 -167
  51. package/dist/index.cjs.map +1 -1
  52. package/dist/index.d.cts +3 -3
  53. package/dist/index.d.ts +3 -3
  54. package/dist/index.js +19 -11
  55. package/dist/keyboard-shortcut.cjs +3 -1
  56. package/dist/keyboard-shortcut.cjs.map +1 -1
  57. package/dist/keyboard-shortcut.js +2 -2
  58. package/dist/text-area.cjs +3 -1
  59. package/dist/text-area.cjs.map +1 -1
  60. package/dist/text-area.js +2 -2
  61. package/dist/tokens.cjs +3 -1
  62. package/dist/tokens.cjs.map +1 -1
  63. package/dist/tokens.d.cts +1 -0
  64. package/dist/tokens.d.ts +1 -0
  65. package/dist/tokens.js +1 -1
  66. package/dist/{types-CW45GBXl.d.cts → types-BDYPVP2N.d.cts} +1 -1
  67. package/dist/{types-D1b8v7EY.d.ts → types-BMwa4bPW.d.ts} +1 -1
  68. package/dist/{types-GCkXbyFm.d.ts → types-C8JtnwNY.d.ts} +200 -4
  69. package/dist/{types-BzXPBy6s.d.cts → types-DTdDFU3O.d.cts} +200 -4
  70. package/package.json +1 -1
  71. package/dist/chunk-2YCBDSPK.js.map +0 -1
  72. package/dist/chunk-RSRNSWJN.js +0 -1
  73. package/dist/chunk-U3IXCSV6.js.map +0 -1
  74. /package/dist/{chunk-UZKNSAAD.js.map → chunk-7MY4X4YL.js.map} +0 -0
  75. /package/dist/{chunk-RSRNSWJN.js.map → chunk-BHHJOG5X.js.map} +0 -0
  76. /package/dist/{chunk-GAZRZZRF.js.map → chunk-CATIRDZP.js.map} +0 -0
  77. /package/dist/{chunk-B4U37WIH.js.map → chunk-CFCLVJIO.js.map} +0 -0
  78. /package/dist/{chunk-PYDVANWI.js.map → chunk-E36VI2HA.js.map} +0 -0
  79. /package/dist/{chunk-JAGNXEWK.js.map → chunk-GK4XW4BC.js.map} +0 -0
  80. /package/dist/{chunk-4VE6ZXXW.js.map → chunk-MQP57DOP.js.map} +0 -0
  81. /package/dist/{chunk-PGR2MDDU.js.map → chunk-W66OJM55.js.map} +0 -0
  82. /package/dist/{chunk-7OYIDM42.js.map → chunk-XKURJ72I.js.map} +0 -0
  83. /package/dist/{dom-to-image-NATF3446.js.map → dom-to-image-QB7KMTAE.js.map} +0 -0
package/dist/blocks.cjs CHANGED
@@ -128,7 +128,9 @@ var init_colors = __esm({
128
128
  "red-200": "#FECACA",
129
129
  "red-400": "#F7776C",
130
130
  "red-500": "#EF4444",
131
- "red-600": "#DC2626"
131
+ "red-600": "#DC2626",
132
+ // Deck
133
+ "deck-canvas": "#faf8f5"
132
134
  };
133
135
  }
134
136
  });
@@ -286,7 +288,8 @@ var blockTypes = {
286
288
  // src/components/artifacts/artifact-base.ts
287
289
  var artifactTypes = {
288
290
  TABLE: "TABLE",
289
- CHART: "CHART"
291
+ CHART: "CHART",
292
+ DECK: "DECK"
290
293
  };
291
294
 
292
295
  // src/components/artifacts/chart-artifact/types.ts
@@ -311,6 +314,34 @@ var DEFAULT_TABLE_ARTIFACT_LABELS = {
311
314
  empty: "No rows to display."
312
315
  };
313
316
 
317
+ // src/components/artifacts/deck-artifact/types.ts
318
+ var deckBlockTypes = {
319
+ TEXT: "TEXT",
320
+ CHART: "CHART",
321
+ TABLE: "TABLE"
322
+ };
323
+ var deckSlideKinds = {
324
+ TITLE: "TITLE",
325
+ AGENDA: "AGENDA",
326
+ SECTION: "SECTION",
327
+ CONTENT: "CONTENT",
328
+ CLOSING: "CLOSING"
329
+ };
330
+ var DEFAULT_DECK_ARTIFACT_LABELS = {
331
+ previous: "Previous slide",
332
+ next: "Next slide",
333
+ position: "Slide {current} of {total}",
334
+ download: "Download",
335
+ unavailable: "Deck content is unavailable.",
336
+ enterFullscreen: "Fullscreen",
337
+ exitFullscreen: "Exit fullscreen",
338
+ thankYou: "Thank you",
339
+ questions: "Questions?",
340
+ agenda: "Agenda",
341
+ chart: DEFAULT_CHART_ARTIFACT_LABELS,
342
+ table: DEFAULT_TABLE_ARTIFACT_LABELS
343
+ };
344
+
314
345
  // src/components/artifacts/chart-artifact/chart-artifact.tsx
315
346
  var import_react13 = require("react");
316
347
 
@@ -403,29 +434,45 @@ var createReactComponent = (type, iconName, iconNamePascal, iconNode) => {
403
434
  var __iconNode = [["path", { "d": "M3 12a9 9 0 1 0 18 0a9 9 0 0 0 -18 0", "key": "svg-0" }], ["path", { "d": "M12 8v4", "key": "svg-1" }], ["path", { "d": "M12 16h.01", "key": "svg-2" }]];
404
435
  var IconAlertCircle = createReactComponent("outline", "alert-circle", "AlertCircle", __iconNode);
405
436
 
437
+ // node_modules/@tabler/icons-react/dist/esm/icons/IconArrowsMaximize.mjs
438
+ var __iconNode2 = [["path", { "d": "M16 4l4 0l0 4", "key": "svg-0" }], ["path", { "d": "M14 10l6 -6", "key": "svg-1" }], ["path", { "d": "M8 20l-4 0l0 -4", "key": "svg-2" }], ["path", { "d": "M4 20l6 -6", "key": "svg-3" }], ["path", { "d": "M16 20l4 0l0 -4", "key": "svg-4" }], ["path", { "d": "M14 14l6 6", "key": "svg-5" }], ["path", { "d": "M8 4l-4 0l0 4", "key": "svg-6" }], ["path", { "d": "M4 4l6 6", "key": "svg-7" }]];
439
+ var IconArrowsMaximize = createReactComponent("outline", "arrows-maximize", "ArrowsMaximize", __iconNode2);
440
+
441
+ // node_modules/@tabler/icons-react/dist/esm/icons/IconArrowsMinimize.mjs
442
+ var __iconNode3 = [["path", { "d": "M5 9l4 0l0 -4", "key": "svg-0" }], ["path", { "d": "M3 3l6 6", "key": "svg-1" }], ["path", { "d": "M5 15l4 0l0 4", "key": "svg-2" }], ["path", { "d": "M3 21l6 -6", "key": "svg-3" }], ["path", { "d": "M19 9l-4 0l0 -4", "key": "svg-4" }], ["path", { "d": "M15 9l6 -6", "key": "svg-5" }], ["path", { "d": "M19 15l-4 0l0 4", "key": "svg-6" }], ["path", { "d": "M15 15l6 6", "key": "svg-7" }]];
443
+ var IconArrowsMinimize = createReactComponent("outline", "arrows-minimize", "ArrowsMinimize", __iconNode3);
444
+
406
445
  // node_modules/@tabler/icons-react/dist/esm/icons/IconCheck.mjs
407
- var __iconNode2 = [["path", { "d": "M5 12l5 5l10 -10", "key": "svg-0" }]];
408
- var IconCheck = createReactComponent("outline", "check", "Check", __iconNode2);
446
+ var __iconNode4 = [["path", { "d": "M5 12l5 5l10 -10", "key": "svg-0" }]];
447
+ var IconCheck = createReactComponent("outline", "check", "Check", __iconNode4);
448
+
449
+ // node_modules/@tabler/icons-react/dist/esm/icons/IconChevronLeft.mjs
450
+ var __iconNode5 = [["path", { "d": "M15 6l-6 6l6 6", "key": "svg-0" }]];
451
+ var IconChevronLeft = createReactComponent("outline", "chevron-left", "ChevronLeft", __iconNode5);
452
+
453
+ // node_modules/@tabler/icons-react/dist/esm/icons/IconChevronRight.mjs
454
+ var __iconNode6 = [["path", { "d": "M9 6l6 6l-6 6", "key": "svg-0" }]];
455
+ var IconChevronRight = createReactComponent("outline", "chevron-right", "ChevronRight", __iconNode6);
409
456
 
410
457
  // node_modules/@tabler/icons-react/dist/esm/icons/IconCopy.mjs
411
- var __iconNode3 = [["path", { "d": "M7 9.667a2.667 2.667 0 0 1 2.667 -2.667h8.666a2.667 2.667 0 0 1 2.667 2.667v8.666a2.667 2.667 0 0 1 -2.667 2.667h-8.666a2.667 2.667 0 0 1 -2.667 -2.667l0 -8.666", "key": "svg-0" }], ["path", { "d": "M4.012 16.737a2.005 2.005 0 0 1 -1.012 -1.737v-10c0 -1.1 .9 -2 2 -2h10c.75 0 1.158 .385 1.5 1", "key": "svg-1" }]];
412
- var IconCopy = createReactComponent("outline", "copy", "Copy", __iconNode3);
458
+ var __iconNode7 = [["path", { "d": "M7 9.667a2.667 2.667 0 0 1 2.667 -2.667h8.666a2.667 2.667 0 0 1 2.667 2.667v8.666a2.667 2.667 0 0 1 -2.667 2.667h-8.666a2.667 2.667 0 0 1 -2.667 -2.667l0 -8.666", "key": "svg-0" }], ["path", { "d": "M4.012 16.737a2.005 2.005 0 0 1 -1.012 -1.737v-10c0 -1.1 .9 -2 2 -2h10c.75 0 1.158 .385 1.5 1", "key": "svg-1" }]];
459
+ var IconCopy = createReactComponent("outline", "copy", "Copy", __iconNode7);
413
460
 
414
461
  // node_modules/@tabler/icons-react/dist/esm/icons/IconDownload.mjs
415
- var __iconNode4 = [["path", { "d": "M4 17v2a2 2 0 0 0 2 2h12a2 2 0 0 0 2 -2v-2", "key": "svg-0" }], ["path", { "d": "M7 11l5 5l5 -5", "key": "svg-1" }], ["path", { "d": "M12 4l0 12", "key": "svg-2" }]];
416
- var IconDownload = createReactComponent("outline", "download", "Download", __iconNode4);
462
+ var __iconNode8 = [["path", { "d": "M4 17v2a2 2 0 0 0 2 2h12a2 2 0 0 0 2 -2v-2", "key": "svg-0" }], ["path", { "d": "M7 11l5 5l5 -5", "key": "svg-1" }], ["path", { "d": "M12 4l0 12", "key": "svg-2" }]];
463
+ var IconDownload = createReactComponent("outline", "download", "Download", __iconNode8);
417
464
 
418
465
  // node_modules/@tabler/icons-react/dist/esm/icons/IconFileSpreadsheet.mjs
419
- var __iconNode5 = [["path", { "d": "M14 3v4a1 1 0 0 0 1 1h4", "key": "svg-0" }], ["path", { "d": "M17 21h-10a2 2 0 0 1 -2 -2v-14a2 2 0 0 1 2 -2h7l5 5v11a2 2 0 0 1 -2 2", "key": "svg-1" }], ["path", { "d": "M8 11h8v7h-8l0 -7", "key": "svg-2" }], ["path", { "d": "M8 15h8", "key": "svg-3" }], ["path", { "d": "M11 11v7", "key": "svg-4" }]];
420
- var IconFileSpreadsheet = createReactComponent("outline", "file-spreadsheet", "FileSpreadsheet", __iconNode5);
466
+ var __iconNode9 = [["path", { "d": "M14 3v4a1 1 0 0 0 1 1h4", "key": "svg-0" }], ["path", { "d": "M17 21h-10a2 2 0 0 1 -2 -2v-14a2 2 0 0 1 2 -2h7l5 5v11a2 2 0 0 1 -2 2", "key": "svg-1" }], ["path", { "d": "M8 11h8v7h-8l0 -7", "key": "svg-2" }], ["path", { "d": "M8 15h8", "key": "svg-3" }], ["path", { "d": "M11 11v7", "key": "svg-4" }]];
467
+ var IconFileSpreadsheet = createReactComponent("outline", "file-spreadsheet", "FileSpreadsheet", __iconNode9);
421
468
 
422
469
  // node_modules/@tabler/icons-react/dist/esm/icons/IconLoader2.mjs
423
- var __iconNode6 = [["path", { "d": "M12 3a9 9 0 1 0 9 9", "key": "svg-0" }]];
424
- var IconLoader2 = createReactComponent("outline", "loader-2", "Loader2", __iconNode6);
470
+ var __iconNode10 = [["path", { "d": "M12 3a9 9 0 1 0 9 9", "key": "svg-0" }]];
471
+ var IconLoader2 = createReactComponent("outline", "loader-2", "Loader2", __iconNode10);
425
472
 
426
473
  // node_modules/@tabler/icons-react/dist/esm/icons/IconPhoto.mjs
427
- var __iconNode7 = [["path", { "d": "M15 8h.01", "key": "svg-0" }], ["path", { "d": "M3 6a3 3 0 0 1 3 -3h12a3 3 0 0 1 3 3v12a3 3 0 0 1 -3 3h-12a3 3 0 0 1 -3 -3v-12", "key": "svg-1" }], ["path", { "d": "M3 16l5 -5c.928 -.893 2.072 -.893 3 0l5 5", "key": "svg-2" }], ["path", { "d": "M14 14l1 -1c.928 -.893 2.072 -.893 3 0l3 3", "key": "svg-3" }]];
428
- var IconPhoto = createReactComponent("outline", "photo", "Photo", __iconNode7);
474
+ var __iconNode11 = [["path", { "d": "M15 8h.01", "key": "svg-0" }], ["path", { "d": "M3 6a3 3 0 0 1 3 -3h12a3 3 0 0 1 3 3v12a3 3 0 0 1 -3 3h-12a3 3 0 0 1 -3 -3v-12", "key": "svg-1" }], ["path", { "d": "M3 16l5 -5c.928 -.893 2.072 -.893 3 0l5 5", "key": "svg-2" }], ["path", { "d": "M14 14l1 -1c.928 -.893 2.072 -.893 3 0l3 3", "key": "svg-3" }]];
475
+ var IconPhoto = createReactComponent("outline", "photo", "Photo", __iconNode11);
429
476
 
430
477
  // src/components/artifacts/artifact-copy-as-image-button/artifact-copy-as-image-button.tsx
431
478
  var import_react6 = require("react");
@@ -1395,11 +1442,6 @@ function coerceNumericColumns(rows, numericKeys) {
1395
1442
 
1396
1443
  // src/components/chart/bar-chart/bar-chart.tsx
1397
1444
  var import_jsx_runtime12 = require("react/jsx-runtime");
1398
- var STACK_TOTAL_KEY = "__stackTotal";
1399
- var VALUE_LABEL_HEADROOM = 20;
1400
- function sumSeries(row, keys) {
1401
- return keys.reduce((sum, key) => sum + (Number(row[key]) || 0), 0);
1402
- }
1403
1445
  function BarChart({
1404
1446
  data,
1405
1447
  xKey,
@@ -1414,7 +1456,6 @@ function BarChart({
1414
1456
  showGrid = true,
1415
1457
  showXAxis = true,
1416
1458
  showYAxis = true,
1417
- showValueLabels,
1418
1459
  xAxisInterval = 0,
1419
1460
  xAxisAngle,
1420
1461
  xAxisTickFormatter
@@ -1425,24 +1466,14 @@ function BarChart({
1425
1466
  [data, seriesKeys]
1426
1467
  );
1427
1468
  const resolvedShowLegend = showLegend ?? series.length > 1;
1428
- const resolvedShowValueLabels = showValueLabels ?? true;
1429
- const plotData = (0, import_react9.useMemo)(() => {
1430
- if (!stacked || !resolvedShowValueLabels) return coercedData;
1431
- return coercedData.map((row) => ({ ...row, [STACK_TOTAL_KEY]: sumSeries(row, seriesKeys) }));
1432
- }, [coercedData, stacked, resolvedShowValueLabels, seriesKeys]);
1433
1469
  const resolvedAngle = xAxisAngle ?? (coercedData.length >= 8 ? -30 : 0);
1434
1470
  const resolvedTickFormatter = (0, import_react9.useMemo)(
1435
1471
  () => xAxisTickFormatter ?? defaultBarTickFormatter(coercedData.length),
1436
1472
  [xAxisTickFormatter, coercedData.length]
1437
1473
  );
1438
1474
  const angledLabelPad = resolvedAngle === 0 ? 0 : Math.min(Math.abs(resolvedAngle) * 0.7, 40);
1439
- const valueLabelHeadroom = resolvedShowValueLabels ? VALUE_LABEL_HEADROOM : 0;
1440
- const chartMargin = {
1441
- ...CHART_MARGIN,
1442
- top: CHART_MARGIN.top + valueLabelHeadroom,
1443
- bottom: CHART_MARGIN.bottom + angledLabelPad
1444
- };
1445
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(ChartContainer, { height, width, className, children: /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_recharts2.BarChart, { data: plotData, margin: chartMargin, barCategoryGap: "22%", children: [
1475
+ const chartMargin = { ...CHART_MARGIN, bottom: CHART_MARGIN.bottom + angledLabelPad };
1476
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(ChartContainer, { height, width, className, children: /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_recharts2.BarChart, { data: coercedData, margin: chartMargin, barCategoryGap: "22%", children: [
1446
1477
  showGrid ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_recharts2.CartesianGrid, { ...CHART_GRID_PROPS }) : null,
1447
1478
  showXAxis ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
1448
1479
  import_recharts2.XAxis,
@@ -1469,23 +1500,17 @@ function BarChart({
1469
1500
  content: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(ChartLegendContent, { iconType: "square" })
1470
1501
  }
1471
1502
  ) : null,
1472
- series.map((s, i) => {
1473
- const isTopSegment = i === series.length - 1;
1474
- const labelDataKey = stacked ? STACK_TOTAL_KEY : s.key;
1475
- const showLabel = resolvedShowValueLabels && (!stacked || isTopSegment);
1476
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
1477
- import_recharts2.Bar,
1478
- {
1479
- dataKey: s.key,
1480
- name: s.label,
1481
- fill: colorForSeriesIndex(i, palette),
1482
- stackId: stacked ? "default" : s.key,
1483
- radius: barRadius(stacked, i, series.length),
1484
- children: showLabel ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_recharts2.LabelList, { dataKey: labelDataKey, position: "top", style: CHART_VALUE_LABEL_STYLE }) : null
1485
- },
1486
- s.key
1487
- );
1488
- })
1503
+ series.map((s, i) => /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
1504
+ import_recharts2.Bar,
1505
+ {
1506
+ dataKey: s.key,
1507
+ name: s.label,
1508
+ fill: colorForSeriesIndex(i, palette),
1509
+ stackId: stacked ? "default" : s.key,
1510
+ radius: barRadius(stacked, i, series.length)
1511
+ },
1512
+ s.key
1513
+ ))
1489
1514
  ] }) });
1490
1515
  }
1491
1516
  function barRadius(stacked, seriesIndex, seriesCount) {
@@ -2020,8 +2045,13 @@ var ChartArtifactService = {
2020
2045
  toClipboardText: chartArtifactToClipboardText
2021
2046
  };
2022
2047
 
2023
- // src/components/artifacts/table-artifact/table-artifact.tsx
2024
- var import_react15 = require("react");
2048
+ // src/components/artifacts/deck-artifact/deck-artifact.tsx
2049
+ var import_react17 = require("react");
2050
+ var import_react_dom = require("react-dom");
2051
+ init_capture_exclude_attribute();
2052
+
2053
+ // src/components/artifacts/deck-artifact/deck-artifact-content.tsx
2054
+ var import_react16 = require("react");
2025
2055
 
2026
2056
  // src/components/ui/table.tsx
2027
2057
  var React3 = __toESM(require("react"), 1);
@@ -2168,9 +2198,333 @@ function renderEmptyRow(colSpan, emptyMessage) {
2168
2198
  return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(TableRow, { className: "hover:bg-transparent", children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(TableCell, { colSpan, className: "py-6 text-center text-sm text-muted-foreground", children: emptyMessage }) });
2169
2199
  }
2170
2200
 
2171
- // src/components/artifacts/table-artifact/use-table-artifact-data.ts
2172
- function useTableArtifactData(presignedUrl, columns) {
2173
- return useRowsArtifactData(presignedUrl, columns, parseCsv);
2201
+ // src/components/artifacts/deck-artifact/deck-markdown.tsx
2202
+ var import_react_markdown = __toESM(require("react-markdown"), 1);
2203
+ var import_remark_breaks = __toESM(require("remark-breaks"), 1);
2204
+ var import_remark_gfm = __toESM(require("remark-gfm"), 1);
2205
+ var import_jsx_runtime22 = require("react/jsx-runtime");
2206
+ function sanitize(text) {
2207
+ return text.split("\n").filter((line) => {
2208
+ const t = line.trim();
2209
+ return !(t.startsWith("<!-- table-title:") && t.endsWith("-->"));
2210
+ }).join("\n");
2211
+ }
2212
+ var MARKDOWN_COMPONENTS = {
2213
+ h1: ({ node: _node, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("h1", { className: "text-[30px] font-semibold leading-tight text-foreground mb-3", ...props }),
2214
+ h2: ({ node: _node, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("h2", { className: "text-[26px] font-semibold leading-tight text-foreground mb-2", ...props }),
2215
+ h3: ({ node: _node, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("h3", { className: "text-[24px] font-semibold leading-tight text-foreground mb-2", ...props }),
2216
+ h4: ({ node: _node, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("h4", { className: "text-[24px] font-semibold leading-tight text-foreground mb-2", ...props }),
2217
+ h5: ({ node: _node, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("h5", { className: "text-[24px] font-semibold leading-tight text-foreground mb-2", ...props }),
2218
+ h6: ({ node: _node, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("h6", { className: "text-[24px] font-semibold leading-tight text-foreground mb-2", ...props }),
2219
+ p: ({ node: _node, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("p", { className: "text-[22px] leading-relaxed text-foreground my-2", ...props }),
2220
+ ul: ({ node: _node, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("ul", { className: "list-disc pl-7 text-[22px] leading-relaxed text-foreground my-2", ...props }),
2221
+ ol: ({ node: _node, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("ol", { className: "list-decimal pl-7 text-[22px] leading-relaxed text-foreground my-2", ...props }),
2222
+ // react-markdown injects list metadata (`ordered` / `index` / `checked`) that must not leak to the DOM.
2223
+ li: ({ node: _node, ordered: _ordered, index: _index, checked: _checked, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("li", { className: "my-1", ...props }),
2224
+ strong: ({ node: _node, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("strong", { className: "font-semibold", ...props }),
2225
+ em: ({ node: _node, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("em", { className: "italic", ...props }),
2226
+ // Gate `<img src>` against an http(s) allowlist. react-markdown v8 percent-encodes the URL but
2227
+ // does NOT protocol-filter image src (unlike link href), so an LLM-authored
2228
+ // `![](javascript:…)` / `![](data:…)` or a tracking-pixel `![](http://…)` would otherwise render
2229
+ // with the raw URL. Unsafe src → render nothing.
2230
+ img: ({ node: _node, src, ...props }) => typeof src === "string" && isSafeDownloadUrl(src) ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("img", { src, className: "max-w-full", ...props }) : null,
2231
+ a: ({ node: _node, ...props }) => (
2232
+ // `rel` is forced AFTER `{...props}` so it can't be overridden — if a consumer ever adds
2233
+ // `linkTarget="_blank"`, LLM-authored links still can't reach `window.opener`.
2234
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("a", { className: "underline underline-offset-2", ...props, rel: "noopener noreferrer" })
2235
+ ),
2236
+ // react-markdown passes `inline` to distinguish inline code from fenced blocks — strip it from the DOM.
2237
+ code: ({ node: _node, inline: _inline, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("code", { className: "rounded bg-muted px-1.5 py-0.5 font-mono text-[18px]", ...props }),
2238
+ blockquote: ({ node: _node, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("blockquote", { className: "border-l-2 border-brown-alpha-12 pl-4 text-[22px] text-muted-foreground", ...props }),
2239
+ hr: ({ node: _node, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("hr", { className: "my-4 border-brown-alpha-12", ...props }),
2240
+ table: ({ node: _node, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { className: "overflow-x-auto", children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("table", { className: "w-full border-collapse text-[20px]", ...props }) }),
2241
+ // react-markdown passes `isHeader` to cell renderers — strip it so it never reaches the DOM.
2242
+ th: ({ node: _node, isHeader: _isHeader, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("th", { className: "border-b border-brown-alpha-12 px-3 py-1.5 text-left font-medium", ...props }),
2243
+ td: ({ node: _node, isHeader: _isHeader, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("td", { className: "border-b border-brown-alpha-12 px-3 py-1.5", ...props })
2244
+ };
2245
+ function DeckMarkdown({ markdown }) {
2246
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_react_markdown.default, { remarkPlugins: [import_remark_gfm.default, import_remark_breaks.default], components: MARKDOWN_COMPONENTS, children: sanitize(markdown) });
2247
+ }
2248
+
2249
+ // src/components/artifacts/deck-artifact/slide-renderers.tsx
2250
+ var import_react15 = require("react");
2251
+ var import_jsx_runtime23 = require("react/jsx-runtime");
2252
+ function safeLogoUrl(meta) {
2253
+ return meta?.logoUrl && isSafeDownloadUrl(meta.logoUrl) ? meta.logoUrl : null;
2254
+ }
2255
+ var DESIGN_W = 1280;
2256
+ var DESIGN_H = 720;
2257
+ var EYEBROW_H = 84;
2258
+ var CANVAS_LOGO_MAX_H = 48;
2259
+ var ACCENT_FONT = { fontFamily: `"${fontFamilies.CRIMSON_PRO}", serif`, fontStyle: "italic" };
2260
+ function SlideFrame({ meta, children, accent = false, bare = false }) {
2261
+ const frameRef = (0, import_react15.useRef)(null);
2262
+ const [scale, setScale] = (0, import_react15.useState)(null);
2263
+ (0, import_react15.useLayoutEffect)(() => {
2264
+ const el = frameRef.current;
2265
+ if (!el) return;
2266
+ const apply = (width) => {
2267
+ if (width > 0) setScale(width / DESIGN_W);
2268
+ };
2269
+ apply(el.clientWidth);
2270
+ const ro = new ResizeObserver((entries) => apply(entries[0]?.contentRect.width ?? 0));
2271
+ ro.observe(el);
2272
+ return () => ro.disconnect();
2273
+ }, []);
2274
+ const bg = accent ? "bg-indigo-600" : "bg-deck-canvas";
2275
+ const eyebrowColor = accent ? "text-white/70" : "text-brown-60";
2276
+ const borderColor = accent ? "border-white/20" : "border-brown-alpha-12";
2277
+ const logoSrc = safeLogoUrl(meta);
2278
+ return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { ref: frameRef, className: `relative aspect-[16/9] w-full overflow-hidden rounded-lg ${bg}`, children: /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
2279
+ "div",
2280
+ {
2281
+ className: "absolute left-0 top-0 origin-top-left",
2282
+ style: {
2283
+ width: DESIGN_W,
2284
+ height: DESIGN_H,
2285
+ transform: `scale(${scale ?? 0})`,
2286
+ visibility: scale === null ? "hidden" : "visible"
2287
+ },
2288
+ children: [
2289
+ !bare ? /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
2290
+ "div",
2291
+ {
2292
+ className: `absolute inset-x-0 top-0 flex items-center justify-between border-b px-16 ${borderColor}`,
2293
+ style: { height: EYEBROW_H },
2294
+ children: [
2295
+ meta?.eyebrow ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: eyebrowColor, style: { ...ACCENT_FONT, fontSize: 22 }, children: meta.eyebrow }) : /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", {}),
2296
+ logoSrc ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("img", { src: logoSrc, alt: "", className: "object-contain", style: { maxHeight: CANVAS_LOGO_MAX_H } }) : null
2297
+ ]
2298
+ }
2299
+ ) : null,
2300
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "absolute inset-x-0 bottom-0 overflow-hidden", style: { top: bare ? 0 : EYEBROW_H }, children })
2301
+ ]
2302
+ }
2303
+ ) });
2304
+ }
2305
+ function TitleSlide({ slide, meta }) {
2306
+ const logoSrc = safeLogoUrl(meta);
2307
+ return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(SlideFrame, { meta, bare: true, children: /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex h-full flex-col justify-center px-24 py-16", children: [
2308
+ logoSrc ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
2309
+ "img",
2310
+ {
2311
+ src: logoSrc,
2312
+ alt: "",
2313
+ className: "mb-16 object-contain object-left",
2314
+ style: { maxHeight: 56, maxWidth: 380 }
2315
+ }
2316
+ ) : null,
2317
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
2318
+ "h1",
2319
+ {
2320
+ className: "font-bold tracking-tight text-brown-100",
2321
+ style: { fontSize: 92, lineHeight: 1.04, maxWidth: 1060 },
2322
+ children: slide.title
2323
+ }
2324
+ ),
2325
+ slide.subtitle ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("p", { className: "mt-7 text-brown-70", style: { ...ACCENT_FONT, fontSize: 34 }, children: slide.subtitle }) : null,
2326
+ slide.description ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("p", { className: "mt-4 leading-relaxed text-brown-70", style: { fontSize: 24, maxWidth: 880 }, children: slide.description }) : null,
2327
+ meta?.date ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("p", { className: "mt-10 text-brown-70", style: { ...ACCENT_FONT, fontSize: 30 }, children: meta.date }) : null
2328
+ ] }) });
2329
+ }
2330
+ function AgendaSlide({ slide, meta, labels }) {
2331
+ const items = slide.items ?? [];
2332
+ return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(SlideFrame, { meta, children: /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "h-full px-24 py-14", children: [
2333
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("h2", { className: "mb-10 font-bold text-brown-90", style: { fontSize: 40 }, children: slide.title || labels.agenda }),
2334
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "flex flex-col", children: items.map((item, i) => /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex items-baseline gap-6 border-b border-brown-alpha-12 py-5", children: [
2335
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "shrink-0 text-indigo-600", style: { ...ACCENT_FONT, fontSize: 28, width: 64 }, children: String(i + 1).padStart(2, "0") }),
2336
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "text-brown-90", style: { fontSize: 28 }, children: item })
2337
+ ] }, i)) })
2338
+ ] }) });
2339
+ }
2340
+ function SectionSlide({ slide, meta }) {
2341
+ return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(SlideFrame, { meta, accent: true, children: /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex h-full flex-col justify-center gap-6 px-24", children: [
2342
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("h2", { className: "font-bold text-white", style: { fontSize: 72, lineHeight: 1.05, maxWidth: 940 }, children: slide.title }),
2343
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "mt-2 bg-white/50", style: { width: 96, height: 5 } })
2344
+ ] }) });
2345
+ }
2346
+ function ClosingSlide({ meta, labels }) {
2347
+ return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(SlideFrame, { meta, children: /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex h-full flex-col items-center justify-center gap-6 px-24 text-center", children: [
2348
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("h1", { className: "font-bold text-brown-100", style: { fontSize: 72 }, children: labels.thankYou }),
2349
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("p", { className: "text-indigo-600", style: { ...ACCENT_FONT, fontSize: 36 }, children: labels.questions })
2350
+ ] }) });
2351
+ }
2352
+
2353
+ // src/components/artifacts/deck-artifact/deck-artifact-content.tsx
2354
+ var import_jsx_runtime24 = require("react/jsx-runtime");
2355
+ var TABLE_BLOCK_MAX_SHIMMER_ROWS = 10;
2356
+ var TABLE_CHROME_RESERVE = 56;
2357
+ var VISUAL_FALLBACK_HEIGHT = 360;
2358
+ function DeckArtifactContent({
2359
+ slides,
2360
+ labels,
2361
+ onNavigate,
2362
+ meta,
2363
+ onDark = false,
2364
+ currentSlide,
2365
+ onSlideChange
2366
+ }) {
2367
+ const navBtnClass = onDark ? "[&_svg]:!text-white hover:!bg-white/20 disabled:opacity-40" : void 0;
2368
+ const navBtnSize = onDark ? "medium" : "small";
2369
+ const isControlled = currentSlide !== void 0;
2370
+ const [internalIndex, setInternalIndex] = (0, import_react16.useState)(0);
2371
+ const index = isControlled ? currentSlide : internalIndex;
2372
+ const current = Math.min(index, slides.length - 1);
2373
+ const slide = slides[current];
2374
+ const goTo = (0, import_react16.useCallback)(
2375
+ (next) => {
2376
+ const clamped = Math.max(0, Math.min(next, slides.length - 1));
2377
+ if (isControlled) onSlideChange?.(clamped);
2378
+ else setInternalIndex(clamped);
2379
+ onNavigate?.(clamped);
2380
+ },
2381
+ [slides.length, onNavigate, isControlled, onSlideChange]
2382
+ );
2383
+ const position = labels.position.replace("{current}", String(current + 1)).replace("{total}", String(slides.length));
2384
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "flex flex-col gap-3 p-4", children: [
2385
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(SlideDispatch, { slide, labels, meta }),
2386
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(
2387
+ "div",
2388
+ {
2389
+ className: `flex items-center justify-between border-t pt-2 ${onDark ? "border-white/20" : "border-brown-alpha-12"}`,
2390
+ children: [
2391
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
2392
+ IconButton,
2393
+ {
2394
+ icon: IconChevronLeft,
2395
+ size: navBtnSize,
2396
+ className: navBtnClass,
2397
+ "aria-label": labels.previous,
2398
+ disabled: current === 0,
2399
+ onClick: () => goTo(current - 1)
2400
+ }
2401
+ ),
2402
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { className: `text-xs font-medium ${onDark ? "text-white/70" : "text-brown-70"}`, children: position }),
2403
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
2404
+ IconButton,
2405
+ {
2406
+ icon: IconChevronRight,
2407
+ size: navBtnSize,
2408
+ className: navBtnClass,
2409
+ "aria-label": labels.next,
2410
+ disabled: current === slides.length - 1,
2411
+ onClick: () => goTo(current + 1)
2412
+ }
2413
+ )
2414
+ ]
2415
+ }
2416
+ )
2417
+ ] });
2418
+ }
2419
+ function SlideDispatch({ slide, labels, meta }) {
2420
+ const kind = slide.kind ?? deckSlideKinds.CONTENT;
2421
+ switch (kind) {
2422
+ case deckSlideKinds.TITLE:
2423
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(TitleSlide, { slide, meta });
2424
+ case deckSlideKinds.AGENDA:
2425
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(AgendaSlide, { slide, meta, labels });
2426
+ case deckSlideKinds.SECTION:
2427
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(SectionSlide, { slide, meta });
2428
+ case deckSlideKinds.CLOSING:
2429
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(ClosingSlide, { meta, labels });
2430
+ case deckSlideKinds.CONTENT:
2431
+ default:
2432
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(ContentSlide, { slide, meta, labels });
2433
+ }
2434
+ }
2435
+ function isVisualBlock(block) {
2436
+ return block.type === deckBlockTypes.CHART || block.type === deckBlockTypes.TABLE;
2437
+ }
2438
+ function ContentSlide({ slide, meta, labels }) {
2439
+ const content = slide.content ?? [];
2440
+ const visuals = content.filter(isVisualBlock);
2441
+ const texts = content.filter(
2442
+ (b) => b.type === deckBlockTypes.TEXT
2443
+ );
2444
+ if (visuals.length === 1 && texts.length > 0) {
2445
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(SlideFrame, { meta, children: /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "flex h-full items-stretch gap-12 px-16 py-12", children: [
2446
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "flex w-[42%] shrink-0 flex-col overflow-hidden", children: /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(AutoFit, { children: [
2447
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("h3", { className: "mb-5 font-bold leading-tight text-foreground", style: { fontSize: 34 }, children: slide.title }),
2448
+ texts.map((block, i) => /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(DeckMarkdown, { markdown: block.markdown }, i))
2449
+ ] }) }),
2450
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "min-h-0 min-w-0 flex-1", children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(FillVisual, { block: visuals[0], labels }) })
2451
+ ] }) });
2452
+ }
2453
+ if (visuals.length > 0) {
2454
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(SlideFrame, { meta, children: /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "flex h-full flex-col gap-5 px-16 py-10", children: [
2455
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("h3", { className: "shrink-0 font-bold leading-tight text-foreground", style: { fontSize: 32 }, children: slide.title }),
2456
+ content.map(
2457
+ (block, i) => isVisualBlock(block) ? /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "min-h-0 min-w-0 flex-1", children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(FillVisual, { block, labels }) }, i) : /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "shrink-0 overflow-hidden", children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(DeckMarkdown, { markdown: block.markdown }) }, i)
2458
+ )
2459
+ ] }) });
2460
+ }
2461
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(SlideFrame, { meta, children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "h-full px-24 py-12", children: /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(AutoFit, { children: [
2462
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("h3", { className: "mb-6 font-bold leading-tight text-foreground", style: { fontSize: 38 }, children: slide.title }),
2463
+ texts.map((block, i) => /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(DeckMarkdown, { markdown: block.markdown }, i))
2464
+ ] }) }) });
2465
+ }
2466
+ function AutoFit({ children }) {
2467
+ const boxRef = (0, import_react16.useRef)(null);
2468
+ const contentRef = (0, import_react16.useRef)(null);
2469
+ const [fit, setFit] = (0, import_react16.useState)({ scale: 1, height: 0 });
2470
+ (0, import_react16.useLayoutEffect)(() => {
2471
+ const boxEl = boxRef.current;
2472
+ const contentEl = contentRef.current;
2473
+ if (!boxEl || !contentEl) return;
2474
+ const measure = () => {
2475
+ const avail = boxEl.clientHeight;
2476
+ const natural = contentEl.offsetHeight;
2477
+ const scale = avail > 0 && natural > avail ? avail / natural : 1;
2478
+ setFit({ scale, height: natural * scale });
2479
+ };
2480
+ measure();
2481
+ const ro = new ResizeObserver(measure);
2482
+ ro.observe(boxEl);
2483
+ ro.observe(contentEl);
2484
+ return () => ro.disconnect();
2485
+ }, []);
2486
+ const scaled = fit.scale < 1;
2487
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { ref: boxRef, className: "flex h-full min-h-0 w-full flex-col justify-center overflow-hidden", children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { style: scaled ? { height: fit.height } : void 0, children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
2488
+ "div",
2489
+ {
2490
+ ref: contentRef,
2491
+ className: "w-full origin-top-left",
2492
+ style: scaled ? { transform: `scale(${fit.scale})` } : void 0,
2493
+ children
2494
+ }
2495
+ ) }) });
2496
+ }
2497
+ function FillVisual({ block, labels }) {
2498
+ const ref = (0, import_react16.useRef)(null);
2499
+ const [height, setHeight] = (0, import_react16.useState)(VISUAL_FALLBACK_HEIGHT);
2500
+ (0, import_react16.useLayoutEffect)(() => {
2501
+ const el = ref.current;
2502
+ if (!el) return;
2503
+ const apply = (h) => {
2504
+ if (h > 0) setHeight(h);
2505
+ };
2506
+ apply(el.clientHeight);
2507
+ const ro = new ResizeObserver((entries) => apply(entries[0]?.contentRect.height ?? 0));
2508
+ ro.observe(el);
2509
+ return () => ro.disconnect();
2510
+ }, []);
2511
+ const chartLabels = labels.chart ?? DEFAULT_CHART_ARTIFACT_LABELS;
2512
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { ref, className: "h-full min-h-0 w-full overflow-hidden", children: block.type === deckBlockTypes.CHART ? (
2513
+ // ChartArtifactContent assumes a non-empty rowset (the standalone ChartArtifact guards
2514
+ // `rows.length > 0` upstream); mirror that guard here so an empty inline chart shows the
2515
+ // localized empty status instead of a blank chart area.
2516
+ block.rows.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(StatusMessage, { $tone: "info", children: chartLabels.empty }) : /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { style: { height }, children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(ChartArtifactContent, { config: block.config, rows: block.rows, labels: chartLabels }) })
2517
+ ) : /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
2518
+ TableArtifactContent,
2519
+ {
2520
+ columns: block.config.columns,
2521
+ data: { status: "ready", rows: block.rows, error: null },
2522
+ knownRowCount: block.config.stats?.rowCount ?? block.rows.length,
2523
+ maxShimmerRows: TABLE_BLOCK_MAX_SHIMMER_ROWS,
2524
+ maxBodyHeight: Math.max(0, height - TABLE_CHROME_RESERVE),
2525
+ labels: labels.table ?? DEFAULT_TABLE_ARTIFACT_LABELS
2526
+ }
2527
+ ) });
2174
2528
  }
2175
2529
 
2176
2530
  // src/components/artifacts/table-artifact/validate.ts
@@ -2189,19 +2543,265 @@ function isValidTableColumn(column) {
2189
2543
  return true;
2190
2544
  }
2191
2545
 
2192
- // src/components/artifacts/table-artifact/table-artifact.tsx
2193
- var import_jsx_runtime22 = require("react/jsx-runtime");
2546
+ // src/components/artifacts/deck-artifact/validate.ts
2547
+ function isValidDeckConfig(config) {
2548
+ if (!config || typeof config !== "object") return false;
2549
+ const candidate = config;
2550
+ if (!Array.isArray(candidate.slides)) return false;
2551
+ if (candidate.slides.length === 0) return false;
2552
+ return candidate.slides.every(isValidDeckSlide);
2553
+ }
2554
+ function isValidDeckSlide(slide) {
2555
+ if (!slide || typeof slide !== "object") return false;
2556
+ const candidate = slide;
2557
+ if (typeof candidate.title !== "string") return false;
2558
+ const kind = typeof candidate.kind === "string" ? candidate.kind : deckSlideKinds.CONTENT;
2559
+ if (kind === deckSlideKinds.CONTENT && !Array.isArray(candidate.content)) return false;
2560
+ const content = Array.isArray(candidate.content) ? candidate.content : [];
2561
+ if (candidate.items != null) {
2562
+ if (!Array.isArray(candidate.items)) return false;
2563
+ if (!candidate.items.every((item) => typeof item === "string")) return false;
2564
+ }
2565
+ return content.every(isValidDeckBlock);
2566
+ }
2567
+ function isValidDeckBlock(block) {
2568
+ if (!block || typeof block !== "object") return false;
2569
+ const candidate = block;
2570
+ switch (candidate.type) {
2571
+ case deckBlockTypes.TEXT:
2572
+ return typeof candidate.markdown === "string";
2573
+ case deckBlockTypes.CHART:
2574
+ return isValidChartConfig(candidate.config) && Array.isArray(candidate.rows);
2575
+ case deckBlockTypes.TABLE:
2576
+ return isValidTableConfig(candidate.config) && Array.isArray(candidate.rows);
2577
+ default:
2578
+ return false;
2579
+ }
2580
+ }
2581
+
2582
+ // src/components/artifacts/deck-artifact/deck-artifact.tsx
2583
+ var import_jsx_runtime25 = require("react/jsx-runtime");
2194
2584
  var TITLE_CLASSES2 = "text-sm font-semibold text-foreground";
2585
+ function DeckArtifact({ artifact, labels, callbacks }) {
2586
+ const validConfig = isValidDeckConfig(artifact.config);
2587
+ const [isFullscreen, setIsFullscreen] = (0, import_react17.useState)(false);
2588
+ const [currentSlide, setCurrentSlide] = (0, import_react17.useState)(0);
2589
+ (0, import_react17.useEffect)(() => {
2590
+ if (validConfig) return;
2591
+ console.warn("[clay] DeckArtifact: malformed `config` \u2014 skipping render.");
2592
+ }, [validConfig]);
2593
+ (0, import_react17.useEffect)(() => {
2594
+ if (!isFullscreen) return;
2595
+ const handleKey = (e) => {
2596
+ if (e.key === "Escape") setIsFullscreen(false);
2597
+ };
2598
+ document.addEventListener("keydown", handleKey);
2599
+ const previousOverflow = document.documentElement.style.overflow;
2600
+ document.documentElement.style.overflow = "hidden";
2601
+ return () => {
2602
+ document.removeEventListener("keydown", handleKey);
2603
+ document.documentElement.style.overflow = previousOverflow;
2604
+ };
2605
+ }, [isFullscreen]);
2606
+ const resolvedLabels = (0, import_react17.useMemo)(
2607
+ () => ({
2608
+ ...DEFAULT_DECK_ARTIFACT_LABELS,
2609
+ ...labels ?? {},
2610
+ chart: { ...DEFAULT_CHART_ARTIFACT_LABELS, ...labels?.chart ?? {} },
2611
+ table: { ...DEFAULT_TABLE_ARTIFACT_LABELS, ...labels?.table ?? {} }
2612
+ }),
2613
+ [labels]
2614
+ );
2615
+ const onNavigate = callbacks?.onNavigate;
2616
+ const handleNavigate = onNavigate ? (slideIndex) => onNavigate(artifact, slideIndex) : void 0;
2617
+ const onDownload = callbacks?.onDownload;
2618
+ const handleDownload = onDownload ? () => onDownload(artifact) : void 0;
2619
+ const presignedUrl = artifact.protectedAsset?.presignedUrl ?? null;
2620
+ const showDownload = presignedUrl !== null && isSafeDownloadUrl(presignedUrl);
2621
+ const meta = artifact.config?.meta;
2622
+ const handleOpenFullscreen = () => setIsFullscreen(true);
2623
+ const handleCloseFullscreen = () => setIsFullscreen(false);
2624
+ const actions = /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(ArtifactActions, { ...{ [CAPTURE_EXCLUDE_ATTRIBUTE]: "" }, children: [
2625
+ showDownload ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(ArtifactDownloadButton, { href: presignedUrl ?? "", label: resolvedLabels.download, onClick: handleDownload }) : null,
2626
+ validConfig ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
2627
+ IconButton,
2628
+ {
2629
+ icon: IconArrowsMaximize,
2630
+ size: "small",
2631
+ "aria-label": resolvedLabels.enterFullscreen,
2632
+ onClick: handleOpenFullscreen
2633
+ }
2634
+ ) : null
2635
+ ] });
2636
+ if (!validConfig) {
2637
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(Artifact, { className: "shadow-none w-full rounded-2xl bg-background/70", children: [
2638
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(ArtifactHeader, { className: "bg-background/70", children: [
2639
+ artifact.title ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(ArtifactTitle, { className: TITLE_CLASSES2, children: artifact.title }) : /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", {}),
2640
+ actions
2641
+ ] }),
2642
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(ArtifactContent, { className: "p-0", children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(StatusMessage, { $tone: "info", children: resolvedLabels.unavailable }) })
2643
+ ] });
2644
+ }
2645
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(import_jsx_runtime25.Fragment, { children: [
2646
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(Artifact, { className: "shadow-none w-full rounded-2xl bg-background/70", children: [
2647
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(ArtifactHeader, { className: "bg-background/70", children: [
2648
+ artifact.title ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(ArtifactTitle, { className: TITLE_CLASSES2, children: artifact.title }) : /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", {}),
2649
+ actions
2650
+ ] }),
2651
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(ArtifactContent, { className: "p-0", children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
2652
+ DeckArtifactContent,
2653
+ {
2654
+ slides: artifact.config.slides,
2655
+ labels: resolvedLabels,
2656
+ onNavigate: handleNavigate,
2657
+ meta,
2658
+ currentSlide,
2659
+ onSlideChange: setCurrentSlide
2660
+ }
2661
+ ) })
2662
+ ] }),
2663
+ isFullscreen && (0, import_react_dom.createPortal)(
2664
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
2665
+ FullscreenOverlay,
2666
+ {
2667
+ artifact,
2668
+ resolvedLabels,
2669
+ onNavigate: handleNavigate,
2670
+ currentSlide,
2671
+ onSlideChange: setCurrentSlide,
2672
+ onClose: handleCloseFullscreen
2673
+ }
2674
+ ),
2675
+ document.body
2676
+ )
2677
+ ] });
2678
+ }
2679
+ function FullscreenOverlay({
2680
+ artifact,
2681
+ resolvedLabels,
2682
+ onNavigate,
2683
+ currentSlide,
2684
+ onSlideChange,
2685
+ onClose
2686
+ }) {
2687
+ const meta = artifact.config?.meta;
2688
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
2689
+ "div",
2690
+ {
2691
+ className: "fixed inset-0 z-[2147483647] flex items-center justify-center bg-black/80",
2692
+ role: "dialog",
2693
+ "aria-modal": "true",
2694
+ "aria-label": resolvedLabels.exitFullscreen,
2695
+ children: /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "relative", style: { width: "min(94vw, calc(82vh * 16 / 9))" }, children: [
2696
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
2697
+ DeckArtifactContent,
2698
+ {
2699
+ slides: artifact.config.slides,
2700
+ labels: resolvedLabels,
2701
+ onNavigate,
2702
+ meta,
2703
+ currentSlide,
2704
+ onSlideChange,
2705
+ onDark: true
2706
+ }
2707
+ ),
2708
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(
2709
+ "button",
2710
+ {
2711
+ className: "absolute -top-10 right-6 flex items-center gap-1.5 text-sm text-white/80 hover:text-white",
2712
+ "aria-label": resolvedLabels.exitFullscreen,
2713
+ onClick: onClose,
2714
+ children: [
2715
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(IconArrowsMinimize, { size: 16 }),
2716
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { children: resolvedLabels.exitFullscreen })
2717
+ ]
2718
+ }
2719
+ )
2720
+ ] })
2721
+ }
2722
+ );
2723
+ }
2724
+
2725
+ // src/components/artifacts/deck-artifact/to-clipboard-text.ts
2726
+ function deckArtifactToClipboardText(artifact) {
2727
+ const header = artifact.title?.trim() || "Deck";
2728
+ const slides = artifact.config?.slides ?? [];
2729
+ const body = slides.map((slide, i) => slideToText(slide, i)).join("\n\n");
2730
+ return body ? `${header}
2731
+
2732
+ ${body}` : header;
2733
+ }
2734
+ function slideToText(slide, index) {
2735
+ const kind = slide.kind ?? deckSlideKinds.CONTENT;
2736
+ const prefix = `Slide ${index + 1}: `;
2737
+ switch (kind) {
2738
+ case deckSlideKinds.TITLE: {
2739
+ const parts = [slide.title];
2740
+ if (slide.subtitle) parts.push(slide.subtitle);
2741
+ if (slide.description) parts.push(slide.description);
2742
+ return `${prefix}${parts.join(" \u2014 ")}`.trim();
2743
+ }
2744
+ case deckSlideKinds.AGENDA: {
2745
+ const items = (slide.items ?? []).map((item, i) => ` ${String(i + 1).padStart(2, "0")}. ${item}`).join("\n");
2746
+ return `${prefix}${slide.title || "Agenda"}${items ? `
2747
+ ${items}` : ""}`.trim();
2748
+ }
2749
+ case deckSlideKinds.SECTION:
2750
+ return `${prefix}${slide.title}`.trim();
2751
+ case deckSlideKinds.CLOSING:
2752
+ return `${prefix}Thank you`.trim();
2753
+ case deckSlideKinds.CONTENT:
2754
+ default: {
2755
+ const blocks = (slide.content ?? []).map(blockToText).filter(Boolean).join("\n\n");
2756
+ return `${prefix}${slide.title}${blocks ? `
2757
+ ${blocks}` : ""}`.trim();
2758
+ }
2759
+ }
2760
+ }
2761
+ function blockToText(block) {
2762
+ switch (block.type) {
2763
+ case deckBlockTypes.TEXT:
2764
+ return block.markdown.trim();
2765
+ case deckBlockTypes.CHART:
2766
+ return `[Chart: ${block.config.variant}]`;
2767
+ case deckBlockTypes.TABLE: {
2768
+ const columnCount = block.config.columns.length;
2769
+ const rowCount = block.rows.length;
2770
+ return `[Table: ${columnCount} column${columnCount === 1 ? "" : "s"} \xD7 ${rowCount} row${rowCount === 1 ? "" : "s"}]`;
2771
+ }
2772
+ default:
2773
+ return "";
2774
+ }
2775
+ }
2776
+
2777
+ // src/components/artifacts/artifact-services/deck-artifact-service.ts
2778
+ var DeckArtifactService = {
2779
+ type: artifactTypes.DECK,
2780
+ Component: DeckArtifact,
2781
+ toClipboardText: deckArtifactToClipboardText
2782
+ };
2783
+
2784
+ // src/components/artifacts/table-artifact/table-artifact.tsx
2785
+ var import_react18 = require("react");
2786
+
2787
+ // src/components/artifacts/table-artifact/use-table-artifact-data.ts
2788
+ function useTableArtifactData(presignedUrl, columns) {
2789
+ return useRowsArtifactData(presignedUrl, columns, parseCsv);
2790
+ }
2791
+
2792
+ // src/components/artifacts/table-artifact/table-artifact.tsx
2793
+ var import_jsx_runtime26 = require("react/jsx-runtime");
2794
+ var TITLE_CLASSES3 = "text-sm font-semibold text-foreground";
2195
2795
  var TABLE_MAX_BODY_HEIGHT = 480;
2196
2796
  var MAX_SHIMMER_ROWS = 10;
2197
2797
  function TableArtifact({ artifact, labels, callbacks }) {
2198
2798
  const validConfig = isValidTableConfig(artifact.config);
2199
2799
  const validColumns = validConfig ? artifact.config.columns : null;
2200
- (0, import_react15.useEffect)(() => {
2800
+ (0, import_react18.useEffect)(() => {
2201
2801
  if (validConfig) return;
2202
2802
  console.warn("[clay] TableArtifact: malformed `config` \u2014 skipping render.");
2203
2803
  }, [validConfig]);
2204
- const resolvedLabels = (0, import_react15.useMemo)(
2804
+ const resolvedLabels = (0, import_react18.useMemo)(
2205
2805
  () => ({ ...DEFAULT_TABLE_ARTIFACT_LABELS, ...labels ?? {} }),
2206
2806
  [labels]
2207
2807
  );
@@ -2213,10 +2813,10 @@ function TableArtifact({ artifact, labels, callbacks }) {
2213
2813
  const onDownload = callbacks?.onDownload;
2214
2814
  const handleDownloadClick = onDownload ? () => onDownload(artifact) : void 0;
2215
2815
  if (!validConfig || !validColumns) {
2216
- return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(Artifact, { className: "shadow-none w-full rounded-2xl bg-background/70", children: [
2217
- /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(ArtifactHeader, { className: "bg-background/70", children: [
2218
- artifact.title ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(ArtifactTitle, { className: TITLE_CLASSES2, children: artifact.title }) : /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", {}),
2219
- presignedUrl ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(ArtifactActions, { children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
2816
+ return /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(Artifact, { className: "shadow-none w-full rounded-2xl bg-background/70", children: [
2817
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(ArtifactHeader, { className: "bg-background/70", children: [
2818
+ artifact.title ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(ArtifactTitle, { className: TITLE_CLASSES3, children: artifact.title }) : /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", {}),
2819
+ presignedUrl ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(ArtifactActions, { children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
2220
2820
  ArtifactDownloadButton,
2221
2821
  {
2222
2822
  href: presignedUrl,
@@ -2225,17 +2825,17 @@ function TableArtifact({ artifact, labels, callbacks }) {
2225
2825
  }
2226
2826
  ) }) : null
2227
2827
  ] }),
2228
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(ArtifactContent, { className: "p-0 overflow-auto", style: { maxHeight: TABLE_MAX_BODY_HEIGHT }, children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(StatusMessage, { $tone: "info", children: resolvedLabels.unavailable }) })
2828
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(ArtifactContent, { className: "p-0 overflow-auto", style: { maxHeight: TABLE_MAX_BODY_HEIGHT }, children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(StatusMessage, { $tone: "info", children: resolvedLabels.unavailable }) })
2229
2829
  ] });
2230
2830
  }
2231
2831
  return (
2232
2832
  // The table body owns its own scroll container (`ArtifactTable` inside `TableArtifactContent`).
2233
2833
  // Disable the outer overflow container so only one scroll context exists — this prevents
2234
2834
  // double-scroll nesting and lets `useScrollShadow` find the correct scroll ancestor.
2235
- /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(Artifact, { className: "shadow-none w-full rounded-2xl bg-background/70", children: [
2236
- /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(ArtifactHeader, { className: "bg-background/70", children: [
2237
- artifact.title ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(ArtifactTitle, { className: TITLE_CLASSES2, children: artifact.title }) : /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", {}),
2238
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(ArtifactActions, { children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
2835
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(Artifact, { className: "shadow-none w-full rounded-2xl bg-background/70", children: [
2836
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(ArtifactHeader, { className: "bg-background/70", children: [
2837
+ artifact.title ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(ArtifactTitle, { className: TITLE_CLASSES3, children: artifact.title }) : /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", {}),
2838
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(ArtifactActions, { children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
2239
2839
  ArtifactDownloadButton,
2240
2840
  {
2241
2841
  href: presignedUrl ?? "",
@@ -2244,7 +2844,7 @@ function TableArtifact({ artifact, labels, callbacks }) {
2244
2844
  }
2245
2845
  ) })
2246
2846
  ] }),
2247
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(ArtifactContent, { className: "p-0 overflow-visible", style: { maxHeight: "none" }, children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
2847
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(ArtifactContent, { className: "p-0 overflow-visible", style: { maxHeight: "none" }, children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
2248
2848
  TableArtifactContent,
2249
2849
  {
2250
2850
  columns: validColumns,
@@ -2275,7 +2875,8 @@ var TableArtifactService = {
2275
2875
  // src/components/artifacts/artifact-services/index.ts
2276
2876
  var ArtifactServices = {
2277
2877
  [artifactTypes.TABLE]: TableArtifactService,
2278
- [artifactTypes.CHART]: ChartArtifactService
2878
+ [artifactTypes.CHART]: ChartArtifactService,
2879
+ [artifactTypes.DECK]: DeckArtifactService
2279
2880
  };
2280
2881
  function artifactToClipboardText(artifact) {
2281
2882
  const entry = ArtifactServices[artifact.type];
@@ -2286,13 +2887,13 @@ function artifactToClipboardText(artifact) {
2286
2887
  }
2287
2888
 
2288
2889
  // src/components/blocks/artifact-ref-block/artifact-ref-block.tsx
2289
- var import_jsx_runtime23 = require("react/jsx-runtime");
2890
+ var import_jsx_runtime27 = require("react/jsx-runtime");
2290
2891
  function ArtifactRefBlock({ block }) {
2291
2892
  const { artifact, labels, callbacks } = block.payload;
2292
2893
  const entry = ArtifactServices[artifact.type];
2293
2894
  if (!entry) return null;
2294
2895
  const Component = entry.Component;
2295
- return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(Component, { artifact, labels, callbacks });
2896
+ return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(Component, { artifact, labels, callbacks });
2296
2897
  }
2297
2898
 
2298
2899
  // src/components/blocks/block-services/artifact-ref-block-service.ts
@@ -2327,9 +2928,9 @@ function markdownToPlainText(markdown) {
2327
2928
  }
2328
2929
 
2329
2930
  // src/components/blocks/text-block/text-block.tsx
2330
- var import_react_markdown = __toESM(require("react-markdown"), 1);
2331
- var import_remark_breaks = __toESM(require("remark-breaks"), 1);
2332
- var import_remark_gfm = __toESM(require("remark-gfm"), 1);
2931
+ var import_react_markdown2 = __toESM(require("react-markdown"), 1);
2932
+ var import_remark_breaks2 = __toESM(require("remark-breaks"), 1);
2933
+ var import_remark_gfm2 = __toESM(require("remark-gfm"), 1);
2333
2934
 
2334
2935
  // src/components/blocks/scrollable-table/scrollable-table-styles.ts
2335
2936
  var import_styled_components3 = __toESM(require("styled-components"), 1);
@@ -2344,13 +2945,13 @@ var TableScroll = import_styled_components3.default.div`
2344
2945
  `;
2345
2946
 
2346
2947
  // src/components/blocks/scrollable-table/scrollable-table.tsx
2347
- var import_jsx_runtime24 = require("react/jsx-runtime");
2948
+ var import_jsx_runtime28 = require("react/jsx-runtime");
2348
2949
  function ScrollableTable({ node: _node, ...props }) {
2349
- return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(TableContainer, { children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(TableScroll, { children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("table", { ...props }) }) });
2950
+ return /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(TableContainer, { children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(TableScroll, { children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("table", { ...props }) }) });
2350
2951
  }
2351
2952
 
2352
2953
  // src/components/blocks/text-block/sanitize.ts
2353
- function sanitize(text) {
2954
+ function sanitize2(text) {
2354
2955
  return text.split("\n").filter((line) => {
2355
2956
  const t = line.trim();
2356
2957
  return !(t.startsWith("<!-- table-title:") && t.endsWith("-->"));
@@ -2490,12 +3091,12 @@ var TextBlockWrapper = import_styled_components4.default.div`
2490
3091
  `;
2491
3092
 
2492
3093
  // src/components/blocks/text-block/text-block.tsx
2493
- var import_jsx_runtime25 = require("react/jsx-runtime");
3094
+ var import_jsx_runtime29 = require("react/jsx-runtime");
2494
3095
  var markdownComponents = {
2495
- table: ((tableProps) => /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(ScrollableTable, { ...tableProps }))
3096
+ table: ((tableProps) => /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(ScrollableTable, { ...tableProps }))
2496
3097
  };
2497
3098
  function TextBlock({ block }) {
2498
- return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(TextBlockWrapper, { children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_react_markdown.default, { remarkPlugins: [import_remark_gfm.default, import_remark_breaks.default], components: markdownComponents, children: sanitize(block.payload.text) }) });
3099
+ return /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(TextBlockWrapper, { children: /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(import_react_markdown2.default, { remarkPlugins: [import_remark_gfm2.default, import_remark_breaks2.default], components: markdownComponents, children: sanitize2(block.payload.text) }) });
2499
3100
  }
2500
3101
 
2501
3102
  // src/components/blocks/block-services/text-block-service.ts
@@ -2517,19 +3118,19 @@ var BlockServices = {
2517
3118
  };
2518
3119
 
2519
3120
  // src/components/blocks/block/block.tsx
2520
- var import_jsx_runtime26 = require("react/jsx-runtime");
3121
+ var import_jsx_runtime30 = require("react/jsx-runtime");
2521
3122
  function Block({ block }) {
2522
3123
  const service = BlockServices[block.type];
2523
3124
  if (!service) return null;
2524
3125
  const { Component } = service;
2525
- return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(Component, { block });
3126
+ return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(Component, { block });
2526
3127
  }
2527
3128
 
2528
3129
  // src/components/blocks/block-context/block-context.tsx
2529
- var import_react16 = require("react");
2530
- var BlockContext = (0, import_react16.createContext)(null);
3130
+ var import_react19 = require("react");
3131
+ var BlockContext = (0, import_react19.createContext)(null);
2531
3132
  function useBlockContext() {
2532
- return (0, import_react16.useContext)(BlockContext) ?? {};
3133
+ return (0, import_react19.useContext)(BlockContext) ?? {};
2533
3134
  }
2534
3135
  // Annotate the CommonJS export names for ESM import in node:
2535
3136
  0 && (module.exports = {
@@ -2547,7 +3148,11 @@ function useBlockContext() {
2547
3148
  @tabler/icons-react/dist/esm/defaultAttributes.mjs:
2548
3149
  @tabler/icons-react/dist/esm/createReactComponent.mjs:
2549
3150
  @tabler/icons-react/dist/esm/icons/IconAlertCircle.mjs:
3151
+ @tabler/icons-react/dist/esm/icons/IconArrowsMaximize.mjs:
3152
+ @tabler/icons-react/dist/esm/icons/IconArrowsMinimize.mjs:
2550
3153
  @tabler/icons-react/dist/esm/icons/IconCheck.mjs:
3154
+ @tabler/icons-react/dist/esm/icons/IconChevronLeft.mjs:
3155
+ @tabler/icons-react/dist/esm/icons/IconChevronRight.mjs:
2551
3156
  @tabler/icons-react/dist/esm/icons/IconCopy.mjs:
2552
3157
  @tabler/icons-react/dist/esm/icons/IconDownload.mjs:
2553
3158
  @tabler/icons-react/dist/esm/icons/IconFileSpreadsheet.mjs: