@opengeni/react 5.0.5-canary.3 → 5.2.0-canary.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 (81) hide show
  1. package/README.md +13 -1
  2. package/dist/artifacts.d.ts +2 -0
  3. package/dist/artifacts.js +1391 -2
  4. package/dist/artifacts.js.map +1 -1
  5. package/dist/chunk-2TKI3WEG.js +73 -0
  6. package/dist/chunk-2TKI3WEG.js.map +1 -0
  7. package/dist/{chunk-V3WX3TQG.js → chunk-45XEUVTK.js} +2 -2
  8. package/dist/{chunk-M2HNWZYR.js → chunk-IHQII5WO.js} +69 -18
  9. package/dist/chunk-IHQII5WO.js.map +1 -0
  10. package/dist/{chunk-HUMIRRYI.js → chunk-IYCR4343.js} +19 -19
  11. package/dist/{chunk-HUMIRRYI.js.map → chunk-IYCR4343.js.map} +1 -1
  12. package/dist/{chunk-6J56T3MG.js → chunk-NYESIADM.js} +14 -5
  13. package/dist/chunk-NYESIADM.js.map +1 -0
  14. package/dist/{chunk-7S2KWUJD.js → chunk-QXJCNVSD.js} +2283 -2215
  15. package/dist/chunk-QXJCNVSD.js.map +1 -0
  16. package/dist/{chunk-BV5A4OTE.js → chunk-T5FRXMC3.js} +21 -2
  17. package/dist/{chunk-BV5A4OTE.js.map → chunk-T5FRXMC3.js.map} +1 -1
  18. package/dist/{chunk-BRFMGY4L.js → chunk-UGMKPUEM.js} +28 -3
  19. package/dist/chunk-UGMKPUEM.js.map +1 -0
  20. package/dist/components/artifacts/inline-html-document.d.ts +2 -0
  21. package/dist/components/artifacts/published-html-artifact-frame.d.ts +2 -0
  22. package/dist/components/artifacts/visualization-assets.gen.d.ts +2 -0
  23. package/dist/components/markdown.d.ts +13 -1
  24. package/dist/components/message-timeline.d.ts +4 -1
  25. package/dist/components/session-conversation.d.ts +3 -0
  26. package/dist/components/user-message-body.d.ts +10 -1
  27. package/dist/composer.js +2 -2
  28. package/dist/{computer-viewer-7TEZC6Y2.js → computer-viewer-AA4JH2AP.js} +2 -2
  29. package/dist/connect.js +1 -1
  30. package/dist/index.d.ts +3 -2
  31. package/dist/index.js +9 -6
  32. package/dist/index.js.map +1 -1
  33. package/dist/interaction.js +1 -1
  34. package/dist/{platform-activity-row-27LKAWZD.js → platform-activity-row-UW4UVVM4.js} +6 -3
  35. package/dist/platform-activity-row-UW4UVVM4.js.map +1 -0
  36. package/dist/session-ui.d.ts +1 -1
  37. package/dist/session-ui.js +6 -5
  38. package/dist/session-ui.js.map +1 -1
  39. package/dist/session.js +2 -2
  40. package/dist/sites-ui.d.ts +2 -1
  41. package/dist/sites.js +12 -4
  42. package/dist/sites.js.map +1 -1
  43. package/dist/timeline/activity-rail.d.ts +1 -0
  44. package/dist/timeline/platform-activity-row.d.ts +1 -1
  45. package/dist/timeline/retained-image.d.ts +16 -0
  46. package/dist/timeline/rolling-activity.d.ts +9 -0
  47. package/dist/timeline/shared.d.ts +4 -1
  48. package/dist/timeline/turn-summary.d.ts +4 -1
  49. package/package.json +4 -4
  50. package/src/artifacts.ts +2 -0
  51. package/src/components/artifacts/inline-html-document.ts +24 -0
  52. package/src/components/artifacts/published-html-artifact-frame.tsx +32 -2
  53. package/src/components/artifacts/visualization-assets/base.css +1015 -0
  54. package/src/components/artifacts/visualization-assets/helpers.html +349 -0
  55. package/src/components/artifacts/visualization-assets.gen.ts +3 -0
  56. package/src/components/copy-button.tsx +7 -2
  57. package/src/components/markdown.tsx +111 -34
  58. package/src/components/message-timeline.tsx +61 -4
  59. package/src/components/session-conversation.tsx +5 -0
  60. package/src/components/user-message-body.tsx +20 -2
  61. package/src/hooks/use-composer.ts +15 -2
  62. package/src/hooks/use-computer-session.ts +36 -1
  63. package/src/index.ts +10 -2
  64. package/src/session-ui.ts +4 -1
  65. package/src/sites-ui.tsx +23 -6
  66. package/src/timeline/activity-rail.tsx +20 -3
  67. package/src/timeline/platform-activity-row.tsx +5 -2
  68. package/src/timeline/retained-image.ts +91 -0
  69. package/src/timeline/rolling-activity.tsx +83 -0
  70. package/src/timeline/shared.tsx +33 -12
  71. package/src/timeline/tool-renderers.tsx +7 -91
  72. package/src/timeline/turn-summary.tsx +21 -15
  73. package/styles/compiled.css +122 -0
  74. package/styles/index.css +49 -0
  75. package/dist/chunk-6J56T3MG.js.map +0 -1
  76. package/dist/chunk-7S2KWUJD.js.map +0 -1
  77. package/dist/chunk-BRFMGY4L.js.map +0 -1
  78. package/dist/chunk-M2HNWZYR.js.map +0 -1
  79. package/dist/platform-activity-row-27LKAWZD.js.map +0 -1
  80. /package/dist/{chunk-V3WX3TQG.js.map → chunk-45XEUVTK.js.map} +0 -0
  81. /package/dist/{computer-viewer-7TEZC6Y2.js.map → computer-viewer-AA4JH2AP.js.map} +0 -0
package/dist/artifacts.js CHANGED
@@ -17,7 +17,10 @@ import {
17
17
  PublishedHtmlArtifactFrame,
18
18
  openGeniSiteBridgePortFromBootstrap,
19
19
  publishedHtmlArtifactDocument
20
- } from "./chunk-BRFMGY4L.js";
20
+ } from "./chunk-UGMKPUEM.js";
21
+ import {
22
+ useRetainedImageObjectUrl
23
+ } from "./chunk-2TKI3WEG.js";
21
24
  import {
22
25
  EditableSpreadsheetArtifactSurface,
23
26
  EditableSpreadsheetGrid,
@@ -31,6 +34,1390 @@ import {
31
34
  } from "./chunk-KCGXPP5V.js";
32
35
  import "./chunk-22KP6LR5.js";
33
36
 
37
+ // src/components/artifacts/visualization-assets.gen.ts
38
+ var VISUALIZATION_CSS = `/* Adapted from Codex visualize 1.0.32; shared with the OpenGeni visualization skill. */
39
+ :root {
40
+ color-scheme: light dark;
41
+ background-color: var(
42
+ --background,
43
+ var(--color-background-primary, light-dark(rgb(255 255 255), rgb(24 24 24)))
44
+ ) !important;
45
+
46
+ /* Agent-facing contract; keep in sync with SKILL.md. */
47
+ --background: var(
48
+ --color-background-primary,
49
+ light-dark(rgb(255 255 255), rgb(24 24 24))
50
+ );
51
+ --foreground: var(
52
+ --color-text-primary,
53
+ light-dark(rgb(26 28 31), rgb(255 255 255))
54
+ );
55
+ --card: color-mix(in oklab, var(--foreground) 5%, var(--background));
56
+ --card-foreground: var(
57
+ --color-text-primary,
58
+ light-dark(rgb(26 28 31), rgb(255 255 255))
59
+ );
60
+ --popover: var(
61
+ --color-background-secondary,
62
+ light-dark(rgb(255 255 255), rgb(45 45 45))
63
+ );
64
+ --popover-foreground: var(
65
+ --color-text-primary,
66
+ light-dark(rgb(26 28 31), rgb(255 255 255))
67
+ );
68
+ --primary: var(
69
+ --color-text-info,
70
+ light-dark(rgb(51 156 255), rgb(131 195 255))
71
+ );
72
+ --primary-foreground: var(
73
+ --color-text-inverse,
74
+ light-dark(rgb(255 255 255), rgb(13 13 13))
75
+ );
76
+ --secondary: var(
77
+ --color-background-secondary,
78
+ light-dark(rgb(255 255 255 / 96%), rgb(54 54 54 / 96%))
79
+ );
80
+ --secondary-foreground: var(
81
+ --color-text-primary,
82
+ light-dark(rgb(26 28 31), rgb(255 255 255))
83
+ );
84
+ --muted: color-mix(in srgb, var(--foreground) 10%, transparent);
85
+ --muted-foreground: var(
86
+ --color-text-secondary,
87
+ light-dark(rgb(26 28 31 / 49.4%), rgb(255 255 255 / 49.8%))
88
+ );
89
+ --accent: var(
90
+ --color-background-info,
91
+ light-dark(rgb(229 242 255), rgb(13 39 63))
92
+ );
93
+ --accent-foreground: var(
94
+ --color-text-info,
95
+ light-dark(rgb(51 156 255), rgb(131 195 255))
96
+ );
97
+ --destructive: var(
98
+ --color-text-warning,
99
+ light-dark(rgb(226 85 7), rgb(255 133 73))
100
+ );
101
+ --border: var(
102
+ --color-border-secondary,
103
+ light-dark(rgb(26 28 31 / 8%), rgb(255 255 255 / 8.2%))
104
+ );
105
+ --input: var(
106
+ --color-border-primary,
107
+ light-dark(
108
+ rgb(26 28 31 / 11.8%),
109
+ color-mix(in oklab, rgb(0 0 0) 10%, transparent)
110
+ )
111
+ );
112
+ --ring: var(
113
+ --color-ring-primary,
114
+ light-dark(rgb(51 156 255), rgb(131 195 255 / 76%))
115
+ );
116
+ --font-size-base: var(--font-text-md-size, 14px);
117
+ --blue: light-dark(rgb(51 156 255), rgb(51 156 255));
118
+ --orange: light-dark(rgb(226 85 7), rgb(251 106 34));
119
+ --green: light-dark(rgb(0 162 64), rgb(64 201 119));
120
+ --red: light-dark(rgb(224 46 42), rgb(255 103 100));
121
+ --purple: light-dark(rgb(146 79 247), rgb(173 123 249));
122
+ --yellow: light-dark(rgb(255 195 0), rgb(255 210 64));
123
+ --viz-series-1: var(--primary);
124
+ --viz-series-2: light-dark(rgb(243 136 59), rgb(245 154 86));
125
+ --viz-series-3: light-dark(rgb(93 201 119), rgb(116 213 139));
126
+ --viz-series-4: light-dark(rgb(235 119 177), rgb(240 143 192));
127
+ --viz-series-5: light-dark(rgb(155 121 236), rgb(170 145 239));
128
+ --viz-series-6: light-dark(rgb(58 185 177), rgb(90 203 194));
129
+
130
+ /* Internal implementation variables; not part of the agent contract. */
131
+ --font-sans: -apple-system, system-ui, "Segoe UI", sans-serif;
132
+ --font-mono:
133
+ ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono",
134
+ monospace;
135
+ --font-size-normal: max(11px, var(--font-size-base));
136
+ --font-size-tooltip: calc(var(--font-size-base) - 1px);
137
+ --font-size-small: max(11px, calc(var(--font-size-base) - 2px));
138
+ --font-size-h1: calc(var(--font-size-normal) * 1.7142857143);
139
+ --font-size-h2: calc(var(--font-size-normal) * 1.4285714286);
140
+ --font-size-h3: calc(var(--font-size-normal) * 1.2857142857);
141
+ --font-weight-normal: 430;
142
+ --font-weight-medium: 500;
143
+ --icon-size: 16px;
144
+ --line-height-normal: calc(var(--font-size-normal) * 1.5);
145
+ --line-height-tooltip: calc(var(--font-size-tooltip) * 1.4285714286);
146
+ --line-height-small: calc(var(--font-size-small) + 4px);
147
+ --corner-shape: round;
148
+ --radius: var(--border-radius-lg, 10px);
149
+ --radius-sm: calc(var(--radius) * 0.6);
150
+ --radius-md: calc(var(--radius) * 0.8);
151
+ --radius-lg: var(--radius);
152
+ --radius-2xl: calc(var(--radius) * 1.6);
153
+ --radius-full: 9999px;
154
+ --shadow-sm: 0 1px 2px -1px rgb(0 0 0 / 8%);
155
+ --checkmark-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 17 17'%3E%3Cpath d='M 12.8961 3.64101C13.1297 3.41418 13.4984 3.37523 13.7779 3.56581C14.0571 3.75635 14.1554 4.11331 14.0299 4.41347L13.9615 4.53847L7.71151 13.7045C7.59411 13.8767 7.4063 13.9877 7.19881 14.0072C6.99136 14.0267 6.78564 13.9533 6.63826 13.806L2.88826 10.056L2.79842 9.9457C2.6192 9.67407 2.64927 9.30496 2.88826 9.06581C3.12738 8.82669 3.49647 8.79676 3.76815 8.97597L3.8785 9.06581L7.03084 12.2182L12.8053 3.74941L12.8961 3.64101Z'/%3E%3C/svg%3E");
156
+
157
+ /* Legacy aliases; not part of the current agent contract. */
158
+ --viz-bg: transparent;
159
+ --viz-panel: var(--card);
160
+ --viz-border: var(--border);
161
+ --viz-text: var(--foreground);
162
+ --viz-muted: var(--muted-foreground);
163
+ --viz-accent: var(--primary);
164
+ --viz-accent-text: var(--primary-foreground);
165
+ --viz-accent-bg: var(--accent);
166
+ --viz-font-size: var(--font-size-base);
167
+ --viz-warning: var(--destructive);
168
+ }
169
+
170
+ :root[data-theme="light"] {
171
+ color-scheme: light;
172
+ }
173
+
174
+ :root[data-theme="dark"] {
175
+ color-scheme: dark;
176
+ }
177
+
178
+ * {
179
+ box-sizing: border-box;
180
+ }
181
+
182
+ html > body {
183
+ /* Preserve MCP aliases for older inline renderers without creating :root cycles. */
184
+ --color-background-primary: var(
185
+ --background,
186
+ light-dark(rgb(255 255 255), rgb(24 24 24))
187
+ );
188
+ --color-text-primary: var(
189
+ --foreground,
190
+ light-dark(rgb(26 28 31), rgb(255 255 255))
191
+ );
192
+ --color-border-secondary: var(
193
+ --border,
194
+ light-dark(rgb(26 28 31 / 8%), rgb(255 255 255 / 8.2%))
195
+ );
196
+
197
+ margin: 0;
198
+ padding: var(--visualize-paint-gutter, 16px);
199
+ color: var(--foreground);
200
+ background: transparent !important;
201
+ font-family: var(--font-sans) !important;
202
+ font-size: var(--font-size-normal);
203
+ font-weight: var(--font-weight-normal);
204
+ line-height: var(--line-height-normal);
205
+ }
206
+
207
+ a {
208
+ color: color-mix(in srgb, var(--viz-accent) 80%, var(--viz-text) 20%);
209
+ cursor: pointer;
210
+ font-weight: var(--font-weight-medium, 500);
211
+ text-decoration: none;
212
+ text-underline-offset: 2px;
213
+ }
214
+
215
+ a:is(:hover, :focus-visible) {
216
+ text-decoration-line: underline;
217
+ text-decoration-style: dashed;
218
+ text-decoration-thickness: 0.5px;
219
+ }
220
+
221
+ h1,
222
+ h2,
223
+ h3,
224
+ h4,
225
+ h5,
226
+ h6,
227
+ p {
228
+ margin-block: 0;
229
+ }
230
+
231
+ h1 {
232
+ font-size: var(--font-size-h1);
233
+ font-weight: var(--font-weight-medium);
234
+ line-height: 1.25;
235
+ }
236
+
237
+ h2 {
238
+ font-size: var(--font-size-h2);
239
+ font-weight: var(--font-weight-medium);
240
+ line-height: 1.25;
241
+ }
242
+
243
+ h3,
244
+ h4,
245
+ h5,
246
+ h6 {
247
+ font-size: var(--font-size-h3);
248
+ font-weight: var(--font-weight-medium);
249
+ line-height: 1.3;
250
+ }
251
+
252
+ b,
253
+ strong,
254
+ th {
255
+ font-weight: var(--font-weight-medium);
256
+ }
257
+
258
+ code:not(pre code) {
259
+ display: inline;
260
+ padding: 1px 6px;
261
+ border-radius: var(--radius-sm);
262
+ corner-shape: var(--corner-shape);
263
+ background: var(--muted);
264
+ font-family: var(--font-mono);
265
+ font-size: 0.92em;
266
+ overflow-wrap: anywhere;
267
+ -webkit-box-decoration-break: clone;
268
+ box-decoration-break: clone;
269
+ word-break: break-word;
270
+ }
271
+
272
+ .table-responsive {
273
+ width: 100%;
274
+ overflow-x: auto;
275
+ scrollbar-width: thin;
276
+ }
277
+
278
+ .table {
279
+ width: 100%;
280
+ border-collapse: collapse;
281
+ color: var(--foreground);
282
+ font: inherit;
283
+ text-align: start;
284
+ }
285
+
286
+ .table :is(th, td) {
287
+ padding-block: 10px;
288
+ padding-inline: 0 24px;
289
+ overflow-wrap: anywhere;
290
+ border-bottom: 1px solid var(--border);
291
+ text-align: start;
292
+ vertical-align: top;
293
+ }
294
+
295
+ .table-responsive > .table :is(th, td) {
296
+ overflow-wrap: break-word;
297
+ }
298
+
299
+ .table :is(th, td):last-child {
300
+ padding-inline-end: 0;
301
+ }
302
+
303
+ .table :is(caption, thead th) {
304
+ font-weight: 600;
305
+ }
306
+
307
+ .table thead th {
308
+ padding-block: 8px;
309
+ border-bottom-color: color-mix(in srgb, var(--foreground) 16%, transparent);
310
+ }
311
+
312
+ .table tbody tr:last-child :is(th, td) {
313
+ border-bottom: 0;
314
+ }
315
+
316
+ .table.table-sm :is(th, td) {
317
+ padding-block: 6px;
318
+ }
319
+
320
+ .table.table-sm :is(th, td):not(:last-child) {
321
+ padding-inline-end: 16px;
322
+ }
323
+
324
+ .table :is(.text-end, [align="right"]) {
325
+ text-align: end;
326
+ font-variant-numeric: tabular-nums;
327
+ }
328
+
329
+ .table :is(.text-center, [align="center"]) {
330
+ text-align: center;
331
+ }
332
+
333
+ .table .text-nowrap {
334
+ white-space: nowrap;
335
+ }
336
+
337
+ #widget {
338
+ display: flex;
339
+ flex-direction: column;
340
+ gap: 12px;
341
+ width: 100%;
342
+ padding: 0;
343
+ background: transparent !important;
344
+ }
345
+
346
+ .card {
347
+ min-width: 0;
348
+ padding: 12px;
349
+ overflow: hidden;
350
+ overflow-wrap: break-word;
351
+ border-radius: var(--radius-2xl);
352
+ corner-shape: var(--corner-shape);
353
+ color: var(--card-foreground);
354
+ background: var(--card);
355
+ }
356
+
357
+ #widget > :not(.card, .progress) {
358
+ width: 100% !important;
359
+ max-width: none !important;
360
+ margin: 0 !important;
361
+ padding: 0 !important;
362
+ border: 0 !important;
363
+ border-radius: 0 !important;
364
+ background: transparent !important;
365
+ box-shadow: none !important;
366
+ }
367
+
368
+ .tooltip {
369
+ position: fixed;
370
+ z-index: 50;
371
+ top: 0;
372
+ left: 0;
373
+ width: max-content;
374
+ max-width: min(
375
+ 20rem,
376
+ var(--tooltip-available-width, calc(100vw - 10px)),
377
+ calc(100vw - 10px)
378
+ );
379
+ max-height: min(
380
+ var(--tooltip-available-height, calc(100vh - 10px)),
381
+ calc(100vh - 10px)
382
+ );
383
+ padding: 4px 8px;
384
+ border: 1px solid var(--border);
385
+ border-radius: var(--radius-lg);
386
+ corner-shape: var(--corner-shape);
387
+ color: var(--popover-foreground);
388
+ background: var(--popover);
389
+ box-shadow: none;
390
+ font-size: var(--font-size-tooltip);
391
+ line-height: var(--line-height-tooltip);
392
+ overflow-wrap: break-word;
393
+ white-space: normal;
394
+ pointer-events: none;
395
+ user-select: none;
396
+ }
397
+
398
+ .viz-grid {
399
+ display: grid;
400
+ grid-template-columns: repeat(auto-fit, minmax(max(180px, 24%), 1fr));
401
+ gap: 10px;
402
+ }
403
+
404
+ .viz-stat {
405
+ display: flex;
406
+ flex-direction: column;
407
+ gap: 2px;
408
+ }
409
+
410
+ .viz-stat-value {
411
+ font-size: var(--font-size-h2);
412
+ font-weight: var(--font-weight-medium);
413
+ line-height: 1.25;
414
+ }
415
+
416
+ .viz-row {
417
+ display: flex;
418
+ flex-wrap: wrap;
419
+ align-items: center;
420
+ gap: 10px;
421
+ }
422
+
423
+ hr {
424
+ width: 100%;
425
+ height: 1px;
426
+ margin-block: 6px;
427
+ border: 0;
428
+ background: var(--border);
429
+ }
430
+
431
+ .nav {
432
+ display: flex;
433
+ min-width: 0;
434
+ align-items: center;
435
+ gap: 4px;
436
+ }
437
+
438
+ .progress {
439
+ display: flex;
440
+ height: 8px;
441
+ margin-block: calc((var(--line-height-normal, 1.5em) - 8px) / 2);
442
+ overflow: hidden;
443
+ border: 0;
444
+ border-radius: var(--radius-full);
445
+ background: var(--muted);
446
+ }
447
+
448
+ .progress-bar:only-child {
449
+ border-radius: var(--radius-full);
450
+ }
451
+
452
+ .progress-bar {
453
+ height: 100%;
454
+ flex-shrink: 0;
455
+ border: 0;
456
+ background: var(--viz-series-1);
457
+ }
458
+
459
+ .viz-badge {
460
+ padding: 3px 8px;
461
+ border-radius: var(--radius-full);
462
+ color: var(--accent-foreground);
463
+ background: var(--accent);
464
+ font-weight: var(--font-weight-medium);
465
+ }
466
+
467
+ small,
468
+ .text-small,
469
+ .viz-badge {
470
+ font-size: var(--font-size-small);
471
+ line-height: var(--line-height-small);
472
+ }
473
+
474
+ .text-muted {
475
+ color: var(--muted-foreground);
476
+ }
477
+
478
+ .tabular-nums {
479
+ font-variant-numeric: tabular-nums;
480
+ }
481
+
482
+ .sr-only {
483
+ position: absolute;
484
+ width: 1px;
485
+ height: 1px;
486
+ padding: 0;
487
+ overflow: hidden;
488
+ clip: rect(0, 0, 0, 0);
489
+ white-space: nowrap;
490
+ border: 0;
491
+ }
492
+
493
+ .viz-controls {
494
+ display: flex;
495
+ flex-wrap: wrap;
496
+ align-items: center;
497
+ gap: 8px;
498
+ }
499
+
500
+ .viz-controls > .form-label {
501
+ display: grid;
502
+ min-width: min(100%, 260px);
503
+ flex: 1 1 280px;
504
+ grid-template-columns: minmax(0, 1fr) auto;
505
+ align-items: baseline;
506
+ gap: 2px 12px;
507
+ margin-bottom: 0;
508
+ }
509
+
510
+ .viz-controls > .form-label > :is(.form-control, .form-range, .form-select) {
511
+ grid-column: 1 / -1;
512
+ }
513
+
514
+ .btn,
515
+ .nav-link,
516
+ .form-check-input,
517
+ .form-control,
518
+ .form-range,
519
+ .form-select {
520
+ font: inherit;
521
+ }
522
+
523
+ .btn,
524
+ .nav-link {
525
+ appearance: button;
526
+ display: inline-flex;
527
+ inline-size: fit-content;
528
+ max-inline-size: 100%;
529
+ min-height: 28px;
530
+ align-items: center;
531
+ justify-content: center;
532
+ gap: 4px;
533
+ margin: 0;
534
+ padding: 0 8px;
535
+ -webkit-app-region: no-drag;
536
+ border: 1px solid var(--input);
537
+ border-radius: var(--radius-lg);
538
+ corner-shape: var(--corner-shape);
539
+ color: var(--secondary-foreground);
540
+ background: var(--secondary);
541
+ cursor: var(--cursor-interaction, pointer);
542
+ text-align: center;
543
+ text-decoration: none;
544
+ white-space: nowrap;
545
+ user-select: none;
546
+ -webkit-font-smoothing: antialiased;
547
+ }
548
+
549
+ .btn:is(.btn-block, .viz-tile) {
550
+ inline-size: 100%;
551
+ }
552
+
553
+ .btn.viz-tile {
554
+ min-width: 0;
555
+ overflow-wrap: anywhere;
556
+ white-space: normal;
557
+ }
558
+
559
+ a.btn {
560
+ cursor: pointer;
561
+ text-decoration: none;
562
+ }
563
+
564
+ .btn:not(:disabled):hover,
565
+ .nav-link:not(:disabled):not([aria-disabled="true"]):hover {
566
+ background: color-mix(in srgb, var(--foreground) 6%, var(--secondary));
567
+ }
568
+
569
+ .btn-primary {
570
+ border-color: transparent;
571
+ color: var(--primary-foreground);
572
+ background: var(--foreground);
573
+ background-clip: padding-box;
574
+ }
575
+
576
+ .btn-primary .text-muted {
577
+ color: color-mix(in srgb, var(--primary-foreground) 50%, transparent);
578
+ }
579
+
580
+ .btn-primary:not(:disabled):hover {
581
+ background: color-mix(in srgb, var(--foreground) 80%, transparent);
582
+ background-clip: padding-box;
583
+ }
584
+
585
+ .btn-ghost {
586
+ border-color: transparent;
587
+ color: var(--muted-foreground);
588
+ background: transparent;
589
+ }
590
+
591
+ .btn-ghost:not(:disabled):hover {
592
+ color: var(--foreground);
593
+ background: color-mix(in srgb, var(--foreground) 6%, var(--secondary));
594
+ }
595
+
596
+ .nav-pills .nav-link {
597
+ min-width: 0;
598
+ border-color: transparent;
599
+ color: var(--muted-foreground);
600
+ background: transparent;
601
+ }
602
+
603
+ .nav-justified .nav-link {
604
+ flex: 1 1 0;
605
+ overflow-wrap: anywhere;
606
+ white-space: normal;
607
+ }
608
+
609
+ .nav-pills .nav-link.active {
610
+ color: var(--foreground);
611
+ background: var(--muted);
612
+ }
613
+
614
+ .btn:disabled,
615
+ .nav-link:disabled,
616
+ .nav-link[aria-disabled="true"] {
617
+ cursor: not-allowed;
618
+ opacity: 0.4;
619
+ }
620
+
621
+ [data-lucide] {
622
+ stroke-width: 1.6;
623
+ }
624
+
625
+ .form-label {
626
+ display: block;
627
+ margin-bottom: 6px;
628
+ color: var(--foreground);
629
+ }
630
+
631
+ .form-control {
632
+ display: block;
633
+ width: 100%;
634
+ min-height: 28px;
635
+ padding: 0 8px;
636
+ outline: none;
637
+ border: 1px solid var(--input);
638
+ border-radius: var(--radius-lg);
639
+ corner-shape: var(--corner-shape);
640
+ color: var(--foreground);
641
+ background: var(--secondary);
642
+ }
643
+
644
+ .form-control::placeholder {
645
+ color: var(--muted-foreground);
646
+ }
647
+
648
+ .form-control[type="file"] {
649
+ padding: 0;
650
+ overflow: hidden;
651
+ cursor: var(--cursor-interaction, pointer);
652
+ }
653
+
654
+ .form-control[type="file"]::file-selector-button {
655
+ min-height: 26px;
656
+ margin-right: 8px;
657
+ padding: 0 8px;
658
+ border: 0;
659
+ border-right: 1px solid var(--input);
660
+ color: var(--secondary-foreground);
661
+ background: var(--secondary);
662
+ cursor: inherit;
663
+ font: inherit;
664
+ }
665
+
666
+ .form-control[type="file"]:not(:disabled):hover::file-selector-button {
667
+ background: color-mix(in srgb, var(--foreground) 6%, var(--secondary));
668
+ }
669
+
670
+ .form-control-color[type="color"] {
671
+ width: 40px;
672
+ height: 28px;
673
+ padding: 3px;
674
+ cursor: var(--cursor-interaction, pointer);
675
+ }
676
+
677
+ .form-control-color[type="color"]::-webkit-color-swatch-wrapper {
678
+ padding: 0;
679
+ }
680
+
681
+ .form-control-color[type="color"]::-webkit-color-swatch {
682
+ border: 0;
683
+ border-radius: calc(var(--radius-lg) - 4px);
684
+ corner-shape: var(--corner-shape);
685
+ }
686
+
687
+ textarea.form-control {
688
+ height: auto;
689
+ min-height: 72px;
690
+ padding: 8px 10px;
691
+ resize: vertical;
692
+ }
693
+
694
+ .form-control:focus-visible {
695
+ border-color: var(--ring);
696
+ box-shadow: inset 0 0 0 1px var(--ring);
697
+ }
698
+
699
+ .form-control:disabled,
700
+ .form-select:disabled {
701
+ cursor: not-allowed;
702
+ opacity: 0.4;
703
+ }
704
+
705
+ .form-select {
706
+ appearance: none;
707
+ display: block;
708
+ width: 100%;
709
+ min-height: 28px;
710
+ margin: 0;
711
+ padding: 0 32px 0 8px;
712
+ outline: none;
713
+ border: 1px solid var(--input);
714
+ border-radius: var(--radius-lg);
715
+ corner-shape: var(--corner-shape);
716
+ color: var(--foreground);
717
+ background-color: var(--secondary);
718
+ background-image:
719
+ linear-gradient(45deg, transparent 50%, var(--muted-foreground) 50%),
720
+ linear-gradient(135deg, var(--muted-foreground) 50%, transparent 50%);
721
+ background-position:
722
+ calc(100% - 14px) 50%,
723
+ calc(100% - 10px) 50%;
724
+ background-repeat: no-repeat;
725
+ background-size: 4px 4px;
726
+ cursor: var(--cursor-interaction, default);
727
+ }
728
+
729
+ .form-select:not(:disabled):hover {
730
+ background-color: color-mix(in srgb, var(--foreground) 6%, var(--secondary));
731
+ }
732
+
733
+ .form-select:focus-visible {
734
+ border-color: var(--ring);
735
+ box-shadow: inset 0 0 0 1px var(--ring);
736
+ }
737
+
738
+ .form-check {
739
+ display: flex;
740
+ min-height: 20px;
741
+ align-items: center;
742
+ gap: 6px;
743
+ }
744
+
745
+ .form-check-input {
746
+ appearance: none;
747
+ width: 14px;
748
+ height: 14px;
749
+ flex: 0 0 auto;
750
+ margin: 0;
751
+ border: 1px solid var(--input);
752
+ color: var(--primary-foreground);
753
+ background-color: transparent;
754
+ cursor: var(--cursor-interaction, default);
755
+ transition:
756
+ background-color 150ms,
757
+ border-color 150ms,
758
+ box-shadow 150ms;
759
+ }
760
+
761
+ .form-check:not(.form-switch) .form-check-input[type="checkbox"] {
762
+ border-color: var(--input);
763
+ border-radius: var(--radius-sm);
764
+ corner-shape: var(--corner-shape);
765
+ background-color: var(--secondary);
766
+ box-shadow: var(--shadow-sm);
767
+ }
768
+
769
+ .form-check:not(.form-switch)
770
+ .form-check-input:not(:disabled):not(:checked):hover {
771
+ background-color: var(--card);
772
+ }
773
+
774
+ .form-check:not(.form-switch) .form-check-input[type="checkbox"]:checked {
775
+ border-color: var(--primary);
776
+ background-color: var(--primary);
777
+ }
778
+
779
+ .form-check:not(.form-switch)
780
+ .form-check-input[type="checkbox"]:checked::before {
781
+ display: block;
782
+ width: 100%;
783
+ height: 100%;
784
+ background: var(--primary-foreground);
785
+ content: "";
786
+ mask: var(--checkmark-image) center / 12px 12px no-repeat;
787
+ }
788
+
789
+ .form-check-input[type="radio"] {
790
+ width: 14px;
791
+ height: 14px;
792
+ border-radius: var(--radius-full);
793
+ }
794
+
795
+ .form-check-input[type="radio"]:checked {
796
+ border: 2px solid var(--primary);
797
+ background:
798
+ radial-gradient(circle, var(--primary-foreground) 0 2.5px, transparent 3px),
799
+ var(--primary);
800
+ }
801
+
802
+ .form-check:not(.form-switch) .form-check-input:focus-visible {
803
+ outline: 2px solid var(--ring);
804
+ outline-offset: 2px;
805
+ }
806
+
807
+ .form-check:not(.form-switch) .form-check-input:disabled {
808
+ cursor: not-allowed;
809
+ pointer-events: none;
810
+ }
811
+
812
+ .form-check:not(.form-switch) .form-check-input:disabled + .form-check-label {
813
+ cursor: not-allowed;
814
+ }
815
+
816
+ .form-switch .form-check-input:disabled,
817
+ .form-switch .form-check-input:disabled + .form-check-label {
818
+ cursor: not-allowed;
819
+ opacity: 0.6;
820
+ }
821
+
822
+ .form-check-label {
823
+ color: var(--foreground);
824
+ cursor: var(--cursor-interaction, default);
825
+ }
826
+
827
+ .form-switch .form-check-input {
828
+ position: relative;
829
+ width: 32px;
830
+ height: 20px;
831
+ border: 0;
832
+ border-radius: var(--radius-full);
833
+ background: var(--muted);
834
+ box-shadow: none;
835
+ transition: background-color 200ms cubic-bezier(0, 0, 0.2, 1);
836
+ }
837
+
838
+ .form-switch .form-check-input::before {
839
+ position: absolute;
840
+ top: 50%;
841
+ left: 0;
842
+ width: 16px;
843
+ height: 16px;
844
+ box-sizing: border-box;
845
+ border: 1px solid light-dark(var(--primary-foreground), var(--foreground));
846
+ border-radius: var(--radius-full);
847
+ background: light-dark(var(--primary-foreground), var(--foreground));
848
+ box-shadow: var(--shadow-sm);
849
+ content: "";
850
+ transform: translate(2px, -50%);
851
+ transition: transform 200ms cubic-bezier(0, 0, 0.2, 1);
852
+ }
853
+
854
+ .form-switch .form-check-input:checked {
855
+ background: var(--primary);
856
+ }
857
+
858
+ .form-switch .form-check-input:checked::before {
859
+ transform: translate(14px, -50%);
860
+ }
861
+
862
+ .form-switch .form-check-input:focus-visible {
863
+ box-shadow: 0 0 0 2px var(--ring);
864
+ }
865
+
866
+ .form-range {
867
+ appearance: none;
868
+ display: block;
869
+ width: 100%;
870
+ height: 28px;
871
+ flex: 1;
872
+ margin: 0;
873
+ padding: 0;
874
+ outline: none;
875
+ border: 0;
876
+ accent-color: var(--primary);
877
+ background: linear-gradient(
878
+ color-mix(in srgb, var(--foreground) 7%, transparent),
879
+ color-mix(in srgb, var(--foreground) 7%, transparent)
880
+ )
881
+ center / 100% 2px no-repeat;
882
+ }
883
+
884
+ .form-range::-webkit-slider-runnable-track {
885
+ height: 28px;
886
+ background: transparent;
887
+ }
888
+
889
+ .form-range::-webkit-slider-thumb {
890
+ appearance: none;
891
+ width: 20px;
892
+ height: 20px;
893
+ margin-top: 4px;
894
+ border: 1px solid var(--border);
895
+ border-radius: var(--radius-full);
896
+ background: light-dark(var(--primary-foreground), var(--foreground));
897
+ }
898
+
899
+ .form-range:focus-visible::-webkit-slider-thumb {
900
+ border-color: var(--ring);
901
+ box-shadow: inset 0 0 0 1px var(--ring);
902
+ }
903
+
904
+ .form-range::-moz-range-track {
905
+ height: 28px;
906
+ background: transparent;
907
+ }
908
+
909
+ .form-range::-moz-range-thumb {
910
+ width: 20px;
911
+ height: 20px;
912
+ border: 1px solid var(--border);
913
+ border-radius: var(--radius-full);
914
+ background: light-dark(var(--primary-foreground), var(--foreground));
915
+ }
916
+
917
+ .form-range:focus-visible::-moz-range-thumb {
918
+ border-color: var(--ring);
919
+ box-shadow: inset 0 0 0 1px var(--ring);
920
+ }
921
+
922
+ .form-range:disabled {
923
+ cursor: not-allowed;
924
+ opacity: 0.4;
925
+ }
926
+
927
+ .btn:not(.btn-primary, .viz-tile):is(
928
+ [aria-pressed="true"],
929
+ [aria-selected="true"],
930
+ .is-selected
931
+ ) {
932
+ border-color: var(--primary);
933
+ color: var(--primary-foreground);
934
+ background: var(--primary);
935
+ }
936
+
937
+ .btn.viz-tile:is([aria-pressed="true"], [aria-selected="true"], .is-selected) {
938
+ border-color: var(--primary);
939
+ box-shadow: inset 0 0 0 1px var(--primary);
940
+ }
941
+
942
+ .btn:focus-visible,
943
+ .nav-link:focus-visible {
944
+ outline: 2px solid var(--ring);
945
+ outline-offset: 2px;
946
+ }
947
+
948
+ @media (pointer: coarse) {
949
+ .btn,
950
+ .nav-link,
951
+ .form-control,
952
+ .form-select {
953
+ min-width: 44px;
954
+ min-height: 44px;
955
+ }
956
+
957
+ /* Keep small-screen WebKit from zooming when a text field receives focus. */
958
+ .form-control,
959
+ .form-select {
960
+ font-size: max(16px, var(--font-size-normal));
961
+ }
962
+
963
+ .form-control[type="file"]::file-selector-button {
964
+ min-width: 44px;
965
+ min-height: 44px;
966
+ }
967
+
968
+ .form-control-color[type="color"] {
969
+ width: 44px;
970
+ height: 44px;
971
+ }
972
+
973
+ .form-control:is(
974
+ [type="date"],
975
+ [type="datetime-local"],
976
+ [type="month"],
977
+ [type="time"],
978
+ [type="week"]
979
+ ) {
980
+ min-width: 0;
981
+ max-width: 100%;
982
+ padding-block: 8px;
983
+ }
984
+
985
+ .form-check {
986
+ min-height: 44px;
987
+ padding-inline: 15px;
988
+ }
989
+
990
+ .form-check-input {
991
+ position: relative;
992
+ }
993
+
994
+ .form-check-input::after {
995
+ position: absolute;
996
+ top: 50%;
997
+ left: 50%;
998
+ width: 44px;
999
+ height: 44px;
1000
+ content: "";
1001
+ transform: translate(-50%, -50%);
1002
+ }
1003
+
1004
+ .form-check-label {
1005
+ display: inline-flex;
1006
+ min-width: 44px;
1007
+ min-height: 44px;
1008
+ align-items: center;
1009
+ }
1010
+
1011
+ .form-range {
1012
+ height: 44px;
1013
+ touch-action: pan-y;
1014
+ }
1015
+
1016
+ .form-range::-webkit-slider-runnable-track {
1017
+ height: 44px;
1018
+ }
1019
+
1020
+ .form-range::-moz-range-track {
1021
+ height: 44px;
1022
+ }
1023
+
1024
+ .form-range::-webkit-slider-thumb {
1025
+ margin-top: 12px;
1026
+ }
1027
+ }
1028
+
1029
+ svg {
1030
+ display: block;
1031
+ max-width: 100%;
1032
+ height: auto;
1033
+ }
1034
+
1035
+ #widget > svg {
1036
+ width: 100%;
1037
+ }
1038
+
1039
+ /* Model-authored chart rules can otherwise stretch icons after these styles load. */
1040
+ svg.lucide {
1041
+ display: block;
1042
+ width: var(--icon-size) !important;
1043
+ height: var(--icon-size) !important;
1044
+ flex: none;
1045
+ margin: 0 !important;
1046
+ stroke-width: 1.6;
1047
+ }
1048
+
1049
+ .text-warning,
1050
+ .text-destructive {
1051
+ color: var(--destructive);
1052
+ }
1053
+ `;
1054
+ var VISUALIZATION_HELPERS = `
1055
+ <script src="https://unpkg.com/@floating-ui/core@1.7.3/dist/floating-ui.core.umd.min.js"></script>
1056
+ <script src="https://unpkg.com/@floating-ui/dom@1.7.4/dist/floating-ui.dom.umd.min.js"></script>
1057
+ <script>
1058
+ (() => {
1059
+ if (window.FloatingUIDOM == null) {
1060
+ return;
1061
+ }
1062
+ const { autoUpdate, computePosition, flip, offset, shift, size } = window.FloatingUIDOM;
1063
+ const tooltipPlacements = new Set(["top", "right", "bottom", "left"]);
1064
+ const tooltipId = \`codex-visualization-tooltip-\${
1065
+ window.crypto?.randomUUID?.() ?? Date.now().toString(36)
1066
+ }\`;
1067
+ const tooltipGap = 5;
1068
+ const hoverDelay = 700;
1069
+ const skipDelay = 300;
1070
+ let activeTrigger = null;
1071
+ let pendingTrigger = null;
1072
+ let tooltip = null;
1073
+ let openTimeout = null;
1074
+ let autoUpdateCleanup = null;
1075
+ let positionRequest = 0;
1076
+ let skipDelayUntil = 0;
1077
+ let lastPointerWasTouch = false;
1078
+ let pinnedByTouch = false;
1079
+
1080
+ const getTrigger = (target) =>
1081
+ target?.nodeType === Node.ELEMENT_NODE ? target.closest("[data-tooltip]") : null;
1082
+ const containsTarget = (trigger, target) =>
1083
+ target?.nodeType != null && trigger.contains(target);
1084
+ const getContent = (trigger) => trigger.getAttribute("data-tooltip")?.trim() ?? "";
1085
+ const getPlacement = (trigger) => {
1086
+ const placement = trigger.getAttribute("data-tooltip-placement");
1087
+ return tooltipPlacements.has(placement) ? placement : "top";
1088
+ };
1089
+ const getTooltip = () => {
1090
+ if (tooltip == null) {
1091
+ tooltip = document.createElement("div");
1092
+ tooltip.id = tooltipId;
1093
+ tooltip.className = "tooltip";
1094
+ tooltip.setAttribute("role", "tooltip");
1095
+ }
1096
+ return tooltip;
1097
+ };
1098
+ const setDescribedBy = (trigger, described) => {
1099
+ const ids = new Set(
1100
+ (trigger.getAttribute("aria-describedby") ?? "").split(/\\s+/).filter(Boolean),
1101
+ );
1102
+ if (described) {
1103
+ ids.add(tooltipId);
1104
+ } else {
1105
+ ids.delete(tooltipId);
1106
+ }
1107
+ if (ids.size === 0) {
1108
+ trigger.removeAttribute("aria-describedby");
1109
+ } else {
1110
+ trigger.setAttribute("aria-describedby", [...ids].join(" "));
1111
+ }
1112
+ };
1113
+ const clearOpenTimeout = () => {
1114
+ if (openTimeout != null) {
1115
+ window.clearTimeout(openTimeout);
1116
+ openTimeout = null;
1117
+ }
1118
+ pendingTrigger = null;
1119
+ };
1120
+ const closeTooltip = (activateSkipDelay = true) => {
1121
+ clearOpenTimeout();
1122
+ pinnedByTouch = false;
1123
+ positionRequest += 1;
1124
+ autoUpdateCleanup?.();
1125
+ autoUpdateCleanup = null;
1126
+ if (activeTrigger == null) {
1127
+ return;
1128
+ }
1129
+ setDescribedBy(activeTrigger, false);
1130
+ activeTrigger = null;
1131
+ tooltip?.remove();
1132
+ if (activateSkipDelay) {
1133
+ skipDelayUntil = Date.now() + skipDelay;
1134
+ }
1135
+ };
1136
+ const updatePosition = (trigger, floating) => {
1137
+ const request = ++positionRequest;
1138
+ void computePosition(trigger, floating, {
1139
+ middleware: [
1140
+ offset(tooltipGap),
1141
+ flip({ padding: tooltipGap }),
1142
+ shift({ padding: tooltipGap }),
1143
+ size({
1144
+ padding: tooltipGap,
1145
+ apply({ availableHeight, availableWidth, elements }) {
1146
+ elements.floating.style.setProperty(
1147
+ "--tooltip-available-width",
1148
+ \`\${Math.max(0, availableWidth)}px\`,
1149
+ );
1150
+ elements.floating.style.setProperty(
1151
+ "--tooltip-available-height",
1152
+ \`\${Math.max(0, availableHeight)}px\`,
1153
+ );
1154
+ },
1155
+ }),
1156
+ ],
1157
+ placement: getPlacement(trigger),
1158
+ strategy: "fixed",
1159
+ })
1160
+ .then(({ x, y }) => {
1161
+ if (activeTrigger !== trigger || request !== positionRequest) {
1162
+ return;
1163
+ }
1164
+ const scale = window.devicePixelRatio || 1;
1165
+ floating.style.transform = \`translate(\${Math.round(x * scale) / scale}px, \${Math.round(y * scale) / scale}px)\`;
1166
+ floating.style.visibility = "visible";
1167
+ })
1168
+ .catch(() => {
1169
+ if (activeTrigger === trigger && request === positionRequest) {
1170
+ closeTooltip(false);
1171
+ }
1172
+ });
1173
+ };
1174
+ const openTooltip = (trigger) => {
1175
+ const content = getContent(trigger);
1176
+ if (!trigger.isConnected || content.length === 0) {
1177
+ return;
1178
+ }
1179
+ clearOpenTimeout();
1180
+ if (activeTrigger === trigger) {
1181
+ return;
1182
+ }
1183
+ closeTooltip();
1184
+ const floating = getTooltip();
1185
+ floating.textContent = content;
1186
+ floating.style.visibility = "hidden";
1187
+ floating.style.transform = "translate(0, 0)";
1188
+ document.body.appendChild(floating);
1189
+ activeTrigger = trigger;
1190
+ setDescribedBy(trigger, true);
1191
+ autoUpdateCleanup = autoUpdate(trigger, floating, () => {
1192
+ updatePosition(trigger, floating);
1193
+ });
1194
+ };
1195
+ const requestOpen = (trigger, immediate = false) => {
1196
+ if (
1197
+ getContent(trigger).length === 0 ||
1198
+ activeTrigger === trigger ||
1199
+ pendingTrigger === trigger
1200
+ ) {
1201
+ return;
1202
+ }
1203
+ clearOpenTimeout();
1204
+ pendingTrigger = trigger;
1205
+ const delay =
1206
+ immediate || activeTrigger != null || Date.now() < skipDelayUntil ? 0 : hoverDelay;
1207
+ if (delay === 0) {
1208
+ openTooltip(trigger);
1209
+ return;
1210
+ }
1211
+ openTimeout = window.setTimeout(() => {
1212
+ openTimeout = null;
1213
+ pendingTrigger = null;
1214
+ openTooltip(trigger);
1215
+ }, delay);
1216
+ };
1217
+ const handlePointerOpen = (event) => {
1218
+ if (event.pointerType === "touch") {
1219
+ return;
1220
+ }
1221
+ const trigger = getTrigger(event.target);
1222
+ if (trigger == null || containsTarget(trigger, event.relatedTarget)) {
1223
+ return;
1224
+ }
1225
+ requestOpen(trigger);
1226
+ };
1227
+ const handlePointer = (event) => {
1228
+ lastPointerWasTouch = event.type === "pointerdown" && event.pointerType === "touch";
1229
+ };
1230
+ const handleTouchClick = (event) => {
1231
+ const isTouch = event.pointerType === "touch" || lastPointerWasTouch;
1232
+ lastPointerWasTouch = false;
1233
+ if (!isTouch || event.detail === 0) {
1234
+ return;
1235
+ }
1236
+ const trigger = getTrigger(event.target);
1237
+ if (
1238
+ trigger == null ||
1239
+ !trigger.isConnected ||
1240
+ getContent(trigger).length === 0 ||
1241
+ (pinnedByTouch && activeTrigger === trigger)
1242
+ ) {
1243
+ if (pinnedByTouch) {
1244
+ closeTooltip();
1245
+ }
1246
+ return;
1247
+ }
1248
+ openTooltip(trigger);
1249
+ pinnedByTouch = activeTrigger === trigger;
1250
+ window.setTimeout(() => {
1251
+ if (activeTrigger === trigger && !trigger.isConnected) {
1252
+ closeTooltip(false);
1253
+ }
1254
+ }, 0);
1255
+ };
1256
+ const handleLeave = (event) => {
1257
+ if (pinnedByTouch) {
1258
+ return;
1259
+ }
1260
+ const trigger = getTrigger(event.target);
1261
+ if (trigger == null || containsTarget(trigger, event.relatedTarget)) {
1262
+ return;
1263
+ }
1264
+ if (activeTrigger === trigger || pendingTrigger === trigger) {
1265
+ closeTooltip();
1266
+ }
1267
+ };
1268
+ const handleFocusIn = (event) => {
1269
+ const trigger = getTrigger(event.target);
1270
+ if (trigger?.matches(":focus-visible")) {
1271
+ requestOpen(trigger, true);
1272
+ }
1273
+ };
1274
+ const handleKeyDown = (event) => {
1275
+ if (event.key === "Escape") {
1276
+ closeTooltip();
1277
+ }
1278
+ };
1279
+ const handleContextMenu = (event) => {
1280
+ lastPointerWasTouch = false;
1281
+ const trigger = getTrigger(event.target);
1282
+ if (activeTrigger === trigger || pendingTrigger === trigger) {
1283
+ closeTooltip();
1284
+ }
1285
+ };
1286
+ const destroy = () => {
1287
+ closeTooltip(false);
1288
+ lastPointerWasTouch = false;
1289
+ document.removeEventListener("pointerover", handlePointerOpen);
1290
+ document.removeEventListener("pointerdown", handlePointer);
1291
+ document.removeEventListener("pointercancel", handlePointer);
1292
+ document.removeEventListener("click", handleTouchClick);
1293
+ document.removeEventListener("pointerout", handleLeave);
1294
+ document.removeEventListener("focusin", handleFocusIn);
1295
+ document.removeEventListener("focusout", handleLeave);
1296
+ document.removeEventListener("keydown", handleKeyDown);
1297
+ document.removeEventListener("contextmenu", handleContextMenu);
1298
+ tooltip = null;
1299
+ };
1300
+
1301
+ document.addEventListener("pointerover", handlePointerOpen);
1302
+ document.addEventListener("pointerdown", handlePointer);
1303
+ document.addEventListener("pointercancel", handlePointer);
1304
+ document.addEventListener("click", handleTouchClick);
1305
+ document.addEventListener("pointerout", handleLeave);
1306
+ document.addEventListener("focusin", handleFocusIn);
1307
+ document.addEventListener("focusout", handleLeave);
1308
+ document.addEventListener("keydown", handleKeyDown);
1309
+ document.addEventListener("contextmenu", handleContextMenu);
1310
+ window.addEventListener("pagehide", destroy, { once: true });
1311
+ })();
1312
+ </script>
1313
+ <script id="codex-visualization-tabs">
1314
+ (() => {
1315
+ const selector = '.nav[role="tablist"] [role="tab"]';
1316
+ const disabled = ':disabled,[aria-disabled="true"]';
1317
+ const selectTab = (selected) => {
1318
+ const panelId = selected.getAttribute("aria-controls");
1319
+ for (const tab of selected.closest('[role="tablist"]').querySelectorAll('[role="tab"]')) {
1320
+ const active = tab === selected;
1321
+ tab.classList.toggle("active", active);
1322
+ tab.setAttribute("aria-selected", String(active));
1323
+ const id = tab.getAttribute("aria-controls");
1324
+ const panel = id && document.getElementById(id);
1325
+ if (panel != null) {
1326
+ panel.hidden = id !== panelId;
1327
+ if (!panel.hidden && selected.id) {
1328
+ panel.setAttribute("aria-labelledby", selected.id);
1329
+ }
1330
+ }
1331
+ }
1332
+ };
1333
+ const interact = (event) => {
1334
+ const tab = event.target?.closest?.(selector);
1335
+ if (event.defaultPrevented || tab == null || tab.matches(disabled)) {
1336
+ return;
1337
+ }
1338
+ if (event.type === "click") {
1339
+ selectTab(tab);
1340
+ return;
1341
+ }
1342
+ const tabs = Array.from(
1343
+ tab.closest('[role="tablist"]').querySelectorAll('[role="tab"]'),
1344
+ ).filter((candidate) => !candidate.matches(disabled));
1345
+ const current = tabs.indexOf(tab);
1346
+ let next;
1347
+ if (event.key === "ArrowRight" || event.key === "ArrowDown") {
1348
+ next = (current + 1) % tabs.length;
1349
+ } else if (event.key === "ArrowLeft" || event.key === "ArrowUp") {
1350
+ next = (current + tabs.length - 1) % tabs.length;
1351
+ } else if (event.key === "Home") {
1352
+ next = 0;
1353
+ } else if (event.key === "End") {
1354
+ next = tabs.length - 1;
1355
+ } else {
1356
+ return;
1357
+ }
1358
+ event.preventDefault();
1359
+ tabs[next].focus();
1360
+ selectTab(tabs[next]);
1361
+ };
1362
+
1363
+ for (const list of document.querySelectorAll('.nav[role="tablist"]')) {
1364
+ const selected =
1365
+ list.querySelector('[role="tab"][aria-selected="true"]') ??
1366
+ list.querySelector('[role="tab"].active') ??
1367
+ list.querySelector('[role="tab"]');
1368
+ if (selected != null) {
1369
+ selectTab(selected);
1370
+ }
1371
+ }
1372
+ document.addEventListener("click", interact);
1373
+ document.addEventListener("keydown", interact);
1374
+ window.addEventListener(
1375
+ "pagehide",
1376
+ () => {
1377
+ document.removeEventListener("click", interact);
1378
+ document.removeEventListener("keydown", interact);
1379
+ },
1380
+ { once: true },
1381
+ );
1382
+ })();
1383
+ </script>
1384
+ <script
1385
+ id="codex-visualization-lucide"
1386
+ async
1387
+ src="https://unpkg.com/lucide@1.17.0/dist/umd/lucide.js"
1388
+ ></script>
1389
+ <script>
1390
+ (() => {
1391
+ const initialize = () => {
1392
+ globalThis.lucide?.createIcons({ attrs: { width: 16, height: 16 } });
1393
+ };
1394
+ if (globalThis.lucide != null) {
1395
+ initialize();
1396
+ return;
1397
+ }
1398
+ document
1399
+ .getElementById("codex-visualization-lucide")
1400
+ ?.addEventListener("load", initialize, { once: true });
1401
+ })();
1402
+ </script>
1403
+ `;
1404
+
1405
+ // src/components/artifacts/inline-html-document.ts
1406
+ function inlineHtmlDocument(fragment) {
1407
+ return '<!doctype html><html><head><meta name="viewport" content="width=device-width,initial-scale=1"><style>' + VISUALIZATION_CSS + "</style><style>html,body{margin:0;min-height:0}body{padding:16px;box-sizing:border-box}</style></head><body>" + fragment + VISUALIZATION_HELPERS + `<script>
1408
+ (()=>{
1409
+ window.addEventListener('message',event=>{
1410
+ if(event.source!==parent||event.data?.type!=='opengeni.preview.theme')return;
1411
+ if(event.data.theme==='light'||event.data.theme==='dark')document.documentElement.style.colorScheme=event.data.theme;
1412
+ previous=0;resize();
1413
+ });
1414
+ let previous=0;
1415
+ const resize=()=>{const height=Math.ceil(document.body.getBoundingClientRect().height);if(height!==previous){previous=height;parent.postMessage({type:'opengeni.preview.height',height},'*')}};
1416
+ new ResizeObserver(resize).observe(document.body);resize();
1417
+ })();
1418
+ </script></body></html>`;
1419
+ }
1420
+
34
1421
  // src/components/artifacts/editable-artifact-workbench.tsx
35
1422
  import {
36
1423
  createBrowserEditableArtifactSession
@@ -174,7 +1561,9 @@ export {
174
1561
  SpreadsheetArtifactSurface,
175
1562
  SpreadsheetGrid,
176
1563
  SpreadsheetProjectionGrid,
1564
+ inlineHtmlDocument,
177
1565
  openGeniSiteBridgePortFromBootstrap,
178
- publishedHtmlArtifactDocument
1566
+ publishedHtmlArtifactDocument,
1567
+ useRetainedImageObjectUrl
179
1568
  };
180
1569
  //# sourceMappingURL=artifacts.js.map