@syntrologie/runtime-sdk 2.1.0-canary.6 → 2.1.0-canary.8

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 (120) hide show
  1. package/dist/RuntimeProvider.d.ts +1 -1
  2. package/dist/RuntimeProvider.js.map +1 -1
  3. package/dist/SmartCanvasApp.d.ts +4 -4
  4. package/dist/SmartCanvasApp.js +2 -2
  5. package/dist/SmartCanvasApp.js.map +1 -1
  6. package/dist/SmartCanvasElement.d.ts +2 -2
  7. package/dist/SmartCanvasElement.js +1 -1
  8. package/dist/SmartCanvasElement.js.map +1 -1
  9. package/dist/SmartCanvasPortal.js.map +1 -1
  10. package/dist/actions/ActionEngine.js +2 -4
  11. package/dist/actions/ActionEngine.js.map +1 -1
  12. package/dist/actions/executors/index.d.ts +1 -1
  13. package/dist/actions/executors/index.js +1 -1
  14. package/dist/actions/executors/index.js.map +1 -1
  15. package/dist/actions/executors/tour.js +1 -1
  16. package/dist/actions/executors/tour.js.map +1 -1
  17. package/dist/actions/validation.js +1 -1
  18. package/dist/actions/validation.js.map +1 -1
  19. package/dist/adaptives/adaptive-chatbot/index.js.map +2 -2
  20. package/dist/adaptives/faq/index.js.map +2 -2
  21. package/dist/adaptives/nav/index.js.map +2 -2
  22. package/dist/api.d.ts +4 -4
  23. package/dist/api.js +4 -7
  24. package/dist/api.js.map +1 -1
  25. package/dist/apps/AppContext.js +3 -5
  26. package/dist/apps/AppContext.js.map +1 -1
  27. package/dist/apps/AppLoader.d.ts +1 -1
  28. package/dist/apps/AppRegistry.js.map +1 -1
  29. package/dist/apps/examples/gamification-app.example.d.ts +8 -8
  30. package/dist/apps/examples/gamification-app.example.js.map +1 -1
  31. package/dist/apps/types.d.ts +1 -1
  32. package/dist/blocks/data/ComparisonBlock.js.map +1 -1
  33. package/dist/blocks/data/StatsBlock.js +2 -4
  34. package/dist/blocks/data/StatsBlock.js.map +1 -1
  35. package/dist/blocks/index.d.ts +2 -2
  36. package/dist/blocks/index.js +3 -4
  37. package/dist/blocks/index.js.map +1 -1
  38. package/dist/blocks/interactive/ChecklistBlock.js.map +1 -1
  39. package/dist/blocks/interactive/RatingBlock.js.map +1 -1
  40. package/dist/blocks/notification/NotificationBlock.js +1 -1
  41. package/dist/blocks/notification/NotificationBlock.js.map +1 -1
  42. package/dist/bootstrap.d.ts +3 -3
  43. package/dist/bootstrap.js +10 -9
  44. package/dist/bootstrap.js.map +1 -1
  45. package/dist/components/ShadowCanvasOverlay.d.ts +2 -2
  46. package/dist/components/ShadowCanvasOverlay.js +2 -2
  47. package/dist/components/ShadowCanvasOverlay.js.map +1 -1
  48. package/dist/components/TileCard.d.ts +2 -2
  49. package/dist/components/TileCard.js +1 -1
  50. package/dist/components/TileCard.js.map +1 -1
  51. package/dist/components/TileWheel.d.ts +1 -1
  52. package/dist/components/TileWheel.js.map +1 -1
  53. package/dist/configFetcher.d.ts +1 -1
  54. package/dist/configFetcher.js +36 -38
  55. package/dist/configFetcher.js.map +1 -1
  56. package/dist/context/ContextManager.d.ts +1 -1
  57. package/dist/context/ContextManager.js +1 -1
  58. package/dist/context/ContextManager.js.map +1 -1
  59. package/dist/context/schema.d.ts +8 -8
  60. package/dist/decisions/engine.d.ts +2 -2
  61. package/dist/decisions/engine.js.map +1 -1
  62. package/dist/decisions/schema.d.ts +34 -34
  63. package/dist/editorLoader.js +2 -2
  64. package/dist/editorLoader.js.map +1 -1
  65. package/dist/events/normalizers/canvas.d.ts +1 -1
  66. package/dist/events/normalizers/canvas.js.map +1 -1
  67. package/dist/events/schema.d.ts +4 -4
  68. package/dist/experiments/adapters/growthbook.d.ts +1 -1
  69. package/dist/experiments/adapters/growthbook.js +1 -1
  70. package/dist/experiments/adapters/growthbook.js.map +1 -1
  71. package/dist/fetchers/cdnFetcher.js.map +1 -1
  72. package/dist/fetchers/experimentsFetcher.d.ts +1 -1
  73. package/dist/fetchers/experimentsFetcher.js.map +1 -1
  74. package/dist/hooks/useCanvasOverlays.d.ts +1 -1
  75. package/dist/hooks/useCanvasOverlays.js +2 -2
  76. package/dist/hooks/useCanvasOverlays.js.map +1 -1
  77. package/dist/hooks/useHostPatches.js.map +1 -1
  78. package/dist/hooks/useShadowCanvasConfig.d.ts +1 -1
  79. package/dist/hooks/useShadowCanvasConfig.js.map +1 -1
  80. package/dist/hostPatcher/core/patcher.js.map +1 -1
  81. package/dist/hostPatcher/policy/defaultPolicy.js.map +1 -1
  82. package/dist/overlays/fetcher.d.ts +1 -1
  83. package/dist/overlays/fetcher.js +12 -14
  84. package/dist/overlays/fetcher.js.map +1 -1
  85. package/dist/overlays/runtime/overlay/runner.js +16 -3
  86. package/dist/overlays/runtime/overlay/runner.js.map +1 -1
  87. package/dist/overlays/runtime/overlay/tooltip.js +3 -5
  88. package/dist/overlays/runtime/overlay/tooltip.js.map +1 -1
  89. package/dist/react.d.ts +1 -1
  90. package/dist/react.js.map +1 -1
  91. package/dist/render/RenderContext.js.map +1 -1
  92. package/dist/runtime.d.ts +6 -6
  93. package/dist/runtime.js +19 -4
  94. package/dist/runtime.js.map +1 -1
  95. package/dist/smart-canvas.esm.js +16 -16
  96. package/dist/smart-canvas.esm.js.map +4 -4
  97. package/dist/smart-canvas.js +1007 -1018
  98. package/dist/smart-canvas.js.map +4 -4
  99. package/dist/smart-canvas.min.js +16 -16
  100. package/dist/smart-canvas.min.js.map +4 -4
  101. package/dist/state/StateStore.d.ts +0 -6
  102. package/dist/state/StateStore.js +7 -1
  103. package/dist/state/StateStore.js.map +1 -1
  104. package/dist/surfaces/Surfaces.js +1 -1
  105. package/dist/surfaces/Surfaces.js.map +1 -1
  106. package/dist/surfaces/positioning.js.map +1 -1
  107. package/dist/telemetry/adapters/posthog.js +1 -1
  108. package/dist/telemetry/adapters/posthog.js.map +1 -1
  109. package/dist/telemetry/registry.d.ts +0 -7
  110. package/dist/telemetry/registry.js +1 -1
  111. package/dist/telemetry/registry.js.map +1 -1
  112. package/dist/theme/ThemeProvider.js.map +1 -1
  113. package/dist/theme/extractHostTheme.js +1 -1
  114. package/dist/theme/extractHostTheme.js.map +1 -1
  115. package/dist/types.d.ts +1 -1
  116. package/dist/types.js +0 -1
  117. package/dist/types.js.map +1 -1
  118. package/dist/version.d.ts +1 -1
  119. package/dist/version.js +1 -1
  120. package/package.json +3 -3
@@ -24640,7 +24640,7 @@ var SyntrologieSDK = (() => {
24640
24640
  });
24641
24641
 
24642
24642
  // src/version.ts
24643
- var SDK_VERSION = "2.1.0-canary.6";
24643
+ var SDK_VERSION = "2.1.0-canary.8";
24644
24644
 
24645
24645
  // src/types.ts
24646
24646
  var SDK_SCHEMA_VERSION = "2.0";
@@ -29293,7 +29293,7 @@ var SyntrologieSDK = (() => {
29293
29293
  this.captureCallback = options.onCapture;
29294
29294
  if (!this.client && typeof window !== "undefined" && options.apiKey) {
29295
29295
  const enableFeatureFlags = options.enableFeatureFlags ?? true;
29296
- const instanceName = "syntro_" + (options.apiKey.slice(-6) || "sdk");
29296
+ const instanceName = `syntro_${options.apiKey.slice(-6) || "sdk"}`;
29297
29297
  this.client = Uo.init(
29298
29298
  options.apiKey,
29299
29299
  {
@@ -32389,7 +32389,7 @@ var SyntrologieSDK = (() => {
32389
32389
  return this.gb.getFeatureValue(key, fallback);
32390
32390
  }
32391
32391
  shouldRenderRectangle(tile) {
32392
- const experiment = tile.experiment;
32392
+ const { experiment } = tile;
32393
32393
  if (!experiment) return true;
32394
32394
  if (!experiment.featureKey) return true;
32395
32395
  const value = this.gb.getFeatureValue(experiment.featureKey, null);
@@ -32524,236 +32524,15 @@ var SyntrologieSDK = (() => {
32524
32524
  // src/components/TileCard.tsx
32525
32525
  var import_react6 = __toESM(require_react(), 1);
32526
32526
 
32527
- // src/blocks/notification/NotificationBlock.tsx
32527
+ // src/blocks/data/StatsBlock.tsx
32528
32528
  var import_react2 = __toESM(require_react(), 1);
32529
32529
  var import_jsx_runtime = __toESM(require_jsx_runtime(), 1);
32530
- var Icons = {
32531
- success: () => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("svg", { width: "20", height: "20", viewBox: "0 0 20 20", fill: "none", children: [
32532
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("circle", { cx: "10", cy: "10", r: "9", stroke: "currentColor", strokeWidth: "1.5" }),
32533
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
32534
- "path",
32535
- {
32536
- d: "M6 10l2.5 2.5L14 7",
32537
- stroke: "currentColor",
32538
- strokeWidth: "1.5",
32539
- strokeLinecap: "round",
32540
- strokeLinejoin: "round"
32541
- }
32542
- )
32543
- ] }),
32544
- warning: () => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("svg", { width: "20", height: "20", viewBox: "0 0 20 20", fill: "none", children: [
32545
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
32546
- "path",
32547
- {
32548
- d: "M10 2L18 17H2L10 2Z",
32549
- stroke: "currentColor",
32550
- strokeWidth: "1.5",
32551
- strokeLinejoin: "round"
32552
- }
32553
- ),
32554
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M10 8v4", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round" }),
32555
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("circle", { cx: "10", cy: "14", r: "0.75", fill: "currentColor" })
32556
- ] }),
32557
- error: () => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("svg", { width: "20", height: "20", viewBox: "0 0 20 20", fill: "none", children: [
32558
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("circle", { cx: "10", cy: "10", r: "9", stroke: "currentColor", strokeWidth: "1.5" }),
32559
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M7 7l6 6M13 7l-6 6", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round" })
32560
- ] }),
32561
- info: () => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("svg", { width: "20", height: "20", viewBox: "0 0 20 20", fill: "none", children: [
32562
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("circle", { cx: "10", cy: "10", r: "9", stroke: "currentColor", strokeWidth: "1.5" }),
32563
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M10 9v5", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round" }),
32564
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("circle", { cx: "10", cy: "6", r: "0.75", fill: "currentColor" })
32565
- ] }),
32566
- alert: () => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("svg", { width: "20", height: "20", viewBox: "0 0 20 20", fill: "none", children: [
32567
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("circle", { cx: "10", cy: "10", r: "9", stroke: "currentColor", strokeWidth: "1.5" }),
32568
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M10 5v6", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round" }),
32569
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("circle", { cx: "10", cy: "14", r: "0.75", fill: "currentColor" })
32570
- ] })
32571
- };
32572
- function DismissButton({ onClick, color }) {
32573
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
32574
- "button",
32575
- {
32576
- onClick: (e2) => {
32577
- e2.stopPropagation();
32578
- onClick();
32579
- },
32580
- style: {
32581
- position: "absolute",
32582
- top: "8px",
32583
- right: "8px",
32584
- width: "20px",
32585
- height: "20px",
32586
- padding: 0,
32587
- border: "none",
32588
- background: "rgba(255, 255, 255, 0.1)",
32589
- borderRadius: "50%",
32590
- cursor: "pointer",
32591
- display: "flex",
32592
- alignItems: "center",
32593
- justifyContent: "center",
32594
- color,
32595
- opacity: 0.6,
32596
- transition: "opacity 0.15s ease"
32597
- },
32598
- onMouseEnter: (e2) => {
32599
- e2.currentTarget.style.opacity = "1";
32600
- },
32601
- onMouseLeave: (e2) => {
32602
- e2.currentTarget.style.opacity = "0.6";
32603
- },
32604
- "aria-label": "Dismiss",
32605
- children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("svg", { width: "10", height: "10", viewBox: "0 0 10 10", fill: "none", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M1 1l8 8M9 1l-8 8", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round" }) })
32606
- }
32607
- );
32608
- }
32609
- function getSemanticColors(type) {
32610
- const colors = {
32611
- success: {
32612
- bg: "var(--sc-color-success-muted, rgba(52, 199, 89, 0.15))",
32613
- border: "var(--sc-color-success, #34c759)",
32614
- icon: "var(--sc-color-success, #34c759)",
32615
- text: "var(--sc-color-text, #f5f5f7)"
32616
- },
32617
- warning: {
32618
- bg: "var(--sc-color-warning-muted, rgba(255, 159, 10, 0.15))",
32619
- border: "var(--sc-color-warning, #ff9f0a)",
32620
- icon: "var(--sc-color-warning, #ff9f0a)",
32621
- text: "var(--sc-color-text, #f5f5f7)"
32622
- },
32623
- error: {
32624
- bg: "var(--sc-color-error-muted, rgba(255, 69, 58, 0.15))",
32625
- border: "var(--sc-color-error, #ff453a)",
32626
- icon: "var(--sc-color-error, #ff453a)",
32627
- text: "var(--sc-color-text, #f5f5f7)"
32628
- },
32629
- info: {
32630
- bg: "var(--sc-color-info-muted, rgba(10, 132, 255, 0.15))",
32631
- border: "var(--sc-color-info, #0a84ff)",
32632
- icon: "var(--sc-color-info, #0a84ff)",
32633
- text: "var(--sc-color-text, #f5f5f7)"
32634
- },
32635
- alert: {
32636
- bg: "var(--sc-color-primary-muted, rgba(99, 102, 241, 0.15))",
32637
- border: "var(--sc-color-primary, #6366f1)",
32638
- icon: "var(--sc-color-primary, #6366f1)",
32639
- text: "var(--sc-color-text, #f5f5f7)"
32640
- }
32641
- };
32642
- return colors[type] || colors.info;
32643
- }
32644
- function NotificationBlock({
32645
- content,
32646
- onDismiss,
32647
- accentColor: _accentColor
32648
- }) {
32649
- const [isDismissed, setIsDismissed] = (0, import_react2.useState)(false);
32650
- const [countdown, setCountdown] = (0, import_react2.useState)(
32651
- content.type === "warning" ? content.countdown ?? null : null
32652
- );
32653
- (0, import_react2.useEffect)(() => {
32654
- if (countdown === null || countdown <= 0) return;
32655
- const timer = setInterval(() => {
32656
- setCountdown((prev) => prev !== null && prev > 0 ? prev - 1 : null);
32657
- }, 1e3);
32658
- return () => clearInterval(timer);
32659
- }, [countdown]);
32660
- const handleDismiss = () => {
32661
- setIsDismissed(true);
32662
- setTimeout(() => onDismiss?.(), 200);
32663
- };
32664
- const colors = getSemanticColors(content.type);
32665
- const Icon = Icons[content.type];
32666
- const containerStyle = {
32667
- position: "relative",
32668
- padding: "var(--sc-spacing-md, 0.75rem)",
32669
- borderRadius: "var(--sc-border-radius-md, 10px)",
32670
- background: colors.bg,
32671
- borderLeft: `3px solid ${colors.border}`,
32672
- opacity: isDismissed ? 0 : 1,
32673
- transform: isDismissed ? "translateX(10px)" : "translateX(0)",
32674
- transition: "opacity 0.2s ease, transform 0.2s ease"
32675
- };
32676
- const headerStyle = {
32677
- display: "flex",
32678
- alignItems: "flex-start",
32679
- gap: "var(--sc-spacing-sm, 0.5rem)"
32680
- };
32681
- const iconStyle = {
32682
- color: colors.icon,
32683
- flexShrink: 0,
32684
- marginTop: "1px"
32685
- };
32686
- const contentStyle = {
32687
- flex: 1,
32688
- minWidth: 0,
32689
- paddingRight: content.dismissible ? "24px" : 0
32690
- };
32691
- const titleStyle = {
32692
- fontSize: "var(--sc-font-size-md, 0.9rem)",
32693
- fontWeight: "var(--sc-font-weight-semibold, 600)",
32694
- color: colors.text,
32695
- margin: 0,
32696
- lineHeight: "var(--sc-line-height-tight, 1.25)"
32697
- };
32698
- const bodyStyle = {
32699
- fontSize: "var(--sc-font-size-sm, 0.8rem)",
32700
- color: "var(--sc-color-text-secondary, #a1a1a6)",
32701
- margin: "var(--sc-spacing-xs, 0.25rem) 0 0",
32702
- lineHeight: "var(--sc-line-height-normal, 1.5)"
32703
- };
32704
- const timestampStyle = {
32705
- fontSize: "var(--sc-font-size-xs, 0.7rem)",
32706
- color: "var(--sc-color-text-muted, #8e8e93)",
32707
- marginTop: "var(--sc-spacing-sm, 0.5rem)"
32708
- };
32709
- return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: containerStyle, children: [
32710
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: headerStyle, children: [
32711
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: iconStyle, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Icon, {}) }),
32712
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: contentStyle, children: [
32713
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("h4", { style: titleStyle, children: content.title }),
32714
- content.body && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { style: bodyStyle, children: content.body }),
32715
- content.type === "error" && content.errorCode && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("p", { style: { ...bodyStyle, fontFamily: "var(--sc-font-family-mono, monospace)" }, children: [
32716
- "Code: ",
32717
- content.errorCode
32718
- ] }),
32719
- content.type === "info" && content.learnMoreUrl && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
32720
- "a",
32721
- {
32722
- href: content.learnMoreUrl,
32723
- target: "_blank",
32724
- rel: "noopener noreferrer",
32725
- style: {
32726
- display: "inline-block",
32727
- marginTop: "var(--sc-spacing-sm, 0.5rem)",
32728
- fontSize: "var(--sc-font-size-sm, 0.8rem)",
32729
- color: colors.icon,
32730
- textDecoration: "none"
32731
- },
32732
- onClick: (e2) => e2.stopPropagation(),
32733
- children: "Learn more \u2192"
32734
- }
32735
- ),
32736
- countdown !== null && countdown > 0 && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("p", { style: { ...bodyStyle, color: colors.icon }, children: [
32737
- "Action required in ",
32738
- countdown,
32739
- "s"
32740
- ] }),
32741
- content.timestamp && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { style: timestampStyle, children: content.timestamp })
32742
- ] })
32743
- ] }),
32744
- content.dismissible && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(DismissButton, { onClick: handleDismiss, color: colors.text })
32745
- ] });
32746
- }
32747
-
32748
- // src/blocks/data/StatsBlock.tsx
32749
- var import_react3 = __toESM(require_react(), 1);
32750
- var import_jsx_runtime2 = __toESM(require_jsx_runtime(), 1);
32751
32530
  function TrendBadge({ trend }) {
32752
32531
  const isPositive = trend.direction === "up";
32753
32532
  const isNegative = trend.direction === "down";
32754
32533
  const color = isPositive ? "var(--sc-color-success, #34c759)" : isNegative ? "var(--sc-color-error, #ff453a)" : "var(--sc-color-text-muted, #8e8e93)";
32755
32534
  const bgColor = isPositive ? "var(--sc-color-success-muted, rgba(52, 199, 89, 0.15))" : isNegative ? "var(--sc-color-error-muted, rgba(255, 69, 58, 0.15))" : "rgba(142, 142, 147, 0.15)";
32756
- const ArrowIcon = () => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
32535
+ const ArrowIcon = () => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
32757
32536
  "svg",
32758
32537
  {
32759
32538
  width: "10",
@@ -32763,7 +32542,7 @@ var SyntrologieSDK = (() => {
32763
32542
  style: {
32764
32543
  transform: isPositive ? "rotate(0deg)" : isNegative ? "rotate(180deg)" : "rotate(90deg)"
32765
32544
  },
32766
- children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
32545
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
32767
32546
  "path",
32768
32547
  {
32769
32548
  d: "M5 1v8M5 1L2 4M5 1l3 3",
@@ -32775,7 +32554,7 @@ var SyntrologieSDK = (() => {
32775
32554
  )
32776
32555
  }
32777
32556
  );
32778
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
32557
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
32779
32558
  "span",
32780
32559
  {
32781
32560
  style: {
@@ -32790,15 +32569,15 @@ var SyntrologieSDK = (() => {
32790
32569
  fontWeight: "var(--sc-font-weight-medium, 500)"
32791
32570
  },
32792
32571
  children: [
32793
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ArrowIcon, {}),
32572
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ArrowIcon, {}),
32794
32573
  trend.value,
32795
- trend.timeframe && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { style: { color: "var(--sc-color-text-muted, #8e8e93)" }, children: trend.timeframe })
32574
+ trend.timeframe && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: { color: "var(--sc-color-text-muted, #8e8e93)" }, children: trend.timeframe })
32796
32575
  ]
32797
32576
  }
32798
32577
  );
32799
32578
  }
32800
32579
  function Sparkline({ data, color }) {
32801
- const { path, width, height } = (0, import_react3.useMemo)(() => {
32580
+ const { path, width, height } = (0, import_react2.useMemo)(() => {
32802
32581
  const w2 = 60;
32803
32582
  const h2 = 24;
32804
32583
  const padding = 2;
@@ -32813,13 +32592,14 @@ var SyntrologieSDK = (() => {
32813
32592
  const y2 = h2 - padding - (value - min2) / range * (h2 - padding * 2);
32814
32593
  return { x: x2, y: y2 };
32815
32594
  });
32816
- const pathData = points.reduce((acc, point, i2) => {
32817
- return acc + (i2 === 0 ? `M ${point.x} ${point.y}` : ` L ${point.x} ${point.y}`);
32818
- }, "");
32595
+ const pathData = points.reduce(
32596
+ (acc, point, i2) => acc + (i2 === 0 ? `M ${point.x} ${point.y}` : ` L ${point.x} ${point.y}`),
32597
+ ""
32598
+ );
32819
32599
  return { path: pathData, width: w2, height: h2 };
32820
32600
  }, [data]);
32821
32601
  if (!path) return null;
32822
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
32602
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
32823
32603
  "svg",
32824
32604
  {
32825
32605
  width,
@@ -32827,7 +32607,7 @@ var SyntrologieSDK = (() => {
32827
32607
  viewBox: `0 0 ${width} ${height}`,
32828
32608
  style: { overflow: "visible" },
32829
32609
  children: [
32830
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
32610
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
32831
32611
  "path",
32832
32612
  {
32833
32613
  d: path,
@@ -32838,11 +32618,11 @@ var SyntrologieSDK = (() => {
32838
32618
  fill: "none"
32839
32619
  }
32840
32620
  ),
32841
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("defs", { children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("linearGradient", { id: "sparkline-gradient", x1: "0", x2: "0", y1: "0", y2: "1", children: [
32842
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("stop", { offset: "0%", stopColor: color, stopOpacity: "0.3" }),
32843
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("stop", { offset: "100%", stopColor: color, stopOpacity: "0" })
32621
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("defs", { children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("linearGradient", { id: "sparkline-gradient", x1: "0", x2: "0", y1: "0", y2: "1", children: [
32622
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("stop", { offset: "0%", stopColor: color, stopOpacity: "0.3" }),
32623
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("stop", { offset: "100%", stopColor: color, stopOpacity: "0" })
32844
32624
  ] }) }),
32845
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
32625
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
32846
32626
  "path",
32847
32627
  {
32848
32628
  d: `${path} L ${width - 2} ${height} L 2 ${height} Z`,
@@ -32889,22 +32669,22 @@ var SyntrologieSDK = (() => {
32889
32669
  justifyContent: "space-between",
32890
32670
  marginTop: "var(--sc-spacing-xs, 0.25rem)"
32891
32671
  };
32892
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: containerStyle, children: [
32893
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: valueContainerStyle, children: [
32894
- content.prefix && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { style: unitStyle, children: content.prefix }),
32895
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { style: valueStyle, children: content.value }),
32896
- content.suffix && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { style: unitStyle, children: content.suffix })
32672
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: containerStyle, children: [
32673
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: valueContainerStyle, children: [
32674
+ content.prefix && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: unitStyle, children: content.prefix }),
32675
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: valueStyle, children: content.value }),
32676
+ content.suffix && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: unitStyle, children: content.suffix })
32897
32677
  ] }),
32898
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { style: labelStyle, children: content.label }),
32899
- (content.trend || content.sparkline) && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: bottomRowStyle, children: [
32900
- content.trend && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(TrendBadge, { trend: content.trend }),
32901
- content.sparkline && content.sparkline.length > 1 && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Sparkline, { data: content.sparkline, color: primaryColor })
32678
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { style: labelStyle, children: content.label }),
32679
+ (content.trend || content.sparkline) && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: bottomRowStyle, children: [
32680
+ content.trend && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TrendBadge, { trend: content.trend }),
32681
+ content.sparkline && content.sparkline.length > 1 && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Sparkline, { data: content.sparkline, color: primaryColor })
32902
32682
  ] })
32903
32683
  ] });
32904
32684
  }
32905
32685
 
32906
32686
  // src/blocks/data/ComparisonBlock.tsx
32907
- var import_jsx_runtime3 = __toESM(require_jsx_runtime(), 1);
32687
+ var import_jsx_runtime2 = __toESM(require_jsx_runtime(), 1);
32908
32688
  function ComparisonItemCard({
32909
32689
  item,
32910
32690
  accentColor,
@@ -32936,10 +32716,10 @@ var SyntrologieSDK = (() => {
32936
32716
  fontWeight: "var(--sc-font-weight-semibold, 600)",
32937
32717
  color: isHighlighted ? accentColor : "var(--sc-color-text, #f5f5f7)"
32938
32718
  };
32939
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { style: cardStyle, children: [
32940
- item.icon && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { style: iconStyle, children: item.icon }),
32941
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { style: labelStyle, children: item.label }),
32942
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { style: valueStyle, children: item.value })
32719
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: cardStyle, children: [
32720
+ item.icon && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { style: iconStyle, children: item.icon }),
32721
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { style: labelStyle, children: item.label }),
32722
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { style: valueStyle, children: item.value })
32943
32723
  ] });
32944
32724
  }
32945
32725
  function ComparisonBlock({ content, accentColor }) {
@@ -32966,7 +32746,7 @@ var SyntrologieSDK = (() => {
32966
32746
  padding: "var(--sc-spacing-sm, 0.5rem) 0"
32967
32747
  };
32968
32748
  if (layout === "table") {
32969
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
32749
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
32970
32750
  "table",
32971
32751
  {
32972
32752
  style: {
@@ -32974,14 +32754,14 @@ var SyntrologieSDK = (() => {
32974
32754
  borderCollapse: "collapse",
32975
32755
  fontSize: "var(--sc-font-size-sm, 0.8rem)"
32976
32756
  },
32977
- children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("tbody", { children: processedItems.map((item, idx) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
32757
+ children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("tbody", { children: processedItems.map((item, idx) => /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
32978
32758
  "tr",
32979
32759
  {
32980
32760
  style: {
32981
32761
  borderBottom: idx < processedItems.length - 1 ? "1px solid var(--sc-color-border-subtle, rgba(255, 255, 255, 0.06))" : void 0
32982
32762
  },
32983
32763
  children: [
32984
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
32764
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
32985
32765
  "td",
32986
32766
  {
32987
32767
  style: {
@@ -32992,12 +32772,12 @@ var SyntrologieSDK = (() => {
32992
32772
  gap: "var(--sc-spacing-sm, 0.5rem)"
32993
32773
  },
32994
32774
  children: [
32995
- item.icon && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { children: item.icon }),
32775
+ item.icon && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { children: item.icon }),
32996
32776
  item.label
32997
32777
  ]
32998
32778
  }
32999
32779
  ),
33000
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
32780
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
33001
32781
  "td",
33002
32782
  {
33003
32783
  style: {
@@ -33016,23 +32796,23 @@ var SyntrologieSDK = (() => {
33016
32796
  }
33017
32797
  );
33018
32798
  }
33019
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: containerStyle, children: processedItems.map((item, idx) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(ComparisonItemCard, { item, accentColor: primaryColor, layout }, idx)) });
32799
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: containerStyle, children: processedItems.map((item, idx) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ComparisonItemCard, { item, accentColor: primaryColor, layout }, idx)) });
33020
32800
  }
33021
32801
 
33022
32802
  // src/blocks/interactive/RatingBlock.tsx
33023
- var import_react4 = __toESM(require_react(), 1);
33024
- var import_jsx_runtime4 = __toESM(require_jsx_runtime(), 1);
32803
+ var import_react3 = __toESM(require_react(), 1);
32804
+ var import_jsx_runtime3 = __toESM(require_jsx_runtime(), 1);
33025
32805
  function StarRating({
33026
32806
  value,
33027
32807
  maxValue,
33028
32808
  onChange,
33029
32809
  color
33030
32810
  }) {
33031
- const [hovered, setHovered] = (0, import_react4.useState)(null);
33032
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { style: { display: "flex", gap: "4px" }, children: Array.from({ length: maxValue }, (_2, i2) => {
32811
+ const [hovered, setHovered] = (0, import_react3.useState)(null);
32812
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: { display: "flex", gap: "4px" }, children: Array.from({ length: maxValue }, (_2, i2) => {
33033
32813
  const starValue = i2 + 1;
33034
32814
  const isFilled = (hovered ?? value ?? 0) >= starValue;
33035
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
32815
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
33036
32816
  "button",
33037
32817
  {
33038
32818
  onClick: () => onChange(starValue),
@@ -33050,14 +32830,14 @@ var SyntrologieSDK = (() => {
33050
32830
  transform: hovered === starValue ? "scale(1.15)" : "scale(1)"
33051
32831
  },
33052
32832
  "aria-label": `Rate ${starValue} out of ${maxValue}`,
33053
- children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
32833
+ children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
33054
32834
  "svg",
33055
32835
  {
33056
32836
  width: "28",
33057
32837
  height: "28",
33058
32838
  viewBox: "0 0 24 24",
33059
32839
  fill: isFilled ? "currentColor" : "none",
33060
- children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
32840
+ children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
33061
32841
  "path",
33062
32842
  {
33063
32843
  d: "M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z",
@@ -33089,8 +32869,8 @@ var SyntrologieSDK = (() => {
33089
32869
  color: isSelected ? "white" : "var(--sc-color-text-muted, #8e8e93)",
33090
32870
  transition: "all 0.15s ease"
33091
32871
  });
33092
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { style: { display: "flex", gap: "12px" }, children: [
33093
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("button", { onClick: () => onChange(1), style: buttonStyle(value === 1), "aria-label": "Thumbs up", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("svg", { width: "32", height: "32", viewBox: "0 0 24 24", fill: "none", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
32872
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { style: { display: "flex", gap: "12px" }, children: [
32873
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("button", { onClick: () => onChange(1), style: buttonStyle(value === 1), "aria-label": "Thumbs up", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("svg", { width: "32", height: "32", viewBox: "0 0 24 24", fill: "none", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
33094
32874
  "path",
33095
32875
  {
33096
32876
  d: "M14 9V5a3 3 0 0 0-3-3l-4 9v11h11.28a2 2 0 0 0 2-1.7l1.38-9a2 2 0 0 0-2-2.3H14zM7 22H4a2 2 0 0 1-2-2v-7a2 2 0 0 1 2-2h3",
@@ -33101,7 +32881,7 @@ var SyntrologieSDK = (() => {
33101
32881
  fill: value === 1 ? "currentColor" : "none"
33102
32882
  }
33103
32883
  ) }) }),
33104
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("button", { onClick: () => onChange(0), style: buttonStyle(value === 0), "aria-label": "Thumbs down", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
32884
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("button", { onClick: () => onChange(0), style: buttonStyle(value === 0), "aria-label": "Thumbs down", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
33105
32885
  "svg",
33106
32886
  {
33107
32887
  width: "32",
@@ -33109,7 +32889,7 @@ var SyntrologieSDK = (() => {
33109
32889
  viewBox: "0 0 24 24",
33110
32890
  fill: "none",
33111
32891
  style: { transform: "rotate(180deg)" },
33112
- children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
32892
+ children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
33113
32893
  "path",
33114
32894
  {
33115
32895
  d: "M14 9V5a3 3 0 0 0-3-3l-4 9v11h11.28a2 2 0 0 0 2-1.7l1.38-9a2 2 0 0 0-2-2.3H14zM7 22H4a2 2 0 0 1-2-2v-7a2 2 0 0 1 2-2h3",
@@ -33130,10 +32910,10 @@ var SyntrologieSDK = (() => {
33130
32910
  onChange,
33131
32911
  color
33132
32912
  }) {
33133
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { style: { display: "flex", flexDirection: "column", gap: "var(--sc-spacing-sm, 0.5rem)" }, children: [
33134
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { style: { display: "flex", gap: "4px", justifyContent: "center" }, children: Array.from({ length: maxValue + 1 }, (_2, i2) => {
32913
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { style: { display: "flex", flexDirection: "column", gap: "var(--sc-spacing-sm, 0.5rem)" }, children: [
32914
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: { display: "flex", gap: "4px", justifyContent: "center" }, children: Array.from({ length: maxValue + 1 }, (_2, i2) => {
33135
32915
  const isSelected = value === i2;
33136
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
32916
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
33137
32917
  "button",
33138
32918
  {
33139
32919
  onClick: () => onChange(i2),
@@ -33156,8 +32936,8 @@ var SyntrologieSDK = (() => {
33156
32936
  i2
33157
32937
  );
33158
32938
  }) }),
33159
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { style: { display: "flex", justifyContent: "space-between", padding: "0 2px" }, children: [
33160
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
32939
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { style: { display: "flex", justifyContent: "space-between", padding: "0 2px" }, children: [
32940
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
33161
32941
  "span",
33162
32942
  {
33163
32943
  style: {
@@ -33167,7 +32947,7 @@ var SyntrologieSDK = (() => {
33167
32947
  children: "Not likely"
33168
32948
  }
33169
32949
  ),
33170
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
32950
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
33171
32951
  "span",
33172
32952
  {
33173
32953
  style: {
@@ -33186,9 +32966,9 @@ var SyntrologieSDK = (() => {
33186
32966
  color
33187
32967
  }) {
33188
32968
  const emojis = ["\u{1F622}", "\u{1F615}", "\u{1F610}", "\u{1F642}", "\u{1F604}"];
33189
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { style: { display: "flex", gap: "8px", justifyContent: "center" }, children: emojis.map((emoji, i2) => {
32969
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: { display: "flex", gap: "8px", justifyContent: "center" }, children: emojis.map((emoji, i2) => {
33190
32970
  const isSelected = value === i2;
33191
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
32971
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
33192
32972
  "button",
33193
32973
  {
33194
32974
  onClick: () => onChange(i2),
@@ -33212,8 +32992,8 @@ var SyntrologieSDK = (() => {
33212
32992
  }) });
33213
32993
  }
33214
32994
  function RatingBlock({ content, onSubmit, accentColor }) {
33215
- const [value, setValue2] = (0, import_react4.useState)(null);
33216
- const [submitted, setSubmitted] = (0, import_react4.useState)(false);
32995
+ const [value, setValue2] = (0, import_react3.useState)(null);
32996
+ const [submitted, setSubmitted] = (0, import_react3.useState)(false);
33217
32997
  const primaryColor = accentColor || "var(--sc-color-primary, #6366f1)";
33218
32998
  const maxValue = content.maxValue ?? (content.variant === "nps" ? 10 : 5);
33219
32999
  const handleChange = (v2) => {
@@ -33239,14 +33019,14 @@ var SyntrologieSDK = (() => {
33239
33019
  margin: 0
33240
33020
  };
33241
33021
  if (submitted) {
33242
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { style: { ...containerStyle, padding: "var(--sc-spacing-lg, 1rem)" }, children: [
33243
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { style: { fontSize: "2rem" }, children: "\u2713" }),
33244
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { style: { ...questionStyle, color: "var(--sc-color-success, #34c759)" }, children: "Thanks for your feedback!" })
33022
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { style: { ...containerStyle, padding: "var(--sc-spacing-lg, 1rem)" }, children: [
33023
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { style: { fontSize: "2rem" }, children: "\u2713" }),
33024
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { style: { ...questionStyle, color: "var(--sc-color-success, #34c759)" }, children: "Thanks for your feedback!" })
33245
33025
  ] });
33246
33026
  }
33247
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { style: containerStyle, children: [
33248
- content.question && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { style: questionStyle, children: content.question }),
33249
- content.variant === "stars" && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
33027
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { style: containerStyle, children: [
33028
+ content.question && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { style: questionStyle, children: content.question }),
33029
+ content.variant === "stars" && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
33250
33030
  StarRating,
33251
33031
  {
33252
33032
  value,
@@ -33255,10 +33035,10 @@ var SyntrologieSDK = (() => {
33255
33035
  color: primaryColor
33256
33036
  }
33257
33037
  ),
33258
- content.variant === "thumbs" && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(ThumbsRating, { value, onChange: handleChange, color: primaryColor }),
33259
- content.variant === "nps" && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(NpsRating, { value, maxValue, onChange: handleChange, color: primaryColor }),
33260
- content.variant === "emoji" && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(EmojiRating, { value, onChange: handleChange, color: primaryColor }),
33261
- value !== null && content.submitActionId && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
33038
+ content.variant === "thumbs" && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(ThumbsRating, { value, onChange: handleChange, color: primaryColor }),
33039
+ content.variant === "nps" && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(NpsRating, { value, maxValue, onChange: handleChange, color: primaryColor }),
33040
+ content.variant === "emoji" && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(EmojiRating, { value, onChange: handleChange, color: primaryColor }),
33041
+ value !== null && content.submitActionId && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
33262
33042
  "button",
33263
33043
  {
33264
33044
  onClick: handleSubmit,
@@ -33281,7 +33061,7 @@ var SyntrologieSDK = (() => {
33281
33061
  }
33282
33062
 
33283
33063
  // src/blocks/interactive/ChecklistBlock.tsx
33284
- var import_jsx_runtime5 = __toESM(require_jsx_runtime(), 1);
33064
+ var import_jsx_runtime4 = __toESM(require_jsx_runtime(), 1);
33285
33065
  function ChecklistBlock({ content, accentColor }) {
33286
33066
  const primaryColor = accentColor || "var(--sc-color-primary, #6366f1)";
33287
33067
  const completedCount = content.items.filter((item) => item.completed).length;
@@ -33374,17 +33154,17 @@ var SyntrologieSDK = (() => {
33374
33154
  window.location.href = href;
33375
33155
  }
33376
33156
  };
33377
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { style: containerStyle, children: [
33378
- content.showProgress !== false && totalCount > 0 && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { style: progressStyle, children: [
33379
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("span", { children: [
33157
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { style: containerStyle, children: [
33158
+ content.showProgress !== false && totalCount > 0 && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { style: progressStyle, children: [
33159
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("span", { children: [
33380
33160
  completedCount,
33381
33161
  " of ",
33382
33162
  totalCount
33383
33163
  ] }),
33384
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { style: progressBarContainerStyle, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { style: progressBarStyle }) })
33164
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { style: progressBarContainerStyle, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { style: progressBarStyle }) })
33385
33165
  ] }),
33386
- content.items.map((item) => /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { style: itemStyle(item.completed ?? false), children: [
33387
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { style: checkboxStyle(item.completed ?? false), children: item.completed && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("svg", { width: "12", height: "12", viewBox: "0 0 24 24", fill: "none", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
33166
+ content.items.map((item) => /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { style: itemStyle(item.completed ?? false), children: [
33167
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { style: checkboxStyle(item.completed ?? false), children: item.completed && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("svg", { width: "12", height: "12", viewBox: "0 0 24 24", fill: "none", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
33388
33168
  "path",
33389
33169
  {
33390
33170
  d: "M20 6L9 17l-5-5",
@@ -33394,11 +33174,11 @@ var SyntrologieSDK = (() => {
33394
33174
  strokeLinejoin: "round"
33395
33175
  }
33396
33176
  ) }) }),
33397
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { style: textContainerStyle, children: [
33398
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { style: titleStyle(item.completed ?? false), children: item.title }),
33399
- item.description && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { style: descriptionStyle, children: item.description })
33177
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { style: textContainerStyle, children: [
33178
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { style: titleStyle(item.completed ?? false), children: item.title }),
33179
+ item.description && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { style: descriptionStyle, children: item.description })
33400
33180
  ] }),
33401
- item.href && !item.completed && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
33181
+ item.href && !item.completed && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
33402
33182
  "button",
33403
33183
  {
33404
33184
  style: linkButtonStyle,
@@ -33414,7 +33194,7 @@ var SyntrologieSDK = (() => {
33414
33194
  },
33415
33195
  children: [
33416
33196
  item.linkLabel || "Go",
33417
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("svg", { width: "12", height: "12", viewBox: "0 0 24 24", fill: "none", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
33197
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("svg", { width: "12", height: "12", viewBox: "0 0 24 24", fill: "none", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
33418
33198
  "path",
33419
33199
  {
33420
33200
  d: "M5 12h14M12 5l7 7-7 7",
@@ -33431,46 +33211,267 @@ var SyntrologieSDK = (() => {
33431
33211
  ] });
33432
33212
  }
33433
33213
 
33434
- // src/blocks/index.tsx
33435
- var import_jsx_runtime6 = __toESM(require_jsx_runtime(), 1);
33436
- function isNotificationContent(content) {
33437
- return ["alert", "success", "warning", "info", "error"].includes(content.type);
33438
- }
33439
- function isStatsContent(content) {
33440
- return content.type === "stats";
33441
- }
33442
- function isComparisonContent(content) {
33443
- return content.type === "comparison";
33444
- }
33445
- function isRatingContent(content) {
33446
- return content.type === "rating";
33447
- }
33448
- function isChecklistContent(content) {
33449
- return content.type === "checklist";
33450
- }
33451
- function renderBlock(content, options = {}) {
33452
- if (isNotificationContent(content)) {
33453
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
33454
- NotificationBlock,
33214
+ // src/blocks/notification/NotificationBlock.tsx
33215
+ var import_react4 = __toESM(require_react(), 1);
33216
+ var import_jsx_runtime5 = __toESM(require_jsx_runtime(), 1);
33217
+ var Icons = {
33218
+ success: () => /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("svg", { width: "20", height: "20", viewBox: "0 0 20 20", fill: "none", children: [
33219
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("circle", { cx: "10", cy: "10", r: "9", stroke: "currentColor", strokeWidth: "1.5" }),
33220
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
33221
+ "path",
33455
33222
  {
33456
- content,
33457
- accentColor: options.accentColor,
33458
- onDismiss: options.onDismiss
33223
+ d: "M6 10l2.5 2.5L14 7",
33224
+ stroke: "currentColor",
33225
+ strokeWidth: "1.5",
33226
+ strokeLinecap: "round",
33227
+ strokeLinejoin: "round"
33459
33228
  }
33460
- );
33461
- }
33462
- if (isStatsContent(content)) {
33463
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(StatsBlock, { content, accentColor: options.accentColor });
33464
- }
33465
- if (isComparisonContent(content)) {
33466
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(ComparisonBlock, { content, accentColor: options.accentColor });
33467
- }
33468
- if (isRatingContent(content)) {
33469
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
33470
- RatingBlock,
33229
+ )
33230
+ ] }),
33231
+ warning: () => /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("svg", { width: "20", height: "20", viewBox: "0 0 20 20", fill: "none", children: [
33232
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
33233
+ "path",
33471
33234
  {
33472
- content,
33473
- accentColor: options.accentColor,
33235
+ d: "M10 2L18 17H2L10 2Z",
33236
+ stroke: "currentColor",
33237
+ strokeWidth: "1.5",
33238
+ strokeLinejoin: "round"
33239
+ }
33240
+ ),
33241
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "M10 8v4", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round" }),
33242
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("circle", { cx: "10", cy: "14", r: "0.75", fill: "currentColor" })
33243
+ ] }),
33244
+ error: () => /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("svg", { width: "20", height: "20", viewBox: "0 0 20 20", fill: "none", children: [
33245
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("circle", { cx: "10", cy: "10", r: "9", stroke: "currentColor", strokeWidth: "1.5" }),
33246
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "M7 7l6 6M13 7l-6 6", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round" })
33247
+ ] }),
33248
+ info: () => /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("svg", { width: "20", height: "20", viewBox: "0 0 20 20", fill: "none", children: [
33249
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("circle", { cx: "10", cy: "10", r: "9", stroke: "currentColor", strokeWidth: "1.5" }),
33250
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "M10 9v5", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round" }),
33251
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("circle", { cx: "10", cy: "6", r: "0.75", fill: "currentColor" })
33252
+ ] }),
33253
+ alert: () => /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("svg", { width: "20", height: "20", viewBox: "0 0 20 20", fill: "none", children: [
33254
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("circle", { cx: "10", cy: "10", r: "9", stroke: "currentColor", strokeWidth: "1.5" }),
33255
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "M10 5v6", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round" }),
33256
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("circle", { cx: "10", cy: "14", r: "0.75", fill: "currentColor" })
33257
+ ] })
33258
+ };
33259
+ function DismissButton({ onClick, color }) {
33260
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
33261
+ "button",
33262
+ {
33263
+ onClick: (e2) => {
33264
+ e2.stopPropagation();
33265
+ onClick();
33266
+ },
33267
+ style: {
33268
+ position: "absolute",
33269
+ top: "8px",
33270
+ right: "8px",
33271
+ width: "20px",
33272
+ height: "20px",
33273
+ padding: 0,
33274
+ border: "none",
33275
+ background: "rgba(255, 255, 255, 0.1)",
33276
+ borderRadius: "50%",
33277
+ cursor: "pointer",
33278
+ display: "flex",
33279
+ alignItems: "center",
33280
+ justifyContent: "center",
33281
+ color,
33282
+ opacity: 0.6,
33283
+ transition: "opacity 0.15s ease"
33284
+ },
33285
+ onMouseEnter: (e2) => {
33286
+ e2.currentTarget.style.opacity = "1";
33287
+ },
33288
+ onMouseLeave: (e2) => {
33289
+ e2.currentTarget.style.opacity = "0.6";
33290
+ },
33291
+ "aria-label": "Dismiss",
33292
+ children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("svg", { width: "10", height: "10", viewBox: "0 0 10 10", fill: "none", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "M1 1l8 8M9 1l-8 8", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round" }) })
33293
+ }
33294
+ );
33295
+ }
33296
+ function getSemanticColors(type) {
33297
+ const colors = {
33298
+ success: {
33299
+ bg: "var(--sc-color-success-muted, rgba(52, 199, 89, 0.15))",
33300
+ border: "var(--sc-color-success, #34c759)",
33301
+ icon: "var(--sc-color-success, #34c759)",
33302
+ text: "var(--sc-color-text, #f5f5f7)"
33303
+ },
33304
+ warning: {
33305
+ bg: "var(--sc-color-warning-muted, rgba(255, 159, 10, 0.15))",
33306
+ border: "var(--sc-color-warning, #ff9f0a)",
33307
+ icon: "var(--sc-color-warning, #ff9f0a)",
33308
+ text: "var(--sc-color-text, #f5f5f7)"
33309
+ },
33310
+ error: {
33311
+ bg: "var(--sc-color-error-muted, rgba(255, 69, 58, 0.15))",
33312
+ border: "var(--sc-color-error, #ff453a)",
33313
+ icon: "var(--sc-color-error, #ff453a)",
33314
+ text: "var(--sc-color-text, #f5f5f7)"
33315
+ },
33316
+ info: {
33317
+ bg: "var(--sc-color-info-muted, rgba(10, 132, 255, 0.15))",
33318
+ border: "var(--sc-color-info, #0a84ff)",
33319
+ icon: "var(--sc-color-info, #0a84ff)",
33320
+ text: "var(--sc-color-text, #f5f5f7)"
33321
+ },
33322
+ alert: {
33323
+ bg: "var(--sc-color-primary-muted, rgba(99, 102, 241, 0.15))",
33324
+ border: "var(--sc-color-primary, #6366f1)",
33325
+ icon: "var(--sc-color-primary, #6366f1)",
33326
+ text: "var(--sc-color-text, #f5f5f7)"
33327
+ }
33328
+ };
33329
+ return colors[type] || colors.info;
33330
+ }
33331
+ function NotificationBlock({
33332
+ content,
33333
+ onDismiss,
33334
+ accentColor: _accentColor
33335
+ }) {
33336
+ const [isDismissed, setIsDismissed] = (0, import_react4.useState)(false);
33337
+ const [countdown, setCountdown] = (0, import_react4.useState)(
33338
+ content.type === "warning" ? content.countdown ?? null : null
33339
+ );
33340
+ (0, import_react4.useEffect)(() => {
33341
+ if (countdown === null || countdown <= 0) return;
33342
+ const timer = setInterval(() => {
33343
+ setCountdown((prev) => prev !== null && prev > 0 ? prev - 1 : null);
33344
+ }, 1e3);
33345
+ return () => clearInterval(timer);
33346
+ }, [countdown]);
33347
+ const handleDismiss = () => {
33348
+ setIsDismissed(true);
33349
+ setTimeout(() => onDismiss?.(), 200);
33350
+ };
33351
+ const colors = getSemanticColors(content.type);
33352
+ const Icon = Icons[content.type];
33353
+ const containerStyle = {
33354
+ position: "relative",
33355
+ padding: "var(--sc-spacing-md, 0.75rem)",
33356
+ borderRadius: "var(--sc-border-radius-md, 10px)",
33357
+ background: colors.bg,
33358
+ borderLeft: `3px solid ${colors.border}`,
33359
+ opacity: isDismissed ? 0 : 1,
33360
+ transform: isDismissed ? "translateX(10px)" : "translateX(0)",
33361
+ transition: "opacity 0.2s ease, transform 0.2s ease"
33362
+ };
33363
+ const headerStyle = {
33364
+ display: "flex",
33365
+ alignItems: "flex-start",
33366
+ gap: "var(--sc-spacing-sm, 0.5rem)"
33367
+ };
33368
+ const iconStyle = {
33369
+ color: colors.icon,
33370
+ flexShrink: 0,
33371
+ marginTop: "1px"
33372
+ };
33373
+ const contentStyle = {
33374
+ flex: 1,
33375
+ minWidth: 0,
33376
+ paddingRight: content.dismissible ? "24px" : 0
33377
+ };
33378
+ const titleStyle = {
33379
+ fontSize: "var(--sc-font-size-md, 0.9rem)",
33380
+ fontWeight: "var(--sc-font-weight-semibold, 600)",
33381
+ color: colors.text,
33382
+ margin: 0,
33383
+ lineHeight: "var(--sc-line-height-tight, 1.25)"
33384
+ };
33385
+ const bodyStyle = {
33386
+ fontSize: "var(--sc-font-size-sm, 0.8rem)",
33387
+ color: "var(--sc-color-text-secondary, #a1a1a6)",
33388
+ margin: "var(--sc-spacing-xs, 0.25rem) 0 0",
33389
+ lineHeight: "var(--sc-line-height-normal, 1.5)"
33390
+ };
33391
+ const timestampStyle = {
33392
+ fontSize: "var(--sc-font-size-xs, 0.7rem)",
33393
+ color: "var(--sc-color-text-muted, #8e8e93)",
33394
+ marginTop: "var(--sc-spacing-sm, 0.5rem)"
33395
+ };
33396
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { style: containerStyle, children: [
33397
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { style: headerStyle, children: [
33398
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { style: iconStyle, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Icon, {}) }),
33399
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { style: contentStyle, children: [
33400
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("h4", { style: titleStyle, children: content.title }),
33401
+ content.body && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { style: bodyStyle, children: content.body }),
33402
+ content.type === "error" && content.errorCode && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("p", { style: { ...bodyStyle, fontFamily: "var(--sc-font-family-mono, monospace)" }, children: [
33403
+ "Code: ",
33404
+ content.errorCode
33405
+ ] }),
33406
+ content.type === "info" && content.learnMoreUrl && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
33407
+ "a",
33408
+ {
33409
+ href: content.learnMoreUrl,
33410
+ target: "_blank",
33411
+ rel: "noopener noreferrer",
33412
+ style: {
33413
+ display: "inline-block",
33414
+ marginTop: "var(--sc-spacing-sm, 0.5rem)",
33415
+ fontSize: "var(--sc-font-size-sm, 0.8rem)",
33416
+ color: colors.icon,
33417
+ textDecoration: "none"
33418
+ },
33419
+ onClick: (e2) => e2.stopPropagation(),
33420
+ children: "Learn more \u2192"
33421
+ }
33422
+ ),
33423
+ countdown !== null && countdown > 0 && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("p", { style: { ...bodyStyle, color: colors.icon }, children: [
33424
+ "Action required in ",
33425
+ countdown,
33426
+ "s"
33427
+ ] }),
33428
+ content.timestamp && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { style: timestampStyle, children: content.timestamp })
33429
+ ] })
33430
+ ] }),
33431
+ content.dismissible && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(DismissButton, { onClick: handleDismiss, color: colors.text })
33432
+ ] });
33433
+ }
33434
+
33435
+ // src/blocks/index.tsx
33436
+ var import_jsx_runtime6 = __toESM(require_jsx_runtime(), 1);
33437
+ function isNotificationContent(content) {
33438
+ return ["alert", "success", "warning", "info", "error"].includes(content.type);
33439
+ }
33440
+ function isStatsContent(content) {
33441
+ return content.type === "stats";
33442
+ }
33443
+ function isComparisonContent(content) {
33444
+ return content.type === "comparison";
33445
+ }
33446
+ function isRatingContent(content) {
33447
+ return content.type === "rating";
33448
+ }
33449
+ function isChecklistContent(content) {
33450
+ return content.type === "checklist";
33451
+ }
33452
+ function renderBlock(content, options = {}) {
33453
+ if (isNotificationContent(content)) {
33454
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
33455
+ NotificationBlock,
33456
+ {
33457
+ content,
33458
+ accentColor: options.accentColor,
33459
+ onDismiss: options.onDismiss
33460
+ }
33461
+ );
33462
+ }
33463
+ if (isStatsContent(content)) {
33464
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(StatsBlock, { content, accentColor: options.accentColor });
33465
+ }
33466
+ if (isComparisonContent(content)) {
33467
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(ComparisonBlock, { content, accentColor: options.accentColor });
33468
+ }
33469
+ if (isRatingContent(content)) {
33470
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
33471
+ RatingBlock,
33472
+ {
33473
+ content,
33474
+ accentColor: options.accentColor,
33474
33475
  onSubmit: options.onRatingSubmit
33475
33476
  }
33476
33477
  );
@@ -33507,85 +33508,6 @@ var SyntrologieSDK = (() => {
33507
33508
  return newBlockTypes.includes(type);
33508
33509
  }
33509
33510
 
33510
- // src/RuntimeProvider.tsx
33511
- var import_react5 = __toESM(require_react(), 1);
33512
- var import_jsx_runtime7 = __toESM(require_jsx_runtime(), 1);
33513
- var RuntimeReactContext = (0, import_react5.createContext)({
33514
- runtime: null,
33515
- context: null
33516
- });
33517
- function RuntimeProvider({ runtime: runtime3, children }) {
33518
- const [context, setContext] = (0, import_react5.useState)(
33519
- runtime3 ? runtime3.context.get() : null
33520
- );
33521
- (0, import_react5.useEffect)(() => {
33522
- if (!runtime3) return;
33523
- setContext(runtime3.context.get());
33524
- const unsubscribe2 = runtime3.context.subscribe((ctx) => {
33525
- setContext(ctx);
33526
- });
33527
- return unsubscribe2;
33528
- }, [runtime3]);
33529
- const value = (0, import_react5.useMemo)(() => ({ runtime: runtime3, context }), [runtime3, context]);
33530
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(RuntimeReactContext.Provider, { value, children });
33531
- }
33532
- function useRuntime() {
33533
- const { runtime: runtime3 } = (0, import_react5.useContext)(RuntimeReactContext);
33534
- return runtime3;
33535
- }
33536
- function useRuntimeContext() {
33537
- const { context } = (0, import_react5.useContext)(RuntimeReactContext);
33538
- return context;
33539
- }
33540
- function usePageContext() {
33541
- const context = useRuntimeContext();
33542
- return context?.page ?? null;
33543
- }
33544
- function useSessionContext() {
33545
- const context = useRuntimeContext();
33546
- return context?.session ?? null;
33547
- }
33548
- function useViewportContext() {
33549
- const context = useRuntimeContext();
33550
- return context?.viewport ?? null;
33551
- }
33552
- function useRuntimeEvents(filter, callback, deps = []) {
33553
- const runtime3 = useRuntime();
33554
- (0, import_react5.useEffect)(() => {
33555
- if (!runtime3) return;
33556
- const unsubscribe2 = filter ? runtime3.events.subscribe(filter, callback) : runtime3.events.subscribe(callback);
33557
- return unsubscribe2;
33558
- }, [runtime3, ...deps]);
33559
- }
33560
- function useRuntimeState() {
33561
- const runtime3 = useRuntime();
33562
- return runtime3?.state ?? null;
33563
- }
33564
- function useDecision(strategy, defaultValue) {
33565
- const runtime3 = useRuntime();
33566
- const [result, setResult] = (0, import_react5.useState)({
33567
- value: defaultValue,
33568
- isFallback: true,
33569
- isLoading: true
33570
- });
33571
- (0, import_react5.useEffect)(() => {
33572
- if (!runtime3 || !strategy) {
33573
- setResult({ value: defaultValue, isFallback: true, isLoading: false });
33574
- return;
33575
- }
33576
- let cancelled = false;
33577
- runtime3.evaluate(strategy).then((res) => {
33578
- if (!cancelled) {
33579
- setResult({ value: res.value, isFallback: res.isFallback, isLoading: false });
33580
- }
33581
- });
33582
- return () => {
33583
- cancelled = true;
33584
- };
33585
- }, [runtime3, strategy, defaultValue]);
33586
- return result;
33587
- }
33588
-
33589
33511
  // src/events/types.ts
33590
33512
  var StandardEvents = {
33591
33513
  // UI events (from PostHog autocapture)
@@ -33700,6 +33622,85 @@ var SyntrologieSDK = (() => {
33700
33622
  custom: customCanvasEvent
33701
33623
  };
33702
33624
 
33625
+ // src/RuntimeProvider.tsx
33626
+ var import_react5 = __toESM(require_react(), 1);
33627
+ var import_jsx_runtime7 = __toESM(require_jsx_runtime(), 1);
33628
+ var RuntimeReactContext = (0, import_react5.createContext)({
33629
+ runtime: null,
33630
+ context: null
33631
+ });
33632
+ function RuntimeProvider({ runtime: runtime3, children }) {
33633
+ const [context, setContext] = (0, import_react5.useState)(
33634
+ runtime3 ? runtime3.context.get() : null
33635
+ );
33636
+ (0, import_react5.useEffect)(() => {
33637
+ if (!runtime3) return;
33638
+ setContext(runtime3.context.get());
33639
+ const unsubscribe2 = runtime3.context.subscribe((ctx) => {
33640
+ setContext(ctx);
33641
+ });
33642
+ return unsubscribe2;
33643
+ }, [runtime3]);
33644
+ const value = (0, import_react5.useMemo)(() => ({ runtime: runtime3, context }), [runtime3, context]);
33645
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(RuntimeReactContext.Provider, { value, children });
33646
+ }
33647
+ function useRuntime() {
33648
+ const { runtime: runtime3 } = (0, import_react5.useContext)(RuntimeReactContext);
33649
+ return runtime3;
33650
+ }
33651
+ function useRuntimeContext() {
33652
+ const { context } = (0, import_react5.useContext)(RuntimeReactContext);
33653
+ return context;
33654
+ }
33655
+ function usePageContext() {
33656
+ const context = useRuntimeContext();
33657
+ return context?.page ?? null;
33658
+ }
33659
+ function useSessionContext() {
33660
+ const context = useRuntimeContext();
33661
+ return context?.session ?? null;
33662
+ }
33663
+ function useViewportContext() {
33664
+ const context = useRuntimeContext();
33665
+ return context?.viewport ?? null;
33666
+ }
33667
+ function useRuntimeEvents(filter, callback, deps = []) {
33668
+ const runtime3 = useRuntime();
33669
+ (0, import_react5.useEffect)(() => {
33670
+ if (!runtime3) return;
33671
+ const unsubscribe2 = filter ? runtime3.events.subscribe(filter, callback) : runtime3.events.subscribe(callback);
33672
+ return unsubscribe2;
33673
+ }, [runtime3, ...deps]);
33674
+ }
33675
+ function useRuntimeState() {
33676
+ const runtime3 = useRuntime();
33677
+ return runtime3?.state ?? null;
33678
+ }
33679
+ function useDecision(strategy, defaultValue) {
33680
+ const runtime3 = useRuntime();
33681
+ const [result, setResult] = (0, import_react5.useState)({
33682
+ value: defaultValue,
33683
+ isFallback: true,
33684
+ isLoading: true
33685
+ });
33686
+ (0, import_react5.useEffect)(() => {
33687
+ if (!runtime3 || !strategy) {
33688
+ setResult({ value: defaultValue, isFallback: true, isLoading: false });
33689
+ return;
33690
+ }
33691
+ let cancelled = false;
33692
+ runtime3.evaluate(strategy).then((res) => {
33693
+ if (!cancelled) {
33694
+ setResult({ value: res.value, isFallback: res.isFallback, isLoading: false });
33695
+ }
33696
+ });
33697
+ return () => {
33698
+ cancelled = true;
33699
+ };
33700
+ }, [runtime3, strategy, defaultValue]);
33701
+ return result;
33702
+ }
33703
+
33703
33704
  // src/components/TileCard.tsx
33704
33705
  var import_jsx_runtime8 = __toESM(require_jsx_runtime(), 1);
33705
33706
  function ChatbotBlock({ config, telemetry, surface }) {
@@ -34660,38 +34661,36 @@ var SyntrologieSDK = (() => {
34660
34661
  featureKey,
34661
34662
  credentials,
34662
34663
  configFeatureKey = "smart-canvas-config"
34663
- }) => {
34664
- return async () => {
34665
- if (experiments && configFeatureKey) {
34666
- const directConfig = experiments.getFeatureValue?.(configFeatureKey, null);
34667
- if (directConfig && typeof directConfig === "object") {
34668
- debug("SmartCanvas Config", "Resolved config directly from feature flag", directConfig);
34669
- return directConfig;
34670
- }
34671
- }
34672
- const uri = resolveConfigUri({ configUri, experiments, featureKey });
34673
- if (!uri) {
34674
- debug("SmartCanvas Config", "No config available \u2014 returning empty config");
34675
- return { tiles: [], overlays: [] };
34664
+ }) => async () => {
34665
+ if (experiments && configFeatureKey) {
34666
+ const directConfig = experiments.getFeatureValue?.(configFeatureKey, null);
34667
+ if (directConfig && typeof directConfig === "object") {
34668
+ debug("SmartCanvas Config", "Resolved config directly from feature flag", directConfig);
34669
+ return directConfig;
34676
34670
  }
34677
- if (!validateConfigUri(uri)) {
34678
- throw new Error(`SmartCanvas: config URI not allowed: ${uri}`);
34679
- }
34680
- const effectiveCredentials = credentials ?? (isSameOrigin(uri) ? "include" : "omit");
34681
- const response = await fetch(uri, {
34682
- credentials: effectiveCredentials,
34683
- headers: {
34684
- "X-SDK-Version": SDK_VERSION,
34685
- "X-SDK-Schema-Version": SDK_SCHEMA_VERSION
34686
- }
34687
- });
34688
- if (!response.ok) {
34689
- throw new Error(`SmartCanvas: failed to fetch config (${response.status})`);
34671
+ }
34672
+ const uri = resolveConfigUri({ configUri, experiments, featureKey });
34673
+ if (!uri) {
34674
+ debug("SmartCanvas Config", "No config available \u2014 returning empty config");
34675
+ return { tiles: [], overlays: [] };
34676
+ }
34677
+ if (!validateConfigUri(uri)) {
34678
+ throw new Error(`SmartCanvas: config URI not allowed: ${uri}`);
34679
+ }
34680
+ const effectiveCredentials = credentials ?? (isSameOrigin(uri) ? "include" : "omit");
34681
+ const response = await fetch(uri, {
34682
+ credentials: effectiveCredentials,
34683
+ headers: {
34684
+ "X-SDK-Version": SDK_VERSION,
34685
+ "X-SDK-Schema-Version": SDK_SCHEMA_VERSION
34690
34686
  }
34691
- const config = await response.json();
34692
- debug("SmartCanvas Config", "Fetched config from URI", config);
34693
- return config;
34694
- };
34687
+ });
34688
+ if (!response.ok) {
34689
+ throw new Error(`SmartCanvas: failed to fetch config (${response.status})`);
34690
+ }
34691
+ const config = await response.json();
34692
+ debug("SmartCanvas Config", "Fetched config from URI", config);
34693
+ return config;
34695
34694
  };
34696
34695
 
34697
34696
  // src/SmartCanvasApp.tsx
@@ -34709,7 +34708,7 @@ var SyntrologieSDK = (() => {
34709
34708
  function matchRoute(pattern, pathname) {
34710
34709
  if (pattern.endsWith("/*")) {
34711
34710
  const prefix = pattern.slice(0, -2);
34712
- return pathname === prefix || pathname.startsWith(prefix + "/");
34711
+ return pathname === prefix || pathname.startsWith(`${prefix}/`);
34713
34712
  }
34714
34713
  return pathname === pattern;
34715
34714
  }
@@ -35138,7 +35137,7 @@ var SyntrologieSDK = (() => {
35138
35137
  debug("Syntro Runtime", "\u2713 Editor URL validated");
35139
35138
  return true;
35140
35139
  } catch (e2) {
35141
- warn("Syntro Runtime", "\u274C Invalid editor URL: " + url, e2);
35140
+ warn("Syntro Runtime", `\u274C Invalid editor URL: ${url}`, e2);
35142
35141
  return false;
35143
35142
  }
35144
35143
  }
@@ -35241,7 +35240,7 @@ var SyntrologieSDK = (() => {
35241
35240
  hasIntegrity: !!options.integrity,
35242
35241
  isDefault: baseEditorUrl === DEFAULT_EDITOR_URL,
35243
35242
  hasApiBase: !!apiBase,
35244
- tokenPrefix: token.slice(0, 10) + "..."
35243
+ tokenPrefix: `${token.slice(0, 10)}...`
35245
35244
  });
35246
35245
  if (!validateEditorUrl(baseEditorUrl)) {
35247
35246
  console.error("[Syntro Runtime] \u274C BLOCKED: Editor from untrusted URL:", baseEditorUrl);
@@ -35290,7 +35289,7 @@ var SyntrologieSDK = (() => {
35290
35289
  let currentFetcher = null;
35291
35290
  let currentBatchHandle = null;
35292
35291
  let isEnabled = true;
35293
- const runtime3 = config.runtime;
35292
+ const { runtime: runtime3 } = config;
35294
35293
  async function applyActions(actions) {
35295
35294
  if (!runtime3?.actions || actions.length === 0) {
35296
35295
  return;
@@ -35423,9 +35422,7 @@ var SyntrologieSDK = (() => {
35423
35422
  registerTelemetryProperties: (properties) => {
35424
35423
  telemetry?.register?.(properties);
35425
35424
  },
35426
- getSessionId: () => {
35427
- return telemetry?.getSessionId?.();
35428
- },
35425
+ getSessionId: () => telemetry?.getSessionId?.(),
35429
35426
  startSessionRecording: () => {
35430
35427
  telemetry?.startSessionRecording?.();
35431
35428
  },
@@ -39543,19 +39540,17 @@ var SyntrologieSDK = (() => {
39543
39540
  experiments,
39544
39541
  featureKey = "smart-canvas-overlay-uri",
39545
39542
  credentials = "include"
39546
- } = {}) => {
39547
- return async () => {
39548
- const uri = resolveConfigUri({ configUri, experiments, featureKey });
39549
- if (!uri) {
39550
- throw new Error("SmartCanvas overlays: recipe URI missing (env + feature unset).");
39551
- }
39552
- const response = await fetch(uri, { credentials });
39553
- if (!response.ok) {
39554
- throw new Error(`SmartCanvas overlays: failed to fetch recipe (${response.status})`);
39555
- }
39556
- const json = await response.json();
39557
- return CanvasRecipeZ.parse(json);
39558
- };
39543
+ } = {}) => async () => {
39544
+ const uri = resolveConfigUri({ configUri, experiments, featureKey });
39545
+ if (!uri) {
39546
+ throw new Error("SmartCanvas overlays: recipe URI missing (env + feature unset).");
39547
+ }
39548
+ const response = await fetch(uri, { credentials });
39549
+ if (!response.ok) {
39550
+ throw new Error(`SmartCanvas overlays: failed to fetch recipe (${response.status})`);
39551
+ }
39552
+ const json = await response.json();
39553
+ return CanvasRecipeZ.parse(json);
39559
39554
  };
39560
39555
 
39561
39556
  // src/metrics/sessionMetrics.ts
@@ -39924,7 +39919,7 @@ var SyntrologieSDK = (() => {
39924
39919
  }
39925
39920
  updatePage() {
39926
39921
  const url = window.location.href;
39927
- const title = document.title;
39922
+ const { title } = document;
39928
39923
  const routeId = matchRoute2(url, this.routes);
39929
39924
  const newPage = {
39930
39925
  url,
@@ -40254,39 +40249,6 @@ var SyntrologieSDK = (() => {
40254
40249
  return FrequencyEntryZ.safeParse(data);
40255
40250
  }
40256
40251
 
40257
- // src/state/helpers/dismissals.ts
40258
- var DISMISSAL_PREFIX = "dismissed:";
40259
- function createDismissalStore(sessionStorage2, userStorage) {
40260
- return {
40261
- mark(key, permanent = false) {
40262
- const storageKey = DISMISSAL_PREFIX + key;
40263
- const storage = permanent ? userStorage : sessionStorage2;
40264
- storage.set(storageKey, true);
40265
- },
40266
- isDismissed(key) {
40267
- const storageKey = DISMISSAL_PREFIX + key;
40268
- return sessionStorage2.has(storageKey) || userStorage.has(storageKey);
40269
- },
40270
- clear(key) {
40271
- const storageKey = DISMISSAL_PREFIX + key;
40272
- sessionStorage2.remove(storageKey);
40273
- userStorage.remove(storageKey);
40274
- },
40275
- clearAll() {
40276
- for (const key of sessionStorage2.keys()) {
40277
- if (key.startsWith(DISMISSAL_PREFIX)) {
40278
- sessionStorage2.remove(key);
40279
- }
40280
- }
40281
- for (const key of userStorage.keys()) {
40282
- if (key.startsWith(DISMISSAL_PREFIX)) {
40283
- userStorage.remove(key);
40284
- }
40285
- }
40286
- }
40287
- };
40288
- }
40289
-
40290
40252
  // src/state/helpers/cooldowns.ts
40291
40253
  var COOLDOWN_PREFIX = "cooldown:";
40292
40254
  function createCooldownStore(storage) {
@@ -40311,8 +40273,41 @@ var SyntrologieSDK = (() => {
40311
40273
  return remaining;
40312
40274
  },
40313
40275
  clear(key) {
40314
- const storageKey = COOLDOWN_PREFIX + key;
40315
- storage.remove(storageKey);
40276
+ const storageKey = COOLDOWN_PREFIX + key;
40277
+ storage.remove(storageKey);
40278
+ }
40279
+ };
40280
+ }
40281
+
40282
+ // src/state/helpers/dismissals.ts
40283
+ var DISMISSAL_PREFIX = "dismissed:";
40284
+ function createDismissalStore(sessionStorage2, userStorage) {
40285
+ return {
40286
+ mark(key, permanent = false) {
40287
+ const storageKey = DISMISSAL_PREFIX + key;
40288
+ const storage = permanent ? userStorage : sessionStorage2;
40289
+ storage.set(storageKey, true);
40290
+ },
40291
+ isDismissed(key) {
40292
+ const storageKey = DISMISSAL_PREFIX + key;
40293
+ return sessionStorage2.has(storageKey) || userStorage.has(storageKey);
40294
+ },
40295
+ clear(key) {
40296
+ const storageKey = DISMISSAL_PREFIX + key;
40297
+ sessionStorage2.remove(storageKey);
40298
+ userStorage.remove(storageKey);
40299
+ },
40300
+ clearAll() {
40301
+ for (const key of sessionStorage2.keys()) {
40302
+ if (key.startsWith(DISMISSAL_PREFIX)) {
40303
+ sessionStorage2.remove(key);
40304
+ }
40305
+ }
40306
+ for (const key of userStorage.keys()) {
40307
+ if (key.startsWith(DISMISSAL_PREFIX)) {
40308
+ userStorage.remove(key);
40309
+ }
40310
+ }
40316
40311
  }
40317
40312
  };
40318
40313
  }
@@ -41178,98 +41173,332 @@ var SyntrologieSDK = (() => {
41178
41173
  scrim.appendChild(slice);
41179
41174
  }
41180
41175
  }
41181
- const setClipPath = (path) => {
41182
- scrim.style.clipPath = path;
41183
- scrim.style.webkitClipPath = path;
41184
- };
41185
- const update = () => {
41186
- const rect = anchorEl.getBoundingClientRect();
41187
- const x2 = Math.max(0, rect.left - padding);
41188
- const y2 = Math.max(0, rect.top - padding);
41189
- const w2 = Math.min(window.innerWidth, rect.width + padding * 2);
41190
- const h2 = Math.min(window.innerHeight, rect.height + padding * 2);
41191
- Object.assign(ring.style, {
41192
- left: `${x2}px`,
41193
- top: `${y2}px`,
41194
- width: `${w2}px`,
41195
- height: `${h2}px`
41196
- });
41197
- if (supportsPathClip) {
41198
- const vw = window.innerWidth;
41199
- const vh = window.innerHeight;
41200
- const r2 = Math.min(radius, w2 / 2, h2 / 2);
41201
- const outer = `M 0 0 L ${vw} 0 L ${vw} ${vh} L 0 ${vh} Z`;
41202
- const inner = `M ${x2 + r2} ${y2} A ${r2} ${r2} 0 0 0 ${x2} ${y2 + r2} L ${x2} ${y2 + h2 - r2} A ${r2} ${r2} 0 0 0 ${x2 + r2} ${y2 + h2} L ${x2 + w2 - r2} ${y2 + h2} A ${r2} ${r2} 0 0 0 ${x2 + w2} ${y2 + h2 - r2} L ${x2 + w2} ${y2 + r2} A ${r2} ${r2} 0 0 0 ${x2 + w2 - r2} ${y2} L ${x2 + r2} ${y2} Z`;
41203
- setClipPath(`path('${outer} ${inner}')`);
41204
- } else {
41205
- const [top, right, bottom, left] = fallbackSlices;
41206
- Object.assign(top.style, {
41207
- left: "0px",
41208
- top: "0px",
41209
- width: "100vw",
41210
- height: `${y2}px`
41211
- });
41212
- Object.assign(bottom.style, {
41213
- left: "0px",
41214
- top: `${y2 + h2}px`,
41215
- width: "100vw",
41216
- height: `${Math.max(0, window.innerHeight - (y2 + h2))}px`
41217
- });
41218
- Object.assign(left.style, {
41219
- left: "0px",
41220
- top: `${y2}px`,
41221
- width: `${x2}px`,
41222
- height: `${h2}px`
41223
- });
41224
- Object.assign(right.style, {
41225
- left: `${x2 + w2}px`,
41226
- top: `${y2}px`,
41227
- width: `${Math.max(0, window.innerWidth - (x2 + w2))}px`,
41228
- height: `${h2}px`
41176
+ const setClipPath = (path) => {
41177
+ scrim.style.clipPath = path;
41178
+ scrim.style.webkitClipPath = path;
41179
+ };
41180
+ const update = () => {
41181
+ const rect = anchorEl.getBoundingClientRect();
41182
+ const x2 = Math.max(0, rect.left - padding);
41183
+ const y2 = Math.max(0, rect.top - padding);
41184
+ const w2 = Math.min(window.innerWidth, rect.width + padding * 2);
41185
+ const h2 = Math.min(window.innerHeight, rect.height + padding * 2);
41186
+ Object.assign(ring.style, {
41187
+ left: `${x2}px`,
41188
+ top: `${y2}px`,
41189
+ width: `${w2}px`,
41190
+ height: `${h2}px`
41191
+ });
41192
+ if (supportsPathClip) {
41193
+ const vw = window.innerWidth;
41194
+ const vh = window.innerHeight;
41195
+ const r2 = Math.min(radius, w2 / 2, h2 / 2);
41196
+ const outer = `M 0 0 L ${vw} 0 L ${vw} ${vh} L 0 ${vh} Z`;
41197
+ const inner = `M ${x2 + r2} ${y2} A ${r2} ${r2} 0 0 0 ${x2} ${y2 + r2} L ${x2} ${y2 + h2 - r2} A ${r2} ${r2} 0 0 0 ${x2 + r2} ${y2 + h2} L ${x2 + w2 - r2} ${y2 + h2} A ${r2} ${r2} 0 0 0 ${x2 + w2} ${y2 + h2 - r2} L ${x2 + w2} ${y2 + r2} A ${r2} ${r2} 0 0 0 ${x2 + w2 - r2} ${y2} L ${x2 + r2} ${y2} Z`;
41198
+ setClipPath(`path('${outer} ${inner}')`);
41199
+ } else {
41200
+ const [top, right, bottom, left] = fallbackSlices;
41201
+ Object.assign(top.style, {
41202
+ left: "0px",
41203
+ top: "0px",
41204
+ width: "100vw",
41205
+ height: `${y2}px`
41206
+ });
41207
+ Object.assign(bottom.style, {
41208
+ left: "0px",
41209
+ top: `${y2 + h2}px`,
41210
+ width: "100vw",
41211
+ height: `${Math.max(0, window.innerHeight - (y2 + h2))}px`
41212
+ });
41213
+ Object.assign(left.style, {
41214
+ left: "0px",
41215
+ top: `${y2}px`,
41216
+ width: `${x2}px`,
41217
+ height: `${h2}px`
41218
+ });
41219
+ Object.assign(right.style, {
41220
+ left: `${x2 + w2}px`,
41221
+ top: `${y2}px`,
41222
+ width: `${Math.max(0, window.innerWidth - (x2 + w2))}px`,
41223
+ height: `${h2}px`
41224
+ });
41225
+ }
41226
+ };
41227
+ const ro2 = new ResizeObserver(() => requestAnimationFrame(update));
41228
+ ro2.observe(anchorEl);
41229
+ const onScroll = () => requestAnimationFrame(update);
41230
+ const onResize = () => requestAnimationFrame(update);
41231
+ window.addEventListener("scroll", onScroll, true);
41232
+ window.addEventListener("resize", onResize);
41233
+ const onKey = (e2) => {
41234
+ if (e2.key === "Escape" && onEsc)
41235
+ handle.destroy();
41236
+ };
41237
+ if (onEsc) {
41238
+ window.addEventListener("keydown", onKey);
41239
+ }
41240
+ const onClick = (event) => {
41241
+ if (blocking) {
41242
+ event.preventDefault();
41243
+ event.stopPropagation();
41244
+ } else if (onClickOutside) {
41245
+ handle.destroy();
41246
+ }
41247
+ };
41248
+ scrim.addEventListener("click", onClick);
41249
+ const handle = {
41250
+ destroy() {
41251
+ ro2.disconnect();
41252
+ window.removeEventListener("scroll", onScroll, true);
41253
+ window.removeEventListener("resize", onResize);
41254
+ if (onEsc) {
41255
+ window.removeEventListener("keydown", onKey);
41256
+ }
41257
+ scrim.removeEventListener("click", onClick);
41258
+ scrim.style.opacity = "0";
41259
+ setTimeout(() => {
41260
+ scrim.remove();
41261
+ ring.remove();
41262
+ }, 220);
41263
+ }
41264
+ };
41265
+ update();
41266
+ return handle;
41267
+ }
41268
+
41269
+ // ../adaptives/adaptive-overlays/dist/sanitizer.js
41270
+ var ALLOWED_TAGS2 = /* @__PURE__ */ new Set([
41271
+ "b",
41272
+ "strong",
41273
+ "i",
41274
+ "em",
41275
+ "u",
41276
+ "span",
41277
+ "div",
41278
+ "p",
41279
+ "br",
41280
+ "ul",
41281
+ "ol",
41282
+ "li",
41283
+ "code",
41284
+ "pre",
41285
+ "small",
41286
+ "sup",
41287
+ "sub",
41288
+ "a",
41289
+ "button"
41290
+ ]);
41291
+ function sanitizeHtml2(html2) {
41292
+ const hasNative = typeof window.Sanitizer === "function";
41293
+ if (hasNative) {
41294
+ try {
41295
+ const s2 = new window.Sanitizer({});
41296
+ const frag = s2.sanitizeToFragment(html2);
41297
+ const div = document.createElement("div");
41298
+ div.append(frag);
41299
+ return div.innerHTML;
41300
+ } catch {
41301
+ }
41302
+ }
41303
+ const tpl = document.createElement("template");
41304
+ tpl.innerHTML = html2;
41305
+ const root = tpl.content;
41306
+ const walker = document.createTreeWalker(root, NodeFilter.SHOW_ELEMENT, null);
41307
+ const toRemove = [];
41308
+ while (walker.nextNode()) {
41309
+ const el = walker.currentNode;
41310
+ const tag = el.tagName.toLowerCase();
41311
+ if (!ALLOWED_TAGS2.has(tag)) {
41312
+ toRemove.push(el);
41313
+ continue;
41314
+ }
41315
+ for (const attr of Array.from(el.attributes)) {
41316
+ const name = attr.name.toLowerCase();
41317
+ const value = attr.value.trim().toLowerCase();
41318
+ const isEvent = name.startsWith("on");
41319
+ const isJsUrl = (name === "href" || name === "src") && value.startsWith("javascript:");
41320
+ if (isEvent || isJsUrl) {
41321
+ el.removeAttribute(attr.name);
41322
+ }
41323
+ }
41324
+ }
41325
+ for (const el of toRemove) {
41326
+ while (el.firstChild) {
41327
+ el.parentNode?.insertBefore(el.firstChild, el);
41328
+ }
41329
+ el.remove();
41330
+ }
41331
+ return tpl.innerHTML;
41332
+ }
41333
+
41334
+ // ../adaptives/adaptive-overlays/dist/modal.js
41335
+ var executeModal = async (action, context) => {
41336
+ const { content, size: size2 = "md", blocking = false, scrim, dismiss, ctaButtons } = action;
41337
+ const scrimEl = document.createElement("div");
41338
+ scrimEl.className = "syntro-modal-scrim";
41339
+ scrimEl.style.cssText = `
41340
+ position: fixed;
41341
+ inset: 0;
41342
+ background: rgba(0, 0, 0, ${scrim?.opacity ?? 0.6});
41343
+ z-index: 2147483645;
41344
+ opacity: 0;
41345
+ transition: opacity 200ms ease-out;
41346
+ `;
41347
+ context.overlayRoot.appendChild(scrimEl);
41348
+ const modal = document.createElement("div");
41349
+ modal.className = `syntro-modal syntro-modal-${size2}`;
41350
+ modal.setAttribute("role", "dialog");
41351
+ modal.setAttribute("aria-modal", "true");
41352
+ const sizeMap = { sm: "360px", md: "480px", lg: "640px" };
41353
+ modal.style.cssText = `
41354
+ position: fixed;
41355
+ top: 50%;
41356
+ left: 50%;
41357
+ transform: translate(-50%, -50%) scale(0.95);
41358
+ max-width: ${sizeMap[size2]};
41359
+ width: 90%;
41360
+ background: white;
41361
+ border-radius: 12px;
41362
+ box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25);
41363
+ z-index: 2147483646;
41364
+ opacity: 0;
41365
+ transition: opacity 200ms ease-out, transform 200ms ease-out;
41366
+ padding: 24px;
41367
+ `;
41368
+ let html2 = "";
41369
+ if (content.title) {
41370
+ html2 += `<h2 class="syntro-modal-title" style="margin: 0 0 12px 0; font-size: 18px; font-weight: 600; color: #111827;">${sanitizeHtml2(content.title)}</h2>`;
41371
+ }
41372
+ html2 += `<div class="syntro-modal-body" style="color: #4b5563; line-height: 1.5;">${sanitizeHtml2(content.body)}</div>`;
41373
+ if (dismiss?.closeButton !== false) {
41374
+ html2 += `
41375
+ <button class="syntro-modal-close" data-syntro-action="dismiss" style="
41376
+ position: absolute;
41377
+ top: 16px;
41378
+ right: 16px;
41379
+ background: none;
41380
+ border: none;
41381
+ cursor: pointer;
41382
+ padding: 4px;
41383
+ color: #6b7280;
41384
+ " aria-label="Close">
41385
+ <svg width="20" height="20" viewBox="0 0 20 20" fill="currentColor">
41386
+ <path fill-rule="evenodd" d="M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z" clip-rule="evenodd"/>
41387
+ </svg>
41388
+ </button>
41389
+ `;
41390
+ }
41391
+ if (ctaButtons && ctaButtons.length > 0) {
41392
+ html2 += `<div class="syntro-modal-actions" style="display: flex; gap: 12px; margin-top: 24px; justify-content: flex-end;">`;
41393
+ for (const btn of ctaButtons) {
41394
+ const isPrimary = btn.primary ?? false;
41395
+ html2 += `
41396
+ <button
41397
+ class="syntro-modal-btn ${isPrimary ? "syntro-modal-btn-primary" : ""}"
41398
+ data-syntro-action="${sanitizeHtml2(btn.actionId)}"
41399
+ style="
41400
+ padding: 10px 20px;
41401
+ border-radius: 8px;
41402
+ font-size: 14px;
41403
+ font-weight: 500;
41404
+ cursor: pointer;
41405
+ transition: background 150ms ease;
41406
+ ${isPrimary ? "background: #4f46e5; color: white; border: none;" : "background: white; color: #374151; border: 1px solid #d1d5db;"}
41407
+ "
41408
+ >
41409
+ ${sanitizeHtml2(btn.label)}
41410
+ </button>
41411
+ `;
41412
+ }
41413
+ html2 += `</div>`;
41414
+ }
41415
+ modal.innerHTML = html2;
41416
+ context.overlayRoot.appendChild(modal);
41417
+ let actionClicked = null;
41418
+ const actionBtns = modal.querySelectorAll("[data-syntro-action]");
41419
+ const actionHandler = (e2) => {
41420
+ const btn = e2.currentTarget;
41421
+ const actionId = btn.getAttribute("data-syntro-action");
41422
+ if (actionId) {
41423
+ actionClicked = actionId;
41424
+ context.publishEvent("action.modal_cta_clicked", {
41425
+ actionId
41229
41426
  });
41427
+ if (actionId === "dismiss") {
41428
+ handle.destroy();
41429
+ }
41230
41430
  }
41231
41431
  };
41232
- const ro2 = new ResizeObserver(() => requestAnimationFrame(update));
41233
- ro2.observe(anchorEl);
41234
- const onScroll = () => requestAnimationFrame(update);
41235
- const onResize = () => requestAnimationFrame(update);
41236
- window.addEventListener("scroll", onScroll, true);
41237
- window.addEventListener("resize", onResize);
41432
+ actionBtns.forEach((btn) => btn.addEventListener("click", actionHandler));
41238
41433
  const onKey = (e2) => {
41239
- if (e2.key === "Escape" && onEsc)
41434
+ if (e2.key === "Escape" && dismiss?.onEsc !== false) {
41240
41435
  handle.destroy();
41436
+ }
41241
41437
  };
41242
- if (onEsc) {
41243
- window.addEventListener("keydown", onKey);
41244
- }
41245
- const onClick = (event) => {
41246
- if (blocking) {
41247
- event.preventDefault();
41248
- event.stopPropagation();
41249
- } else if (onClickOutside) {
41438
+ window.addEventListener("keydown", onKey);
41439
+ const onScrimClick = () => {
41440
+ if (!blocking) {
41250
41441
  handle.destroy();
41251
41442
  }
41252
41443
  };
41253
- scrim.addEventListener("click", onClick);
41444
+ scrimEl.addEventListener("click", onScrimClick);
41445
+ const originalInert = [];
41446
+ if (blocking) {
41447
+ Array.from(document.body.children).forEach((el) => {
41448
+ if (el !== context.overlayRoot && el.getAttribute("inert") === null) {
41449
+ el.setAttribute("inert", "");
41450
+ originalInert.push(el);
41451
+ }
41452
+ });
41453
+ }
41454
+ let timeoutId;
41455
+ if (dismiss?.timeoutMs) {
41456
+ timeoutId = setTimeout(() => {
41457
+ handle.destroy();
41458
+ }, dismiss.timeoutMs);
41459
+ }
41460
+ const focusableEls = modal.querySelectorAll('button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])');
41461
+ if (focusableEls.length > 0) {
41462
+ requestAnimationFrame(() => focusableEls[0].focus());
41463
+ }
41464
+ requestAnimationFrame(() => {
41465
+ scrimEl.style.opacity = "1";
41466
+ modal.style.opacity = "1";
41467
+ modal.style.transform = "translate(-50%, -50%) scale(1)";
41468
+ });
41469
+ context.publishEvent("action.applied", {
41470
+ id: context.generateId(),
41471
+ kind: "overlays:modal",
41472
+ size: size2,
41473
+ blocking
41474
+ });
41254
41475
  const handle = {
41255
41476
  destroy() {
41256
- ro2.disconnect();
41257
- window.removeEventListener("scroll", onScroll, true);
41258
- window.removeEventListener("resize", onResize);
41259
- if (onEsc) {
41260
- window.removeEventListener("keydown", onKey);
41477
+ if (timeoutId) {
41478
+ clearTimeout(timeoutId);
41261
41479
  }
41262
- scrim.removeEventListener("click", onClick);
41263
- scrim.style.opacity = "0";
41480
+ window.removeEventListener("keydown", onKey);
41481
+ scrimEl.removeEventListener("click", onScrimClick);
41482
+ actionBtns.forEach((btn) => btn.removeEventListener("click", actionHandler));
41483
+ originalInert.forEach((el) => el.removeAttribute("inert"));
41484
+ modal.style.opacity = "0";
41485
+ modal.style.transform = "translate(-50%, -50%) scale(0.95)";
41486
+ scrimEl.style.opacity = "0";
41264
41487
  setTimeout(() => {
41265
- scrim.remove();
41266
- ring.remove();
41267
- }, 220);
41488
+ modal.remove();
41489
+ scrimEl.remove();
41490
+ }, 200);
41491
+ context.publishEvent("action.modal_dismissed", {
41492
+ actionClicked
41493
+ });
41268
41494
  }
41269
41495
  };
41270
- update();
41271
- return handle;
41272
- }
41496
+ return {
41497
+ cleanup: () => {
41498
+ handle.destroy();
41499
+ }
41500
+ };
41501
+ };
41273
41502
 
41274
41503
  // ../../node_modules/@floating-ui/utils/dist/floating-ui.utils.mjs
41275
41504
  var sides = ["top", "right", "bottom", "left"];
@@ -42695,113 +42924,48 @@ var SyntrologieSDK = (() => {
42695
42924
  frameLoop();
42696
42925
  }
42697
42926
  function frameLoop() {
42698
- const nextRefRect = getBoundingClientRect(reference);
42699
- if (prevRefRect && !rectsAreEqual(prevRefRect, nextRefRect)) {
42700
- update();
42701
- }
42702
- prevRefRect = nextRefRect;
42703
- frameId = requestAnimationFrame(frameLoop);
42704
- }
42705
- update();
42706
- return () => {
42707
- var _resizeObserver2;
42708
- ancestors.forEach((ancestor) => {
42709
- ancestorScroll && ancestor.removeEventListener("scroll", update);
42710
- ancestorResize && ancestor.removeEventListener("resize", update);
42711
- });
42712
- cleanupIo == null || cleanupIo();
42713
- (_resizeObserver2 = resizeObserver) == null || _resizeObserver2.disconnect();
42714
- resizeObserver = null;
42715
- if (animationFrame) {
42716
- cancelAnimationFrame(frameId);
42717
- }
42718
- };
42719
- }
42720
- var offset2 = offset;
42721
- var shift2 = shift;
42722
- var flip2 = flip;
42723
- var hide2 = hide;
42724
- var arrow2 = arrow;
42725
- var computePosition2 = (reference, floating, options) => {
42726
- const cache2 = /* @__PURE__ */ new Map();
42727
- const mergedOptions = {
42728
- platform,
42729
- ...options
42730
- };
42731
- const platformWithCache = {
42732
- ...mergedOptions.platform,
42733
- _c: cache2
42734
- };
42735
- return computePosition(reference, floating, {
42736
- ...mergedOptions,
42737
- platform: platformWithCache
42738
- });
42739
- };
42740
-
42741
- // ../adaptives/adaptive-overlays/dist/sanitizer.js
42742
- var ALLOWED_TAGS2 = /* @__PURE__ */ new Set([
42743
- "b",
42744
- "strong",
42745
- "i",
42746
- "em",
42747
- "u",
42748
- "span",
42749
- "div",
42750
- "p",
42751
- "br",
42752
- "ul",
42753
- "ol",
42754
- "li",
42755
- "code",
42756
- "pre",
42757
- "small",
42758
- "sup",
42759
- "sub",
42760
- "a",
42761
- "button"
42762
- ]);
42763
- function sanitizeHtml2(html2) {
42764
- const hasNative = typeof window.Sanitizer === "function";
42765
- if (hasNative) {
42766
- try {
42767
- const s2 = new window.Sanitizer({});
42768
- const frag = s2.sanitizeToFragment(html2);
42769
- const div = document.createElement("div");
42770
- div.append(frag);
42771
- return div.innerHTML;
42772
- } catch {
42773
- }
42774
- }
42775
- const tpl = document.createElement("template");
42776
- tpl.innerHTML = html2;
42777
- const root = tpl.content;
42778
- const walker = document.createTreeWalker(root, NodeFilter.SHOW_ELEMENT, null);
42779
- const toRemove = [];
42780
- while (walker.nextNode()) {
42781
- const el = walker.currentNode;
42782
- const tag = el.tagName.toLowerCase();
42783
- if (!ALLOWED_TAGS2.has(tag)) {
42784
- toRemove.push(el);
42785
- continue;
42786
- }
42787
- for (const attr of Array.from(el.attributes)) {
42788
- const name = attr.name.toLowerCase();
42789
- const value = attr.value.trim().toLowerCase();
42790
- const isEvent = name.startsWith("on");
42791
- const isJsUrl = (name === "href" || name === "src") && value.startsWith("javascript:");
42792
- if (isEvent || isJsUrl) {
42793
- el.removeAttribute(attr.name);
42794
- }
42927
+ const nextRefRect = getBoundingClientRect(reference);
42928
+ if (prevRefRect && !rectsAreEqual(prevRefRect, nextRefRect)) {
42929
+ update();
42795
42930
  }
42931
+ prevRefRect = nextRefRect;
42932
+ frameId = requestAnimationFrame(frameLoop);
42796
42933
  }
42797
- for (const el of toRemove) {
42798
- while (el.firstChild) {
42799
- el.parentNode?.insertBefore(el.firstChild, el);
42934
+ update();
42935
+ return () => {
42936
+ var _resizeObserver2;
42937
+ ancestors.forEach((ancestor) => {
42938
+ ancestorScroll && ancestor.removeEventListener("scroll", update);
42939
+ ancestorResize && ancestor.removeEventListener("resize", update);
42940
+ });
42941
+ cleanupIo == null || cleanupIo();
42942
+ (_resizeObserver2 = resizeObserver) == null || _resizeObserver2.disconnect();
42943
+ resizeObserver = null;
42944
+ if (animationFrame) {
42945
+ cancelAnimationFrame(frameId);
42800
42946
  }
42801
- el.remove();
42802
- }
42803
- return tpl.innerHTML;
42947
+ };
42804
42948
  }
42949
+ var offset2 = offset;
42950
+ var shift2 = shift;
42951
+ var flip2 = flip;
42952
+ var hide2 = hide;
42953
+ var arrow2 = arrow;
42954
+ var computePosition2 = (reference, floating, options) => {
42955
+ const cache2 = /* @__PURE__ */ new Map();
42956
+ const mergedOptions = {
42957
+ platform,
42958
+ ...options
42959
+ };
42960
+ const platformWithCache = {
42961
+ ...mergedOptions.platform,
42962
+ _c: cache2
42963
+ };
42964
+ return computePosition(reference, floating, {
42965
+ ...mergedOptions,
42966
+ platform: platformWithCache
42967
+ });
42968
+ };
42805
42969
 
42806
42970
  // ../adaptives/adaptive-overlays/dist/tooltip.js
42807
42971
  function getAnchorReference(anchorEl) {
@@ -42885,296 +43049,125 @@ var SyntrologieSDK = (() => {
42885
43049
  bottom: "top",
42886
43050
  left: "right"
42887
43051
  };
42888
- Object.assign(arrowEl.style, {
42889
- left: arrowX != null ? `${arrowX}px` : "",
42890
- top: arrowY != null ? `${arrowY}px` : "",
42891
- right: "",
42892
- bottom: "",
42893
- [staticSide[side]]: "-4px"
42894
- });
42895
- const rotation = {
42896
- top: "0deg",
42897
- right: "90deg",
42898
- bottom: "180deg",
42899
- left: "270deg"
42900
- };
42901
- arrowEl.style.transform = `rotate(${rotation[side] || "0deg"})`;
42902
- }
42903
- });
42904
- const onKey = (e2) => {
42905
- if (e2.key === "Escape")
42906
- handle.destroy();
42907
- };
42908
- window.addEventListener("keydown", onKey);
42909
- const originalInert = [];
42910
- if (opts.blocking) {
42911
- Array.from(document.body.children).forEach((el) => {
42912
- if (el !== overlayRoot && el.getAttribute("inert") === null) {
42913
- el.setAttribute("inert", "");
42914
- originalInert.push(el.id || el.tagName);
42915
- }
42916
- });
42917
- const focusableEls = Array.from(div.querySelectorAll('button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])'));
42918
- if (focusableEls.length > 0) {
42919
- const firstFocusable = focusableEls[0];
42920
- const lastFocusable = focusableEls[focusableEls.length - 1];
42921
- const trapFocus = (e2) => {
42922
- if (e2.key !== "Tab")
42923
- return;
42924
- if (e2.shiftKey) {
42925
- if (document.activeElement === firstFocusable) {
42926
- lastFocusable.focus();
42927
- e2.preventDefault();
42928
- }
42929
- } else {
42930
- if (document.activeElement === lastFocusable) {
42931
- firstFocusable.focus();
42932
- e2.preventDefault();
42933
- }
42934
- }
42935
- };
42936
- div.addEventListener("keydown", trapFocus);
42937
- requestAnimationFrame(() => firstFocusable.focus());
42938
- }
42939
- }
42940
- const attachTrigger = () => {
42941
- if (opts.trigger === "hover") {
42942
- const enter = () => {
42943
- div.style.visibility = "visible";
42944
- div.style.opacity = "1";
42945
- };
42946
- const leave = () => {
42947
- div.style.visibility = "hidden";
42948
- div.style.opacity = "0";
42949
- };
42950
- div.style.visibility = "hidden";
42951
- div.style.opacity = "0";
42952
- div.style.transition = "opacity 200ms ease, visibility 200ms";
42953
- anchorEl.addEventListener("mouseenter", enter);
42954
- anchorEl.addEventListener("mouseleave", leave);
42955
- anchorEl.addEventListener("focus", enter);
42956
- anchorEl.addEventListener("blur", leave);
42957
- return () => {
42958
- anchorEl.removeEventListener("mouseenter", enter);
42959
- anchorEl.removeEventListener("mouseleave", leave);
42960
- anchorEl.removeEventListener("focus", enter);
42961
- anchorEl.removeEventListener("blur", leave);
42962
- };
42963
- }
42964
- if (opts.trigger === "click") {
42965
- const toggle = () => {
42966
- const isVisible = div.style.visibility === "visible";
42967
- if (isVisible) {
42968
- handle.destroy();
42969
- } else {
42970
- div.style.visibility = "visible";
42971
- div.style.opacity = "1";
42972
- }
42973
- };
42974
- div.style.visibility = "hidden";
42975
- div.style.opacity = "0";
42976
- div.style.transition = "opacity 200ms ease, visibility 200ms";
42977
- anchorEl.addEventListener("click", toggle);
42978
- return () => anchorEl.removeEventListener("click", toggle);
42979
- }
42980
- div.style.opacity = "0";
42981
- div.style.transition = "opacity 200ms ease";
42982
- requestAnimationFrame(() => {
42983
- div.style.opacity = "1";
42984
- });
42985
- return () => {
42986
- };
42987
- };
42988
- const removeTrigger = attachTrigger();
42989
- const handle = {
42990
- el: div,
42991
- destroy() {
42992
- cleanup();
42993
- removeTrigger();
42994
- window.removeEventListener("keydown", onKey);
42995
- actionBtns.forEach((btn) => btn.removeEventListener("click", actionHandler));
42996
- if (opts.blocking) {
42997
- Array.from(document.body.children).forEach((el) => {
42998
- if (el !== overlayRoot) {
42999
- el.removeAttribute("inert");
43000
- }
43001
- });
43002
- }
43003
- div.style.opacity = "0";
43004
- setTimeout(() => div.remove(), 200);
43005
- }
43006
- };
43007
- return handle;
43008
- }
43009
-
43010
- // ../adaptives/adaptive-overlays/dist/modal.js
43011
- var executeModal = async (action, context) => {
43012
- const { content, size: size2 = "md", blocking = false, scrim, dismiss, ctaButtons } = action;
43013
- const scrimEl = document.createElement("div");
43014
- scrimEl.className = "syntro-modal-scrim";
43015
- scrimEl.style.cssText = `
43016
- position: fixed;
43017
- inset: 0;
43018
- background: rgba(0, 0, 0, ${scrim?.opacity ?? 0.6});
43019
- z-index: 2147483645;
43020
- opacity: 0;
43021
- transition: opacity 200ms ease-out;
43022
- `;
43023
- context.overlayRoot.appendChild(scrimEl);
43024
- const modal = document.createElement("div");
43025
- modal.className = `syntro-modal syntro-modal-${size2}`;
43026
- modal.setAttribute("role", "dialog");
43027
- modal.setAttribute("aria-modal", "true");
43028
- const sizeMap = { sm: "360px", md: "480px", lg: "640px" };
43029
- modal.style.cssText = `
43030
- position: fixed;
43031
- top: 50%;
43032
- left: 50%;
43033
- transform: translate(-50%, -50%) scale(0.95);
43034
- max-width: ${sizeMap[size2]};
43035
- width: 90%;
43036
- background: white;
43037
- border-radius: 12px;
43038
- box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25);
43039
- z-index: 2147483646;
43040
- opacity: 0;
43041
- transition: opacity 200ms ease-out, transform 200ms ease-out;
43042
- padding: 24px;
43043
- `;
43044
- let html2 = "";
43045
- if (content.title) {
43046
- html2 += `<h2 class="syntro-modal-title" style="margin: 0 0 12px 0; font-size: 18px; font-weight: 600; color: #111827;">${sanitizeHtml2(content.title)}</h2>`;
43047
- }
43048
- html2 += `<div class="syntro-modal-body" style="color: #4b5563; line-height: 1.5;">${sanitizeHtml2(content.body)}</div>`;
43049
- if (dismiss?.closeButton !== false) {
43050
- html2 += `
43051
- <button class="syntro-modal-close" data-syntro-action="dismiss" style="
43052
- position: absolute;
43053
- top: 16px;
43054
- right: 16px;
43055
- background: none;
43056
- border: none;
43057
- cursor: pointer;
43058
- padding: 4px;
43059
- color: #6b7280;
43060
- " aria-label="Close">
43061
- <svg width="20" height="20" viewBox="0 0 20 20" fill="currentColor">
43062
- <path fill-rule="evenodd" d="M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z" clip-rule="evenodd"/>
43063
- </svg>
43064
- </button>
43065
- `;
43066
- }
43067
- if (ctaButtons && ctaButtons.length > 0) {
43068
- html2 += `<div class="syntro-modal-actions" style="display: flex; gap: 12px; margin-top: 24px; justify-content: flex-end;">`;
43069
- for (const btn of ctaButtons) {
43070
- const isPrimary = btn.primary ?? false;
43071
- html2 += `
43072
- <button
43073
- class="syntro-modal-btn ${isPrimary ? "syntro-modal-btn-primary" : ""}"
43074
- data-syntro-action="${sanitizeHtml2(btn.actionId)}"
43075
- style="
43076
- padding: 10px 20px;
43077
- border-radius: 8px;
43078
- font-size: 14px;
43079
- font-weight: 500;
43080
- cursor: pointer;
43081
- transition: background 150ms ease;
43082
- ${isPrimary ? "background: #4f46e5; color: white; border: none;" : "background: white; color: #374151; border: 1px solid #d1d5db;"}
43083
- "
43084
- >
43085
- ${sanitizeHtml2(btn.label)}
43086
- </button>
43087
- `;
43088
- }
43089
- html2 += `</div>`;
43090
- }
43091
- modal.innerHTML = html2;
43092
- context.overlayRoot.appendChild(modal);
43093
- let actionClicked = null;
43094
- const actionBtns = modal.querySelectorAll("[data-syntro-action]");
43095
- const actionHandler = (e2) => {
43096
- const btn = e2.currentTarget;
43097
- const actionId = btn.getAttribute("data-syntro-action");
43098
- if (actionId) {
43099
- actionClicked = actionId;
43100
- context.publishEvent("action.modal_cta_clicked", {
43101
- actionId
43052
+ Object.assign(arrowEl.style, {
43053
+ left: arrowX != null ? `${arrowX}px` : "",
43054
+ top: arrowY != null ? `${arrowY}px` : "",
43055
+ right: "",
43056
+ bottom: "",
43057
+ [staticSide[side]]: "-4px"
43102
43058
  });
43103
- if (actionId === "dismiss") {
43104
- handle.destroy();
43105
- }
43059
+ const rotation = {
43060
+ top: "0deg",
43061
+ right: "90deg",
43062
+ bottom: "180deg",
43063
+ left: "270deg"
43064
+ };
43065
+ arrowEl.style.transform = `rotate(${rotation[side] || "0deg"})`;
43106
43066
  }
43107
- };
43108
- actionBtns.forEach((btn) => btn.addEventListener("click", actionHandler));
43067
+ });
43109
43068
  const onKey = (e2) => {
43110
- if (e2.key === "Escape" && dismiss?.onEsc !== false) {
43069
+ if (e2.key === "Escape")
43111
43070
  handle.destroy();
43112
- }
43113
43071
  };
43114
43072
  window.addEventListener("keydown", onKey);
43115
- const onScrimClick = () => {
43116
- if (!blocking) {
43117
- handle.destroy();
43118
- }
43119
- };
43120
- scrimEl.addEventListener("click", onScrimClick);
43121
43073
  const originalInert = [];
43122
- if (blocking) {
43074
+ if (opts.blocking) {
43123
43075
  Array.from(document.body.children).forEach((el) => {
43124
- if (el !== context.overlayRoot && el.getAttribute("inert") === null) {
43076
+ if (el !== overlayRoot && el.getAttribute("inert") === null) {
43125
43077
  el.setAttribute("inert", "");
43126
- originalInert.push(el);
43078
+ originalInert.push(el.id || el.tagName);
43127
43079
  }
43128
43080
  });
43081
+ const focusableEls = Array.from(div.querySelectorAll('button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])'));
43082
+ if (focusableEls.length > 0) {
43083
+ const firstFocusable = focusableEls[0];
43084
+ const lastFocusable = focusableEls[focusableEls.length - 1];
43085
+ const trapFocus = (e2) => {
43086
+ if (e2.key !== "Tab")
43087
+ return;
43088
+ if (e2.shiftKey) {
43089
+ if (document.activeElement === firstFocusable) {
43090
+ lastFocusable.focus();
43091
+ e2.preventDefault();
43092
+ }
43093
+ } else if (document.activeElement === lastFocusable) {
43094
+ firstFocusable.focus();
43095
+ e2.preventDefault();
43096
+ }
43097
+ };
43098
+ div.addEventListener("keydown", trapFocus);
43099
+ requestAnimationFrame(() => firstFocusable.focus());
43100
+ }
43129
43101
  }
43130
- let timeoutId;
43131
- if (dismiss?.timeoutMs) {
43132
- timeoutId = setTimeout(() => {
43133
- handle.destroy();
43134
- }, dismiss.timeoutMs);
43135
- }
43136
- const focusableEls = modal.querySelectorAll('button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])');
43137
- if (focusableEls.length > 0) {
43138
- requestAnimationFrame(() => focusableEls[0].focus());
43139
- }
43140
- requestAnimationFrame(() => {
43141
- scrimEl.style.opacity = "1";
43142
- modal.style.opacity = "1";
43143
- modal.style.transform = "translate(-50%, -50%) scale(1)";
43144
- });
43145
- context.publishEvent("action.applied", {
43146
- id: context.generateId(),
43147
- kind: "overlays:modal",
43148
- size: size2,
43149
- blocking
43150
- });
43102
+ const attachTrigger = () => {
43103
+ if (opts.trigger === "hover") {
43104
+ const enter = () => {
43105
+ div.style.visibility = "visible";
43106
+ div.style.opacity = "1";
43107
+ };
43108
+ const leave = () => {
43109
+ div.style.visibility = "hidden";
43110
+ div.style.opacity = "0";
43111
+ };
43112
+ div.style.visibility = "hidden";
43113
+ div.style.opacity = "0";
43114
+ div.style.transition = "opacity 200ms ease, visibility 200ms";
43115
+ anchorEl.addEventListener("mouseenter", enter);
43116
+ anchorEl.addEventListener("mouseleave", leave);
43117
+ anchorEl.addEventListener("focus", enter);
43118
+ anchorEl.addEventListener("blur", leave);
43119
+ return () => {
43120
+ anchorEl.removeEventListener("mouseenter", enter);
43121
+ anchorEl.removeEventListener("mouseleave", leave);
43122
+ anchorEl.removeEventListener("focus", enter);
43123
+ anchorEl.removeEventListener("blur", leave);
43124
+ };
43125
+ }
43126
+ if (opts.trigger === "click") {
43127
+ const toggle = () => {
43128
+ const isVisible = div.style.visibility === "visible";
43129
+ if (isVisible) {
43130
+ handle.destroy();
43131
+ } else {
43132
+ div.style.visibility = "visible";
43133
+ div.style.opacity = "1";
43134
+ }
43135
+ };
43136
+ div.style.visibility = "hidden";
43137
+ div.style.opacity = "0";
43138
+ div.style.transition = "opacity 200ms ease, visibility 200ms";
43139
+ anchorEl.addEventListener("click", toggle);
43140
+ return () => anchorEl.removeEventListener("click", toggle);
43141
+ }
43142
+ div.style.opacity = "0";
43143
+ div.style.transition = "opacity 200ms ease";
43144
+ requestAnimationFrame(() => {
43145
+ div.style.opacity = "1";
43146
+ });
43147
+ return () => {
43148
+ };
43149
+ };
43150
+ const removeTrigger = attachTrigger();
43151
43151
  const handle = {
43152
+ el: div,
43152
43153
  destroy() {
43153
- if (timeoutId) {
43154
- clearTimeout(timeoutId);
43155
- }
43154
+ cleanup();
43155
+ removeTrigger();
43156
43156
  window.removeEventListener("keydown", onKey);
43157
- scrimEl.removeEventListener("click", onScrimClick);
43158
43157
  actionBtns.forEach((btn) => btn.removeEventListener("click", actionHandler));
43159
- originalInert.forEach((el) => el.removeAttribute("inert"));
43160
- modal.style.opacity = "0";
43161
- modal.style.transform = "translate(-50%, -50%) scale(0.95)";
43162
- scrimEl.style.opacity = "0";
43163
- setTimeout(() => {
43164
- modal.remove();
43165
- scrimEl.remove();
43166
- }, 200);
43167
- context.publishEvent("action.modal_dismissed", {
43168
- actionClicked
43169
- });
43170
- }
43171
- };
43172
- return {
43173
- cleanup: () => {
43174
- handle.destroy();
43158
+ if (opts.blocking) {
43159
+ Array.from(document.body.children).forEach((el) => {
43160
+ if (el !== overlayRoot) {
43161
+ el.removeAttribute("inert");
43162
+ }
43163
+ });
43164
+ }
43165
+ div.style.opacity = "0";
43166
+ setTimeout(() => div.remove(), 200);
43175
43167
  }
43176
43168
  };
43177
- };
43169
+ return handle;
43170
+ }
43178
43171
 
43179
43172
  // ../adaptives/adaptive-overlays/dist/runtime.js
43180
43173
  var executeHighlight = async (action, context) => {
@@ -43319,7 +43312,7 @@ var SyntrologieSDK = (() => {
43319
43312
  if (!anchorEl) {
43320
43313
  throw new Error(`Anchor not found: ${action.anchorId}`);
43321
43314
  }
43322
- const content = action.content;
43315
+ const { content } = action;
43323
43316
  let html2 = "";
43324
43317
  if (content.title) {
43325
43318
  html2 += `<div class="syntro-tt-title">${sanitizeHtml2(content.title)}</div>`;
@@ -43428,7 +43421,7 @@ var SyntrologieSDK = (() => {
43428
43421
  if (!step.route) return true;
43429
43422
  const currentRoute = getCurrentRoute();
43430
43423
  if (step.route.includes("*")) {
43431
- const pattern = new RegExp("^" + step.route.replace(/\*/g, ".*") + "$");
43424
+ const pattern = new RegExp(`^${step.route.replace(/\*/g, ".*")}$`);
43432
43425
  return pattern.test(currentRoute);
43433
43426
  }
43434
43427
  return currentRoute === step.route;
@@ -43760,7 +43753,7 @@ var SyntrologieSDK = (() => {
43760
43753
  });
43761
43754
  return { valid: false, errors, warnings: [] };
43762
43755
  }
43763
- const kind = action.kind;
43756
+ const { kind } = action;
43764
43757
  if (!kind || typeof kind !== "string") {
43765
43758
  errors.push({
43766
43759
  code: "MISSING_KIND",
@@ -43871,7 +43864,7 @@ var SyntrologieSDK = (() => {
43871
43864
  });
43872
43865
  return { valid: false, errors, warnings };
43873
43866
  }
43874
- const kind = action.kind;
43867
+ const { kind } = action;
43875
43868
  if (!kind || typeof kind !== "string") {
43876
43869
  errors.push({
43877
43870
  code: "MISSING_KIND",
@@ -44420,9 +44413,7 @@ var SyntrologieSDK = (() => {
44420
44413
  // Allow composite executors (like tours) to execute nested actions
44421
44414
  applyAction: apply,
44422
44415
  // Allow composite executors to subscribe to events
44423
- subscribeEvent: eventBus ? (name, callback) => {
44424
- return eventBus.subscribe({ names: [name] }, (event) => callback(event.props));
44425
- } : void 0
44416
+ subscribeEvent: eventBus ? (name, callback) => eventBus.subscribe({ names: [name] }, (event) => callback(event.props)) : void 0
44426
44417
  };
44427
44418
  }
44428
44419
  async function executeMountWidget(action, context) {
@@ -44616,18 +44607,6 @@ var SyntrologieSDK = (() => {
44616
44607
  };
44617
44608
  }
44618
44609
 
44619
- // src/surfaces/types.ts
44620
- function getSlotType(slot) {
44621
- if (slot.startsWith("inline:")) return "inline";
44622
- if (slot.startsWith("adjacent:")) return "adjacent";
44623
- return "static";
44624
- }
44625
- function getSlotAnchorId(slot) {
44626
- if (slot.startsWith("inline:")) return slot.slice(7);
44627
- if (slot.startsWith("adjacent:")) return slot.slice(9);
44628
- return null;
44629
- }
44630
-
44631
44610
  // src/hostPatcher/core/sanitizer.ts
44632
44611
  function sanitizeWithFallback(html2) {
44633
44612
  const hasNative = typeof window.Sanitizer === "function";
@@ -44689,6 +44668,18 @@ var SyntrologieSDK = (() => {
44689
44668
  return tpl.innerHTML = root.firstChild ? tpl.innerHTML : tpl.innerHTML;
44690
44669
  }
44691
44670
 
44671
+ // src/surfaces/types.ts
44672
+ function getSlotType(slot) {
44673
+ if (slot.startsWith("inline:")) return "inline";
44674
+ if (slot.startsWith("adjacent:")) return "adjacent";
44675
+ return "static";
44676
+ }
44677
+ function getSlotAnchorId(slot) {
44678
+ if (slot.startsWith("inline:")) return slot.slice(7);
44679
+ if (slot.startsWith("adjacent:")) return slot.slice(9);
44680
+ return null;
44681
+ }
44682
+
44692
44683
  // src/surfaces/positioning.ts
44693
44684
  var STATIC_SLOT_STYLES = {
44694
44685
  drawer_right: {
@@ -45348,11 +45339,9 @@ var SyntrologieSDK = (() => {
45348
45339
  },
45349
45340
  // Events access
45350
45341
  events: {
45351
- subscribe: (callback) => {
45352
- return runtime3.events.subscribe((event) => {
45353
- callback(event);
45354
- });
45355
- },
45342
+ subscribe: (callback) => runtime3.events.subscribe((event) => {
45343
+ callback(event);
45344
+ }),
45356
45345
  publish: (name, props) => {
45357
45346
  runtime3.events.publish(name, {
45358
45347
  ...props,
@@ -46266,27 +46255,6 @@ var SyntrologieSDK = (() => {
46266
46255
  return runtime3;
46267
46256
  }
46268
46257
 
46269
- // src/token.ts
46270
- var TOKEN_PREFIX = "syn_";
46271
- function decodeToken(token) {
46272
- if (!token.startsWith(TOKEN_PREFIX)) {
46273
- throw new Error("Invalid Syntro token: must start with 'syn_'");
46274
- }
46275
- const base64 = token.slice(TOKEN_PREFIX.length);
46276
- const standardBase64 = base64.replace(/-/g, "+").replace(/_/g, "/");
46277
- const json = atob(standardBase64);
46278
- const payload = JSON.parse(json);
46279
- if (payload.v !== 1) {
46280
- throw new Error(`Unsupported token version: ${payload.v}`);
46281
- }
46282
- return payload;
46283
- }
46284
- function encodeToken(payload) {
46285
- const json = JSON.stringify(payload);
46286
- const base64 = btoa(json).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
46287
- return TOKEN_PREFIX + base64;
46288
- }
46289
-
46290
46258
  // src/experiments/registry.ts
46291
46259
  var adapters = {
46292
46260
  growthbook: (config) => createGrowthBookClient({
@@ -46304,21 +46272,6 @@ var SyntrologieSDK = (() => {
46304
46272
  return factory(config);
46305
46273
  }
46306
46274
 
46307
- // src/telemetry/registry.ts
46308
- var adapters2 = {
46309
- posthog: (config) => createPostHogClient(config),
46310
- noop: () => createNoopClient()
46311
- };
46312
- function createTelemetryClient(provider, config) {
46313
- const factory = adapters2[provider];
46314
- if (!factory) {
46315
- throw new Error(
46316
- `Unknown telemetry provider: ${provider}. Supported: ${Object.keys(adapters2).join(", ")}`
46317
- );
46318
- }
46319
- return factory(config);
46320
- }
46321
-
46322
46275
  // src/fetchers/cdnFetcher.ts
46323
46276
  var ALLOWED_CDN_HOSTS = ["cdn.syntrologie.com", "localhost", "127.0.0.1"];
46324
46277
  function validateCdnUrl(url) {
@@ -46483,6 +46436,42 @@ var SyntrologieSDK = (() => {
46483
46436
  return factory(options);
46484
46437
  }
46485
46438
 
46439
+ // src/telemetry/registry.ts
46440
+ var adapters2 = {
46441
+ posthog: (config) => createPostHogClient(config),
46442
+ noop: () => createNoopClient()
46443
+ };
46444
+ function createTelemetryClient(provider, config) {
46445
+ const factory = adapters2[provider];
46446
+ if (!factory) {
46447
+ throw new Error(
46448
+ `Unknown telemetry provider: ${provider}. Supported: ${Object.keys(adapters2).join(", ")}`
46449
+ );
46450
+ }
46451
+ return factory(config);
46452
+ }
46453
+
46454
+ // src/token.ts
46455
+ var TOKEN_PREFIX = "syn_";
46456
+ function decodeToken(token) {
46457
+ if (!token.startsWith(TOKEN_PREFIX)) {
46458
+ throw new Error("Invalid Syntro token: must start with 'syn_'");
46459
+ }
46460
+ const base64 = token.slice(TOKEN_PREFIX.length);
46461
+ const standardBase64 = base64.replace(/-/g, "+").replace(/_/g, "/");
46462
+ const json = atob(standardBase64);
46463
+ const payload = JSON.parse(json);
46464
+ if (payload.v !== 1) {
46465
+ throw new Error(`Unsupported token version: ${payload.v}`);
46466
+ }
46467
+ return payload;
46468
+ }
46469
+ function encodeToken(payload) {
46470
+ const json = JSON.stringify(payload);
46471
+ const base64 = btoa(json).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
46472
+ return TOKEN_PREFIX + base64;
46473
+ }
46474
+
46486
46475
  // src/bootstrap.ts
46487
46476
  function getEnvVar(name) {
46488
46477
  if (typeof process !== "undefined" && process.env) {
@@ -46565,7 +46554,7 @@ var SyntrologieSDK = (() => {
46565
46554
  debug("Syntro Bootstrap", "====== INIT ======");
46566
46555
  debug("Syntro Bootstrap", "Options:", {
46567
46556
  hasToken: !!options.token,
46568
- tokenPrefix: options.token?.slice(0, 15) + "...",
46557
+ tokenPrefix: `${options.token?.slice(0, 15)}...`,
46569
46558
  hasCanvasOptions: !!options.canvas
46570
46559
  });
46571
46560
  const editorMode = isEditorMode();