@datatechsolutions/ui 2.11.93 → 3.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (138) hide show
  1. package/dist/astrlabe/contracts.d.mts +3 -3
  2. package/dist/astrlabe/contracts.d.ts +3 -3
  3. package/dist/astrlabe/index.js +108 -108
  4. package/dist/astrlabe/index.mjs +4 -4
  5. package/dist/astrlabe/workflow-canvas.js +4 -4
  6. package/dist/astrlabe/workflow-canvas.mjs +3 -3
  7. package/dist/brand/index.d.mts +1 -15
  8. package/dist/brand/index.d.ts +1 -15
  9. package/dist/brand/index.js +0 -14
  10. package/dist/brand/index.js.map +1 -1
  11. package/dist/brand/index.mjs +0 -14
  12. package/dist/brand/index.mjs.map +1 -1
  13. package/dist/{chunk-24QKSC74.js → chunk-3JJWPOK6.js} +6 -6
  14. package/dist/{chunk-24QKSC74.js.map → chunk-3JJWPOK6.js.map} +1 -1
  15. package/dist/{chunk-HGN5W56D.mjs → chunk-3ZUMJTDT.mjs} +3 -3
  16. package/dist/{chunk-HGN5W56D.mjs.map → chunk-3ZUMJTDT.mjs.map} +1 -1
  17. package/dist/{chunk-LKJZGFM4.mjs → chunk-5GDKCFM5.mjs} +3 -3
  18. package/dist/{chunk-LKJZGFM4.mjs.map → chunk-5GDKCFM5.mjs.map} +1 -1
  19. package/dist/{chunk-ZHUPYX4Q.mjs → chunk-5RM6NGZ6.mjs} +3 -3
  20. package/dist/{chunk-ZHUPYX4Q.mjs.map → chunk-5RM6NGZ6.mjs.map} +1 -1
  21. package/dist/{chunk-DB64YDV2.js → chunk-AOUUZ52N.js} +55 -55
  22. package/dist/{chunk-DB64YDV2.js.map → chunk-AOUUZ52N.js.map} +1 -1
  23. package/dist/{chunk-VGSWSQQU.mjs → chunk-B67DP7MI.mjs} +4 -4
  24. package/dist/{chunk-VGSWSQQU.mjs.map → chunk-B67DP7MI.mjs.map} +1 -1
  25. package/dist/{chunk-NYQAEPC7.js → chunk-EFOXN3LC.js} +159 -168
  26. package/dist/chunk-EFOXN3LC.js.map +1 -0
  27. package/dist/{chunk-ARVLVWUC.js → chunk-F54Q2YJY.js} +97 -15
  28. package/dist/chunk-F54Q2YJY.js.map +1 -0
  29. package/dist/{chunk-GMZ3PTNK.mjs → chunk-H2D2CRTD.mjs} +7 -7
  30. package/dist/{chunk-GMZ3PTNK.mjs.map → chunk-H2D2CRTD.mjs.map} +1 -1
  31. package/dist/{chunk-PTGPQJZJ.js → chunk-HDCUWUNH.js} +15 -15
  32. package/dist/{chunk-PTGPQJZJ.js.map → chunk-HDCUWUNH.js.map} +1 -1
  33. package/dist/{chunk-ZKUYNCAG.js → chunk-I2NZGVBG.js} +1595 -2140
  34. package/dist/chunk-I2NZGVBG.js.map +1 -0
  35. package/dist/{chunk-MLAXYDEU.mjs → chunk-IRPS5UCS.mjs} +3 -3
  36. package/dist/{chunk-MLAXYDEU.mjs.map → chunk-IRPS5UCS.mjs.map} +1 -1
  37. package/dist/{chunk-TEQYIK2B.mjs → chunk-IRT4T3CU.mjs} +92 -101
  38. package/dist/chunk-IRT4T3CU.mjs.map +1 -0
  39. package/dist/{chunk-A3BFURJB.mjs → chunk-JN6IL6OH.mjs} +1595 -2138
  40. package/dist/chunk-JN6IL6OH.mjs.map +1 -0
  41. package/dist/{chunk-NA57KK4O.js → chunk-JSNRCYSO.js} +4 -4
  42. package/dist/{chunk-NA57KK4O.js.map → chunk-JSNRCYSO.js.map} +1 -1
  43. package/dist/{chunk-XSBZNPUO.js → chunk-KR2X2WHJ.js} +53 -53
  44. package/dist/{chunk-XSBZNPUO.js.map → chunk-KR2X2WHJ.js.map} +1 -1
  45. package/dist/{chunk-YEWXDCCI.mjs → chunk-LEKZUS6N.mjs} +4 -4
  46. package/dist/{chunk-YEWXDCCI.mjs.map → chunk-LEKZUS6N.mjs.map} +1 -1
  47. package/dist/{chunk-6NAZVG2O.mjs → chunk-MVBIAXVN.mjs} +4 -4
  48. package/dist/{chunk-6NAZVG2O.mjs.map → chunk-MVBIAXVN.mjs.map} +1 -1
  49. package/dist/{chunk-4TY55HGO.mjs → chunk-OL73LBX5.mjs} +3 -3
  50. package/dist/{chunk-4TY55HGO.mjs.map → chunk-OL73LBX5.mjs.map} +1 -1
  51. package/dist/{chunk-HUGHELRM.mjs → chunk-QYA53LUF.mjs} +6 -6
  52. package/dist/chunk-QYA53LUF.mjs.map +1 -0
  53. package/dist/{chunk-DWFLIXES.mjs → chunk-R4TQWXNG.mjs} +3 -3
  54. package/dist/{chunk-DWFLIXES.mjs.map → chunk-R4TQWXNG.mjs.map} +1 -1
  55. package/dist/{chunk-SMKN4ZVB.js → chunk-RGI74SQH.js} +4 -4
  56. package/dist/{chunk-SMKN4ZVB.js.map → chunk-RGI74SQH.js.map} +1 -1
  57. package/dist/{chunk-FZTOP6EE.js → chunk-RL35XATZ.js} +141 -141
  58. package/dist/chunk-RL35XATZ.js.map +1 -0
  59. package/dist/{chunk-BUI7BCUN.js → chunk-RXZNACMI.js} +33 -33
  60. package/dist/{chunk-BUI7BCUN.js.map → chunk-RXZNACMI.js.map} +1 -1
  61. package/dist/{chunk-ST3GH5OM.js → chunk-SU3YPWFW.js} +26 -26
  62. package/dist/{chunk-ST3GH5OM.js.map → chunk-SU3YPWFW.js.map} +1 -1
  63. package/dist/{chunk-DIMLLLZR.js → chunk-TIJJHW2Z.js} +36 -36
  64. package/dist/{chunk-DIMLLLZR.js.map → chunk-TIJJHW2Z.js.map} +1 -1
  65. package/dist/{chunk-2RDGJXYZ.js → chunk-TVMLV675.js} +67 -67
  66. package/dist/{chunk-2RDGJXYZ.js.map → chunk-TVMLV675.js.map} +1 -1
  67. package/dist/{chunk-Y3WJAYOY.mjs → chunk-UDDZTTLO.mjs} +6 -6
  68. package/dist/chunk-UDDZTTLO.mjs.map +1 -0
  69. package/dist/{chunk-43GCSCQA.js → chunk-W5OEBO6E.js} +12 -12
  70. package/dist/chunk-W5OEBO6E.js.map +1 -0
  71. package/dist/{chunk-3Z366CVM.js → chunk-Y6AEE56Q.js} +67 -67
  72. package/dist/{chunk-3Z366CVM.js.map → chunk-Y6AEE56Q.js.map} +1 -1
  73. package/dist/{chunk-RXFAQFE7.mjs → chunk-YIB2YAM5.mjs} +3 -3
  74. package/dist/{chunk-RXFAQFE7.mjs.map → chunk-YIB2YAM5.mjs.map} +1 -1
  75. package/dist/{chunk-OLXOBT42.mjs → chunk-YV72JM4B.mjs} +4 -4
  76. package/dist/{chunk-OLXOBT42.mjs.map → chunk-YV72JM4B.mjs.map} +1 -1
  77. package/dist/{chunk-MEEFOZC4.js → chunk-ZM5MVWIT.js} +4 -4
  78. package/dist/{chunk-MEEFOZC4.js.map → chunk-ZM5MVWIT.js.map} +1 -1
  79. package/dist/{chunk-PU2KTO4O.mjs → chunk-ZV5EZXXO.mjs} +97 -15
  80. package/dist/chunk-ZV5EZXXO.mjs.map +1 -0
  81. package/dist/index.d.mts +8 -41
  82. package/dist/index.d.ts +8 -41
  83. package/dist/index.js +745 -753
  84. package/dist/index.mjs +2 -2
  85. package/dist/platform/admin/index.js +11 -11
  86. package/dist/platform/admin/index.mjs +5 -5
  87. package/dist/platform/agents-workspace.js +7 -7
  88. package/dist/platform/agents-workspace.mjs +6 -6
  89. package/dist/platform/app-shell.js +4 -4
  90. package/dist/platform/app-shell.mjs +3 -3
  91. package/dist/platform/auth/index.js +28 -28
  92. package/dist/platform/auth/index.mjs +5 -5
  93. package/dist/platform/billing/index.js +4 -4
  94. package/dist/platform/billing/index.mjs +3 -3
  95. package/dist/platform/impersonation/index.js +4 -4
  96. package/dist/platform/impersonation/index.mjs +3 -3
  97. package/dist/platform/index.d.mts +1 -1
  98. package/dist/platform/index.d.ts +1 -1
  99. package/dist/platform/index.js +99 -99
  100. package/dist/platform/index.js.map +1 -1
  101. package/dist/platform/index.mjs +19 -19
  102. package/dist/platform/index.mjs.map +1 -1
  103. package/dist/platform/pages/index.d.mts +4 -5
  104. package/dist/platform/pages/index.d.ts +4 -5
  105. package/dist/platform/pages/index.js +197 -197
  106. package/dist/platform/pages/index.js.map +1 -1
  107. package/dist/platform/pages/index.mjs +9 -9
  108. package/dist/platform/pages/index.mjs.map +1 -1
  109. package/dist/platform/settings/index.js +8 -8
  110. package/dist/platform/settings/index.mjs +7 -7
  111. package/dist/platform/telemetry/index.d.mts +42 -0
  112. package/dist/platform/telemetry/index.d.ts +42 -0
  113. package/dist/platform/telemetry/index.js +75 -0
  114. package/dist/platform/telemetry/index.js.map +1 -0
  115. package/dist/platform/telemetry/index.mjs +68 -0
  116. package/dist/platform/telemetry/index.mjs.map +1 -0
  117. package/dist/platform/workflow-api-client.d.mts +1 -1
  118. package/dist/platform/workflow-api-client.d.ts +1 -1
  119. package/dist/platform/workflow-api-client.js +61 -61
  120. package/dist/platform/workflow-api-client.mjs +1 -1
  121. package/dist/platform/workflow-canvas-shell.js +5 -5
  122. package/dist/platform/workflow-canvas-shell.mjs +4 -4
  123. package/dist/{workflow-api-client-DVLhcpUj.d.ts → workflow-api-client-BKD8OfP_.d.ts} +61 -30
  124. package/dist/{workflow-api-client-DpBxHTHr.d.mts → workflow-api-client-DoYj7nHz.d.mts} +61 -30
  125. package/package.json +7 -1
  126. package/dist/chunk-43GCSCQA.js.map +0 -1
  127. package/dist/chunk-A3BFURJB.mjs.map +0 -1
  128. package/dist/chunk-ARVLVWUC.js.map +0 -1
  129. package/dist/chunk-FZTOP6EE.js.map +0 -1
  130. package/dist/chunk-HUGHELRM.mjs.map +0 -1
  131. package/dist/chunk-NYQAEPC7.js.map +0 -1
  132. package/dist/chunk-PU2KTO4O.mjs.map +0 -1
  133. package/dist/chunk-TEQYIK2B.mjs.map +0 -1
  134. package/dist/chunk-Y3WJAYOY.mjs.map +0 -1
  135. package/dist/chunk-ZKUYNCAG.js.map +0 -1
  136. package/src/brand/logos/fuel-icon.svg +0 -32
  137. package/src/brand/logos/fuel-logo-dark.svg +0 -43
  138. package/src/brand/logos/fuel-logo.svg +0 -43
@@ -4,7 +4,7 @@
4
4
  var chunkUZ3CMNUJ_js = require('./chunk-UZ3CMNUJ.js');
5
5
  var chunkYXN2K77G_js = require('./chunk-YXN2K77G.js');
6
6
  var chunkS7KHTUHA_js = require('./chunk-S7KHTUHA.js');
7
- var chunkARVLVWUC_js = require('./chunk-ARVLVWUC.js');
7
+ var chunkF54Q2YJY_js = require('./chunk-F54Q2YJY.js');
8
8
  var Headless6 = require('@headlessui/react');
9
9
  var clsx = require('clsx');
10
10
  var React12 = require('react');
@@ -19,8 +19,8 @@ var dateFns = require('date-fns');
19
19
  var locale = require('date-fns/locale');
20
20
  var reactTransitionProgress = require('react-transition-progress');
21
21
  var lucideReact = require('lucide-react');
22
- var d3Geo = require('d3-geo');
23
22
  var ProgressPrimitive = require('@radix-ui/react-progress');
23
+ var d3Geo = require('d3-geo');
24
24
  var TabsPrimitive = require('@radix-ui/react-tabs');
25
25
  var nextIntl = require('next-intl');
26
26
  var zustand = require('zustand');
@@ -2906,7 +2906,7 @@ function InputRequestForm({
2906
2906
  try {
2907
2907
  const payload = decision === "approved" ? sanitizeForSubmit(values) : void 0;
2908
2908
  const reason = decision === "rejected" ? typeof values.reason === "string" ? values.reason : "rejected" : void 0;
2909
- await chunkARVLVWUC_js.submitApproval(runId, data.nodeId, {
2909
+ await chunkF54Q2YJY_js.submitApproval(runId, data.nodeId, {
2910
2910
  approved: decision === "approved",
2911
2911
  ...payload ? { payload } : {},
2912
2912
  ...reason ? { reason } : {}
@@ -3154,7 +3154,7 @@ function StreamingDashboard({
3154
3154
  if (phase === "completed" || phase === "failed" || phase === "cancelled") {
3155
3155
  return;
3156
3156
  }
3157
- const unsubscribe = chunkARVLVWUC_js.subscribeToRunEvents(
3157
+ const unsubscribe = chunkF54Q2YJY_js.subscribeToRunEvents(
3158
3158
  runId,
3159
3159
  (event) => handleEvent(event),
3160
3160
  (err) => {
@@ -3165,15 +3165,15 @@ function StreamingDashboard({
3165
3165
  }, [runId]);
3166
3166
  function handleEvent(event) {
3167
3167
  switch (event.type) {
3168
- case "run_started":
3168
+ case "run-started":
3169
3169
  setPhase("running");
3170
3170
  break;
3171
- case "node_started":
3171
+ case "node-started":
3172
3172
  if (event.nodeId) {
3173
3173
  setTimeline((prev) => upsertTimelineRunning(prev, event));
3174
3174
  }
3175
3175
  break;
3176
- case "node_completed":
3176
+ case "node-completed":
3177
3177
  if (event.nodeId) {
3178
3178
  setTimeline(
3179
3179
  (prev) => upsertTimelineDone(prev, event, "done")
@@ -3181,18 +3181,14 @@ function StreamingDashboard({
3181
3181
  mergeNodeOutput(event);
3182
3182
  }
3183
3183
  break;
3184
- // The engine emits `node_error` (not `node_failed`) for executor
3185
- // errors. Keep `node_failed` as a soft alias in case a future
3186
- // event source uses it.
3187
- case "node_error":
3188
- case "node_failed":
3184
+ case "node-failed":
3189
3185
  if (event.nodeId) {
3190
3186
  setTimeline(
3191
3187
  (prev) => upsertTimelineDone(prev, event, "failed")
3192
3188
  );
3193
3189
  }
3194
3190
  break;
3195
- case "run_paused":
3191
+ case "run-paused":
3196
3192
  setPhase("paused");
3197
3193
  if (event.nodeId) {
3198
3194
  setTimeline(
@@ -3201,20 +3197,22 @@ function StreamingDashboard({
3201
3197
  }
3202
3198
  appendPauseSection(event);
3203
3199
  break;
3204
- case "ui_render":
3200
+ case "ui-render":
3205
3201
  appendSectionFromEvent(event);
3206
3202
  break;
3207
- case "run_completed":
3203
+ case "run-completed":
3208
3204
  setPhase("completed");
3209
3205
  break;
3210
- case "run_failed":
3206
+ case "run-failed":
3211
3207
  setPhase("failed");
3212
- setError(event.error ?? "Workflow run failed");
3208
+ setError(
3209
+ event.data?.error ?? "Workflow run failed"
3210
+ );
3213
3211
  break;
3214
3212
  }
3215
3213
  }
3216
3214
  function mergeNodeOutput(event) {
3217
- const output = event.outputs;
3215
+ const output = event.data?.outputs;
3218
3216
  if (!output) return;
3219
3217
  const candidateSpec = isDashboardSpecLike(output) ? output : null;
3220
3218
  if (candidateSpec) {
@@ -3229,14 +3227,14 @@ function StreamingDashboard({
3229
3227
  }
3230
3228
  }
3231
3229
  function appendSectionFromEvent(event) {
3232
- const sectionPayload = event.outputs?.section ?? event.outputs;
3230
+ const sectionPayload = event.data?.section ?? event.data;
3233
3231
  if (!sectionPayload || !sectionPayload.type) return;
3234
3232
  setSpec((prev) => appendSectionToSpec(prev, sectionPayload));
3235
3233
  specRef.current = appendSectionToSpec(specRef.current, sectionPayload);
3236
3234
  }
3237
3235
  function appendPauseSection(event) {
3238
- const promptValue = event.outputs?.prompt;
3239
- const payloadValue = event.outputs?.payload;
3236
+ const promptValue = event.data?.prompt;
3237
+ const payloadValue = event.data?.payload;
3240
3238
  const prompt = typeof promptValue === "string" ? promptValue : void 0;
3241
3239
  const section = {
3242
3240
  type: "note",
@@ -3339,9 +3337,10 @@ function Timeline({ entries }) {
3339
3337
  function upsertTimelineRunning(prev, event) {
3340
3338
  if (!event.nodeId) return prev;
3341
3339
  const idx = prev.findIndex((entry) => entry.nodeId === event.nodeId);
3340
+ const nodeType = typeof event.data?.nodeType === "string" ? event.data.nodeType : void 0;
3342
3341
  const fresh = {
3343
3342
  nodeId: event.nodeId,
3344
- nodeType: event.nodeType,
3343
+ nodeType,
3345
3344
  status: "running",
3346
3345
  startedAt: event.timestamp
3347
3346
  };
@@ -3353,16 +3352,18 @@ function upsertTimelineRunning(prev, event) {
3353
3352
  function upsertTimelineDone(prev, event, status) {
3354
3353
  if (!event.nodeId) return prev;
3355
3354
  const idx = prev.findIndex((entry) => entry.nodeId === event.nodeId);
3355
+ const nodeType = typeof event.data?.nodeType === "string" ? event.data.nodeType : void 0;
3356
+ const error = typeof event.data?.error === "string" ? event.data.error : void 0;
3356
3357
  if (idx === -1) {
3357
3358
  return [
3358
3359
  ...prev,
3359
3360
  {
3360
3361
  nodeId: event.nodeId,
3361
- nodeType: event.nodeType,
3362
+ nodeType,
3362
3363
  status,
3363
3364
  startedAt: event.timestamp,
3364
3365
  finishedAt: event.timestamp,
3365
- error: event.error
3366
+ error
3366
3367
  }
3367
3368
  ];
3368
3369
  }
@@ -3371,7 +3372,7 @@ function upsertTimelineDone(prev, event, status) {
3371
3372
  ...next[idx],
3372
3373
  status,
3373
3374
  finishedAt: event.timestamp,
3374
- error: event.error ?? next[idx].error
3375
+ error: error ?? next[idx].error
3375
3376
  };
3376
3377
  return next;
3377
3378
  }
@@ -3614,7 +3615,7 @@ var defaultFilterTypeConfig = {
3614
3615
  icon: HeroIcons.ClockIcon,
3615
3616
  className: "bg-amber-100 text-amber-700 dark:bg-amber-900/30 dark:text-amber-400"
3616
3617
  },
3617
- fuel: {
3618
+ category: {
3618
3619
  icon: HeroIcons.MapIcon,
3619
3620
  className: "bg-green-100 text-green-700 dark:bg-green-900/30 dark:text-green-400"
3620
3621
  },
@@ -9773,9 +9774,6 @@ function getDockAccent(id, accentRgb) {
9773
9774
  if (id === "models") {
9774
9775
  return { icon: "text-sky-600 dark:text-sky-400", bg: "bg-sky-100 dark:bg-sky-900/35", dot: "bg-sky-500 dark:bg-sky-400", rgb: "14, 165, 233" };
9775
9776
  }
9776
- if (id === "fuels") {
9777
- return { icon: "text-orange-600 dark:text-orange-400", bg: "bg-orange-100 dark:bg-orange-900/35", dot: "bg-orange-500 dark:bg-orange-400", rgb: "249, 115, 22" };
9778
- }
9779
9777
  if (id === "rules") {
9780
9778
  return { icon: "text-emerald-600 dark:text-emerald-400", bg: "bg-emerald-100 dark:bg-emerald-900/35", dot: "bg-emerald-500 dark:bg-emerald-400", rgb: "16, 185, 129" };
9781
9779
  }
@@ -10468,7 +10466,6 @@ function DashboardProgressShell({ children }) {
10468
10466
  }
10469
10467
  var APP_COLORS = {
10470
10468
  astrlabe: "bg-sky-500/30 text-sky-100 ring-sky-400/30",
10471
- "fuel-price-ai": "bg-emerald-500/30 text-emerald-100 ring-emerald-400/30",
10472
10469
  "kori-erp": "bg-amber-500/30 text-amber-100 ring-amber-400/30",
10473
10470
  windsock: "bg-indigo-500/30 text-indigo-100 ring-indigo-400/30"
10474
10471
  };
@@ -11089,7 +11086,7 @@ var ICON_MAP = {
11089
11086
  "plus-circle": getIcon("PlusCircleIcon"),
11090
11087
  "link": getIcon("LinkIcon"),
11091
11088
  "folder-open": getIcon("FolderOpenIcon"),
11092
- "fuel": getIcon("BeakerIcon")
11089
+ "beaker": getIcon("BeakerIcon")
11093
11090
  };
11094
11091
  var ACCENT_MAP = {
11095
11092
  "map-pin": {
@@ -11168,7 +11165,7 @@ var ACCENT_MAP = {
11168
11165
  container: "bg-slate-50/80 dark:bg-slate-900/30 border-slate-100/50 dark:border-slate-800/30",
11169
11166
  icon: "text-slate-500 dark:text-slate-400"
11170
11167
  },
11171
- "fuel": {
11168
+ "beaker": {
11172
11169
  container: "bg-emerald-50/80 dark:bg-emerald-900/30 border-emerald-100/50 dark:border-emerald-800/30",
11173
11170
  icon: "text-emerald-500 dark:text-emerald-400"
11174
11171
  }
@@ -11364,7 +11361,6 @@ function PageErrorState({
11364
11361
  );
11365
11362
  }
11366
11363
  var WINDSOCK_LOADER = { gradient: "from-emerald-500 to-teal-600", accentRing: "ring-emerald-500/30" };
11367
- var FUEL_PRICE_LOADER = { gradient: "from-blue-500 to-indigo-600", accentRing: "ring-blue-500/30" };
11368
11364
  var KORI_ERP_LOADER = { gradient: "from-purple-500 to-violet-600", accentRing: "ring-purple-500/30" };
11369
11365
  var WIRE_LOADER = { gradient: "from-sky-500 to-indigo-600", accentRing: "ring-indigo-500/30" };
11370
11366
  function BrandedLoader({
@@ -13324,1995 +13320,667 @@ function UserMobileInfo({ user, labels = {} }) {
13324
13320
  ] })
13325
13321
  ] });
13326
13322
  }
13327
- var MIN_ZOOM = 0.8;
13328
- var MAX_ZOOM = 4;
13329
- var ZOOM_STEP = 0.5;
13330
- function useGeoMapState({
13331
- items,
13332
- getRegionCode,
13333
- regionCoordinates,
13334
- defaultCenter = [0, 0]
13335
- }) {
13336
- const [zoom, setZoom] = React12.useState(1);
13337
- const [center, setCenter] = React12.useState(defaultCenter);
13338
- const [hoveredRegion, setHoveredRegion] = React12.useState(null);
13339
- const [animatedRegions, setAnimatedRegions] = React12.useState(/* @__PURE__ */ new Set());
13340
- const [panOffset, setPanOffset] = React12.useState([0, 0]);
13341
- const handleZoomIn = React12.useCallback(() => {
13342
- setZoom((previous) => Math.min(previous + ZOOM_STEP, MAX_ZOOM));
13323
+ var INCIDENTS = [
13324
+ { id: "lambda-timeout", label: "Lambda Timeout", service: "kori-customers", severity: "critical", color: "text-red-400", bg: "bg-red-500/15" },
13325
+ { id: "db-pool", label: "DB Pool Exhausted", service: "inventory-analytics", severity: "critical", color: "text-orange-400", bg: "bg-orange-500/15" },
13326
+ { id: "deploy-fail", label: "Deploy Rollback", service: "windsock-auth", severity: "high", color: "text-amber-400", bg: "bg-amber-500/15" },
13327
+ { id: "memory-leak", label: "Memory Leak", service: "astrlabe-workflows", severity: "medium", color: "text-sky-400", bg: "bg-sky-500/15" }
13328
+ ];
13329
+ var INCIDENT_DETAILS = {
13330
+ "lambda-timeout": {
13331
+ rootCause: "Cold starts + unoptimized Sequelize query scanning 2.3M rows without index on organization_id",
13332
+ agentAnalysis: "Correlated Lambda Duration spike with Aurora slow query log. Found full table scan on customers table \u2014 missing index on (organization_id, created_at). Cold start adds 4.2s, query adds 24.8s = timeout.",
13333
+ remediation: "CREATE INDEX CONCURRENTLY idx_customers_org_created ON customers(organization_id, created_at); Set provisioned concurrency to 5.",
13334
+ result: "p99 latency: 29s \u2192 340ms. Zero timeouts in last 2 hours.",
13335
+ timeline: [
13336
+ { time: "03:14", event: "CloudWatch alarm: kori-customers Duration > 29s", color: "text-red-400" },
13337
+ { time: "03:14", event: "Agent triggered \u2014 pulling CloudWatch metrics + Aurora slow query log", color: "text-sky-400" },
13338
+ { time: "03:15", event: "Root cause identified: missing index on customers(organization_id)", color: "text-amber-400" },
13339
+ { time: "03:15", event: "Remediation: CREATE INDEX CONCURRENTLY executed", color: "text-purple-400" },
13340
+ { time: "03:16", event: "Provisioned concurrency set to 5 via CDK update", color: "text-purple-400" },
13341
+ { time: "03:18", event: "Verified: p99 latency 340ms, 0 timeouts", color: "text-emerald-400" }
13342
+ ]
13343
+ },
13344
+ "db-pool": {
13345
+ rootCause: "inventory-analytics Lambda opening new connections per invocation without reusing pool. 300 concurrent executions = 300 connections.",
13346
+ agentAnalysis: "Correlated RDS Proxy connection count with Lambda concurrency. Found pool initialization inside handler function (runs every invocation) instead of module scope (runs once per cold start).",
13347
+ remediation: "Moved pool init to module scope. Set Lambda reserved concurrency to 50. Enabled RDS Proxy idle connection pruning at 60s.",
13348
+ result: "Steady-state connections: 300 \u2192 12. Zero connection errors in last 4 hours.",
13349
+ timeline: [
13350
+ { time: "02:41", event: "CloudWatch alarm: inventory-analytics DatabaseConnections = 300", color: "text-red-400" },
13351
+ { time: "02:41", event: "Agent triggered \u2014 analyzing connection patterns + Lambda code", color: "text-sky-400" },
13352
+ { time: "02:42", event: "Root cause: pool created inside handler, not module scope", color: "text-amber-400" },
13353
+ { time: "02:43", event: "Fix applied: pool init moved to module scope", color: "text-purple-400" },
13354
+ { time: "02:43", event: "Reserved concurrency set to 50", color: "text-purple-400" },
13355
+ { time: "02:45", event: "Verified: 12 steady connections, 0 errors", color: "text-emerald-400" }
13356
+ ]
13357
+ },
13358
+ "deploy-fail": {
13359
+ rootCause: "New Lambda handler binary missing from S3 asset bucket. CDK synth succeeded but cargo-lambda build artifact was not uploaded due to CI timeout.",
13360
+ agentAnalysis: 'Traced CloudFormation events: Lambda function update failed with "S3 key not found". Cross-referenced with GitHub Actions run \u2014 cargo-lambda build step timed out at 10min limit. Build artifact never uploaded to cdk.out.',
13361
+ remediation: "Triggered rebuild with extended timeout (20min). Verified S3 asset uploaded. Re-deployed stack successfully.",
13362
+ result: "Stack status: UPDATE_COMPLETE. All 129 handlers healthy. CI timeout increased to 20min.",
13363
+ timeline: [
13364
+ { time: "14:22", event: "CDK deploy failed: UPDATE_ROLLBACK_COMPLETE", color: "text-red-400" },
13365
+ { time: "14:22", event: "Agent triggered \u2014 reading CloudFormation events", color: "text-sky-400" },
13366
+ { time: "14:23", event: "Root cause: S3 asset missing \u2014 CI build timeout", color: "text-amber-400" },
13367
+ { time: "14:24", event: "Rebuild triggered with 20min timeout", color: "text-purple-400" },
13368
+ { time: "14:38", event: "Build complete. Stack redeployed successfully.", color: "text-purple-400" },
13369
+ { time: "14:40", event: "Verified: all 129 handlers healthy", color: "text-emerald-400" }
13370
+ ]
13371
+ },
13372
+ "memory-leak": {
13373
+ rootCause: "Workflow execution SSE connections not closed on client disconnect. EventSource objects accumulate in Node.js heap across warm invocations.",
13374
+ agentAnalysis: "Memory usage trend shows linear growth correlated with SSE connection count. Found missing cleanup in workflow-runner SSE handler \u2014 no abort signal listener. Warm Lambda instances accumulate stale connections across invocations.",
13375
+ remediation: "Added AbortSignal listener to SSE handler. Implemented connection TTL of 5 minutes. Forced Lambda recycling at 90% memory threshold.",
13376
+ result: "Memory stable at 45-55%. Zero OOM kills in last 8 hours.",
13377
+ timeline: [
13378
+ { time: "10:00", event: "Memory trending alarm: 85% and rising", color: "text-amber-400" },
13379
+ { time: "10:00", event: "Agent triggered \u2014 analyzing memory trend + heap snapshots", color: "text-sky-400" },
13380
+ { time: "10:02", event: "Root cause: SSE connections not closed on disconnect", color: "text-amber-400" },
13381
+ { time: "10:03", event: "Fix: AbortSignal listener + 5min TTL added", color: "text-purple-400" },
13382
+ { time: "10:03", event: "Lambda recycling at 90% memory threshold", color: "text-purple-400" },
13383
+ { time: "10:10", event: "Verified: memory stable at 48%, 0 OOM kills", color: "text-emerald-400" }
13384
+ ]
13385
+ }
13386
+ };
13387
+ var AVATARS = {
13388
+ triage: "https://api.dicebear.com/9.x/lorelei/svg?seed=Sentinel&hair=variant31&beardProbability=0&mouth=happy01",
13389
+ debug: "https://api.dicebear.com/9.x/notionists/svg?seed=Debugger&hair=variant35&beardProbability=0&gestureProbability=0&glasses=variant03&glassesProbability=100",
13390
+ remediate: "https://api.dicebear.com/9.x/lorelei/svg?seed=Fixer&hair=variant31&beardProbability=0&glasses=variant01&glassesProbability=100&mouth=happy01"
13391
+ };
13392
+ function buildNodes(incident) {
13393
+ return [
13394
+ { id: "alert", label: "Alert Detected", subtitle: `${incident.service} \xB7 ${incident.severity}`, icon: HeroIcons.ExclamationTriangleIcon, color: "text-red-400", bg: "bg-red-500/15", glow: "rgba(239,68,68,0.5)", step: 0, badges: [{ text: incident.severity, color: "bg-red-500/20 text-red-300" }] },
13395
+ { id: "metrics", label: "Pull Metrics", subtitle: "CloudWatch \xB7 15min window", icon: HeroIcons.ChartBarIcon, color: "text-sky-400", bg: "bg-sky-500/15", glow: "rgba(14,165,233,0.5)", step: 1, badges: [{ text: "datasource", color: "bg-sky-500/20 text-sky-300" }] },
13396
+ { id: "logs", label: "Analyze Logs", subtitle: "CloudWatch Logs \xB7 error filter", icon: HeroIcons.CommandLineIcon, color: "text-sky-400", bg: "bg-sky-500/15", glow: "rgba(14,165,233,0.5)", step: 1, badges: [{ text: "datasource", color: "bg-sky-500/20 text-sky-300" }] },
13397
+ { id: "infra", label: "Infra State", subtitle: "CDK \xB7 stack status \xB7 config", icon: HeroIcons.CloudIcon, color: "text-sky-400", bg: "bg-sky-500/15", glow: "rgba(14,165,233,0.5)", step: 1, badges: [{ text: "datasource", color: "bg-sky-500/20 text-sky-300" }] },
13398
+ { id: "correlate", label: "Correlate", subtitle: "3 sources \u2192 unified context", icon: HeroIcons.BoltIcon, color: "text-amber-400", bg: "bg-amber-500/15", glow: "rgba(245,158,11,0.5)", step: 2, badges: [{ text: "aggregator", color: "bg-amber-500/20 text-amber-300" }] },
13399
+ { id: "debug-agent", label: "Debug Agent", subtitle: "Root cause analysis", icon: HeroIcons.CpuChipIcon, color: "text-purple-400", bg: "bg-purple-500/15", glow: "rgba(168,85,247,0.5)", step: 3, avatar: AVATARS.debug, badges: [{ text: "agent", color: "bg-purple-500/20 text-purple-300" }, { text: "Claude", color: "bg-violet-500/20 text-violet-300" }] },
13400
+ { id: "plan", label: "Remediation Plan", subtitle: "Generate fix + rollback plan", icon: HeroIcons.DocumentMagnifyingGlassIcon, color: "text-amber-400", bg: "bg-amber-500/15", glow: "rgba(245,158,11,0.5)", step: 4, avatar: AVATARS.triage, badges: [{ text: "agent", color: "bg-purple-500/20 text-purple-300" }, { text: "advanced", color: "bg-amber-500/20 text-amber-300" }] },
13401
+ { id: "execute", label: "Auto-Remediate", subtitle: "Apply fix \xB7 human-in-the-loop", icon: HeroIcons.WrenchScrewdriverIcon, color: "text-red-400", bg: "bg-red-500/15", glow: "rgba(239,68,68,0.5)", step: 5, avatar: AVATARS.remediate, badges: [{ text: "agent", color: "bg-purple-500/20 text-purple-300" }, { text: "HITL", color: "bg-amber-500/20 text-amber-300" }] },
13402
+ { id: "verify", label: "Verify", subtitle: "Confirm resolution \xB7 metrics ok", icon: HeroIcons.ShieldCheckIcon, color: "text-emerald-400", bg: "bg-emerald-500/15", glow: "rgba(16,185,129,0.5)", step: 6, badges: [{ text: "check", color: "bg-emerald-500/20 text-emerald-300" }] },
13403
+ { id: "resolved", label: "Resolved", subtitle: "Incident closed \xB7 MTTR 4min", icon: HeroIcons.CheckCircleIcon, color: "text-emerald-400", bg: "bg-emerald-500/15", glow: "rgba(16,185,129,0.5)", step: 7 }
13404
+ ];
13405
+ }
13406
+ var STEP_LABELS = [
13407
+ "Alert detected \u2014 triaging",
13408
+ "Pulling metrics, logs, infra state (parallel)",
13409
+ "Correlating across sources",
13410
+ "Debug agent analyzing root cause",
13411
+ "Generating remediation plan",
13412
+ "Executing auto-remediation",
13413
+ "Verifying resolution",
13414
+ "Resolved \u2014 incident closed"
13415
+ ];
13416
+ function IncidentPipelineDemo({
13417
+ defaultIncident = "lambda-timeout",
13418
+ onIncidentChange
13419
+ } = {}) {
13420
+ const [activeIncident, setActiveIncident] = React12.useState(defaultIncident);
13421
+ const incident = INCIDENTS.find((i) => i.id === activeIncident);
13422
+ const detail = INCIDENT_DETAILS[activeIncident];
13423
+ const nodes = React12.useMemo(() => buildNodes(incident), [activeIncident]);
13424
+ const [activeStep, setActiveStep] = React12.useState(-1);
13425
+ const intervalRef = React12.useRef(null);
13426
+ const isIdle = activeStep === -1;
13427
+ const isRunning = activeStep >= 0 && activeStep < 7;
13428
+ const isComplete = activeStep === 7;
13429
+ const handleRun = React12.useCallback(() => {
13430
+ if (intervalRef.current) clearInterval(intervalRef.current);
13431
+ setActiveStep(0);
13432
+ let step2 = 0;
13433
+ intervalRef.current = setInterval(() => {
13434
+ step2 += 1;
13435
+ if (step2 > 7) {
13436
+ if (intervalRef.current) clearInterval(intervalRef.current);
13437
+ setActiveStep(7);
13438
+ } else {
13439
+ setActiveStep(step2);
13440
+ }
13441
+ }, 1200);
13343
13442
  }, []);
13344
- const handleZoomOut = React12.useCallback(() => {
13345
- setZoom((previous) => Math.max(previous - ZOOM_STEP, MIN_ZOOM));
13443
+ const handleStop = React12.useCallback(() => {
13444
+ if (intervalRef.current) clearInterval(intervalRef.current);
13445
+ setActiveStep(-1);
13346
13446
  }, []);
13347
- const handleMoveEnd = React12.useCallback(
13348
- (position) => {
13349
- setCenter(position.coordinates);
13350
- setZoom(position.zoom);
13351
- },
13352
- []
13353
- );
13354
- const handlePan = React12.useCallback((dx, dy) => {
13355
- setPanOffset((previous) => [previous[0] + dx, previous[1] + dy]);
13447
+ const handleIncidentSelect = React12.useCallback((id) => {
13448
+ setActiveIncident(id);
13449
+ onIncidentChange?.(id);
13450
+ if (!isIdle) handleStop();
13451
+ }, [isIdle, handleStop, onIncidentChange]);
13452
+ React12.useEffect(() => () => {
13453
+ if (intervalRef.current) clearInterval(intervalRef.current);
13356
13454
  }, []);
13357
- const regionGroups = React12.useMemo(() => {
13358
- const grouped = /* @__PURE__ */ new Map();
13359
- items.forEach((item) => {
13360
- const code = getRegionCode(item);
13361
- if (!grouped.has(code)) {
13362
- grouped.set(code, []);
13363
- }
13364
- grouped.get(code).push(item);
13365
- });
13366
- return Array.from(grouped.entries()).filter(([code]) => regionCoordinates[code]).map(([code, regionItems]) => ({
13367
- code,
13368
- items: regionItems,
13369
- coordinates: regionCoordinates[code]
13370
- })).sort((a, b) => b.items.length - a.items.length);
13371
- }, [items, getRegionCode, regionCoordinates]);
13372
- const animationCodes = React12.useMemo(
13373
- () => regionGroups.map((regionData) => regionData.code),
13374
- [regionGroups]
13375
- );
13376
- const animationSignature = React12.useMemo(
13377
- () => animationCodes.join("|"),
13378
- [animationCodes]
13379
- );
13380
- React12.useEffect(() => {
13381
- if (animationCodes.length === 0) return;
13382
- setAnimatedRegions(/* @__PURE__ */ new Set());
13383
- const timers = [];
13384
- animationCodes.forEach((code, index) => {
13385
- const timer = setTimeout(() => {
13386
- setAnimatedRegions((previous) => /* @__PURE__ */ new Set([...previous, code]));
13387
- }, index * 100);
13388
- timers.push(timer);
13389
- });
13390
- return () => timers.forEach(clearTimeout);
13391
- }, [animationSignature]);
13392
- const getMarkerSize = React12.useCallback(
13393
- (count) => {
13394
- const baseSize = count >= 10 ? 14 : count >= 5 ? 11 : count >= 2 ? 8 : 6;
13395
- return baseSize / Math.sqrt(zoom);
13396
- },
13397
- [zoom]
13398
- );
13399
- const getFontSize = React12.useCallback(
13400
- (markerSize) => {
13401
- const baseSize = markerSize > 10 ? 10 : 8;
13402
- const scaledSize = baseSize / Math.sqrt(zoom);
13403
- return `${Math.max(scaledSize, 6)}px`;
13404
- },
13405
- [zoom]
13406
- );
13407
- return {
13408
- zoom,
13409
- setZoom,
13410
- handleZoomIn,
13411
- handleZoomOut,
13412
- handleMoveEnd,
13413
- MIN_ZOOM,
13414
- MAX_ZOOM,
13415
- center,
13416
- setCenter,
13417
- panOffset,
13418
- handlePan,
13419
- hoveredRegion,
13420
- setHoveredRegion,
13421
- animatedRegions,
13422
- regionGroups,
13423
- getMarkerSize,
13424
- getFontSize
13455
+ const getStatus = (node2) => {
13456
+ if (activeStep < 0) return "idle";
13457
+ if (node2.step < activeStep) return "complete";
13458
+ if (node2.step === activeStep) return "active";
13459
+ return "idle";
13425
13460
  };
13426
- }
13427
- var MAP_DEFAULT_STATE_COLOR = "rgba(100, 116, 139, 0.35)";
13428
- var MAP_DEFAULT_MARKER_COLOR = "#6366f1";
13429
- var VIEWBOX_WIDTH = 1e3;
13430
- var VIEWBOX_HEIGHT = 500;
13431
- var ALBERS_WIDTH = 960;
13432
- var ALBERS_HEIGHT = 600;
13433
- function GeoMapCanvasInner({
13434
- regionGroups,
13435
- regionColorMap,
13436
- animatedRegions,
13437
- zoom,
13438
- panOffset,
13439
- hoveredRegion,
13440
- onPan,
13441
- onRegionHover,
13442
- onRegionClick,
13443
- isRegionActive,
13444
- getMarkerSize,
13445
- getFontSize,
13446
- geoJsonUrl,
13447
- regionPropertyKey = "code",
13448
- projectionType = "mercator",
13449
- ariaLabel = "Interactive map"
13450
- }, ref) {
13451
- const [geoData, setGeoData] = React12.useState(null);
13452
- const svgRef = React12.useRef(null);
13453
- const dragState = React12.useRef(null);
13454
- React12.useEffect(() => {
13455
- let cancelled = false;
13456
- async function loadGeoData() {
13457
- try {
13458
- const response = await fetch(geoJsonUrl);
13459
- if (!response.ok) return;
13460
- const data = await response.json();
13461
- if (!cancelled) setGeoData(data);
13462
- } catch {
13463
- }
13464
- }
13465
- loadGeoData();
13466
- return () => {
13467
- cancelled = true;
13468
- };
13469
- }, [geoJsonUrl]);
13470
- const handleMouseDown = React12.useCallback(
13471
- (event) => {
13472
- if (event.button !== 0) return;
13473
- dragState.current = {
13474
- active: true,
13475
- startX: event.clientX,
13476
- startY: event.clientY,
13477
- lastX: event.clientX,
13478
- lastY: event.clientY,
13479
- didDrag: false
13480
- };
13481
- },
13482
- []
13483
- );
13484
- const handleMouseMove = React12.useCallback(
13485
- (event) => {
13486
- if (!dragState.current?.active || !svgRef.current) return;
13487
- const totalDx = event.clientX - dragState.current.startX;
13488
- const totalDy = event.clientY - dragState.current.startY;
13489
- if (!dragState.current.didDrag) {
13490
- if (Math.abs(totalDx) < 5 && Math.abs(totalDy) < 5) return;
13491
- dragState.current.didDrag = true;
13461
+ const rows = React12.useMemo(() => {
13462
+ const result = [];
13463
+ let step2 = -1;
13464
+ for (const node2 of nodes) {
13465
+ if (node2.step !== step2) {
13466
+ result.push([]);
13467
+ step2 = node2.step;
13492
13468
  }
13493
- const dx = event.clientX - dragState.current.lastX;
13494
- const dy = event.clientY - dragState.current.lastY;
13495
- const rect = svgRef.current.getBoundingClientRect();
13496
- const viewBoxWidth = VIEWBOX_WIDTH / zoom;
13497
- const scaleRatio = viewBoxWidth / rect.width;
13498
- onPan(dx * scaleRatio, dy * scaleRatio);
13499
- dragState.current.lastX = event.clientX;
13500
- dragState.current.lastY = event.clientY;
13501
- },
13502
- [zoom, onPan]
13503
- );
13504
- const handleMouseUp = React12.useCallback(() => {
13505
- if (dragState.current) {
13506
- dragState.current.active = false;
13507
- }
13508
- }, []);
13509
- const wasDragAction = React12.useCallback(() => {
13510
- return dragState.current?.didDrag === true;
13511
- }, []);
13512
- const getLighterColor = (hexColor) => {
13513
- const r = parseInt(hexColor.slice(1, 3), 16);
13514
- const g = parseInt(hexColor.slice(3, 5), 16);
13515
- const b = parseInt(hexColor.slice(5, 7), 16);
13516
- return `rgba(${r}, ${g}, ${b}, 0.15)`;
13517
- };
13518
- const lighterColors = React12.useMemo(() => {
13519
- const colors3 = /* @__PURE__ */ new Map();
13520
- regionColorMap.forEach((color, code) => {
13521
- colors3.set(code, getLighterColor(color));
13522
- });
13523
- return colors3;
13524
- }, [regionColorMap]);
13525
- const featureCollection = React12.useMemo(() => {
13526
- if (!geoData) return null;
13527
- return {
13528
- type: "FeatureCollection",
13529
- features: geoData.features
13530
- };
13531
- }, [geoData]);
13532
- const projection = React12.useMemo(() => {
13533
- if (!featureCollection) return null;
13534
- if (projectionType === "albersUsa") {
13535
- return d3Geo.geoAlbersUsa();
13536
- }
13537
- return d3Geo.geoMercator().fitSize([VIEWBOX_WIDTH, VIEWBOX_HEIGHT], featureCollection);
13538
- }, [featureCollection, projectionType]);
13539
- const pathGenerator = React12.useMemo(() => {
13540
- if (!projection) return null;
13541
- return d3Geo.geoPath(projection);
13542
- }, [projection]);
13543
- const regionsWithItems = React12.useMemo(() => {
13544
- return new Set(regionGroups.map((regionData) => regionData.code));
13545
- }, [regionGroups]);
13546
- const hasAnyActiveFilter = React12.useMemo(() => {
13547
- return regionGroups.some((regionData) => isRegionActive?.(regionData.code));
13548
- }, [regionGroups, isRegionActive]);
13549
- const featureBounds = React12.useMemo(() => {
13550
- if (!pathGenerator || !geoData) return null;
13551
- let minX = Infinity, minY = Infinity, maxX = -Infinity, maxY = -Infinity;
13552
- for (const feature of geoData.features) {
13553
- const bounds = pathGenerator.bounds(feature);
13554
- if (!bounds || !isFinite(bounds[0][0])) continue;
13555
- minX = Math.min(minX, bounds[0][0]);
13556
- minY = Math.min(minY, bounds[0][1]);
13557
- maxX = Math.max(maxX, bounds[1][0]);
13558
- maxY = Math.max(maxY, bounds[1][1]);
13469
+ result[result.length - 1].push(node2);
13559
13470
  }
13560
- if (!isFinite(minX)) return null;
13561
- const pad = 15;
13562
- return { x: minX - pad, y: minY - pad, width: maxX - minX + pad * 2, height: maxY - minY + pad * 2 };
13563
- }, [pathGenerator, geoData]);
13564
- const effectiveWidth = featureBounds?.width ?? (projectionType === "albersUsa" ? ALBERS_WIDTH : VIEWBOX_WIDTH);
13565
- const effectiveHeight = featureBounds?.height ?? (projectionType === "albersUsa" ? ALBERS_HEIGHT : VIEWBOX_HEIGHT);
13566
- const baseX = featureBounds?.x ?? 0;
13567
- const baseY = featureBounds?.y ?? 0;
13568
- const viewBoxParts = React12.useMemo(() => {
13569
- const width = effectiveWidth / zoom;
13570
- const height = effectiveHeight / zoom;
13571
- const x = baseX + (effectiveWidth - width) / 2 - panOffset[0];
13572
- const y = baseY + (effectiveHeight - height) / 2 - panOffset[1];
13573
- return { x, y, width, height };
13574
- }, [zoom, panOffset, effectiveWidth, effectiveHeight, baseX, baseY]);
13575
- const viewBox = `${viewBoxParts.x} ${viewBoxParts.y} ${viewBoxParts.width} ${viewBoxParts.height}`;
13576
- return /* @__PURE__ */ jsxRuntime.jsx(
13577
- "div",
13578
- {
13579
- ref,
13580
- className: "relative w-full h-full overflow-hidden rounded-2xl border border-white/20 dark:border-white/[0.12] shadow-lg shadow-black/5 dark:shadow-black/30",
13581
- "data-testid": "map-canvas",
13582
- children: /* @__PURE__ */ jsxRuntime.jsxs(
13583
- "svg",
13584
- {
13585
- ref: svgRef,
13586
- viewBox,
13587
- className: "w-full h-full cursor-grab active:cursor-grabbing",
13588
- "aria-label": ariaLabel,
13589
- style: { touchAction: "none", background: "transparent" },
13590
- onMouseDown: handleMouseDown,
13591
- onMouseMove: handleMouseMove,
13592
- onMouseUp: handleMouseUp,
13593
- onMouseLeave: handleMouseUp,
13594
- children: [
13595
- /* @__PURE__ */ jsxRuntime.jsxs("defs", { children: [
13596
- /* @__PURE__ */ jsxRuntime.jsx("filter", { id: "glow-active", x: "-20%", y: "-20%", width: "140%", height: "140%", children: /* @__PURE__ */ jsxRuntime.jsx("feDropShadow", { dx: "0", dy: "0", stdDeviation: "3", floodColor: "#fff", floodOpacity: "0.6" }) }),
13597
- /* @__PURE__ */ jsxRuntime.jsx("filter", { id: "inactive-dim", x: "0%", y: "0%", width: "100%", height: "100%", children: /* @__PURE__ */ jsxRuntime.jsx("feColorMatrix", { type: "saturate", values: "0.3" }) }),
13598
- /* @__PURE__ */ jsxRuntime.jsx("filter", { id: "marker-glow", x: "-50%", y: "-50%", width: "200%", height: "200%", children: /* @__PURE__ */ jsxRuntime.jsx("feDropShadow", { dx: "0", dy: "0", stdDeviation: "4", floodColor: "#fff", floodOpacity: "0.7" }) }),
13599
- /* @__PURE__ */ jsxRuntime.jsx("clipPath", { id: "geo-inset-clip", children: /* @__PURE__ */ jsxRuntime.jsx(
13600
- "rect",
13601
- {
13602
- x: viewBoxParts.x + 2,
13603
- y: viewBoxParts.y + 2,
13604
- width: viewBoxParts.width - 4,
13605
- height: viewBoxParts.height - 4
13606
- }
13607
- ) })
13471
+ return result;
13472
+ }, [nodes]);
13473
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "liquid-surface rounded-2xl overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col", children: [
13474
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1.5 border-b border-white/5 px-3 py-2 shrink-0 overflow-x-auto", children: [
13475
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center rounded-lg bg-white/[0.03] p-0.5 gap-0.5 shrink-0", children: [
13476
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "px-1.5 text-[7px] font-bold uppercase tracking-wider text-gray-600", children: "Incident" }),
13477
+ INCIDENTS.map((inc) => /* @__PURE__ */ jsxRuntime.jsx(
13478
+ "button",
13479
+ {
13480
+ type: "button",
13481
+ onClick: () => handleIncidentSelect(inc.id),
13482
+ className: `rounded-md px-2 py-1 text-[9px] font-semibold transition-all duration-200 ${activeIncident === inc.id ? `${inc.bg} ${inc.color} shadow-sm` : "text-gray-500 hover:text-gray-300 hover:bg-white/5"}`,
13483
+ children: inc.label
13484
+ },
13485
+ inc.id
13486
+ ))
13487
+ ] }),
13488
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "ml-auto flex items-center gap-2 shrink-0", children: [
13489
+ activeStep >= 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-0.5", children: STEP_LABELS.map((_, index) => /* @__PURE__ */ jsxRuntime.jsx("div", { className: `h-1 w-2.5 rounded-full transition-all duration-500 ${index < activeStep || isComplete ? "bg-emerald-500" : index === activeStep ? "bg-red-500 animate-pulse" : "bg-white/10"}` }, index)) }),
13490
+ isComplete && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1 rounded-full bg-emerald-500/10 px-2 py-0.5", children: [
13491
+ /* @__PURE__ */ jsxRuntime.jsx(HeroIcons.CheckCircleIcon, { className: "h-3 w-3 text-emerald-400" }),
13492
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[8px] font-semibold text-emerald-400", children: "Resolved \xB7 MTTR 4min" })
13493
+ ] }),
13494
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: `h-2 w-2 rounded-full ${isRunning ? "bg-red-500 animate-pulse" : isComplete ? "bg-emerald-500" : "bg-gray-600"}` }),
13495
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "max-w-[160px] truncate text-[9px] text-gray-500", children: activeStep >= 0 ? STEP_LABELS[activeStep] : "Ready" }),
13496
+ isIdle ? /* @__PURE__ */ jsxRuntime.jsxs("button", { type: "button", onClick: handleRun, className: "flex items-center gap-1 rounded-lg bg-gradient-to-r from-red-600 to-rose-600 px-3 py-1 text-[10px] font-semibold text-white shadow-lg shadow-red-500/20 hover:shadow-red-500/30 hover:scale-105 active:scale-95 transition-all", children: [
13497
+ /* @__PURE__ */ jsxRuntime.jsx(HeroIcons.PlayIcon, { className: "h-3 w-3" }),
13498
+ " Simulate"
13499
+ ] }) : isRunning ? /* @__PURE__ */ jsxRuntime.jsxs("button", { type: "button", onClick: handleStop, className: "flex items-center gap-1 rounded-lg bg-rose-600/80 px-3 py-1 text-[10px] font-semibold text-white", children: [
13500
+ /* @__PURE__ */ jsxRuntime.jsx(HeroIcons.StopIcon, { className: "h-3 w-3" }),
13501
+ " Stop"
13502
+ ] }) : /* @__PURE__ */ jsxRuntime.jsxs("button", { type: "button", onClick: handleRun, className: "flex items-center gap-1 rounded-lg border border-white/10 px-3 py-1 text-[10px] font-medium text-gray-300 hover:bg-white/5", children: [
13503
+ /* @__PURE__ */ jsxRuntime.jsx(HeroIcons.ArrowPathIcon, { className: "h-3 w-3" }),
13504
+ " Replay"
13505
+ ] })
13506
+ ] })
13507
+ ] }),
13508
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-0 overflow-x-auto px-6 py-4", children: [
13509
+ /* @__PURE__ */ jsxRuntime.jsx("style", { children: `
13510
+ @keyframes nodeGlow { 0%, 100% { box-shadow: 0 0 12px var(--glow); } 50% { box-shadow: 0 0 28px var(--glow); } }
13511
+ @keyframes edgeFlow { to { stroke-dashoffset: -12; } }
13512
+ ` }),
13513
+ rows.map((row, rowIndex) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex shrink-0 items-center gap-0", children: [
13514
+ rowIndex > 0 && /* @__PURE__ */ jsxRuntime.jsx("svg", { width: "40", height: "2", className: "mx-1.5 shrink-0", children: /* @__PURE__ */ jsxRuntime.jsx("line", { x1: "0", y1: "1", x2: "40", y2: "1", stroke: activeStep >= rows[rowIndex][0].step ? "#10b981" : "#374151", strokeWidth: "2", strokeDasharray: "4 3", style: { animation: activeStep === rows[rowIndex][0].step ? "edgeFlow 0.8s linear infinite" : "none" } }) }),
13515
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: `flex ${row.length > 1 ? "flex-col gap-2" : ""}`, children: row.map((node2) => {
13516
+ const status = getStatus(node2);
13517
+ return /* @__PURE__ */ jsxRuntime.jsxs(
13518
+ "div",
13519
+ {
13520
+ className: `liquid-surface rounded-2xl px-4 py-3 transition-all duration-500 ${row.length > 1 ? "w-[180px]" : "w-[220px]"} ${status === "active" ? "scale-[1.03] ring-2 ring-red-500/50" : status === "complete" ? "ring-1 ring-emerald-500/30" : "opacity-40"}`,
13521
+ style: status === "active" ? { "--glow": node2.glow, animation: "nodeGlow 1.5s ease-in-out infinite" } : void 0,
13522
+ children: [
13523
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mb-1.5 flex items-center gap-2.5", children: [
13524
+ node2.avatar ? /* @__PURE__ */ jsxRuntime.jsx("img", { src: node2.avatar, alt: "", className: "h-9 w-9 rounded-xl shrink-0" }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: `flex h-9 w-9 items-center justify-center rounded-xl shrink-0 ${node2.bg}`, children: /* @__PURE__ */ jsxRuntime.jsx(node2.icon, { className: `h-5 w-5 ${node2.color}` }) }),
13525
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "min-w-0 flex-1", children: [
13526
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "truncate text-[13px] font-semibold text-white", children: node2.label }),
13527
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "truncate text-[9px] text-gray-500", children: node2.subtitle })
13528
+ ] }),
13529
+ status === "complete" && /* @__PURE__ */ jsxRuntime.jsx(HeroIcons.CheckCircleIcon, { className: "h-5 w-5 shrink-0 text-emerald-400" })
13530
+ ] }),
13531
+ node2.badges && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-wrap gap-1 mt-1", children: node2.badges.map((badge) => /* @__PURE__ */ jsxRuntime.jsx("span", { className: `rounded-full px-2 py-0.5 text-[8px] font-semibold ${badge.color}`, children: badge.text }, badge.text)) })
13532
+ ]
13533
+ },
13534
+ node2.id
13535
+ );
13536
+ }) })
13537
+ ] }, rowIndex))
13538
+ ] }),
13539
+ activeStep >= 3 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "border-t border-white/5 px-3 py-2", children: [
13540
+ /* @__PURE__ */ jsxRuntime.jsx("style", { children: `
13541
+ .slide-active .fk-detail { opacity: 0; animation: fkDetailIn 0.4s ease forwards; }
13542
+ .slide-active .fk-detail:nth-child(1) { animation-delay: 0s; }
13543
+ .slide-active .fk-detail:nth-child(2) { animation-delay: 0.15s; }
13544
+ .slide-active .fk-detail:nth-child(3) { animation-delay: 0.3s; }
13545
+ .slide-active .fk-detail:nth-child(4) { animation-delay: 0.45s; }
13546
+ .slide-active .fk-detail:nth-child(5) { animation-delay: 0.6s; }
13547
+ @keyframes fkDetailIn { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: translateY(0); } }
13548
+ ` }),
13549
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-3 gap-2", children: [
13550
+ activeStep >= 3 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "fk-detail liquid-surface rounded-xl p-3", children: [
13551
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mb-1.5 flex items-center gap-2", children: [
13552
+ /* @__PURE__ */ jsxRuntime.jsx("img", { src: AVATARS.debug, alt: "", className: "h-6 w-6 rounded-lg" }),
13553
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1 min-w-0", children: [
13554
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-[10px] font-semibold text-white", children: "Debug Agent" }),
13555
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-[8px] text-gray-500", children: "Root cause analysis \xB7 1.2s" })
13608
13556
  ] }),
13609
- /* @__PURE__ */ jsxRuntime.jsx("g", { clipPath: "url(#geo-inset-clip)", children: geoData && pathGenerator ? geoData.features.map((feature, index) => {
13610
- const regionCode = feature.properties?.[regionPropertyKey] || feature.properties?.name || "";
13611
- const hasItems = regionsWithItems.has(regionCode);
13612
- const regionColor = regionColorMap.get(regionCode) ?? MAP_DEFAULT_STATE_COLOR;
13613
- const isActive = isRegionActive?.(regionCode);
13614
- const isHovered = hoveredRegion === regionCode;
13615
- const isDimmed = hasAnyActiveFilter && !isActive && hasItems;
13616
- let pathData = pathGenerator(feature);
13617
- if (pathData && projectionType === "albersUsa") {
13618
- const subpaths = pathData.split("Z").filter(Boolean);
13619
- const cleaned = subpaths.filter((sub) => {
13620
- const lCount = (sub.match(/L/g) || []).length;
13621
- if (lCount !== 3) return true;
13622
- const nums = sub.match(/-?\d+\.?\d*/g)?.map(Number);
13623
- if (!nums || nums.length !== 8) return true;
13624
- const [x1, y1, x2, y2, x3, y3, x4, y4] = nums;
13625
- const xs = /* @__PURE__ */ new Set([x1, x2, x3, x4]);
13626
- const ys = /* @__PURE__ */ new Set([y1, y2, y3, y4]);
13627
- return xs.size !== 2 || ys.size !== 2;
13628
- });
13629
- pathData = cleaned.length > 0 ? cleaned.join("Z") + "Z" : null;
13630
- }
13631
- if (!pathData) return null;
13632
- return /* @__PURE__ */ jsxRuntime.jsx(
13633
- "path",
13634
- {
13635
- d: pathData,
13636
- fillRule: "evenodd",
13637
- "data-region": hasItems ? regionCode : void 0,
13638
- onMouseEnter: () => hasItems && onRegionHover(regionCode),
13639
- onMouseLeave: () => onRegionHover(null),
13640
- onClick: () => {
13641
- if (hasItems && !wasDragAction()) {
13642
- onRegionClick(regionCode);
13643
- }
13644
- },
13645
- fill: hasItems ? isHovered ? regionColor : isActive ? regionColor : lighterColors.get(regionCode) || getLighterColor(regionColor) : MAP_DEFAULT_STATE_COLOR,
13646
- stroke: isActive ? "#fff" : isDimmed ? "rgba(148, 163, 184, 0.15)" : "rgba(148, 163, 184, 0.40)",
13647
- strokeWidth: (isActive ? 2.5 : 0.5) / zoom,
13648
- filter: isActive ? "url(#glow-active)" : isDimmed ? "url(#inactive-dim)" : void 0,
13649
- opacity: isDimmed ? 0.45 : 1,
13650
- style: {
13651
- transition: "fill 0.3s ease, opacity 0.3s ease",
13652
- cursor: hasItems ? "pointer" : void 0
13653
- }
13654
- },
13655
- `${regionCode}-${index}`
13656
- );
13657
- }) : null }),
13658
- projection ? regionGroups.map((regionData) => {
13659
- const point = projection(regionData.coordinates);
13660
- if (!point) return null;
13661
- const [x, y] = point;
13662
- const isAnimated = animatedRegions.has(regionData.code);
13663
- const markerSize = getMarkerSize(regionData.items.length);
13664
- const markerColor = regionColorMap.get(regionData.code) ?? MAP_DEFAULT_MARKER_COLOR;
13665
- const isActive = isRegionActive?.(regionData.code);
13666
- const isDimmed = hasAnyActiveFilter && !isActive;
13667
- return /* @__PURE__ */ jsxRuntime.jsx(
13668
- "g",
13669
- {
13670
- transform: `translate(${x}, ${y})`,
13671
- "data-region": regionData.code,
13672
- "data-testid": `marker-${regionData.code}`,
13673
- onMouseEnter: () => onRegionHover(regionData.code),
13674
- onMouseLeave: () => onRegionHover(null),
13675
- onClick: () => {
13676
- if (!wasDragAction()) {
13677
- onRegionClick(regionData.code);
13678
- }
13679
- },
13680
- children: /* @__PURE__ */ jsxRuntime.jsxs(
13681
- "g",
13682
- {
13683
- style: {
13684
- transform: isAnimated ? "scale(1)" : "scale(0)",
13685
- transformOrigin: "0 0",
13686
- opacity: isAnimated ? isDimmed ? 0.35 : 1 : 0,
13687
- transition: "all 0.4s cubic-bezier(0.34, 1.56, 0.64, 1)",
13688
- cursor: "pointer"
13689
- },
13690
- filter: isActive ? "url(#marker-glow)" : void 0,
13691
- children: [
13692
- isActive ? /* @__PURE__ */ jsxRuntime.jsx(
13693
- "circle",
13694
- {
13695
- r: markerSize + 6,
13696
- fill: "none",
13697
- stroke: "#fff",
13698
- strokeWidth: 2,
13699
- opacity: 0.8
13700
- }
13701
- ) : /* @__PURE__ */ jsxRuntime.jsx(
13702
- "circle",
13703
- {
13704
- r: markerSize + 4,
13705
- fill: "none",
13706
- stroke: markerColor,
13707
- strokeWidth: 1,
13708
- opacity: isDimmed ? 0 : 0.4,
13709
- className: isDimmed ? void 0 : "animate-ping",
13710
- style: isDimmed ? void 0 : { animationDuration: "2s" }
13711
- }
13712
- ),
13713
- /* @__PURE__ */ jsxRuntime.jsx(
13714
- "circle",
13715
- {
13716
- r: markerSize,
13717
- fill: markerColor,
13718
- stroke: isActive ? "#fff" : markerColor,
13719
- strokeWidth: isActive ? 3 : 2,
13720
- className: "transition-colors",
13721
- style: {
13722
- filter: isActive ? "brightness(1.2) saturate(1.3)" : isDimmed ? "saturate(0.3) brightness(0.8)" : "none"
13723
- }
13724
- }
13725
- ),
13726
- regionData.items.length > 1 && /* @__PURE__ */ jsxRuntime.jsx(
13727
- "text",
13728
- {
13729
- textAnchor: "middle",
13730
- dominantBaseline: "central",
13731
- style: {
13732
- fontFamily: "system-ui",
13733
- fontSize: getFontSize(markerSize),
13734
- fontWeight: "bold",
13735
- fill: "#fff",
13736
- pointerEvents: "none",
13737
- opacity: isDimmed ? 0.5 : 1
13738
- },
13739
- children: regionData.items.length
13740
- }
13741
- )
13742
- ]
13743
- }
13744
- )
13745
- },
13746
- regionData.code
13747
- );
13748
- }) : null
13749
- ]
13750
- }
13751
- )
13752
- }
13753
- );
13557
+ /* @__PURE__ */ jsxRuntime.jsx(HeroIcons.CheckCircleIcon, { className: "h-3.5 w-3.5 shrink-0 text-emerald-400" })
13558
+ ] }),
13559
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-[9px] leading-relaxed text-gray-300", children: detail.rootCause }),
13560
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "mt-1.5 text-[8px] leading-relaxed text-gray-400", children: detail.agentAnalysis })
13561
+ ] }),
13562
+ activeStep >= 4 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "fk-detail liquid-surface rounded-xl p-3", children: [
13563
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mb-1.5 flex items-center gap-2", children: [
13564
+ /* @__PURE__ */ jsxRuntime.jsx("img", { src: AVATARS.triage, alt: "", className: "h-6 w-6 rounded-lg" }),
13565
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1 min-w-0", children: [
13566
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-[10px] font-semibold text-white", children: "Triage Agent" }),
13567
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-[8px] text-gray-500", children: "Remediation plan \xB7 0.8s" })
13568
+ ] }),
13569
+ /* @__PURE__ */ jsxRuntime.jsx(HeroIcons.CheckCircleIcon, { className: "h-3.5 w-3.5 shrink-0 text-emerald-400" })
13570
+ ] }),
13571
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "font-mono text-[8px] leading-relaxed text-gray-300", children: detail.remediation })
13572
+ ] }),
13573
+ activeStep >= 5 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "fk-detail liquid-surface rounded-xl p-3", children: [
13574
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mb-1.5 flex items-center gap-2", children: [
13575
+ /* @__PURE__ */ jsxRuntime.jsx("img", { src: AVATARS.remediate, alt: "", className: "h-6 w-6 rounded-lg" }),
13576
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1 min-w-0", children: [
13577
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-[10px] font-semibold text-white", children: "Remediate Agent" }),
13578
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-[8px] text-gray-500", children: "Executing fix \xB7 human-in-the-loop" })
13579
+ ] }),
13580
+ activeStep >= 6 ? /* @__PURE__ */ jsxRuntime.jsx(HeroIcons.CheckCircleIcon, { className: "h-3.5 w-3.5 shrink-0 text-emerald-400" }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-3 w-3 shrink-0 rounded-full bg-amber-500 animate-pulse" })
13581
+ ] }),
13582
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-[8px] leading-relaxed text-amber-300/80", children: "Applying changes with rollback plan ready. Awaiting verification..." })
13583
+ ] })
13584
+ ] }),
13585
+ activeStep >= 6 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-2 grid grid-cols-2 gap-2", children: [
13586
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "fk-detail rounded-xl border border-emerald-500/20 bg-emerald-500/[0.06] p-2.5", children: [
13587
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mb-1 flex items-center gap-1.5", children: [
13588
+ /* @__PURE__ */ jsxRuntime.jsx(HeroIcons.CheckCircleIcon, { className: "h-3.5 w-3.5 text-emerald-400" }),
13589
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[10px] font-bold text-emerald-400", children: "Result" })
13590
+ ] }),
13591
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-[9px] font-semibold text-emerald-300", children: detail.result })
13592
+ ] }),
13593
+ isComplete && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "fk-detail liquid-surface rounded-xl p-2.5", children: [
13594
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "mb-1 block text-[10px] font-bold text-gray-400", children: "Timeline" }),
13595
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-0.5", children: detail.timeline.map((entry, i) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start gap-1.5", children: [
13596
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "shrink-0 font-mono text-[7px] text-gray-600", children: entry.time }),
13597
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: `h-1 w-1 mt-1 shrink-0 rounded-full ${entry.color.replace("text-", "bg-")}` }),
13598
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[7px] text-gray-400", children: entry.event })
13599
+ ] }, i)) })
13600
+ ] })
13601
+ ] })
13602
+ ] })
13603
+ ] }) });
13754
13604
  }
13755
- var GeoMapCanvas = React12__namespace.default.forwardRef(GeoMapCanvasInner);
13756
- var MapZoomControls = React12__namespace.default.forwardRef(
13757
- ({ zoom, minZoom, maxZoom, onZoomIn, onZoomOut, labels }, ref) => {
13758
- return /* @__PURE__ */ jsxRuntime.jsxs(
13759
- "div",
13605
+ function IconTile({ icon: Icon, gradient, size = "md" }) {
13606
+ const wrapper = size === "md" ? "h-12 w-12" : "h-10 w-10";
13607
+ const icon = size === "md" ? "h-6 w-6" : "h-5 w-5";
13608
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: `${wrapper} rounded-xl bg-gradient-to-br ${gradient} flex items-center justify-center`, children: /* @__PURE__ */ jsxRuntime.jsx(Icon, { className: `${icon} text-white` }) });
13609
+ }
13610
+ function BentoFeatureGrid({
13611
+ aiPanel,
13612
+ metricsPanel,
13613
+ securityPanel,
13614
+ agentsPanel,
13615
+ className
13616
+ }) {
13617
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: `w-full min-h-screen h-full flex items-center justify-center p-4 md:p-6 lg:p-8 ${className ?? ""}`, children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full h-full max-w-7xl", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid gap-4 lg:grid-cols-3 lg:grid-rows-2 h-full min-h-[600px] lg:min-h-[700px]", children: [
13618
+ /* @__PURE__ */ jsxRuntime.jsxs(
13619
+ framerMotion.motion.div,
13760
13620
  {
13761
- ref,
13762
- className: "flex flex-col gap-1",
13763
- "data-testid": "map-zoom-controls",
13621
+ initial: { opacity: 0, y: 20 },
13622
+ animate: { opacity: 1, y: 0 },
13623
+ transition: { duration: 0.6, delay: 0.1 },
13624
+ className: "relative lg:row-span-2",
13764
13625
  children: [
13765
- /* @__PURE__ */ jsxRuntime.jsx(
13766
- "button",
13767
- {
13768
- onClick: onZoomIn,
13769
- disabled: zoom >= maxZoom,
13770
- className: "p-2 liquid-surface rounded-lg disabled:opacity-50 disabled:cursor-not-allowed transition-colors",
13771
- "aria-label": labels?.zoomIn ?? "Zoom in",
13772
- "data-testid": "zoom-in-button",
13773
- children: /* @__PURE__ */ jsxRuntime.jsx(HeroIcons.PlusIcon, { className: "h-5 w-5 text-gray-700 dark:text-gray-300" })
13774
- }
13775
- ),
13776
- /* @__PURE__ */ jsxRuntime.jsx(
13777
- "button",
13778
- {
13779
- onClick: onZoomOut,
13780
- disabled: zoom <= minZoom,
13781
- className: "p-2 liquid-surface rounded-lg disabled:opacity-50 disabled:cursor-not-allowed transition-colors",
13782
- "aria-label": labels?.zoomOut ?? "Zoom out",
13783
- "data-testid": "zoom-out-button",
13784
- children: /* @__PURE__ */ jsxRuntime.jsx(HeroIcons.MinusIcon, { className: "h-5 w-5 text-gray-700 dark:text-gray-300" })
13785
- }
13786
- ),
13787
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-1 px-2 py-1 liquid-surface rounded-lg text-center", children: /* @__PURE__ */ jsxRuntime.jsxs(
13788
- "span",
13789
- {
13790
- className: "text-xs font-medium text-gray-600 dark:text-gray-400",
13791
- "data-testid": "zoom-level",
13792
- children: [
13793
- Math.round(zoom * 100),
13794
- "%"
13795
- ]
13796
- }
13797
- ) })
13798
- ]
13799
- }
13800
- );
13801
- }
13802
- );
13803
- MapZoomControls.displayName = "MapZoomControls";
13804
- function InteractiveGeoMapInner({
13805
- items,
13806
- getRegionCode,
13807
- regionCoordinates,
13808
- defaultCenter,
13809
- geoJsonUrl,
13810
- regionPropertyKey,
13811
- projectionType,
13812
- getRegionColor,
13813
- isRegionActive,
13814
- onRegionToggle,
13815
- renderHoverContent,
13816
- formatCounter,
13817
- zoomLabels,
13818
- ariaLabel,
13819
- className
13820
- }, ref) {
13821
- const mapStateOptions = {
13822
- items,
13823
- getRegionCode,
13824
- regionCoordinates,
13825
- defaultCenter
13826
- };
13827
- const mapState = useGeoMapState(mapStateOptions);
13828
- const regionColorMap = React12.useMemo(() => {
13829
- const colorMap2 = /* @__PURE__ */ new Map();
13830
- for (const code of Object.keys(regionCoordinates)) {
13831
- colorMap2.set(code, getRegionColor(code));
13832
- }
13833
- mapState.regionGroups.forEach((regionData) => {
13834
- if (!colorMap2.has(regionData.code)) {
13835
- colorMap2.set(regionData.code, getRegionColor(regionData.code));
13626
+ aiPanel.bgTint && /* @__PURE__ */ jsxRuntime.jsx("div", { className: `absolute inset-px rounded-2xl bg-gradient-to-br ${aiPanel.bgTint}` }),
13627
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `relative flex h-full flex-col overflow-hidden rounded-2xl border ${aiPanel.borderColor ?? "border-gray-200 dark:border-gray-800"} bg-white/50 dark:bg-zinc-900/50 backdrop-blur-sm`, children: [
13628
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "px-6 pt-6 pb-4", children: [
13629
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3 mb-3", children: [
13630
+ /* @__PURE__ */ jsxRuntime.jsx(IconTile, { icon: aiPanel.icon, gradient: aiPanel.gradient, size: "md" }),
13631
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-lg font-bold text-gray-900 dark:text-white", children: aiPanel.title })
13632
+ ] }),
13633
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-gray-600 dark:text-gray-400", children: aiPanel.description })
13634
+ ] }),
13635
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "relative min-h-[200px] w-full grow p-6", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-3", children: aiPanel.items.map((item, index) => /* @__PURE__ */ jsxRuntime.jsxs(
13636
+ framerMotion.motion.div,
13637
+ {
13638
+ initial: { opacity: 0, x: -20 },
13639
+ animate: { opacity: 1, x: 0 },
13640
+ transition: { delay: 0.3 + index * 0.2 },
13641
+ className: `flex items-center gap-3 p-3 rounded-xl ${item.bgTint}`,
13642
+ children: [
13643
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: `h-2 w-2 rounded-full animate-pulse ${item.dotColor}` }),
13644
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: `text-xs font-medium ${item.textColor}`, children: item.label })
13645
+ ]
13646
+ },
13647
+ `${item.label}-${index}`
13648
+ )) }) })
13649
+ ] }),
13650
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pointer-events-none absolute inset-px rounded-2xl shadow-sm" })
13651
+ ]
13836
13652
  }
13837
- });
13838
- return colorMap2;
13839
- }, [regionCoordinates, mapState.regionGroups, getRegionColor]);
13840
- const handleRegionClick = (code) => {
13841
- onRegionToggle?.(code);
13842
- };
13843
- const hoveredRegionData = React12.useMemo(() => {
13844
- if (!mapState.hoveredRegion) return null;
13845
- return mapState.regionGroups.find(
13846
- (regionData) => regionData.code === mapState.hoveredRegion
13847
- ) ?? null;
13848
- }, [mapState.hoveredRegion, mapState.regionGroups]);
13849
- const counterText = React12.useMemo(() => {
13850
- if (!formatCounter) return null;
13851
- const hasActiveFilter = isRegionActive && mapState.regionGroups.some(
13852
- (regionData) => isRegionActive(regionData.code)
13853
- );
13854
- if (hasActiveFilter) {
13855
- const activeRegions = mapState.regionGroups.filter(
13856
- (regionData) => isRegionActive(regionData.code)
13857
- );
13858
- const activeItemCount = activeRegions.reduce(
13859
- (sum, regionData) => sum + regionData.items.length,
13860
- 0
13861
- );
13862
- return formatCounter(items.length, mapState.regionGroups.length, activeItemCount, activeRegions.length);
13863
- }
13864
- return formatCounter(items.length, mapState.regionGroups.length);
13865
- }, [formatCounter, isRegionActive, mapState.regionGroups, items.length]);
13866
- return /* @__PURE__ */ jsxRuntime.jsx(
13867
- "div",
13868
- {
13869
- ref,
13870
- className: `space-y-4 h-full ${className ?? ""}`,
13871
- "data-testid": "interactive-geo-map-container",
13872
- children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative h-full", children: [
13873
- /* @__PURE__ */ jsxRuntime.jsx(
13874
- GeoMapCanvas,
13875
- {
13876
- regionGroups: mapState.regionGroups,
13877
- regionColorMap,
13878
- animatedRegions: mapState.animatedRegions,
13879
- zoom: mapState.zoom,
13880
- panOffset: mapState.panOffset,
13881
- hoveredRegion: mapState.hoveredRegion,
13882
- onPan: mapState.handlePan,
13883
- onRegionHover: mapState.setHoveredRegion,
13884
- onRegionClick: handleRegionClick,
13885
- isRegionActive,
13886
- getMarkerSize: mapState.getMarkerSize,
13887
- getFontSize: mapState.getFontSize,
13888
- geoJsonUrl,
13889
- regionPropertyKey,
13890
- projectionType,
13891
- ariaLabel
13892
- }
13893
- ),
13894
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute top-3 right-3 z-10", children: /* @__PURE__ */ jsxRuntime.jsx(
13895
- MapZoomControls,
13896
- {
13897
- zoom: mapState.zoom,
13898
- minZoom: mapState.MIN_ZOOM,
13899
- maxZoom: mapState.MAX_ZOOM,
13900
- onZoomIn: mapState.handleZoomIn,
13901
- onZoomOut: mapState.handleZoomOut,
13902
- labels: zoomLabels
13903
- }
13904
- ) }),
13905
- mapState.hoveredRegion && hoveredRegionData && renderHoverContent && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute top-3 left-3 z-10 pointer-events-none", children: renderHoverContent(mapState.hoveredRegion, hoveredRegionData.items) }),
13906
- counterText && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute bottom-3 left-3 z-10 pointer-events-none", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "liquid-surface rounded-lg px-3 py-1.5", children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs font-medium text-gray-600 dark:text-gray-300", children: counterText }) }) })
13907
- ] })
13908
- }
13909
- );
13910
- }
13911
- var InteractiveGeoMap = React12__namespace.default.forwardRef(InteractiveGeoMapInner);
13912
- var DEFAULT_LEGEND_COLOR = "#6366f1";
13913
- var GeoMapLegend = React12__namespace.default.forwardRef(
13914
- ({ items, colorMap: colorMap2, getFlagUrl, getLabel, labels, maxItems = 5 }, ref) => {
13915
- return /* @__PURE__ */ jsxRuntime.jsxs(
13916
- "div",
13653
+ ),
13654
+ /* @__PURE__ */ jsxRuntime.jsxs(
13655
+ framerMotion.motion.div,
13917
13656
  {
13918
- ref,
13919
- className: "liquid-surface rounded-lg p-3",
13920
- "data-testid": "map-legend",
13657
+ initial: { opacity: 0, y: 20 },
13658
+ animate: { opacity: 1, y: 0 },
13659
+ transition: { duration: 0.6, delay: 0.2 },
13660
+ className: "relative max-lg:row-start-1",
13921
13661
  children: [
13922
- /* @__PURE__ */ jsxRuntime.jsx("h4", { className: "text-xs font-semibold text-gray-700 dark:text-gray-300 mb-2", children: labels.title }),
13923
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1.5", children: [
13924
- items.slice(0, maxItems).map((item) => {
13925
- const flagUrl = getFlagUrl?.(item.code);
13926
- const regionColor = colorMap2.get(item.code) ?? DEFAULT_LEGEND_COLOR;
13927
- const displayLabel = getLabel?.(item.code) ?? item.code;
13662
+ metricsPanel.bgTint && /* @__PURE__ */ jsxRuntime.jsx("div", { className: `absolute inset-px rounded-2xl bg-gradient-to-br ${metricsPanel.bgTint}` }),
13663
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `relative flex h-full flex-col overflow-hidden rounded-2xl border ${metricsPanel.borderColor ?? "border-gray-200 dark:border-gray-800"} bg-white/50 dark:bg-zinc-900/50 backdrop-blur-sm`, children: [
13664
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "px-6 pt-6 pb-4", children: [
13665
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3 mb-3", children: [
13666
+ /* @__PURE__ */ jsxRuntime.jsx(IconTile, { icon: metricsPanel.icon, gradient: metricsPanel.gradient, size: "sm" }),
13667
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-base font-bold text-gray-900 dark:text-white", children: metricsPanel.title })
13668
+ ] }),
13669
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-gray-600 dark:text-gray-400", children: metricsPanel.description })
13670
+ ] }),
13671
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-1 items-center justify-center px-6 pb-6", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-2 gap-3 w-full", children: metricsPanel.metrics.map((metric, index) => /* @__PURE__ */ jsxRuntime.jsxs(
13672
+ framerMotion.motion.div,
13673
+ {
13674
+ initial: { scale: 0 },
13675
+ animate: { scale: 1 },
13676
+ transition: { delay: 0.5 + index * 0.1 },
13677
+ className: `${metric.bgTint} rounded-xl p-3 text-center`,
13678
+ children: [
13679
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: `text-2xl font-bold ${metric.valueColor}`, children: metric.value }),
13680
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-[10px] text-gray-600 dark:text-gray-400", children: metric.label })
13681
+ ]
13682
+ },
13683
+ `${metric.label}-${index}`
13684
+ )) }) })
13685
+ ] }),
13686
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pointer-events-none absolute inset-px rounded-2xl shadow-sm" })
13687
+ ]
13688
+ }
13689
+ ),
13690
+ /* @__PURE__ */ jsxRuntime.jsxs(
13691
+ framerMotion.motion.div,
13692
+ {
13693
+ initial: { opacity: 0, y: 20 },
13694
+ animate: { opacity: 1, y: 0 },
13695
+ transition: { duration: 0.6, delay: 0.3 },
13696
+ className: "relative max-lg:row-start-3 lg:col-start-2 lg:row-start-2",
13697
+ children: [
13698
+ securityPanel.bgTint && /* @__PURE__ */ jsxRuntime.jsx("div", { className: `absolute inset-px rounded-2xl bg-gradient-to-br ${securityPanel.bgTint}` }),
13699
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `relative flex h-full flex-col overflow-hidden rounded-2xl border ${securityPanel.borderColor ?? "border-gray-200 dark:border-gray-800"} bg-white/50 dark:bg-zinc-900/50 backdrop-blur-sm`, children: [
13700
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "px-6 pt-6 pb-4", children: [
13701
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3 mb-3", children: [
13702
+ /* @__PURE__ */ jsxRuntime.jsx(IconTile, { icon: securityPanel.icon, gradient: securityPanel.gradient, size: "sm" }),
13703
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-base font-bold text-gray-900 dark:text-white", children: securityPanel.title })
13704
+ ] }),
13705
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-gray-600 dark:text-gray-400", children: securityPanel.description })
13706
+ ] }),
13707
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-1 items-center px-6 pb-6", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full space-y-2", children: securityPanel.bars.map((bar, index) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
13708
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: `h-1.5 flex-1 rounded-full overflow-hidden ${bar.trackColor}`, children: /* @__PURE__ */ jsxRuntime.jsx(
13709
+ framerMotion.motion.div,
13710
+ {
13711
+ initial: { width: 0 },
13712
+ animate: { width: "100%" },
13713
+ transition: { delay: 0.7 + index * 0.2, duration: 1 },
13714
+ className: `h-full ${bar.fillColor}`
13715
+ }
13716
+ ) }),
13717
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: `text-[10px] font-medium ${bar.labelColor}`, children: bar.label })
13718
+ ] }, `${bar.label}-${index}`)) }) })
13719
+ ] }),
13720
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pointer-events-none absolute inset-px rounded-2xl shadow-sm" })
13721
+ ]
13722
+ }
13723
+ ),
13724
+ /* @__PURE__ */ jsxRuntime.jsxs(
13725
+ framerMotion.motion.div,
13726
+ {
13727
+ initial: { opacity: 0, y: 20 },
13728
+ animate: { opacity: 1, y: 0 },
13729
+ transition: { duration: 0.6, delay: 0.4 },
13730
+ className: "relative lg:row-span-2",
13731
+ children: [
13732
+ agentsPanel.bgTint && /* @__PURE__ */ jsxRuntime.jsx("div", { className: `absolute inset-px rounded-2xl bg-gradient-to-br ${agentsPanel.bgTint}` }),
13733
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `relative flex h-full flex-col overflow-hidden rounded-2xl border ${agentsPanel.borderColor ?? "border-gray-200 dark:border-gray-800"} bg-white/50 dark:bg-zinc-900/50 backdrop-blur-sm`, children: [
13734
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "px-6 pt-6 pb-4", children: [
13735
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3 mb-3", children: [
13736
+ /* @__PURE__ */ jsxRuntime.jsx(IconTile, { icon: agentsPanel.icon, gradient: agentsPanel.gradient, size: "md" }),
13737
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-lg font-bold text-gray-900 dark:text-white", children: agentsPanel.title })
13738
+ ] }),
13739
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-gray-600 dark:text-gray-400", children: agentsPanel.description })
13740
+ ] }),
13741
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "relative w-full grow p-6", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-2 gap-3", children: agentsPanel.agents.map((agent, index) => {
13742
+ const delay = 0.5 + index * 0.1;
13928
13743
  return /* @__PURE__ */ jsxRuntime.jsxs(
13929
- "div",
13744
+ framerMotion.motion.div,
13930
13745
  {
13931
- className: "flex items-center gap-2",
13932
- "data-testid": `legend-item-${item.code}`,
13746
+ initial: { opacity: 0, scale: 0.8 },
13747
+ animate: { opacity: 1, scale: 1 },
13748
+ transition: { delay },
13749
+ className: `relative overflow-hidden rounded-xl bg-gradient-to-br ${agent.color} p-3 text-white`,
13933
13750
  children: [
13934
- flagUrl ? (
13935
- // eslint-disable-next-line @next/next/no-img-element
13936
- /* @__PURE__ */ jsxRuntime.jsx(
13937
- "img",
13751
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative z-10", children: [
13752
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs font-bold", children: agent.name }),
13753
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-1 h-1 w-12 bg-white/30 rounded-full", children: /* @__PURE__ */ jsxRuntime.jsx(
13754
+ framerMotion.motion.div,
13938
13755
  {
13939
- src: flagUrl,
13940
- alt: item.code,
13941
- className: "w-4 h-4 shadow-sm"
13756
+ initial: { width: 0 },
13757
+ animate: { width: "100%" },
13758
+ transition: { delay: delay + 0.3, duration: 0.8 },
13759
+ className: "h-full bg-white rounded-full"
13942
13760
  }
13943
- )
13944
- ) : /* @__PURE__ */ jsxRuntime.jsx(
13945
- "div",
13946
- {
13947
- className: "w-4 h-4 rounded-full",
13948
- style: { backgroundColor: regionColor },
13949
- "data-testid": `legend-color-${item.code}`
13950
- }
13951
- ),
13952
- /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-xs text-gray-600 dark:text-gray-400", children: [
13953
- displayLabel,
13954
- " (",
13955
- item.count,
13956
- ")"
13957
- ] })
13761
+ ) })
13762
+ ] }),
13763
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute top-0 right-0 w-16 h-16 bg-white/10 rounded-full -mr-8 -mt-8" })
13958
13764
  ]
13959
13765
  },
13960
- item.code
13766
+ agent.name
13961
13767
  );
13962
- }),
13963
- items.length > maxItems && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-xs text-gray-500 dark:text-gray-400 italic pt-1", children: [
13964
- "+",
13965
- items.length - maxItems,
13966
- " ",
13967
- labels.more
13968
- ] })
13969
- ] })
13768
+ }) }) })
13769
+ ] }),
13770
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pointer-events-none absolute inset-px rounded-2xl shadow-sm" })
13970
13771
  ]
13971
13772
  }
13972
- );
13973
- }
13974
- );
13975
- GeoMapLegend.displayName = "GeoMapLegend";
13976
-
13977
- // src/lib/themes/brazil.ts
13978
- var BRAZIL_STATE_PALETTES = {
13979
- AC: { primary: "#009b43", secondary: "#ffcf44", text: "light" },
13980
- AL: { primary: "#d9251d", secondary: "#01a2ce", text: "light" },
13981
- AM: { primary: "#213572", secondary: "#d9251d", text: "light" },
13982
- AP: { primary: "#213572", secondary: "#009b43", text: "light" },
13983
- BA: { primary: "#213572", secondary: "#d9251d", text: "light" },
13984
- CE: { primary: "#009b43", secondary: "#ffcf44", text: "light" },
13985
- DF: { primary: "#009b43", secondary: "#ffcf44", text: "light" },
13986
- ES: { primary: "#ea5a8d", secondary: "#01a2ce", text: "light" },
13987
- GO: { primary: "#009b43", secondary: "#213572", text: "light" },
13988
- MA: { primary: "#213572", secondary: "#d9251d", text: "light" },
13989
- MG: { primary: "#d9251d", secondary: "#f0f0f0", text: "light" },
13990
- MS: { primary: "#009b43", secondary: "#01a2ce", text: "light" },
13991
- MT: { primary: "#213572", secondary: "#009b43", text: "light" },
13992
- PA: { primary: "#d9251d", secondary: "#213572", text: "light" },
13993
- PB: { primary: "#d9251d", secondary: "#1d1d1b", text: "light" },
13994
- PE: { primary: "#213572", secondary: "#ffcf44", text: "light" },
13995
- PI: { primary: "#009b43", secondary: "#ffcf44", text: "light" },
13996
- PR: { primary: "#009b43", secondary: "#213572", text: "light" },
13997
- RJ: { primary: "#01a2ce", secondary: "#009b43", text: "light" },
13998
- RN: { primary: "#009b43", secondary: "#01a2ce", text: "light" },
13999
- RO: { primary: "#213572", secondary: "#009b43", text: "light" },
14000
- RR: { primary: "#009b43", secondary: "#01a2ce", text: "light" },
14001
- RS: { primary: "#009b43", secondary: "#d9251d", text: "light" },
14002
- SC: { primary: "#d9251d", secondary: "#a6ce39", text: "light" },
14003
- SE: { primary: "#009b43", secondary: "#213572", text: "light" },
14004
- SP: { primary: "#1d1d1b", secondary: "#d9251d", text: "light" },
14005
- TO: { primary: "#ef9926", secondary: "#213572", text: "dark" }
14006
- };
14007
- var BRAZIL_ACCENT_MAP = {
14008
- AC: "green",
14009
- AL: "red",
14010
- AM: "blue",
14011
- AP: "blue",
14012
- BA: "blue",
14013
- CE: "green",
14014
- DF: "green",
14015
- ES: "pink",
14016
- GO: "green",
14017
- MA: "blue",
14018
- MG: "red",
14019
- MS: "green",
14020
- MT: "blue",
14021
- PA: "red",
14022
- PB: "red",
14023
- PE: "blue",
14024
- PI: "green",
14025
- PR: "green",
14026
- RJ: "blue",
14027
- RN: "green",
14028
- RO: "blue",
14029
- RR: "green",
14030
- RS: "green",
14031
- SC: "red",
14032
- SE: "green",
14033
- SP: "black",
14034
- TO: "yellow"
14035
- };
14036
- var VALID_UFS = Object.keys(BRAZIL_STATE_PALETTES);
14037
- var BR_THEME_CONFIG = {
14038
- palettes: BRAZIL_STATE_PALETTES,
14039
- accents: BRAZIL_ACCENT_MAP,
14040
- flagUrlTemplate: (code) => VALID_UFS.includes(code) ? `/flags/${code}.svg` : null
14041
- };
14042
- var BRAZIL_STATE_COORDINATES = {
14043
- AC: [-70, -9],
14044
- AL: [-36.6, -9.5],
14045
- AM: [-64, -4],
14046
- AP: [-51, 1],
14047
- BA: [-41.5, -12.5],
14048
- CE: [-39, -5],
14049
- DF: [-47.9, -15.8],
14050
- ES: [-40.3, -19.5],
14051
- GO: [-49.5, -16],
14052
- MA: [-45, -5],
14053
- MG: [-44.5, -18.5],
14054
- MS: [-55, -21],
14055
- MT: [-56, -13],
14056
- PA: [-52, -4],
14057
- PB: [-36.8, -7.1],
14058
- PE: [-37.5, -8.3],
14059
- PI: [-43, -7.5],
14060
- PR: [-51.5, -25],
14061
- RJ: [-43.2, -22.5],
14062
- RN: [-36.5, -5.8],
14063
- RO: [-63, -11],
14064
- RR: [-61, 2],
14065
- RS: [-53, -30],
14066
- SC: [-49.5, -27.5],
14067
- SE: [-37, -10.5],
14068
- SP: [-48.5, -22.5],
14069
- TO: [-48, -10]
14070
- };
14071
- var BRAZIL_MAP_CENTER = [-54, -15];
14072
- var BRAZIL_MACRO_REGIONS = [
14073
- {
14074
- key: "sudeste",
14075
- label: "",
14076
- codes: ["SP", "RJ", "MG", "ES"],
14077
- gradient: "from-blue-500/15 to-indigo-500/10 dark:from-blue-500/20 dark:to-indigo-500/15",
14078
- iconColor: "text-blue-600 dark:text-blue-400"
14079
- },
14080
- {
14081
- key: "sul",
14082
- label: "",
14083
- codes: ["PR", "SC", "RS"],
14084
- gradient: "from-emerald-500/15 to-teal-500/10 dark:from-emerald-500/20 dark:to-teal-500/15",
14085
- iconColor: "text-emerald-600 dark:text-emerald-400"
14086
- },
14087
- {
14088
- key: "nordeste",
14089
- label: "",
14090
- codes: ["BA", "PE", "CE", "MA", "PB", "RN", "AL", "SE", "PI"],
14091
- gradient: "from-orange-500/15 to-amber-500/10 dark:from-orange-500/20 dark:to-amber-500/15",
14092
- iconColor: "text-orange-600 dark:text-orange-400"
14093
- },
14094
- {
14095
- key: "centroOeste",
14096
- label: "",
14097
- codes: ["GO", "MT", "MS", "DF"],
14098
- gradient: "from-purple-500/15 to-fuchsia-500/10 dark:from-purple-500/20 dark:to-fuchsia-500/15",
14099
- iconColor: "text-purple-600 dark:text-purple-400"
14100
- },
14101
- {
14102
- key: "norte",
14103
- label: "",
14104
- codes: ["PA", "AM", "RO", "TO", "AC", "AP", "RR"],
14105
- gradient: "from-cyan-500/15 to-sky-500/10 dark:from-cyan-500/20 dark:to-sky-500/15",
14106
- iconColor: "text-cyan-600 dark:text-cyan-400"
14107
- }
14108
- ];
14109
- var getBrazilFlagUrl = (uf) => getSubdivisionFlagUrl("BR", uf);
14110
- var getBrazilHexColor = (uf) => getSubdivisionHexColor("BR", uf);
14111
- var getBrazilPalette = (uf) => getSubdivisionPalette("BR", uf);
14112
- var getBrazilGradient = (uf, direction) => getSubdivisionGradient("BR", uf, direction);
14113
- var getBrazilColors = (uf) => getSubdivisionColors("BR", uf);
14114
- var getBrazilAccent = (uf) => getSubdivisionAccent("BR", uf);
14115
- var isValidBrazilState = (uf) => isValidSubdivision("BR", uf);
14116
- var FUELS = [
14117
- { id: "gasolina", label: "Gasolina", color: "text-orange-400", bg: "bg-orange-500/15", ring: "ring-orange-500/40" },
14118
- { id: "etanol", label: "Etanol", color: "text-emerald-400", bg: "bg-emerald-500/15", ring: "ring-emerald-500/40" },
14119
- { id: "diesel", label: "Diesel", color: "text-slate-300", bg: "bg-slate-500/15", ring: "ring-slate-500/40" },
14120
- { id: "gnv", label: "GNV", color: "text-cyan-400", bg: "bg-cyan-500/15", ring: "ring-cyan-500/40" }
14121
- ];
14122
- var FUEL_PRICING = {
14123
- gasolina: {
14124
- currentPrice: "R$ 5.77",
14125
- aiPrice: "R$ 5.89",
14126
- delta: "+R$ 0.12",
14127
- deltaUp: true,
14128
- confidence: "94%",
14129
- revenue: "R$ 2.4M",
14130
- volume: "890K L",
14131
- margin: "12.8%",
14132
- minMax: "MIN 5.20 \u2014 MAX 6.10",
14133
- competitors: [
14134
- { name: "Shell Paulista", distance: "0.8km", price: "R$ 5.99", change: "+1.7%", up: true },
14135
- { name: "Ipiranga Centro", distance: "1.2km", price: "R$ 5.85", change: "-0.7%", up: false },
14136
- { name: "BR Distribuidora", distance: "2.1km", price: "R$ 5.92", change: "+0.5%", up: true }
14137
- ]
14138
- },
14139
- etanol: {
14140
- currentPrice: "R$ 3.45",
14141
- aiPrice: "R$ 3.49",
14142
- delta: "+R$ 0.04",
14143
- deltaUp: true,
14144
- confidence: "91%",
14145
- revenue: "R$ 980K",
14146
- volume: "620K L",
14147
- margin: "14.2%",
14148
- minMax: "MIN 2.90 \u2014 MAX 3.80",
14149
- competitors: [
14150
- { name: "Shell Paulista", distance: "0.8km", price: "R$ 3.59", change: "+2.9%", up: true },
14151
- { name: "Ipiranga Centro", distance: "1.2km", price: "R$ 3.42", change: "-0.9%", up: false },
14152
- { name: "BR Distribuidora", distance: "2.1km", price: "R$ 3.55", change: "+1.1%", up: true }
14153
- ]
14154
- },
14155
- diesel: {
14156
- currentPrice: "R$ 6.04",
14157
- aiPrice: "R$ 6.12",
14158
- delta: "+R$ 0.08",
14159
- deltaUp: true,
14160
- confidence: "89%",
14161
- revenue: "R$ 1.8M",
14162
- volume: "450K L",
14163
- margin: "10.5%",
14164
- minMax: "MIN 5.60 \u2014 MAX 6.50",
14165
- competitors: [
14166
- { name: "Shell Paulista", distance: "0.8km", price: "R$ 6.19", change: "+1.1%", up: true },
14167
- { name: "Ipiranga Centro", distance: "1.2km", price: "R$ 6.02", change: "-0.5%", up: false },
14168
- { name: "BR Distribuidora", distance: "2.1km", price: "R$ 6.15", change: "+0.8%", up: true }
14169
- ]
14170
- },
14171
- gnv: {
14172
- currentPrice: "R$ 4.22",
14173
- aiPrice: "R$ 4.29",
14174
- delta: "+R$ 0.07",
14175
- deltaUp: true,
14176
- confidence: "87%",
14177
- revenue: "R$ 420K",
14178
- volume: "180K m\xB3",
14179
- margin: "15.1%",
14180
- minMax: "MIN 3.80 \u2014 MAX 4.60",
14181
- competitors: [
14182
- { name: "GNV Center SP", distance: "1.5km", price: "R$ 4.35", change: "+1.4%", up: true },
14183
- { name: "Posto GNV Sul", distance: "2.8km", price: "R$ 4.19", change: "-0.7%", up: false },
14184
- { name: "Auto Gas BR", distance: "3.2km", price: "R$ 4.28", change: "+0.2%", up: true }
14185
- ]
14186
- }
14187
- };
14188
- var STATIONS = [
14189
- { id: "1", name: "Posto Paulista", region: "SP", value: 42e4, fuel: "gasolina", price: "R$ 5.89" },
14190
- { id: "2", name: "Posto Moema", region: "SP", value: 38e4, fuel: "etanol", price: "R$ 3.49" },
14191
- { id: "3", name: "Posto Campinas", region: "SP", value: 34e4, fuel: "diesel", price: "R$ 6.12" },
14192
- { id: "4", name: "Posto Santos", region: "SP", value: 29e4, fuel: "gnv", price: "R$ 4.29" },
14193
- { id: "5", name: "Posto Barra", region: "RJ", value: 31e4, fuel: "gasolina", price: "R$ 6.05" },
14194
- { id: "6", name: "Posto Niter\xF3i", region: "RJ", value: 26e4, fuel: "etanol", price: "R$ 3.59" },
14195
- { id: "7", name: "Posto Savassi", region: "MG", value: 29e4, fuel: "gasolina", price: "R$ 5.79" },
14196
- { id: "8", name: "Posto Contagem", region: "MG", value: 22e4, fuel: "diesel", price: "R$ 6.05" },
14197
- { id: "9", name: "Posto Boa Viagem", region: "PE", value: 24e4, fuel: "gasolina", price: "R$ 5.85" },
14198
- { id: "10", name: "Posto Moinhos", region: "RS", value: 26e4, fuel: "etanol", price: "R$ 3.42" },
14199
- { id: "11", name: "Posto Curitiba", region: "PR", value: 27e4, fuel: "diesel", price: "R$ 5.99" },
14200
- { id: "12", name: "Posto Salvador", region: "BA", value: 25e4, fuel: "gasolina", price: "R$ 5.82" },
14201
- { id: "13", name: "Posto Bras\xEDlia", region: "DF", value: 3e5, fuel: "gnv", price: "R$ 4.15" },
14202
- { id: "14", name: "Posto Goi\xE2nia", region: "GO", value: 21e4, fuel: "gasolina", price: "R$ 5.78" },
14203
- { id: "15", name: "Posto Bel\xE9m", region: "PA", value: 19e4, fuel: "diesel", price: "R$ 6.25" }
14204
- ];
14205
- var AVATARS = {
14206
- data: "https://api.dicebear.com/9.x/lorelei/svg?seed=Laura&hair=variant31&beardProbability=0&mouth=happy01",
14207
- market: "https://api.dicebear.com/9.x/notionists/svg?seed=Paulo&hair=variant35&beardProbability=0&gestureProbability=0&glasses=variant03&glassesProbability=100",
14208
- pricing: "https://api.dicebear.com/9.x/lorelei/svg?seed=Roberta&hair=variant31&beardProbability=0&glasses=variant01&glassesProbability=100&mouth=happy01"
14209
- };
14210
- function buildPipelineNodes(fuelLabel, aiPrice, state, stationName) {
14211
- const isAll = state === "ALL";
14212
- const location = stationName ? `${stationName} (${state})` : isAll ? "All Regions" : `${state} Region`;
14213
- const stateLabel = isAll ? "BR" : state;
14214
- return [
14215
- { id: "start", label: "Start", subtitle: `${fuelLabel} \xB7 ${location}`, icon: HeroIcons.PlayIcon, color: "text-emerald-400", bg: "bg-emerald-500/15", glow: "rgba(16,185,129,0.5)", step: 0 },
14216
- { id: "bigquery", label: "BigQuery Sales", subtitle: `${fuelLabel} \xB7 ${stateLabel} sales_daily`, icon: HeroIcons.ServerStackIcon, color: "text-blue-400", bg: "bg-blue-500/15", glow: "rgba(59,130,246,0.5)", badges: [{ text: "datasource", color: "bg-blue-500/20 text-blue-300" }], step: 1 },
14217
- { id: "postgres", label: "Pricing DB", subtitle: `${stateLabel} competitor_prices`, icon: HeroIcons.ServerStackIcon, color: "text-blue-400", bg: "bg-blue-500/15", glow: "rgba(59,130,246,0.5)", badges: [{ text: "datasource", color: "bg-blue-500/20 text-blue-300" }], step: 1 },
14218
- { id: "weather", label: "Weather", subtitle: `${stateLabel} \xB7 OpenMeteo API`, icon: HeroIcons.CloudIcon, color: "text-cyan-400", bg: "bg-cyan-500/15", glow: "rgba(6,182,212,0.5)", badges: [{ text: "tool", color: "bg-cyan-500/20 text-cyan-300" }, { text: "external", color: "bg-gray-500/20 text-gray-300" }], step: 1 },
14219
- { id: "market", label: "Market Data", subtitle: "Brent, USD/BRL, Petrobras", icon: HeroIcons.ArrowTrendingUpIcon, color: "text-amber-400", bg: "bg-amber-500/15", glow: "rgba(245,158,11,0.5)", badges: [{ text: "tool", color: "bg-amber-500/20 text-amber-300" }, { text: "market", color: "bg-gray-500/20 text-gray-300" }], step: 1 },
14220
- { id: "news", label: "News", subtitle: `${fuelLabel} \xB7 ${stateLabel} headlines`, icon: HeroIcons.NewspaperIcon, color: "text-orange-400", bg: "bg-orange-500/15", glow: "rgba(249,115,22,0.5)", badges: [{ text: "tool", color: "bg-orange-500/20 text-orange-300" }, { text: "external", color: "bg-gray-500/20 text-gray-300" }], step: 1 },
14221
- { id: "agg", label: "Aggregate", subtitle: `5 inputs \u2192 ${fuelLabel} \xB7 ${stateLabel}`, icon: HeroIcons.BoltIcon, color: "text-teal-400", bg: "bg-teal-500/15", glow: "rgba(20,184,166,0.5)", badges: [{ text: "aggregator", color: "bg-teal-500/20 text-teal-300" }], step: 2 },
14222
- { id: "data-analyst", label: "Data Analyst", subtitle: `${fuelLabel} \xB7 ${stateLabel} patterns`, icon: HeroIcons.CpuChipIcon, color: "text-purple-400", bg: "bg-purple-500/15", glow: "rgba(168,85,247,0.5)", avatar: AVATARS.data, badges: [{ text: "agent", color: "bg-purple-500/20 text-purple-300" }, { text: "intermediate", color: "bg-blue-500/20 text-blue-300" }], step: 3 },
14223
- { id: "market-analyst", label: "Market Analyst", subtitle: `${fuelLabel} \xB7 ${stateLabel} trends`, icon: HeroIcons.CpuChipIcon, color: "text-purple-400", bg: "bg-purple-500/15", glow: "rgba(168,85,247,0.5)", avatar: AVATARS.market, badges: [{ text: "agent", color: "bg-purple-500/20 text-purple-300" }, { text: "advanced", color: "bg-amber-500/20 text-amber-300" }], step: 4 },
14224
- { id: "pricing-mgr", label: "Pricing Manager", subtitle: `${fuelLabel} \xB7 ${location}`, icon: HeroIcons.CpuChipIcon, color: "text-purple-400", bg: "bg-purple-500/15", glow: "rgba(168,85,247,0.5)", avatar: AVATARS.pricing, badges: [{ text: "agent", color: "bg-purple-500/20 text-purple-300" }, { text: "advanced", color: "bg-amber-500/20 text-amber-300" }], step: 5 },
14225
- { id: "rule", label: "Peak Hours", subtitle: `+2% \xB7 ${fuelLabel} \xB7 ${stateLabel}`, icon: HeroIcons.ShieldCheckIcon, color: "text-rose-400", bg: "bg-rose-500/15", glow: "rgba(244,63,94,0.5)", badges: [{ text: "rule", color: "bg-rose-500/20 text-rose-300" }, { text: "percentage", color: "bg-gray-500/20 text-gray-300" }], step: 6 },
14226
- { id: "end", label: "End", subtitle: `${aiPrice} \xB7 ${location}`, icon: HeroIcons.StopIcon, color: "text-red-400", bg: "bg-red-500/15", glow: "rgba(239,68,68,0.5)", step: 7 }
14227
- ];
13773
+ )
13774
+ ] }) }) });
14228
13775
  }
14229
- var STEP_LABELS = [
14230
- "Triggering pipeline",
14231
- "Fetching data sources (parallel)",
14232
- "Aggregating context",
14233
- "Running Data Analyst",
14234
- "Running Market Analyst",
14235
- "Running Pricing Manager",
14236
- "Applying business rules",
14237
- "Complete \u2014 R$ 5.89/L \xB7 94% confidence"
14238
- ];
14239
- function PipelinePreview({ activeFuel, activeState, activeStation, onActiveFuelChange, onActiveStateChange, onActiveStationChange, onStepChange }) {
14240
- const fuelMeta = FUELS.find((f) => f.id === activeFuel);
14241
- const fuelPricing = FUEL_PRICING[activeFuel];
14242
- const stationsInState = React12.useMemo(() => activeState === "ALL" ? [] : STATIONS.filter((s) => s.region === activeState && s.fuel === activeFuel), [activeFuel, activeState]);
14243
- const availableStates = React12.useMemo(() => [...new Set(STATIONS.filter((s) => s.fuel === activeFuel).map((s) => s.region))], [activeFuel]);
14244
- const selectedStationName = activeStation ? STATIONS.find((s) => s.id === activeStation)?.name.replace("Posto ", "") ?? null : null;
14245
- const pipelineNodes = React12.useMemo(() => buildPipelineNodes(fuelMeta.label, fuelPricing.aiPrice, activeState, selectedStationName), [activeFuel, activeState, activeStation, fuelMeta.label, fuelPricing.aiPrice, selectedStationName]);
14246
- const [activeStep, setActiveStep] = React12.useState(-1);
14247
- const intervalRef = React12.useRef(null);
14248
- const isIdle = activeStep === -1;
14249
- const isRunning = activeStep >= 0 && activeStep < 7;
14250
- const isComplete = activeStep === 7;
14251
- const handleRun = React12.useCallback(() => {
14252
- if (intervalRef.current) clearInterval(intervalRef.current);
14253
- setActiveStep(0);
14254
- onStepChange?.(0);
14255
- let step2 = 0;
14256
- intervalRef.current = setInterval(() => {
14257
- step2 += 1;
14258
- if (step2 > 7) {
14259
- if (intervalRef.current) clearInterval(intervalRef.current);
14260
- setActiveStep(7);
14261
- onStepChange?.(7);
14262
- } else {
14263
- setActiveStep(step2);
14264
- onStepChange?.(step2);
14265
- }
14266
- }, 1400);
14267
- }, [onStepChange]);
14268
- const handleStop = React12.useCallback(() => {
14269
- if (intervalRef.current) clearInterval(intervalRef.current);
14270
- setActiveStep(-1);
14271
- onStepChange?.(-1);
14272
- }, [onStepChange]);
14273
- React12.useEffect(() => () => {
14274
- if (intervalRef.current) clearInterval(intervalRef.current);
14275
- }, []);
14276
- const getStatus = (node2) => {
14277
- if (activeStep < 0) return "idle";
14278
- if (node2.step < activeStep) return "complete";
14279
- if (node2.step === activeStep) return "active";
14280
- return "idle";
14281
- };
14282
- const rows = React12.useMemo(() => {
14283
- const result = [];
14284
- let step2 = -1;
14285
- for (const node2 of pipelineNodes) {
14286
- if (node2.step !== step2) {
14287
- result.push([]);
14288
- step2 = node2.step;
14289
- }
14290
- result[result.length - 1].push(node2);
14291
- }
14292
- return result;
14293
- }, [pipelineNodes]);
14294
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "h-full flex flex-col", children: [
14295
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1.5 px-3 py-2 border-b border-white/5 shrink-0 overflow-x-auto", children: [
14296
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center rounded-lg bg-white/[0.03] p-0.5 gap-0.5 shrink-0", children: [
14297
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[7px] font-bold uppercase tracking-wider text-gray-600 px-1.5", children: "Fuel" }),
14298
- FUELS.map((fuel) => /* @__PURE__ */ jsxRuntime.jsx(
14299
- "button",
13776
+ var CustomerAnalyticsDemo = () => /* @__PURE__ */ jsxRuntime.jsx(
13777
+ framerMotion.motion.div,
13778
+ {
13779
+ initial: { opacity: 0 },
13780
+ animate: { opacity: 1 },
13781
+ exit: { opacity: 0 },
13782
+ transition: { duration: 0.5 },
13783
+ className: "flex flex-col h-full overflow-hidden",
13784
+ children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1 flex flex-col overflow-hidden", children: [
13785
+ /* @__PURE__ */ jsxRuntime.jsxs(
13786
+ framerMotion.motion.div,
13787
+ {
13788
+ initial: { y: -20, opacity: 0 },
13789
+ animate: { y: 0, opacity: 1 },
13790
+ transition: { duration: 0.5, delay: 0.3 },
13791
+ className: "h-14 border-b bg-background/95 backdrop-blur-sm flex items-center justify-between px-4",
13792
+ children: [
13793
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3", children: [
13794
+ /* @__PURE__ */ jsxRuntime.jsx("h2", { className: "text-sm font-semibold", children: "An\xE1lise de Clientes" }),
13795
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs px-2 py-1 rounded-full bg-blue-500/10 text-blue-600 dark:text-blue-400 font-medium", children: "IA Analytics" })
13796
+ ] }),
13797
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
13798
+ /* @__PURE__ */ jsxRuntime.jsx(HeroIcons.BellIcon, { className: "h-4 w-4 text-muted-foreground" }),
13799
+ /* @__PURE__ */ jsxRuntime.jsx(HeroIcons.MagnifyingGlassIcon, { className: "h-4 w-4 text-muted-foreground" })
13800
+ ] })
13801
+ ]
13802
+ }
13803
+ ),
13804
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1 overflow-y-auto p-4 space-y-3", children: [
13805
+ /* @__PURE__ */ jsxRuntime.jsxs(
13806
+ framerMotion.motion.div,
14300
13807
  {
14301
- type: "button",
14302
- onClick: () => {
14303
- onActiveFuelChange?.(fuel.id);
14304
- if (!isIdle) handleStop();
14305
- },
14306
- className: `px-2 py-1 rounded-md text-[9px] font-semibold transition-all duration-200 ${activeFuel === fuel.id ? `${fuel.bg} ${fuel.color} shadow-sm` : "text-gray-500 hover:text-gray-300 hover:bg-white/5"}`,
14307
- children: fuel.label
14308
- },
14309
- fuel.id
14310
- ))
14311
- ] }),
14312
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center rounded-lg bg-white/[0.03] p-0.5 gap-0.5 shrink-0", children: [
14313
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[7px] font-bold uppercase tracking-wider text-gray-600 px-1.5", children: "State" }),
14314
- /* @__PURE__ */ jsxRuntime.jsx(
14315
- "button",
14316
- {
14317
- type: "button",
14318
- onClick: () => {
14319
- onActiveStateChange?.("ALL");
14320
- onActiveStationChange?.(null);
14321
- if (!isIdle) handleStop();
14322
- },
14323
- className: `px-2 py-1 rounded-md text-[9px] font-semibold transition-all duration-200 ${activeState === "ALL" ? "bg-white/10 text-white shadow-sm" : "text-gray-500 hover:text-gray-300 hover:bg-white/5"}`,
14324
- children: "All"
14325
- }
14326
- ),
14327
- availableStates.map((state) => /* @__PURE__ */ jsxRuntime.jsxs(
14328
- "button",
14329
- {
14330
- type: "button",
14331
- onClick: () => {
14332
- onActiveStateChange?.(state);
14333
- onActiveStationChange?.(null);
14334
- if (!isIdle) handleStop();
14335
- },
14336
- className: `flex items-center gap-1 px-1.5 py-1 rounded-md text-[9px] font-semibold transition-all duration-200 ${activeState === state ? "bg-white/10 text-white shadow-sm" : "text-gray-500 hover:text-gray-300 hover:bg-white/5"}`,
13808
+ initial: { opacity: 0, y: 20 },
13809
+ animate: { opacity: 1, y: 0 },
13810
+ transition: { delay: 0.5 },
13811
+ className: "grid grid-cols-2 gap-3",
14337
13812
  children: [
14338
- /* @__PURE__ */ jsxRuntime.jsx("img", { src: `/flags/${state}.svg`, alt: state, className: "h-3.5 w-3.5 rounded-sm", loading: "lazy" }),
14339
- state
13813
+ /* @__PURE__ */ jsxRuntime.jsxs(Card, { className: "p-3 bg-gradient-to-br from-blue-500 to-cyan-500 text-white", children: [
13814
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between mb-2", children: [
13815
+ /* @__PURE__ */ jsxRuntime.jsx(HeroIcons.UsersIcon, { className: "h-5 w-5" }),
13816
+ /* @__PURE__ */ jsxRuntime.jsx(Badge, { className: "bg-white/20 text-white border-white/30 h-5 text-xs", children: "+12%" })
13817
+ ] }),
13818
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-2xl font-bold", children: "2.547" }),
13819
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs opacity-90", children: "Clientes Ativos" })
13820
+ ] }),
13821
+ /* @__PURE__ */ jsxRuntime.jsxs(Card, { className: "p-3 bg-gradient-to-br from-purple-500 to-pink-500 text-white", children: [
13822
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between mb-2", children: [
13823
+ /* @__PURE__ */ jsxRuntime.jsx(HeroIcons.ArrowTrendingUpIcon, { className: "h-5 w-5" }),
13824
+ /* @__PURE__ */ jsxRuntime.jsx(Badge, { className: "bg-white/20 text-white border-white/30 h-5 text-xs", children: "+28%" })
13825
+ ] }),
13826
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-2xl font-bold", children: "R$ 485k" }),
13827
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs opacity-90", children: "Receita Mensal" })
13828
+ ] })
14340
13829
  ]
14341
- },
14342
- state
14343
- ))
14344
- ] }),
14345
- activeState !== "ALL" && stationsInState.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center rounded-lg bg-white/[0.03] p-0.5 gap-0.5 shrink-0", children: [
14346
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[7px] font-bold uppercase tracking-wider text-gray-600 px-1.5", children: "Station" }),
13830
+ }
13831
+ ),
14347
13832
  /* @__PURE__ */ jsxRuntime.jsx(
14348
- "button",
13833
+ framerMotion.motion.div,
14349
13834
  {
14350
- type: "button",
14351
- onClick: () => {
14352
- onActiveStationChange?.(null);
14353
- if (!isIdle) handleStop();
14354
- },
14355
- className: `px-2 py-1 rounded-md text-[9px] font-semibold transition-all duration-200 ${!activeStation ? "bg-white/10 text-white shadow-sm" : "text-gray-500 hover:text-gray-300 hover:bg-white/5"}`,
14356
- children: "All"
13835
+ initial: { opacity: 0, y: 20 },
13836
+ animate: { opacity: 1, y: 0 },
13837
+ transition: { delay: 0.7 },
13838
+ children: /* @__PURE__ */ jsxRuntime.jsxs(Card, { className: "border-2", children: [
13839
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-3 border-b bg-gradient-to-r from-blue-600 to-cyan-600 text-white", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
13840
+ /* @__PURE__ */ jsxRuntime.jsx(HeroIcons.SparklesIcon, { className: "h-4 w-4" }),
13841
+ /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-sm font-bold", children: "Insights IA" })
13842
+ ] }) }),
13843
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "p-3 space-y-3", children: [
13844
+ /* @__PURE__ */ jsxRuntime.jsxs(
13845
+ framerMotion.motion.div,
13846
+ {
13847
+ initial: { opacity: 0, x: -10 },
13848
+ animate: { opacity: 1, x: 0 },
13849
+ transition: { delay: 0.9 },
13850
+ className: "flex items-start gap-2",
13851
+ children: [
13852
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-6 w-6 rounded-full bg-green-500/10 flex items-center justify-center flex-shrink-0", children: /* @__PURE__ */ jsxRuntime.jsx(HeroIcons.CheckCircleIcon, { className: "h-3 w-3 text-green-500" }) }),
13853
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1", children: [
13854
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs font-medium", children: "Segmento Premium crescendo" }),
13855
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-[10px] text-muted-foreground", children: "+45% de convers\xE3o em produtos acima de R$ 500" })
13856
+ ] })
13857
+ ]
13858
+ }
13859
+ ),
13860
+ /* @__PURE__ */ jsxRuntime.jsxs(
13861
+ framerMotion.motion.div,
13862
+ {
13863
+ initial: { opacity: 0, x: -10 },
13864
+ animate: { opacity: 1, x: 0 },
13865
+ transition: { delay: 1.1 },
13866
+ className: "flex items-start gap-2",
13867
+ children: [
13868
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-6 w-6 rounded-full bg-blue-500/10 flex items-center justify-center flex-shrink-0", children: /* @__PURE__ */ jsxRuntime.jsx(HeroIcons.ArrowTrendingUpIcon, { className: "h-3 w-3 text-blue-500" }) }),
13869
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1", children: [
13870
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs font-medium", children: "Reten\xE7\xE3o melhorou 32%" }),
13871
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-[10px] text-muted-foreground", children: "Ap\xF3s implementa\xE7\xE3o do programa de fidelidade" })
13872
+ ] })
13873
+ ]
13874
+ }
13875
+ ),
13876
+ /* @__PURE__ */ jsxRuntime.jsxs(
13877
+ framerMotion.motion.div,
13878
+ {
13879
+ initial: { opacity: 0, x: -10 },
13880
+ animate: { opacity: 1, x: 0 },
13881
+ transition: { delay: 1.3 },
13882
+ className: "flex items-start gap-2",
13883
+ children: [
13884
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-6 w-6 rounded-full bg-purple-500/10 flex items-center justify-center flex-shrink-0", children: /* @__PURE__ */ jsxRuntime.jsx(HeroIcons.UsersIcon, { className: "h-3 w-3 text-purple-500" }) }),
13885
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1", children: [
13886
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs font-medium", children: "847 clientes em risco" }),
13887
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-[10px] text-muted-foreground", children: "Sem compras h\xE1 60+ dias - recomendar campanha" })
13888
+ ] })
13889
+ ]
13890
+ }
13891
+ )
13892
+ ] })
13893
+ ] })
14357
13894
  }
14358
13895
  ),
14359
- stationsInState.map((station) => /* @__PURE__ */ jsxRuntime.jsx(
14360
- "button",
13896
+ /* @__PURE__ */ jsxRuntime.jsx(
13897
+ framerMotion.motion.div,
14361
13898
  {
14362
- type: "button",
14363
- onClick: () => {
14364
- onActiveStationChange?.(station.id);
14365
- if (!isIdle) handleStop();
14366
- },
14367
- className: `px-2 py-1 rounded-md text-[9px] font-semibold transition-all duration-200 ${activeStation === station.id ? "bg-blue-500/15 text-blue-300 shadow-sm" : "text-gray-500 hover:text-gray-300 hover:bg-white/5"}`,
14368
- children: station.name.replace("Posto ", "")
14369
- },
14370
- station.id
14371
- ))
14372
- ] }),
14373
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "ml-auto flex items-center gap-2 shrink-0", children: [
14374
- activeStep >= 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-0.5", children: STEP_LABELS.map((_, index) => /* @__PURE__ */ jsxRuntime.jsx("div", { className: `h-1 w-2.5 rounded-full transition-all duration-500 ${index < activeStep || isComplete ? "bg-emerald-500" : index === activeStep ? "bg-blue-500 animate-pulse" : "bg-white/10"}` }, index)) }),
14375
- isComplete && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1 rounded-full bg-emerald-500/10 px-2 py-0.5", children: [
14376
- /* @__PURE__ */ jsxRuntime.jsx(HeroIcons.CheckCircleIcon, { className: "h-3 w-3 text-emerald-400" }),
14377
- /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-[8px] font-semibold text-emerald-400", children: [
14378
- fuelPricing.aiPrice,
14379
- " \xB7 ",
14380
- fuelPricing.confidence
14381
- ] })
14382
- ] }),
14383
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: `h-2 w-2 rounded-full ${isRunning ? "bg-blue-500 animate-pulse" : isComplete ? "bg-emerald-500" : "bg-gray-600"}` }),
14384
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[9px] text-gray-500 max-w-[120px] truncate", children: activeStep >= 0 ? STEP_LABELS[activeStep] : "Ready" }),
14385
- isIdle ? /* @__PURE__ */ jsxRuntime.jsxs("button", { type: "button", onClick: handleRun, className: "flex items-center gap-1 rounded-lg bg-gradient-to-r from-blue-600 to-indigo-600 px-3 py-1 text-[10px] font-semibold text-white shadow-lg shadow-blue-500/20 hover:shadow-blue-500/30 hover:scale-105 active:scale-95 transition-all", children: [
14386
- /* @__PURE__ */ jsxRuntime.jsx(HeroIcons.PlayIcon, { className: "h-3 w-3" }),
14387
- " Run"
14388
- ] }) : isRunning ? /* @__PURE__ */ jsxRuntime.jsxs("button", { type: "button", onClick: handleStop, className: "flex items-center gap-1 rounded-lg bg-rose-600/80 px-3 py-1 text-[10px] font-semibold text-white", children: [
14389
- /* @__PURE__ */ jsxRuntime.jsx(HeroIcons.StopIcon, { className: "h-3 w-3" }),
14390
- " Stop"
14391
- ] }) : /* @__PURE__ */ jsxRuntime.jsxs("button", { type: "button", onClick: handleRun, className: "flex items-center gap-1 rounded-lg border border-white/10 px-3 py-1 text-[10px] font-medium text-gray-300 hover:bg-white/5", children: [
14392
- /* @__PURE__ */ jsxRuntime.jsx(HeroIcons.PlayIcon, { className: "h-3 w-3" }),
14393
- " Run Again"
14394
- ] })
13899
+ initial: { opacity: 0, y: 20 },
13900
+ animate: { opacity: 1, y: 0 },
13901
+ transition: { delay: 1.5 },
13902
+ children: /* @__PURE__ */ jsxRuntime.jsxs(Card, { className: "p-3", children: [
13903
+ /* @__PURE__ */ jsxRuntime.jsx("h4", { className: "text-xs font-semibold mb-2", children: "Top Clientes (\xDAltimo M\xEAs)" }),
13904
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-2", children: ["Maria Silva", "Jo\xE3o Santos", "Ana Costa"].map((name, i) => /* @__PURE__ */ jsxRuntime.jsxs(
13905
+ framerMotion.motion.div,
13906
+ {
13907
+ initial: { opacity: 0, x: -10 },
13908
+ animate: { opacity: 1, x: 0 },
13909
+ transition: { delay: 1.7 + i * 0.2 },
13910
+ className: "flex items-center justify-between",
13911
+ children: [
13912
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
13913
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-6 w-6 rounded-full bg-gradient-to-br from-gray-400 to-gray-600 flex items-center justify-center text-white text-[10px] font-bold", children: name.charAt(0) }),
13914
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs font-medium", children: name })
13915
+ ] }),
13916
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-xs text-muted-foreground", children: [
13917
+ "R$ ",
13918
+ Math.floor(Math.random() * 50 + 10),
13919
+ "k"
13920
+ ] })
13921
+ ]
13922
+ },
13923
+ name
13924
+ )) })
13925
+ ] })
13926
+ }
13927
+ )
14395
13928
  ] })
14396
- ] }),
14397
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1 flex items-center gap-0 overflow-x-auto px-6 py-4", children: [
14398
- /* @__PURE__ */ jsxRuntime.jsx("style", { children: `
14399
- @keyframes nodeGlow { 0%, 100% { box-shadow: 0 0 12px var(--glow); } 50% { box-shadow: 0 0 28px var(--glow); } }
14400
- @keyframes edgeFlow { to { stroke-dashoffset: -12; } }
14401
- ` }),
14402
- rows.map((row, rowIndex) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-0 shrink-0", children: [
14403
- rowIndex > 0 && row[0] && /* @__PURE__ */ jsxRuntime.jsx("svg", { width: "40", height: "2", className: "shrink-0 mx-1.5", children: /* @__PURE__ */ jsxRuntime.jsx("line", { x1: "0", y1: "1", x2: "40", y2: "1", stroke: activeStep >= row[0].step ? "#10b981" : "#374151", strokeWidth: "2", strokeDasharray: "4 3", style: { animation: activeStep === row[0].step ? "edgeFlow 0.8s linear infinite" : "none" } }) }),
14404
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: `flex ${row.length > 1 ? "flex-col gap-2" : ""}`, children: row.map((node2) => {
14405
- const status = getStatus(node2);
14406
- return /* @__PURE__ */ jsxRuntime.jsxs(
14407
- "div",
14408
- {
14409
- className: `liquid-surface rounded-2xl px-4 py-3 transition-all duration-500 ${row.length > 1 ? "w-[180px]" : "w-[220px]"} ${status === "active" ? "ring-2 ring-blue-500/50 scale-[1.03]" : status === "complete" ? "ring-1 ring-emerald-500/30" : "opacity-40"}`,
14410
- style: status === "active" ? { "--glow": node2.glow, animation: "nodeGlow 1.5s ease-in-out infinite" } : void 0,
14411
- children: [
14412
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2.5 mb-1.5", children: [
14413
- node2.avatar ? /* @__PURE__ */ jsxRuntime.jsx("img", { src: node2.avatar, alt: "", className: "h-9 w-9 rounded-xl shrink-0" }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: `flex h-9 w-9 items-center justify-center rounded-xl shrink-0 ${node2.bg}`, children: /* @__PURE__ */ jsxRuntime.jsx(node2.icon, { className: `h-5 w-5 ${node2.color}` }) }),
14414
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "min-w-0 flex-1", children: [
14415
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-[13px] font-semibold text-white truncate", children: node2.label }),
14416
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-[9px] text-gray-500 truncate", children: node2.subtitle })
14417
- ] }),
14418
- status === "complete" ? /* @__PURE__ */ jsxRuntime.jsx(HeroIcons.CheckCircleIcon, { className: "h-5 w-5 text-emerald-400 shrink-0" }) : null
14419
- ] }),
14420
- node2.badges && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-wrap gap-1 mt-1", children: node2.badges.map((badge) => /* @__PURE__ */ jsxRuntime.jsx("span", { className: `rounded-full px-2 py-0.5 text-[8px] font-semibold ${badge.color}`, children: badge.text }, badge.text)) })
14421
- ]
14422
- },
14423
- node2.id
14424
- );
14425
- }) })
14426
- ] }, rowIndex))
14427
13929
  ] })
14428
- ] });
14429
- }
14430
- function AgentAnalysisCard2({ name, avatar, duration, output }) {
14431
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "liquid-surface rounded-xl p-3 transition-all duration-300", children: [
14432
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 mb-1.5", children: [
14433
- /* @__PURE__ */ jsxRuntime.jsx("img", { src: avatar, alt: "", className: "h-6 w-6 rounded-lg" }),
14434
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1 min-w-0", children: [
14435
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-[10px] font-semibold text-white", children: name }),
14436
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-[8px] text-gray-500", children: duration })
14437
- ] }),
14438
- /* @__PURE__ */ jsxRuntime.jsx(HeroIcons.CheckCircleIcon, { className: "h-3.5 w-3.5 text-emerald-400 shrink-0" })
14439
- ] }),
14440
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-[8px] text-gray-400 leading-relaxed", children: output })
14441
- ] });
14442
- }
14443
- function MarketPricesCard2({ competitors }) {
14444
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "liquid-surface rounded-xl p-3.5", children: [
14445
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mb-2 flex items-center gap-1.5 text-[10px] font-semibold text-gray-400", children: [
14446
- /* @__PURE__ */ jsxRuntime.jsx(HeroIcons.TableCellsIcon, { className: "h-3 w-3 text-sky-500" }),
14447
- "Market Prices"
14448
- ] }),
14449
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-1", children: competitors.map((competitor) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between text-[9px]", children: [
14450
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-gray-400 truncate mr-2", children: competitor.name }),
14451
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1.5 shrink-0", children: [
14452
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-gray-500", children: competitor.distance }),
14453
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-semibold text-white", children: competitor.price }),
14454
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: `font-semibold ${competitor.up ? "text-emerald-400" : "text-rose-400"}`, children: competitor.change })
14455
- ] })
14456
- ] }, competitor.name)) })
14457
- ] });
14458
- }
14459
- var TOOL_OUTPUTS = {
14460
- SP: {
14461
- weather: "Clear skies next 7 days. Temp 28-32\xB0C. No rain expected \u2014 stable demand pattern for commuters.",
14462
- market: "Brent $82.40 (+2.3%). USD/BRL 5.12 (stable). Petrobras wholesale +1.2% effective Monday.",
14463
- news: "OPEC holds production steady. Petrobras announces refinery maintenance in Cubat\xE3o \u2014 supply may tighten in SP region next week."
14464
- },
14465
- RJ: {
14466
- weather: "Scattered rain Thu-Fri. Temp 26-30\xB0C. Weekend clear \u2014 expect lower weekday volumes, rebound Sat-Sun.",
14467
- market: "Brent $82.40 (+2.3%). USD/BRL 5.12. Reduc refinery running at 92% capacity \u2014 normal supply.",
14468
- news: "Rio toll road expansion opening next month. New stations in Barra da Tijuca corridor \u2014 increased competition expected."
14469
- },
14470
- MG: {
14471
- weather: "Dry season continues. Temp 24-28\xB0C. Rural demand rising with harvest season logistics.",
14472
- market: "Brent $82.40. REGAP refinery at full capacity. Ethanol supply strong from Tri\xE2ngulo Mineiro mills.",
14473
- news: "MG state reduces ICMS on diesel by 2% starting next month. Fleet operators may shift purchasing patterns."
14474
- },
14475
- PE: {
14476
- weather: "Tropical heat 30-34\xB0C. Brief showers. High AC usage boosting GNV demand for taxi fleets.",
14477
- market: "Northeast wholesale prices 3% below Southeast. Lower logistics costs from Suape port proximity.",
14478
- news: "Recife urban mobility plan adds 50 GNV buses. Growing alternative fuel adoption in metro region."
14479
- },
14480
- RS: {
14481
- weather: "Cold front arriving. Temp dropping to 12-18\xB0C. Diesel demand spike expected for heating and freight.",
14482
- market: "Brent $82.40. Cross-border pricing from Argentina putting downward pressure on border stations.",
14483
- news: "RS floods recovery driving construction diesel demand. Federal highway repairs boosting freight volumes."
14484
- },
14485
- ALL: {
14486
- weather: "National: mixed conditions. Clear in SE, rain in NE coast, cold front in South. Regional demand patterns diverging.",
14487
- market: "Brent $82.40 (+2.3%). USD/BRL 5.12. Petrobras wholesale adjustment +1.2% Monday. Ethanol harvest underway.",
14488
- news: "OPEC holds output. Petrobras maintenance in SP. MG cuts diesel ICMS. RS recovery drives freight demand."
14489
- }
14490
- };
14491
- var AGENT_ANALYSES = {
14492
- gasolina: {
14493
- dataAnalyst: "Sales volume up 12% MoM in SP region. Peak demand 6-9 AM and 5-8 PM. Weekend volumes 18% lower. 3 stations below target margin at current pricing.",
14494
- marketAnalyst: "Shell Paulista raised prices +1.7% yesterday. Ipiranga holding steady. Brent crude up 2.3% this week. USD/BRL stable at 5.12. Weather forecast clear \u2014 no demand impact expected.",
14495
- pricingManager: "Recommend R$ 5.89/L (+R$ 0.12). Captures competitor gap while maintaining 12.8% margin. Peak hours rule adds +2% during rush. All prices within MIN 5.20 \u2014 MAX 6.10 guardrails."
14496
- },
14497
- etanol: {
14498
- dataAnalyst: "Etanol demand rising seasonally. Volume 620K L with 14.2% margin. Sugar crop outlook positive \u2014 supply stable through Q2.",
14499
- marketAnalyst: "Etanol/gasoline ratio at 68% \u2014 below the 70% threshold that drives consumer switching. Competitors averaging R$ 3.52 in SP region.",
14500
- pricingManager: "Recommend R$ 3.49/L (+R$ 0.04). Conservative increase to maintain ratio advantage. Confidence 91% based on stable supply and competitor positioning."
14501
- },
14502
- diesel: {
14503
- dataAnalyst: "Diesel volumes declining 3% \u2014 seasonal fleet maintenance cycle. B2B contracts account for 72% of volume. Margin pressure from logistics operators.",
14504
- marketAnalyst: "Diesel supply tightening globally. Brent+crack spread widening. Competitor BR Distribuidora cut prices -0.5% to gain fleet contracts.",
14505
- pricingManager: "Recommend R$ 6.12/L (+R$ 0.08). Modest increase justified by supply constraints. Fleet contracts locked \u2014 minimal churn risk. Confidence 89%."
14506
- },
14507
- gnv: {
14508
- dataAnalyst: "GNV adoption accelerating \u2014 15% new vehicle conversions in SP. Volume 180K m\xB3 with highest margin at 15.1%. Limited competition in the segment.",
14509
- marketAnalyst: "Only 3 GNV competitors within 5km radius. GNV Center SP at R$ 4.35 is the price ceiling. Natural gas wholesale costs flat this quarter.",
14510
- pricingManager: "Recommend R$ 4.29/L (+R$ 0.07). Room to increase given limited competition. Confidence 87% \u2014 lower due to smaller dataset but strong margin signal."
14511
13930
  }
14512
- };
14513
- function FuelDashboardView({ activeFuel, onActiveFuelChange }) {
14514
- const [activeState, setActiveState] = React12.useState("ALL");
14515
- const [activeStation, setActiveStation] = React12.useState(null);
14516
- const [pipelineStep, setPipelineStep] = React12.useState(-1);
14517
- const pricing = FUEL_PRICING[activeFuel];
14518
- const fuelMeta = FUELS.find((f) => f.id === activeFuel);
14519
- const analysis = AGENT_ANALYSES[activeFuel];
14520
- const selectedMapState = activeState === "ALL" ? null : activeState;
14521
- const toggleMapState = React12.useCallback((code) => {
14522
- setActiveState((prev) => prev === code ? "ALL" : code);
14523
- setActiveStation(null);
14524
- }, []);
14525
- const isMapActive = React12.useCallback((code) => code === selectedMapState, [selectedMapState]);
14526
- const toolOutputs = TOOL_OUTPUTS[selectedMapState ?? "ALL"] ?? TOOL_OUTPUTS["ALL"];
14527
- const filteredStations = React12.useMemo(() => {
14528
- const byFuel = STATIONS.filter((s) => s.fuel === activeFuel);
14529
- return selectedMapState ? byFuel.filter((s) => s.region === selectedMapState) : byFuel;
14530
- }, [activeFuel, selectedMapState]);
14531
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "liquid-surface rounded-xl overflow-hidden", children: [
14532
- /* @__PURE__ */ jsxRuntime.jsx(
14533
- PipelinePreview,
14534
- {
14535
- activeFuel,
14536
- activeState,
14537
- activeStation,
14538
- onActiveFuelChange,
14539
- onActiveStateChange: setActiveState,
14540
- onActiveStationChange: setActiveStation,
14541
- onStepChange: setPipelineStep
14542
- }
14543
- ),
14544
- pipelineStep >= 3 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "border-t border-white/5 px-3 py-2", children: [
14545
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-3 gap-2", children: [
14546
- pipelineStep >= 3 && /* @__PURE__ */ jsxRuntime.jsx(AgentAnalysisCard2, { name: "Data Analyst", avatar: AVATARS.data, duration: "1.8s", output: analysis.dataAnalyst }),
14547
- pipelineStep >= 4 && /* @__PURE__ */ jsxRuntime.jsx(AgentAnalysisCard2, { name: "Market Analyst", avatar: AVATARS.market, duration: "2.1s", output: analysis.marketAnalyst }),
14548
- pipelineStep >= 5 && /* @__PURE__ */ jsxRuntime.jsx(AgentAnalysisCard2, { name: "Pricing Manager", avatar: AVATARS.pricing, duration: "1.4s", output: analysis.pricingManager })
14549
- ] }),
14550
- pipelineStep >= 6 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-2 grid grid-cols-[200px_1fr_1fr] gap-2", children: [
14551
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "liquid-surface rounded-xl overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsx(
14552
- InteractiveGeoMap,
14553
- {
14554
- items: STATIONS.filter((s) => s.fuel === activeFuel),
14555
- getRegionCode: (item) => item.region,
14556
- regionCoordinates: BRAZIL_STATE_COORDINATES,
14557
- defaultCenter: BRAZIL_MAP_CENTER,
14558
- geoJsonUrl: "/maps/brazil.geo.json",
14559
- regionPropertyKey: "code",
14560
- projectionType: "mercator",
14561
- getRegionColor: (code) => BRAZIL_STATE_PALETTES[code]?.primary ?? "#374151",
14562
- isRegionActive: isMapActive,
14563
- onRegionToggle: toggleMapState,
14564
- formatCounter: (total, regions, activeItems) => selectedMapState ? `${activeItems ?? 0} ${fuelMeta.label} stations in ${selectedMapState}` : `${total} stations \xB7 ${regions} states`,
14565
- ariaLabel: `Brazil ${fuelMeta.label} stations`,
14566
- className: "h-full"
14567
- }
14568
- ) }),
14569
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "liquid-surface rounded-xl p-3", children: [
14570
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mb-2 flex items-center gap-1.5 text-[10px] font-semibold text-gray-400", children: [
14571
- /* @__PURE__ */ jsxRuntime.jsx(HeroIcons.RocketLaunchIcon, { className: "h-3.5 w-3.5 text-amber-500" }),
14572
- "AI Recommendations \u2014 ",
14573
- fuelMeta.label,
14574
- selectedMapState && /* @__PURE__ */ jsxRuntime.jsx("img", { src: `/flags/${selectedMapState}.svg`, alt: selectedMapState, className: "h-4 w-4 rounded-sm" }),
14575
- selectedMapState && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[9px] font-bold text-white", children: selectedMapState }),
14576
- /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "ml-auto rounded-full bg-emerald-500/10 px-1.5 py-0.5 text-[8px] font-semibold text-emerald-400", children: [
14577
- pricing.confidence,
14578
- " confidence"
14579
- ] })
14580
- ] }),
14581
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-0.5", children: [
14582
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-[auto_1fr_auto_auto_auto_auto] items-center gap-x-3 px-2 py-1 text-[8px] font-bold uppercase tracking-wider text-gray-600", children: [
14583
- /* @__PURE__ */ jsxRuntime.jsx("span", { children: "State" }),
14584
- /* @__PURE__ */ jsxRuntime.jsx("span", { children: "Station" }),
14585
- /* @__PURE__ */ jsxRuntime.jsx("span", { children: "Current" }),
14586
- /* @__PURE__ */ jsxRuntime.jsx("span", { children: "AI Price" }),
14587
- /* @__PURE__ */ jsxRuntime.jsx("span", { children: "Delta" }),
14588
- /* @__PURE__ */ jsxRuntime.jsx("span", { children: "Status" })
14589
- ] }),
14590
- filteredStations.slice(0, 6).map((station) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-[auto_1fr_auto_auto_auto_auto] items-center gap-x-3 rounded-lg px-2 py-1.5 hover:bg-white/[0.03] text-[9px]", children: [
14591
- /* @__PURE__ */ jsxRuntime.jsx("img", { src: `/flags/${station.region}.svg`, alt: station.region, className: "h-4 w-4 rounded-sm" }),
14592
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-gray-300 truncate", children: station.name }),
14593
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-gray-500 line-through", children: station.price }),
14594
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-bold text-white", children: pricing.aiPrice }),
14595
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-semibold text-emerald-400", children: pricing.delta }),
14596
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "rounded-full bg-emerald-500/15 px-1.5 py-0.5 text-[7px] font-semibold text-emerald-400", children: "\u2713" })
14597
- ] }, station.id)),
14598
- filteredStations.length === 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "px-2 py-3 text-center text-[9px] text-gray-500 italic", children: [
14599
- "No ",
14600
- fuelMeta.label,
14601
- " stations in ",
14602
- selectedMapState
14603
- ] })
14604
- ] }),
14605
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-2 flex items-center gap-2 border-t border-white/5 pt-2", children: [
14606
- /* @__PURE__ */ jsxRuntime.jsxs("button", { type: "button", className: "rounded-lg bg-emerald-600 px-2.5 py-1 text-[9px] font-semibold text-white flex items-center gap-1", children: [
14607
- /* @__PURE__ */ jsxRuntime.jsx(HeroIcons.HandThumbUpIcon, { className: "h-3 w-3" }),
14608
- " Approve ",
14609
- selectedMapState ? filteredStations.length : "All"
13931
+ );
13932
+ var FinancialDemo = () => /* @__PURE__ */ jsxRuntime.jsx(
13933
+ framerMotion.motion.div,
13934
+ {
13935
+ initial: { opacity: 0 },
13936
+ animate: { opacity: 1 },
13937
+ exit: { opacity: 0 },
13938
+ transition: { duration: 0.5 },
13939
+ className: "flex flex-col h-full overflow-hidden",
13940
+ children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1 flex flex-col overflow-hidden", children: [
13941
+ /* @__PURE__ */ jsxRuntime.jsxs(
13942
+ framerMotion.motion.div,
13943
+ {
13944
+ initial: { y: -20, opacity: 0 },
13945
+ animate: { y: 0, opacity: 1 },
13946
+ transition: { duration: 0.5, delay: 0.3 },
13947
+ className: "h-14 border-b bg-background/95 backdrop-blur-sm flex items-center justify-between px-4",
13948
+ children: [
13949
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3", children: [
13950
+ /* @__PURE__ */ jsxRuntime.jsx("h2", { className: "text-sm font-semibold", children: "Planejamento Financeiro" }),
13951
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs px-2 py-1 rounded-full bg-green-500/10 text-green-600 dark:text-green-400 font-medium", children: "Q4 2024" })
14610
13952
  ] }),
14611
- /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", className: "rounded-lg bg-gray-700 px-2.5 py-1 text-[9px] font-semibold text-gray-300", children: "Modify" }),
14612
- /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "ml-auto text-[8px] text-purple-400 flex items-center gap-1", children: [
14613
- /* @__PURE__ */ jsxRuntime.jsx(HeroIcons.AdjustmentsHorizontalIcon, { className: "h-3 w-3" }),
14614
- " ",
14615
- pricing.minMax
13953
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
13954
+ /* @__PURE__ */ jsxRuntime.jsx(HeroIcons.BellIcon, { className: "h-4 w-4 text-muted-foreground" }),
13955
+ /* @__PURE__ */ jsxRuntime.jsx(HeroIcons.MagnifyingGlassIcon, { className: "h-4 w-4 text-muted-foreground" })
14616
13956
  ] })
14617
- ] })
14618
- ] }),
14619
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-2", children: [
14620
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "liquid-surface rounded-xl p-2.5", children: [
14621
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mb-1.5 flex items-center gap-1.5 text-[8px] font-bold uppercase tracking-wider text-gray-600", children: [
14622
- "Tool Outputs",
14623
- selectedMapState && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "normal-case tracking-normal font-semibold text-white", children: [
14624
- " \u2014 ",
14625
- selectedMapState
14626
- ] })
14627
- ] }),
14628
- [
14629
- { icon: HeroIcons.CloudIcon, tool: "Weather", color: "text-cyan-400", bg: "bg-cyan-500/15", output: toolOutputs.weather },
14630
- { icon: HeroIcons.ArrowTrendingUpIcon, tool: "Market", color: "text-amber-400", bg: "bg-amber-500/15", output: toolOutputs.market },
14631
- { icon: HeroIcons.NewspaperIcon, tool: "News", color: "text-orange-400", bg: "bg-orange-500/15", output: toolOutputs.news }
14632
- ].map((t) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mb-1.5", children: [
14633
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1.5 mb-0.5", children: [
14634
- /* @__PURE__ */ jsxRuntime.jsx(t.icon, { className: `h-3 w-3 ${t.color}` }),
14635
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: `text-[9px] font-semibold ${t.color}`, children: t.tool }),
14636
- /* @__PURE__ */ jsxRuntime.jsx(HeroIcons.CheckCircleIcon, { className: "ml-auto h-3 w-3 text-emerald-400" })
14637
- ] }),
14638
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-[8px] text-gray-400 leading-relaxed", children: t.output })
14639
- ] }, t.tool))
14640
- ] }),
14641
- /* @__PURE__ */ jsxRuntime.jsx(MarketPricesCard2, { competitors: pricing.competitors })
14642
- ] })
14643
- ] })
14644
- ] })
14645
- ] });
14646
- }
14647
- function FuelPipelineDemo({ defaultFuel = "gasolina", onFuelChange } = {}) {
14648
- const [activeFuel, setActiveFuel] = React12.useState(defaultFuel);
14649
- const handleFuelChange = React12.useCallback((fuel) => {
14650
- setActiveFuel(fuel);
14651
- onFuelChange?.(fuel);
14652
- }, [onFuelChange]);
14653
- return /* @__PURE__ */ jsxRuntime.jsx(FuelDashboardView, { activeFuel, onActiveFuelChange: handleFuelChange });
14654
- }
14655
- var INCIDENTS = [
14656
- { id: "lambda-timeout", label: "Lambda Timeout", service: "kori-customers", severity: "critical", color: "text-red-400", bg: "bg-red-500/15" },
14657
- { id: "db-pool", label: "DB Pool Exhausted", service: "fuel-analytics", severity: "critical", color: "text-orange-400", bg: "bg-orange-500/15" },
14658
- { id: "deploy-fail", label: "Deploy Rollback", service: "windsock-auth", severity: "high", color: "text-amber-400", bg: "bg-amber-500/15" },
14659
- { id: "memory-leak", label: "Memory Leak", service: "astrlabe-workflows", severity: "medium", color: "text-sky-400", bg: "bg-sky-500/15" }
14660
- ];
14661
- var INCIDENT_DETAILS = {
14662
- "lambda-timeout": {
14663
- rootCause: "Cold starts + unoptimized Sequelize query scanning 2.3M rows without index on organization_id",
14664
- agentAnalysis: "Correlated Lambda Duration spike with Aurora slow query log. Found full table scan on customers table \u2014 missing index on (organization_id, created_at). Cold start adds 4.2s, query adds 24.8s = timeout.",
14665
- remediation: "CREATE INDEX CONCURRENTLY idx_customers_org_created ON customers(organization_id, created_at); Set provisioned concurrency to 5.",
14666
- result: "p99 latency: 29s \u2192 340ms. Zero timeouts in last 2 hours.",
14667
- timeline: [
14668
- { time: "03:14", event: "CloudWatch alarm: kori-customers Duration > 29s", color: "text-red-400" },
14669
- { time: "03:14", event: "Agent triggered \u2014 pulling CloudWatch metrics + Aurora slow query log", color: "text-sky-400" },
14670
- { time: "03:15", event: "Root cause identified: missing index on customers(organization_id)", color: "text-amber-400" },
14671
- { time: "03:15", event: "Remediation: CREATE INDEX CONCURRENTLY executed", color: "text-purple-400" },
14672
- { time: "03:16", event: "Provisioned concurrency set to 5 via CDK update", color: "text-purple-400" },
14673
- { time: "03:18", event: "Verified: p99 latency 340ms, 0 timeouts", color: "text-emerald-400" }
14674
- ]
14675
- },
14676
- "db-pool": {
14677
- rootCause: "fuel-analytics Lambda opening new connections per invocation without reusing pool. 300 concurrent executions = 300 connections.",
14678
- agentAnalysis: "Correlated RDS Proxy connection count with Lambda concurrency. Found pool initialization inside handler function (runs every invocation) instead of module scope (runs once per cold start).",
14679
- remediation: "Moved pool init to module scope. Set Lambda reserved concurrency to 50. Enabled RDS Proxy idle connection pruning at 60s.",
14680
- result: "Steady-state connections: 300 \u2192 12. Zero connection errors in last 4 hours.",
14681
- timeline: [
14682
- { time: "02:41", event: "CloudWatch alarm: fuel-analytics DatabaseConnections = 300", color: "text-red-400" },
14683
- { time: "02:41", event: "Agent triggered \u2014 analyzing connection patterns + Lambda code", color: "text-sky-400" },
14684
- { time: "02:42", event: "Root cause: pool created inside handler, not module scope", color: "text-amber-400" },
14685
- { time: "02:43", event: "Fix applied: pool init moved to module scope", color: "text-purple-400" },
14686
- { time: "02:43", event: "Reserved concurrency set to 50", color: "text-purple-400" },
14687
- { time: "02:45", event: "Verified: 12 steady connections, 0 errors", color: "text-emerald-400" }
14688
- ]
14689
- },
14690
- "deploy-fail": {
14691
- rootCause: "New Lambda handler binary missing from S3 asset bucket. CDK synth succeeded but cargo-lambda build artifact was not uploaded due to CI timeout.",
14692
- agentAnalysis: 'Traced CloudFormation events: Lambda function update failed with "S3 key not found". Cross-referenced with GitHub Actions run \u2014 cargo-lambda build step timed out at 10min limit. Build artifact never uploaded to cdk.out.',
14693
- remediation: "Triggered rebuild with extended timeout (20min). Verified S3 asset uploaded. Re-deployed stack successfully.",
14694
- result: "Stack status: UPDATE_COMPLETE. All 129 handlers healthy. CI timeout increased to 20min.",
14695
- timeline: [
14696
- { time: "14:22", event: "CDK deploy failed: UPDATE_ROLLBACK_COMPLETE", color: "text-red-400" },
14697
- { time: "14:22", event: "Agent triggered \u2014 reading CloudFormation events", color: "text-sky-400" },
14698
- { time: "14:23", event: "Root cause: S3 asset missing \u2014 CI build timeout", color: "text-amber-400" },
14699
- { time: "14:24", event: "Rebuild triggered with 20min timeout", color: "text-purple-400" },
14700
- { time: "14:38", event: "Build complete. Stack redeployed successfully.", color: "text-purple-400" },
14701
- { time: "14:40", event: "Verified: all 129 handlers healthy", color: "text-emerald-400" }
14702
- ]
14703
- },
14704
- "memory-leak": {
14705
- rootCause: "Workflow execution SSE connections not closed on client disconnect. EventSource objects accumulate in Node.js heap across warm invocations.",
14706
- agentAnalysis: "Memory usage trend shows linear growth correlated with SSE connection count. Found missing cleanup in workflow-runner SSE handler \u2014 no abort signal listener. Warm Lambda instances accumulate stale connections across invocations.",
14707
- remediation: "Added AbortSignal listener to SSE handler. Implemented connection TTL of 5 minutes. Forced Lambda recycling at 90% memory threshold.",
14708
- result: "Memory stable at 45-55%. Zero OOM kills in last 8 hours.",
14709
- timeline: [
14710
- { time: "10:00", event: "Memory trending alarm: 85% and rising", color: "text-amber-400" },
14711
- { time: "10:00", event: "Agent triggered \u2014 analyzing memory trend + heap snapshots", color: "text-sky-400" },
14712
- { time: "10:02", event: "Root cause: SSE connections not closed on disconnect", color: "text-amber-400" },
14713
- { time: "10:03", event: "Fix: AbortSignal listener + 5min TTL added", color: "text-purple-400" },
14714
- { time: "10:03", event: "Lambda recycling at 90% memory threshold", color: "text-purple-400" },
14715
- { time: "10:10", event: "Verified: memory stable at 48%, 0 OOM kills", color: "text-emerald-400" }
14716
- ]
14717
- }
14718
- };
14719
- var AVATARS2 = {
14720
- triage: "https://api.dicebear.com/9.x/lorelei/svg?seed=Sentinel&hair=variant31&beardProbability=0&mouth=happy01",
14721
- debug: "https://api.dicebear.com/9.x/notionists/svg?seed=Debugger&hair=variant35&beardProbability=0&gestureProbability=0&glasses=variant03&glassesProbability=100",
14722
- remediate: "https://api.dicebear.com/9.x/lorelei/svg?seed=Fixer&hair=variant31&beardProbability=0&glasses=variant01&glassesProbability=100&mouth=happy01"
14723
- };
14724
- function buildNodes(incident) {
14725
- return [
14726
- { id: "alert", label: "Alert Detected", subtitle: `${incident.service} \xB7 ${incident.severity}`, icon: HeroIcons.ExclamationTriangleIcon, color: "text-red-400", bg: "bg-red-500/15", glow: "rgba(239,68,68,0.5)", step: 0, badges: [{ text: incident.severity, color: "bg-red-500/20 text-red-300" }] },
14727
- { id: "metrics", label: "Pull Metrics", subtitle: "CloudWatch \xB7 15min window", icon: HeroIcons.ChartBarIcon, color: "text-sky-400", bg: "bg-sky-500/15", glow: "rgba(14,165,233,0.5)", step: 1, badges: [{ text: "datasource", color: "bg-sky-500/20 text-sky-300" }] },
14728
- { id: "logs", label: "Analyze Logs", subtitle: "CloudWatch Logs \xB7 error filter", icon: HeroIcons.CommandLineIcon, color: "text-sky-400", bg: "bg-sky-500/15", glow: "rgba(14,165,233,0.5)", step: 1, badges: [{ text: "datasource", color: "bg-sky-500/20 text-sky-300" }] },
14729
- { id: "infra", label: "Infra State", subtitle: "CDK \xB7 stack status \xB7 config", icon: HeroIcons.CloudIcon, color: "text-sky-400", bg: "bg-sky-500/15", glow: "rgba(14,165,233,0.5)", step: 1, badges: [{ text: "datasource", color: "bg-sky-500/20 text-sky-300" }] },
14730
- { id: "correlate", label: "Correlate", subtitle: "3 sources \u2192 unified context", icon: HeroIcons.BoltIcon, color: "text-amber-400", bg: "bg-amber-500/15", glow: "rgba(245,158,11,0.5)", step: 2, badges: [{ text: "aggregator", color: "bg-amber-500/20 text-amber-300" }] },
14731
- { id: "debug-agent", label: "Debug Agent", subtitle: "Root cause analysis", icon: HeroIcons.CpuChipIcon, color: "text-purple-400", bg: "bg-purple-500/15", glow: "rgba(168,85,247,0.5)", step: 3, avatar: AVATARS2.debug, badges: [{ text: "agent", color: "bg-purple-500/20 text-purple-300" }, { text: "Claude", color: "bg-violet-500/20 text-violet-300" }] },
14732
- { id: "plan", label: "Remediation Plan", subtitle: "Generate fix + rollback plan", icon: HeroIcons.DocumentMagnifyingGlassIcon, color: "text-amber-400", bg: "bg-amber-500/15", glow: "rgba(245,158,11,0.5)", step: 4, avatar: AVATARS2.triage, badges: [{ text: "agent", color: "bg-purple-500/20 text-purple-300" }, { text: "advanced", color: "bg-amber-500/20 text-amber-300" }] },
14733
- { id: "execute", label: "Auto-Remediate", subtitle: "Apply fix \xB7 human-in-the-loop", icon: HeroIcons.WrenchScrewdriverIcon, color: "text-red-400", bg: "bg-red-500/15", glow: "rgba(239,68,68,0.5)", step: 5, avatar: AVATARS2.remediate, badges: [{ text: "agent", color: "bg-purple-500/20 text-purple-300" }, { text: "HITL", color: "bg-amber-500/20 text-amber-300" }] },
14734
- { id: "verify", label: "Verify", subtitle: "Confirm resolution \xB7 metrics ok", icon: HeroIcons.ShieldCheckIcon, color: "text-emerald-400", bg: "bg-emerald-500/15", glow: "rgba(16,185,129,0.5)", step: 6, badges: [{ text: "check", color: "bg-emerald-500/20 text-emerald-300" }] },
14735
- { id: "resolved", label: "Resolved", subtitle: "Incident closed \xB7 MTTR 4min", icon: HeroIcons.CheckCircleIcon, color: "text-emerald-400", bg: "bg-emerald-500/15", glow: "rgba(16,185,129,0.5)", step: 7 }
14736
- ];
14737
- }
14738
- var STEP_LABELS2 = [
14739
- "Alert detected \u2014 triaging",
14740
- "Pulling metrics, logs, infra state (parallel)",
14741
- "Correlating across sources",
14742
- "Debug agent analyzing root cause",
14743
- "Generating remediation plan",
14744
- "Executing auto-remediation",
14745
- "Verifying resolution",
14746
- "Resolved \u2014 incident closed"
14747
- ];
14748
- function IncidentPipelineDemo({
14749
- defaultIncident = "lambda-timeout",
14750
- onIncidentChange
14751
- } = {}) {
14752
- const [activeIncident, setActiveIncident] = React12.useState(defaultIncident);
14753
- const incident = INCIDENTS.find((i) => i.id === activeIncident);
14754
- const detail = INCIDENT_DETAILS[activeIncident];
14755
- const nodes = React12.useMemo(() => buildNodes(incident), [activeIncident]);
14756
- const [activeStep, setActiveStep] = React12.useState(-1);
14757
- const intervalRef = React12.useRef(null);
14758
- const isIdle = activeStep === -1;
14759
- const isRunning = activeStep >= 0 && activeStep < 7;
14760
- const isComplete = activeStep === 7;
14761
- const handleRun = React12.useCallback(() => {
14762
- if (intervalRef.current) clearInterval(intervalRef.current);
14763
- setActiveStep(0);
14764
- let step2 = 0;
14765
- intervalRef.current = setInterval(() => {
14766
- step2 += 1;
14767
- if (step2 > 7) {
14768
- if (intervalRef.current) clearInterval(intervalRef.current);
14769
- setActiveStep(7);
14770
- } else {
14771
- setActiveStep(step2);
14772
- }
14773
- }, 1200);
14774
- }, []);
14775
- const handleStop = React12.useCallback(() => {
14776
- if (intervalRef.current) clearInterval(intervalRef.current);
14777
- setActiveStep(-1);
14778
- }, []);
14779
- const handleIncidentSelect = React12.useCallback((id) => {
14780
- setActiveIncident(id);
14781
- onIncidentChange?.(id);
14782
- if (!isIdle) handleStop();
14783
- }, [isIdle, handleStop, onIncidentChange]);
14784
- React12.useEffect(() => () => {
14785
- if (intervalRef.current) clearInterval(intervalRef.current);
14786
- }, []);
14787
- const getStatus = (node2) => {
14788
- if (activeStep < 0) return "idle";
14789
- if (node2.step < activeStep) return "complete";
14790
- if (node2.step === activeStep) return "active";
14791
- return "idle";
14792
- };
14793
- const rows = React12.useMemo(() => {
14794
- const result = [];
14795
- let step2 = -1;
14796
- for (const node2 of nodes) {
14797
- if (node2.step !== step2) {
14798
- result.push([]);
14799
- step2 = node2.step;
14800
- }
14801
- result[result.length - 1].push(node2);
14802
- }
14803
- return result;
14804
- }, [nodes]);
14805
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "liquid-surface rounded-2xl overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col", children: [
14806
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1.5 border-b border-white/5 px-3 py-2 shrink-0 overflow-x-auto", children: [
14807
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center rounded-lg bg-white/[0.03] p-0.5 gap-0.5 shrink-0", children: [
14808
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "px-1.5 text-[7px] font-bold uppercase tracking-wider text-gray-600", children: "Incident" }),
14809
- INCIDENTS.map((inc) => /* @__PURE__ */ jsxRuntime.jsx(
14810
- "button",
13957
+ ]
13958
+ }
13959
+ ),
13960
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1 overflow-y-auto p-4 space-y-3", children: [
13961
+ /* @__PURE__ */ jsxRuntime.jsxs(
13962
+ framerMotion.motion.div,
14811
13963
  {
14812
- type: "button",
14813
- onClick: () => handleIncidentSelect(inc.id),
14814
- className: `rounded-md px-2 py-1 text-[9px] font-semibold transition-all duration-200 ${activeIncident === inc.id ? `${inc.bg} ${inc.color} shadow-sm` : "text-gray-500 hover:text-gray-300 hover:bg-white/5"}`,
14815
- children: inc.label
14816
- },
14817
- inc.id
14818
- ))
14819
- ] }),
14820
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "ml-auto flex items-center gap-2 shrink-0", children: [
14821
- activeStep >= 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-0.5", children: STEP_LABELS2.map((_, index) => /* @__PURE__ */ jsxRuntime.jsx("div", { className: `h-1 w-2.5 rounded-full transition-all duration-500 ${index < activeStep || isComplete ? "bg-emerald-500" : index === activeStep ? "bg-red-500 animate-pulse" : "bg-white/10"}` }, index)) }),
14822
- isComplete && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1 rounded-full bg-emerald-500/10 px-2 py-0.5", children: [
14823
- /* @__PURE__ */ jsxRuntime.jsx(HeroIcons.CheckCircleIcon, { className: "h-3 w-3 text-emerald-400" }),
14824
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[8px] font-semibold text-emerald-400", children: "Resolved \xB7 MTTR 4min" })
14825
- ] }),
14826
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: `h-2 w-2 rounded-full ${isRunning ? "bg-red-500 animate-pulse" : isComplete ? "bg-emerald-500" : "bg-gray-600"}` }),
14827
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "max-w-[160px] truncate text-[9px] text-gray-500", children: activeStep >= 0 ? STEP_LABELS2[activeStep] : "Ready" }),
14828
- isIdle ? /* @__PURE__ */ jsxRuntime.jsxs("button", { type: "button", onClick: handleRun, className: "flex items-center gap-1 rounded-lg bg-gradient-to-r from-red-600 to-rose-600 px-3 py-1 text-[10px] font-semibold text-white shadow-lg shadow-red-500/20 hover:shadow-red-500/30 hover:scale-105 active:scale-95 transition-all", children: [
14829
- /* @__PURE__ */ jsxRuntime.jsx(HeroIcons.PlayIcon, { className: "h-3 w-3" }),
14830
- " Simulate"
14831
- ] }) : isRunning ? /* @__PURE__ */ jsxRuntime.jsxs("button", { type: "button", onClick: handleStop, className: "flex items-center gap-1 rounded-lg bg-rose-600/80 px-3 py-1 text-[10px] font-semibold text-white", children: [
14832
- /* @__PURE__ */ jsxRuntime.jsx(HeroIcons.StopIcon, { className: "h-3 w-3" }),
14833
- " Stop"
14834
- ] }) : /* @__PURE__ */ jsxRuntime.jsxs("button", { type: "button", onClick: handleRun, className: "flex items-center gap-1 rounded-lg border border-white/10 px-3 py-1 text-[10px] font-medium text-gray-300 hover:bg-white/5", children: [
14835
- /* @__PURE__ */ jsxRuntime.jsx(HeroIcons.ArrowPathIcon, { className: "h-3 w-3" }),
14836
- " Replay"
14837
- ] })
14838
- ] })
14839
- ] }),
14840
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-0 overflow-x-auto px-6 py-4", children: [
14841
- /* @__PURE__ */ jsxRuntime.jsx("style", { children: `
14842
- @keyframes nodeGlow { 0%, 100% { box-shadow: 0 0 12px var(--glow); } 50% { box-shadow: 0 0 28px var(--glow); } }
14843
- @keyframes edgeFlow { to { stroke-dashoffset: -12; } }
14844
- ` }),
14845
- rows.map((row, rowIndex) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex shrink-0 items-center gap-0", children: [
14846
- rowIndex > 0 && /* @__PURE__ */ jsxRuntime.jsx("svg", { width: "40", height: "2", className: "mx-1.5 shrink-0", children: /* @__PURE__ */ jsxRuntime.jsx("line", { x1: "0", y1: "1", x2: "40", y2: "1", stroke: activeStep >= rows[rowIndex][0].step ? "#10b981" : "#374151", strokeWidth: "2", strokeDasharray: "4 3", style: { animation: activeStep === rows[rowIndex][0].step ? "edgeFlow 0.8s linear infinite" : "none" } }) }),
14847
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: `flex ${row.length > 1 ? "flex-col gap-2" : ""}`, children: row.map((node2) => {
14848
- const status = getStatus(node2);
14849
- return /* @__PURE__ */ jsxRuntime.jsxs(
14850
- "div",
14851
- {
14852
- className: `liquid-surface rounded-2xl px-4 py-3 transition-all duration-500 ${row.length > 1 ? "w-[180px]" : "w-[220px]"} ${status === "active" ? "scale-[1.03] ring-2 ring-red-500/50" : status === "complete" ? "ring-1 ring-emerald-500/30" : "opacity-40"}`,
14853
- style: status === "active" ? { "--glow": node2.glow, animation: "nodeGlow 1.5s ease-in-out infinite" } : void 0,
14854
- children: [
14855
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mb-1.5 flex items-center gap-2.5", children: [
14856
- node2.avatar ? /* @__PURE__ */ jsxRuntime.jsx("img", { src: node2.avatar, alt: "", className: "h-9 w-9 rounded-xl shrink-0" }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: `flex h-9 w-9 items-center justify-center rounded-xl shrink-0 ${node2.bg}`, children: /* @__PURE__ */ jsxRuntime.jsx(node2.icon, { className: `h-5 w-5 ${node2.color}` }) }),
14857
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "min-w-0 flex-1", children: [
14858
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "truncate text-[13px] font-semibold text-white", children: node2.label }),
14859
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "truncate text-[9px] text-gray-500", children: node2.subtitle })
14860
- ] }),
14861
- status === "complete" && /* @__PURE__ */ jsxRuntime.jsx(HeroIcons.CheckCircleIcon, { className: "h-5 w-5 shrink-0 text-emerald-400" })
13964
+ initial: { opacity: 0, y: 20 },
13965
+ animate: { opacity: 1, y: 0 },
13966
+ transition: { delay: 0.5 },
13967
+ className: "grid grid-cols-2 gap-3",
13968
+ children: [
13969
+ /* @__PURE__ */ jsxRuntime.jsxs(Card, { className: "p-3 bg-gradient-to-br from-green-500 to-emerald-500 text-white", children: [
13970
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between mb-2", children: [
13971
+ /* @__PURE__ */ jsxRuntime.jsx(HeroIcons.ArrowTrendingUpIcon, { className: "h-5 w-5" }),
13972
+ /* @__PURE__ */ jsxRuntime.jsx(Badge, { className: "bg-white/20 text-white border-white/30 h-5 text-xs", children: "+18%" })
14862
13973
  ] }),
14863
- node2.badges && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-wrap gap-1 mt-1", children: node2.badges.map((badge) => /* @__PURE__ */ jsxRuntime.jsx("span", { className: `rounded-full px-2 py-0.5 text-[8px] font-semibold ${badge.color}`, children: badge.text }, badge.text)) })
14864
- ]
14865
- },
14866
- node2.id
14867
- );
14868
- }) })
14869
- ] }, rowIndex))
14870
- ] }),
14871
- activeStep >= 3 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "border-t border-white/5 px-3 py-2", children: [
14872
- /* @__PURE__ */ jsxRuntime.jsx("style", { children: `
14873
- .slide-active .fk-detail { opacity: 0; animation: fkDetailIn 0.4s ease forwards; }
14874
- .slide-active .fk-detail:nth-child(1) { animation-delay: 0s; }
14875
- .slide-active .fk-detail:nth-child(2) { animation-delay: 0.15s; }
14876
- .slide-active .fk-detail:nth-child(3) { animation-delay: 0.3s; }
14877
- .slide-active .fk-detail:nth-child(4) { animation-delay: 0.45s; }
14878
- .slide-active .fk-detail:nth-child(5) { animation-delay: 0.6s; }
14879
- @keyframes fkDetailIn { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: translateY(0); } }
14880
- ` }),
14881
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-3 gap-2", children: [
14882
- activeStep >= 3 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "fk-detail liquid-surface rounded-xl p-3", children: [
14883
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mb-1.5 flex items-center gap-2", children: [
14884
- /* @__PURE__ */ jsxRuntime.jsx("img", { src: AVATARS2.debug, alt: "", className: "h-6 w-6 rounded-lg" }),
14885
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1 min-w-0", children: [
14886
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-[10px] font-semibold text-white", children: "Debug Agent" }),
14887
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-[8px] text-gray-500", children: "Root cause analysis \xB7 1.2s" })
14888
- ] }),
14889
- /* @__PURE__ */ jsxRuntime.jsx(HeroIcons.CheckCircleIcon, { className: "h-3.5 w-3.5 shrink-0 text-emerald-400" })
14890
- ] }),
14891
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-[9px] leading-relaxed text-gray-300", children: detail.rootCause }),
14892
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: "mt-1.5 text-[8px] leading-relaxed text-gray-400", children: detail.agentAnalysis })
14893
- ] }),
14894
- activeStep >= 4 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "fk-detail liquid-surface rounded-xl p-3", children: [
14895
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mb-1.5 flex items-center gap-2", children: [
14896
- /* @__PURE__ */ jsxRuntime.jsx("img", { src: AVATARS2.triage, alt: "", className: "h-6 w-6 rounded-lg" }),
14897
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1 min-w-0", children: [
14898
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-[10px] font-semibold text-white", children: "Triage Agent" }),
14899
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-[8px] text-gray-500", children: "Remediation plan \xB7 0.8s" })
14900
- ] }),
14901
- /* @__PURE__ */ jsxRuntime.jsx(HeroIcons.CheckCircleIcon, { className: "h-3.5 w-3.5 shrink-0 text-emerald-400" })
14902
- ] }),
14903
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: "font-mono text-[8px] leading-relaxed text-gray-300", children: detail.remediation })
14904
- ] }),
14905
- activeStep >= 5 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "fk-detail liquid-surface rounded-xl p-3", children: [
14906
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mb-1.5 flex items-center gap-2", children: [
14907
- /* @__PURE__ */ jsxRuntime.jsx("img", { src: AVATARS2.remediate, alt: "", className: "h-6 w-6 rounded-lg" }),
14908
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1 min-w-0", children: [
14909
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-[10px] font-semibold text-white", children: "Remediate Agent" }),
14910
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-[8px] text-gray-500", children: "Executing fix \xB7 human-in-the-loop" })
14911
- ] }),
14912
- activeStep >= 6 ? /* @__PURE__ */ jsxRuntime.jsx(HeroIcons.CheckCircleIcon, { className: "h-3.5 w-3.5 shrink-0 text-emerald-400" }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-3 w-3 shrink-0 rounded-full bg-amber-500 animate-pulse" })
14913
- ] }),
14914
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-[8px] leading-relaxed text-amber-300/80", children: "Applying changes with rollback plan ready. Awaiting verification..." })
14915
- ] })
14916
- ] }),
14917
- activeStep >= 6 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-2 grid grid-cols-2 gap-2", children: [
14918
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "fk-detail rounded-xl border border-emerald-500/20 bg-emerald-500/[0.06] p-2.5", children: [
14919
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mb-1 flex items-center gap-1.5", children: [
14920
- /* @__PURE__ */ jsxRuntime.jsx(HeroIcons.CheckCircleIcon, { className: "h-3.5 w-3.5 text-emerald-400" }),
14921
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[10px] font-bold text-emerald-400", children: "Result" })
14922
- ] }),
14923
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-[9px] font-semibold text-emerald-300", children: detail.result })
14924
- ] }),
14925
- isComplete && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "fk-detail liquid-surface rounded-xl p-2.5", children: [
14926
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "mb-1 block text-[10px] font-bold text-gray-400", children: "Timeline" }),
14927
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-0.5", children: detail.timeline.map((entry, i) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start gap-1.5", children: [
14928
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "shrink-0 font-mono text-[7px] text-gray-600", children: entry.time }),
14929
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: `h-1 w-1 mt-1 shrink-0 rounded-full ${entry.color.replace("text-", "bg-")}` }),
14930
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[7px] text-gray-400", children: entry.event })
14931
- ] }, i)) })
14932
- ] })
14933
- ] })
14934
- ] })
14935
- ] }) });
14936
- }
14937
- function IconTile({ icon: Icon, gradient, size = "md" }) {
14938
- const wrapper = size === "md" ? "h-12 w-12" : "h-10 w-10";
14939
- const icon = size === "md" ? "h-6 w-6" : "h-5 w-5";
14940
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className: `${wrapper} rounded-xl bg-gradient-to-br ${gradient} flex items-center justify-center`, children: /* @__PURE__ */ jsxRuntime.jsx(Icon, { className: `${icon} text-white` }) });
14941
- }
14942
- function BentoFeatureGrid({
14943
- aiPanel,
14944
- metricsPanel,
14945
- securityPanel,
14946
- agentsPanel,
14947
- className
14948
- }) {
14949
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className: `w-full min-h-screen h-full flex items-center justify-center p-4 md:p-6 lg:p-8 ${className ?? ""}`, children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full h-full max-w-7xl", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid gap-4 lg:grid-cols-3 lg:grid-rows-2 h-full min-h-[600px] lg:min-h-[700px]", children: [
14950
- /* @__PURE__ */ jsxRuntime.jsxs(
14951
- framerMotion.motion.div,
14952
- {
14953
- initial: { opacity: 0, y: 20 },
14954
- animate: { opacity: 1, y: 0 },
14955
- transition: { duration: 0.6, delay: 0.1 },
14956
- className: "relative lg:row-span-2",
14957
- children: [
14958
- aiPanel.bgTint && /* @__PURE__ */ jsxRuntime.jsx("div", { className: `absolute inset-px rounded-2xl bg-gradient-to-br ${aiPanel.bgTint}` }),
14959
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `relative flex h-full flex-col overflow-hidden rounded-2xl border ${aiPanel.borderColor ?? "border-gray-200 dark:border-gray-800"} bg-white/50 dark:bg-zinc-900/50 backdrop-blur-sm`, children: [
14960
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "px-6 pt-6 pb-4", children: [
14961
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3 mb-3", children: [
14962
- /* @__PURE__ */ jsxRuntime.jsx(IconTile, { icon: aiPanel.icon, gradient: aiPanel.gradient, size: "md" }),
14963
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-lg font-bold text-gray-900 dark:text-white", children: aiPanel.title })
14964
- ] }),
14965
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-gray-600 dark:text-gray-400", children: aiPanel.description })
14966
- ] }),
14967
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "relative min-h-[200px] w-full grow p-6", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-3", children: aiPanel.items.map((item, index) => /* @__PURE__ */ jsxRuntime.jsxs(
14968
- framerMotion.motion.div,
14969
- {
14970
- initial: { opacity: 0, x: -20 },
14971
- animate: { opacity: 1, x: 0 },
14972
- transition: { delay: 0.3 + index * 0.2 },
14973
- className: `flex items-center gap-3 p-3 rounded-xl ${item.bgTint}`,
14974
- children: [
14975
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: `h-2 w-2 rounded-full animate-pulse ${item.dotColor}` }),
14976
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: `text-xs font-medium ${item.textColor}`, children: item.label })
14977
- ]
14978
- },
14979
- `${item.label}-${index}`
14980
- )) }) })
14981
- ] }),
14982
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pointer-events-none absolute inset-px rounded-2xl shadow-sm" })
14983
- ]
14984
- }
14985
- ),
14986
- /* @__PURE__ */ jsxRuntime.jsxs(
14987
- framerMotion.motion.div,
14988
- {
14989
- initial: { opacity: 0, y: 20 },
14990
- animate: { opacity: 1, y: 0 },
14991
- transition: { duration: 0.6, delay: 0.2 },
14992
- className: "relative max-lg:row-start-1",
14993
- children: [
14994
- metricsPanel.bgTint && /* @__PURE__ */ jsxRuntime.jsx("div", { className: `absolute inset-px rounded-2xl bg-gradient-to-br ${metricsPanel.bgTint}` }),
14995
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `relative flex h-full flex-col overflow-hidden rounded-2xl border ${metricsPanel.borderColor ?? "border-gray-200 dark:border-gray-800"} bg-white/50 dark:bg-zinc-900/50 backdrop-blur-sm`, children: [
14996
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "px-6 pt-6 pb-4", children: [
14997
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3 mb-3", children: [
14998
- /* @__PURE__ */ jsxRuntime.jsx(IconTile, { icon: metricsPanel.icon, gradient: metricsPanel.gradient, size: "sm" }),
14999
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-base font-bold text-gray-900 dark:text-white", children: metricsPanel.title })
15000
- ] }),
15001
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-gray-600 dark:text-gray-400", children: metricsPanel.description })
15002
- ] }),
15003
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-1 items-center justify-center px-6 pb-6", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-2 gap-3 w-full", children: metricsPanel.metrics.map((metric, index) => /* @__PURE__ */ jsxRuntime.jsxs(
15004
- framerMotion.motion.div,
15005
- {
15006
- initial: { scale: 0 },
15007
- animate: { scale: 1 },
15008
- transition: { delay: 0.5 + index * 0.1 },
15009
- className: `${metric.bgTint} rounded-xl p-3 text-center`,
15010
- children: [
15011
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: `text-2xl font-bold ${metric.valueColor}`, children: metric.value }),
15012
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-[10px] text-gray-600 dark:text-gray-400", children: metric.label })
15013
- ]
15014
- },
15015
- `${metric.label}-${index}`
15016
- )) }) })
15017
- ] }),
15018
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pointer-events-none absolute inset-px rounded-2xl shadow-sm" })
15019
- ]
15020
- }
15021
- ),
15022
- /* @__PURE__ */ jsxRuntime.jsxs(
15023
- framerMotion.motion.div,
15024
- {
15025
- initial: { opacity: 0, y: 20 },
15026
- animate: { opacity: 1, y: 0 },
15027
- transition: { duration: 0.6, delay: 0.3 },
15028
- className: "relative max-lg:row-start-3 lg:col-start-2 lg:row-start-2",
15029
- children: [
15030
- securityPanel.bgTint && /* @__PURE__ */ jsxRuntime.jsx("div", { className: `absolute inset-px rounded-2xl bg-gradient-to-br ${securityPanel.bgTint}` }),
15031
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `relative flex h-full flex-col overflow-hidden rounded-2xl border ${securityPanel.borderColor ?? "border-gray-200 dark:border-gray-800"} bg-white/50 dark:bg-zinc-900/50 backdrop-blur-sm`, children: [
15032
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "px-6 pt-6 pb-4", children: [
15033
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3 mb-3", children: [
15034
- /* @__PURE__ */ jsxRuntime.jsx(IconTile, { icon: securityPanel.icon, gradient: securityPanel.gradient, size: "sm" }),
15035
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-base font-bold text-gray-900 dark:text-white", children: securityPanel.title })
15036
- ] }),
15037
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-gray-600 dark:text-gray-400", children: securityPanel.description })
15038
- ] }),
15039
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-1 items-center px-6 pb-6", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full space-y-2", children: securityPanel.bars.map((bar, index) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
15040
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: `h-1.5 flex-1 rounded-full overflow-hidden ${bar.trackColor}`, children: /* @__PURE__ */ jsxRuntime.jsx(
15041
- framerMotion.motion.div,
15042
- {
15043
- initial: { width: 0 },
15044
- animate: { width: "100%" },
15045
- transition: { delay: 0.7 + index * 0.2, duration: 1 },
15046
- className: `h-full ${bar.fillColor}`
15047
- }
15048
- ) }),
15049
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: `text-[10px] font-medium ${bar.labelColor}`, children: bar.label })
15050
- ] }, `${bar.label}-${index}`)) }) })
15051
- ] }),
15052
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pointer-events-none absolute inset-px rounded-2xl shadow-sm" })
15053
- ]
15054
- }
15055
- ),
15056
- /* @__PURE__ */ jsxRuntime.jsxs(
15057
- framerMotion.motion.div,
15058
- {
15059
- initial: { opacity: 0, y: 20 },
15060
- animate: { opacity: 1, y: 0 },
15061
- transition: { duration: 0.6, delay: 0.4 },
15062
- className: "relative lg:row-span-2",
15063
- children: [
15064
- agentsPanel.bgTint && /* @__PURE__ */ jsxRuntime.jsx("div", { className: `absolute inset-px rounded-2xl bg-gradient-to-br ${agentsPanel.bgTint}` }),
15065
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `relative flex h-full flex-col overflow-hidden rounded-2xl border ${agentsPanel.borderColor ?? "border-gray-200 dark:border-gray-800"} bg-white/50 dark:bg-zinc-900/50 backdrop-blur-sm`, children: [
15066
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "px-6 pt-6 pb-4", children: [
15067
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3 mb-3", children: [
15068
- /* @__PURE__ */ jsxRuntime.jsx(IconTile, { icon: agentsPanel.icon, gradient: agentsPanel.gradient, size: "md" }),
15069
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-lg font-bold text-gray-900 dark:text-white", children: agentsPanel.title })
15070
- ] }),
15071
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-gray-600 dark:text-gray-400", children: agentsPanel.description })
15072
- ] }),
15073
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "relative w-full grow p-6", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-2 gap-3", children: agentsPanel.agents.map((agent, index) => {
15074
- const delay = 0.5 + index * 0.1;
15075
- return /* @__PURE__ */ jsxRuntime.jsxs(
15076
- framerMotion.motion.div,
15077
- {
15078
- initial: { opacity: 0, scale: 0.8 },
15079
- animate: { opacity: 1, scale: 1 },
15080
- transition: { delay },
15081
- className: `relative overflow-hidden rounded-xl bg-gradient-to-br ${agent.color} p-3 text-white`,
15082
- children: [
15083
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative z-10", children: [
15084
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs font-bold", children: agent.name }),
15085
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-1 h-1 w-12 bg-white/30 rounded-full", children: /* @__PURE__ */ jsxRuntime.jsx(
15086
- framerMotion.motion.div,
15087
- {
15088
- initial: { width: 0 },
15089
- animate: { width: "100%" },
15090
- transition: { delay: delay + 0.3, duration: 0.8 },
15091
- className: "h-full bg-white rounded-full"
15092
- }
15093
- ) })
15094
- ] }),
15095
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute top-0 right-0 w-16 h-16 bg-white/10 rounded-full -mr-8 -mt-8" })
15096
- ]
15097
- },
15098
- agent.name
15099
- );
15100
- }) }) })
15101
- ] }),
15102
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pointer-events-none absolute inset-px rounded-2xl shadow-sm" })
15103
- ]
15104
- }
15105
- )
15106
- ] }) }) });
15107
- }
15108
- var CustomerAnalyticsDemo = () => /* @__PURE__ */ jsxRuntime.jsx(
15109
- framerMotion.motion.div,
15110
- {
15111
- initial: { opacity: 0 },
15112
- animate: { opacity: 1 },
15113
- exit: { opacity: 0 },
15114
- transition: { duration: 0.5 },
15115
- className: "flex flex-col h-full overflow-hidden",
15116
- children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1 flex flex-col overflow-hidden", children: [
15117
- /* @__PURE__ */ jsxRuntime.jsxs(
15118
- framerMotion.motion.div,
15119
- {
15120
- initial: { y: -20, opacity: 0 },
15121
- animate: { y: 0, opacity: 1 },
15122
- transition: { duration: 0.5, delay: 0.3 },
15123
- className: "h-14 border-b bg-background/95 backdrop-blur-sm flex items-center justify-between px-4",
15124
- children: [
15125
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3", children: [
15126
- /* @__PURE__ */ jsxRuntime.jsx("h2", { className: "text-sm font-semibold", children: "An\xE1lise de Clientes" }),
15127
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs px-2 py-1 rounded-full bg-blue-500/10 text-blue-600 dark:text-blue-400 font-medium", children: "IA Analytics" })
15128
- ] }),
15129
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
15130
- /* @__PURE__ */ jsxRuntime.jsx(HeroIcons.BellIcon, { className: "h-4 w-4 text-muted-foreground" }),
15131
- /* @__PURE__ */ jsxRuntime.jsx(HeroIcons.MagnifyingGlassIcon, { className: "h-4 w-4 text-muted-foreground" })
15132
- ] })
15133
- ]
15134
- }
15135
- ),
15136
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1 overflow-y-auto p-4 space-y-3", children: [
15137
- /* @__PURE__ */ jsxRuntime.jsxs(
15138
- framerMotion.motion.div,
15139
- {
15140
- initial: { opacity: 0, y: 20 },
15141
- animate: { opacity: 1, y: 0 },
15142
- transition: { delay: 0.5 },
15143
- className: "grid grid-cols-2 gap-3",
15144
- children: [
15145
- /* @__PURE__ */ jsxRuntime.jsxs(Card, { className: "p-3 bg-gradient-to-br from-blue-500 to-cyan-500 text-white", children: [
15146
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between mb-2", children: [
15147
- /* @__PURE__ */ jsxRuntime.jsx(HeroIcons.UsersIcon, { className: "h-5 w-5" }),
15148
- /* @__PURE__ */ jsxRuntime.jsx(Badge, { className: "bg-white/20 text-white border-white/30 h-5 text-xs", children: "+12%" })
15149
- ] }),
15150
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-2xl font-bold", children: "2.547" }),
15151
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs opacity-90", children: "Clientes Ativos" })
13974
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-2xl font-bold", children: "R$ 1.2M" }),
13975
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs opacity-90", children: "Receita do Trimestre" })
15152
13976
  ] }),
15153
- /* @__PURE__ */ jsxRuntime.jsxs(Card, { className: "p-3 bg-gradient-to-br from-purple-500 to-pink-500 text-white", children: [
13977
+ /* @__PURE__ */ jsxRuntime.jsxs(Card, { className: "p-3 bg-gradient-to-br from-red-500 to-orange-500 text-white", children: [
15154
13978
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between mb-2", children: [
15155
- /* @__PURE__ */ jsxRuntime.jsx(HeroIcons.ArrowTrendingUpIcon, { className: "h-5 w-5" }),
15156
- /* @__PURE__ */ jsxRuntime.jsx(Badge, { className: "bg-white/20 text-white border-white/30 h-5 text-xs", children: "+28%" })
13979
+ /* @__PURE__ */ jsxRuntime.jsx(HeroIcons.DocumentTextIcon, { className: "h-5 w-5" }),
13980
+ /* @__PURE__ */ jsxRuntime.jsx(Badge, { className: "bg-white/20 text-white border-white/30 h-5 text-xs", children: "Auto" })
15157
13981
  ] }),
15158
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-2xl font-bold", children: "R$ 485k" }),
15159
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs opacity-90", children: "Receita Mensal" })
15160
- ] })
15161
- ]
15162
- }
15163
- ),
15164
- /* @__PURE__ */ jsxRuntime.jsx(
15165
- framerMotion.motion.div,
15166
- {
15167
- initial: { opacity: 0, y: 20 },
15168
- animate: { opacity: 1, y: 0 },
15169
- transition: { delay: 0.7 },
15170
- children: /* @__PURE__ */ jsxRuntime.jsxs(Card, { className: "border-2", children: [
15171
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-3 border-b bg-gradient-to-r from-blue-600 to-cyan-600 text-white", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
15172
- /* @__PURE__ */ jsxRuntime.jsx(HeroIcons.SparklesIcon, { className: "h-4 w-4" }),
15173
- /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-sm font-bold", children: "Insights IA" })
15174
- ] }) }),
15175
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "p-3 space-y-3", children: [
15176
- /* @__PURE__ */ jsxRuntime.jsxs(
15177
- framerMotion.motion.div,
15178
- {
15179
- initial: { opacity: 0, x: -10 },
15180
- animate: { opacity: 1, x: 0 },
15181
- transition: { delay: 0.9 },
15182
- className: "flex items-start gap-2",
15183
- children: [
15184
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-6 w-6 rounded-full bg-green-500/10 flex items-center justify-center flex-shrink-0", children: /* @__PURE__ */ jsxRuntime.jsx(HeroIcons.CheckCircleIcon, { className: "h-3 w-3 text-green-500" }) }),
15185
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1", children: [
15186
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs font-medium", children: "Segmento Premium crescendo" }),
15187
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-[10px] text-muted-foreground", children: "+45% de convers\xE3o em produtos acima de R$ 500" })
15188
- ] })
15189
- ]
15190
- }
15191
- ),
15192
- /* @__PURE__ */ jsxRuntime.jsxs(
15193
- framerMotion.motion.div,
15194
- {
15195
- initial: { opacity: 0, x: -10 },
15196
- animate: { opacity: 1, x: 0 },
15197
- transition: { delay: 1.1 },
15198
- className: "flex items-start gap-2",
15199
- children: [
15200
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-6 w-6 rounded-full bg-blue-500/10 flex items-center justify-center flex-shrink-0", children: /* @__PURE__ */ jsxRuntime.jsx(HeroIcons.ArrowTrendingUpIcon, { className: "h-3 w-3 text-blue-500" }) }),
15201
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1", children: [
15202
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs font-medium", children: "Reten\xE7\xE3o melhorou 32%" }),
15203
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-[10px] text-muted-foreground", children: "Ap\xF3s implementa\xE7\xE3o do programa de fidelidade" })
15204
- ] })
15205
- ]
15206
- }
15207
- ),
15208
- /* @__PURE__ */ jsxRuntime.jsxs(
15209
- framerMotion.motion.div,
15210
- {
15211
- initial: { opacity: 0, x: -10 },
15212
- animate: { opacity: 1, x: 0 },
15213
- transition: { delay: 1.3 },
15214
- className: "flex items-start gap-2",
15215
- children: [
15216
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-6 w-6 rounded-full bg-purple-500/10 flex items-center justify-center flex-shrink-0", children: /* @__PURE__ */ jsxRuntime.jsx(HeroIcons.UsersIcon, { className: "h-3 w-3 text-purple-500" }) }),
15217
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1", children: [
15218
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs font-medium", children: "847 clientes em risco" }),
15219
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-[10px] text-muted-foreground", children: "Sem compras h\xE1 60+ dias - recomendar campanha" })
15220
- ] })
15221
- ]
15222
- }
15223
- )
15224
- ] })
15225
- ] })
15226
- }
15227
- ),
15228
- /* @__PURE__ */ jsxRuntime.jsx(
15229
- framerMotion.motion.div,
15230
- {
15231
- initial: { opacity: 0, y: 20 },
15232
- animate: { opacity: 1, y: 0 },
15233
- transition: { delay: 1.5 },
15234
- children: /* @__PURE__ */ jsxRuntime.jsxs(Card, { className: "p-3", children: [
15235
- /* @__PURE__ */ jsxRuntime.jsx("h4", { className: "text-xs font-semibold mb-2", children: "Top Clientes (\xDAltimo M\xEAs)" }),
15236
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-2", children: ["Maria Silva", "Jo\xE3o Santos", "Ana Costa"].map((name, i) => /* @__PURE__ */ jsxRuntime.jsxs(
15237
- framerMotion.motion.div,
15238
- {
15239
- initial: { opacity: 0, x: -10 },
15240
- animate: { opacity: 1, x: 0 },
15241
- transition: { delay: 1.7 + i * 0.2 },
15242
- className: "flex items-center justify-between",
15243
- children: [
15244
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
15245
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-6 w-6 rounded-full bg-gradient-to-br from-gray-400 to-gray-600 flex items-center justify-center text-white text-[10px] font-bold", children: name.charAt(0) }),
15246
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs font-medium", children: name })
15247
- ] }),
15248
- /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-xs text-muted-foreground", children: [
15249
- "R$ ",
15250
- Math.floor(Math.random() * 50 + 10),
15251
- "k"
15252
- ] })
15253
- ]
15254
- },
15255
- name
15256
- )) })
15257
- ] })
15258
- }
15259
- )
15260
- ] })
15261
- ] })
15262
- }
15263
- );
15264
- var FinancialDemo = () => /* @__PURE__ */ jsxRuntime.jsx(
15265
- framerMotion.motion.div,
15266
- {
15267
- initial: { opacity: 0 },
15268
- animate: { opacity: 1 },
15269
- exit: { opacity: 0 },
15270
- transition: { duration: 0.5 },
15271
- className: "flex flex-col h-full overflow-hidden",
15272
- children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1 flex flex-col overflow-hidden", children: [
15273
- /* @__PURE__ */ jsxRuntime.jsxs(
15274
- framerMotion.motion.div,
15275
- {
15276
- initial: { y: -20, opacity: 0 },
15277
- animate: { y: 0, opacity: 1 },
15278
- transition: { duration: 0.5, delay: 0.3 },
15279
- className: "h-14 border-b bg-background/95 backdrop-blur-sm flex items-center justify-between px-4",
15280
- children: [
15281
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3", children: [
15282
- /* @__PURE__ */ jsxRuntime.jsx("h2", { className: "text-sm font-semibold", children: "Planejamento Financeiro" }),
15283
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs px-2 py-1 rounded-full bg-green-500/10 text-green-600 dark:text-green-400 font-medium", children: "Q4 2024" })
15284
- ] }),
15285
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
15286
- /* @__PURE__ */ jsxRuntime.jsx(HeroIcons.BellIcon, { className: "h-4 w-4 text-muted-foreground" }),
15287
- /* @__PURE__ */ jsxRuntime.jsx(HeroIcons.MagnifyingGlassIcon, { className: "h-4 w-4 text-muted-foreground" })
15288
- ] })
15289
- ]
15290
- }
15291
- ),
15292
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1 overflow-y-auto p-4 space-y-3", children: [
15293
- /* @__PURE__ */ jsxRuntime.jsxs(
15294
- framerMotion.motion.div,
15295
- {
15296
- initial: { opacity: 0, y: 20 },
15297
- animate: { opacity: 1, y: 0 },
15298
- transition: { delay: 0.5 },
15299
- className: "grid grid-cols-2 gap-3",
15300
- children: [
15301
- /* @__PURE__ */ jsxRuntime.jsxs(Card, { className: "p-3 bg-gradient-to-br from-green-500 to-emerald-500 text-white", children: [
15302
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between mb-2", children: [
15303
- /* @__PURE__ */ jsxRuntime.jsx(HeroIcons.ArrowTrendingUpIcon, { className: "h-5 w-5" }),
15304
- /* @__PURE__ */ jsxRuntime.jsx(Badge, { className: "bg-white/20 text-white border-white/30 h-5 text-xs", children: "+18%" })
15305
- ] }),
15306
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-2xl font-bold", children: "R$ 1.2M" }),
15307
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs opacity-90", children: "Receita do Trimestre" })
15308
- ] }),
15309
- /* @__PURE__ */ jsxRuntime.jsxs(Card, { className: "p-3 bg-gradient-to-br from-red-500 to-orange-500 text-white", children: [
15310
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between mb-2", children: [
15311
- /* @__PURE__ */ jsxRuntime.jsx(HeroIcons.DocumentTextIcon, { className: "h-5 w-5" }),
15312
- /* @__PURE__ */ jsxRuntime.jsx(Badge, { className: "bg-white/20 text-white border-white/30 h-5 text-xs", children: "Auto" })
15313
- ] }),
15314
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-2xl font-bold", children: "R$ 387k" }),
15315
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs opacity-90", children: "Impostos Calculados" })
13982
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-2xl font-bold", children: "R$ 387k" }),
13983
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs opacity-90", children: "Impostos Calculados" })
15316
13984
  ] })
15317
13985
  ]
15318
13986
  }
@@ -18251,186 +16919,975 @@ function DepartmentAssistantDemo({
18251
16919
  },
18252
16920
  `dashboard-${flow.id}`
18253
16921
  )
18254
- ] }) }),
18255
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between border-t border-white/5 px-5 py-3", children: [
18256
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 text-[11px] text-gray-500 dark:text-gray-400", children: [
18257
- /* @__PURE__ */ jsxRuntime.jsx(HeroIcons.BoltIcon, { className: `h-3.5 w-3.5 ${t.progressActiveBar.replace("bg-", "text-")}` }),
18258
- /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "font-medium", children: [
18259
- stage === "input" && L.footerInput,
18260
- stage === "workflow" && L.footerWorkflow,
18261
- stage === "dashboard" && L.footerDashboard
18262
- ] })
18263
- ] }),
18264
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-1", children: flows.map((entry, index) => /* @__PURE__ */ jsxRuntime.jsx(
18265
- "span",
18266
- {
18267
- className: `h-1 rounded-full transition-all duration-500 ${index === flowIndex ? `w-8 ${t.progressActiveBar}` : "w-1.5 bg-gray-300 dark:bg-white/10"}`
18268
- },
18269
- entry.id
18270
- )) })
18271
- ] })
18272
- ] });
16922
+ ] }) }),
16923
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between border-t border-white/5 px-5 py-3", children: [
16924
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 text-[11px] text-gray-500 dark:text-gray-400", children: [
16925
+ /* @__PURE__ */ jsxRuntime.jsx(HeroIcons.BoltIcon, { className: `h-3.5 w-3.5 ${t.progressActiveBar.replace("bg-", "text-")}` }),
16926
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "font-medium", children: [
16927
+ stage === "input" && L.footerInput,
16928
+ stage === "workflow" && L.footerWorkflow,
16929
+ stage === "dashboard" && L.footerDashboard
16930
+ ] })
16931
+ ] }),
16932
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-1", children: flows.map((entry, index) => /* @__PURE__ */ jsxRuntime.jsx(
16933
+ "span",
16934
+ {
16935
+ className: `h-1 rounded-full transition-all duration-500 ${index === flowIndex ? `w-8 ${t.progressActiveBar}` : "w-1.5 bg-gray-300 dark:bg-white/10"}`
16936
+ },
16937
+ entry.id
16938
+ )) })
16939
+ ] })
16940
+ ] });
16941
+ }
16942
+ function StageChip({ label, stageIndex, mine, activeBadge }) {
16943
+ const isActive = stageIndex === mine;
16944
+ const isDone = stageIndex > mine;
16945
+ return /* @__PURE__ */ jsxRuntime.jsxs(
16946
+ "div",
16947
+ {
16948
+ className: `inline-flex items-center gap-1.5 rounded-full px-2.5 py-0.5 font-semibold transition-colors ${isActive ? activeBadge : isDone ? "bg-emerald-500/10 text-emerald-600 dark:text-emerald-300" : "bg-white/5 text-gray-500 dark:text-gray-500"}`,
16949
+ children: [
16950
+ isDone ? /* @__PURE__ */ jsxRuntime.jsx(HeroIcons.CheckCircleIcon, { className: "h-3.5 w-3.5" }) : isActive ? /* @__PURE__ */ jsxRuntime.jsx(HeroIcons.BoltIcon, { className: "h-3.5 w-3.5 animate-pulse" }) : /* @__PURE__ */ jsxRuntime.jsx("span", { className: "h-1.5 w-1.5 rounded-full bg-current" }),
16951
+ label
16952
+ ]
16953
+ }
16954
+ );
16955
+ }
16956
+ function InputStage3({
16957
+ userPrompt,
16958
+ assistantMessage,
16959
+ phase,
16960
+ assistantComplete,
16961
+ department,
16962
+ assistantAvatar,
16963
+ assistantName,
16964
+ agents,
16965
+ agentAvatars,
16966
+ avatarGradient,
16967
+ cursorClass,
16968
+ conversationLabel,
16969
+ personaTagFn,
16970
+ composerHint,
16971
+ composerEnter
16972
+ }) {
16973
+ const cursor = /* @__PURE__ */ jsxRuntime.jsx("span", { className: `ml-0.5 inline-block w-[2px] h-4 align-middle ${cursorClass} animate-pulse` });
16974
+ const showAssistant = phase === "assistant";
16975
+ const personaName = assistantName ?? department;
16976
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex h-full flex-col px-4 py-6 sm:px-8", children: [
16977
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mb-5 flex items-center justify-center gap-2 text-[10px] font-semibold uppercase tracking-wider text-gray-400 dark:text-gray-500", children: [
16978
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "h-1 w-1 rounded-full bg-emerald-500 animate-pulse" }),
16979
+ conversationLabel(personaName, department)
16980
+ ] }),
16981
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mx-auto flex w-full max-w-3xl flex-1 flex-col justify-end gap-4 overflow-hidden", children: [
16982
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-end", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "liquid-surface max-w-[88%] rounded-2xl rounded-tr-md px-5 py-3.5", children: /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-base leading-relaxed text-gray-900 dark:text-white", children: [
16983
+ userPrompt,
16984
+ phase === "user" && cursor
16985
+ ] }) }) }),
16986
+ showAssistant && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-end gap-2.5", children: [
16987
+ assistantAvatar ? /* @__PURE__ */ jsxRuntime.jsx(
16988
+ "img",
16989
+ {
16990
+ src: assistantAvatar,
16991
+ alt: personaName,
16992
+ className: `h-11 w-11 shrink-0 rounded-2xl bg-white/40 dark:bg-white/[0.06] ring-2 ring-white/30 dark:ring-white/10 shadow-md`
16993
+ }
16994
+ ) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: `flex h-11 w-11 shrink-0 items-center justify-center rounded-2xl bg-gradient-to-br ${avatarGradient} shadow-md`, children: /* @__PURE__ */ jsxRuntime.jsx(HeroIcons.SparklesIcon, { className: "h-5 w-5 text-white" }) }),
16995
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "liquid-surface max-w-[88%] rounded-2xl rounded-bl-md px-5 py-3.5", children: [
16996
+ assistantMessage.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mb-1 text-[10px] font-bold uppercase tracking-wider text-gray-500 dark:text-gray-400", children: personaTagFn(personaName) }),
16997
+ assistantMessage.length === 0 ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1 py-1", children: [
16998
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: `h-1.5 w-1.5 rounded-full ${cursorClass} animate-pulse` }),
16999
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: `h-1.5 w-1.5 rounded-full ${cursorClass} animate-pulse`, style: { animationDelay: "150ms" } }),
17000
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: `h-1.5 w-1.5 rounded-full ${cursorClass} animate-pulse`, style: { animationDelay: "300ms" } })
17001
+ ] }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
17002
+ /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-base leading-relaxed text-gray-900 dark:text-white", children: [
17003
+ assistantMessage,
17004
+ !assistantComplete && cursor
17005
+ ] }),
17006
+ assistantComplete && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-3 flex flex-wrap gap-2", children: agents.map((agent) => {
17007
+ const avatar = agentAvatars?.[agent];
17008
+ return /* @__PURE__ */ jsxRuntime.jsxs(
17009
+ "span",
17010
+ {
17011
+ className: "inline-flex items-center gap-1.5 rounded-full bg-white/40 dark:bg-white/[0.08] py-0.5 pl-0.5 pr-3 text-[11px] font-semibold text-gray-700 dark:text-gray-200 shadow-sm",
17012
+ children: [
17013
+ avatar ? /* @__PURE__ */ jsxRuntime.jsx("img", { src: avatar, alt: "", className: "h-6 w-6 rounded-full bg-white/40 dark:bg-white/[0.06]" }) : /* @__PURE__ */ jsxRuntime.jsx("span", { className: `flex h-6 w-6 items-center justify-center rounded-full bg-gradient-to-br ${avatarGradient}`, children: /* @__PURE__ */ jsxRuntime.jsx(HeroIcons.BoltIcon, { className: "h-3 w-3 text-white" }) }),
17014
+ agent
17015
+ ]
17016
+ },
17017
+ agent
17018
+ );
17019
+ }) })
17020
+ ] })
17021
+ ] })
17022
+ ] })
17023
+ ] }),
17024
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mx-auto mt-5 w-full max-w-3xl", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "liquid-surface flex items-center gap-3 rounded-full px-4 py-2.5 opacity-60", children: [
17025
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-xs italic text-gray-500 dark:text-gray-400", children: composerHint }),
17026
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "ml-auto flex items-center gap-1 text-[10px] text-gray-400 dark:text-gray-500", children: composerEnter })
17027
+ ] }) })
17028
+ ] });
17029
+ }
17030
+ var koriDepartmentFlows = [
17031
+ {
17032
+ id: "sales",
17033
+ name: "Vendas",
17034
+ icon: HeroIcons.ShoppingCartIcon,
17035
+ accent: "from-blue-500 to-indigo-500",
17036
+ prompt: "Qualificar lead empresa XPTO e preparar proposta comercial",
17037
+ agents: ["Sales", "CRM", "Scoring", "Proposal"],
17038
+ workflow: salesWorkflow,
17039
+ dashboard: /* @__PURE__ */ jsxRuntime.jsx(SalesDemo, {})
17040
+ },
17041
+ {
17042
+ id: "financial",
17043
+ name: "Financeiro",
17044
+ icon: HeroIcons.BanknotesIcon,
17045
+ accent: "from-emerald-500 to-teal-500",
17046
+ prompt: "Gerar relat\xF3rio financeiro e calcular impostos do trimestre",
17047
+ agents: ["Finance", "Tax", "Reports", "Compliance"],
17048
+ workflow: financialWorkflow,
17049
+ dashboard: /* @__PURE__ */ jsxRuntime.jsx(FinancialDemo, {})
17050
+ },
17051
+ {
17052
+ id: "marketing",
17053
+ name: "Marketing",
17054
+ icon: HeroIcons.MegaphoneIcon,
17055
+ accent: "from-pink-500 to-rose-500",
17056
+ prompt: "Criar campanha de Black Friday para e-commerce",
17057
+ agents: ["Marketing", "Design", "E-commerce", "Email"],
17058
+ workflow: marketingWorkflow,
17059
+ dashboard: /* @__PURE__ */ jsxRuntime.jsx(MarketingDemo, {})
17060
+ },
17061
+ {
17062
+ id: "inventory",
17063
+ name: "Estoque",
17064
+ icon: HeroIcons.CubeIcon,
17065
+ accent: "from-orange-500 to-amber-500",
17066
+ prompt: "Verificar estoque e sugerir reposi\xE7\xF5es autom\xE1ticas",
17067
+ agents: ["Inventory", "Supply", "Forecast", "Logistics"],
17068
+ workflow: inventoryWorkflow,
17069
+ dashboard: /* @__PURE__ */ jsxRuntime.jsx(InventoryDemo, {})
17070
+ },
17071
+ {
17072
+ id: "hr",
17073
+ name: "RH",
17074
+ icon: HeroIcons.UsersIcon,
17075
+ accent: "from-green-500 to-emerald-500",
17076
+ prompt: "Processar candidaturas para vaga de Desenvolvedor Senior",
17077
+ agents: ["HR", "Recruiter", "Skills", "Interview"],
17078
+ workflow: hrWorkflow,
17079
+ dashboard: /* @__PURE__ */ jsxRuntime.jsx(HRRecruitmentDemo, {})
17080
+ },
17081
+ {
17082
+ id: "analytics",
17083
+ name: "Analytics",
17084
+ icon: HeroIcons.DocumentTextIcon,
17085
+ accent: "from-indigo-500 to-violet-500",
17086
+ prompt: "Analisar comportamento dos clientes e identificar oportunidades",
17087
+ agents: ["Analytics", "CRM", "Insights", "Reports"],
17088
+ workflow: customerAnalyticsWorkflow,
17089
+ dashboard: /* @__PURE__ */ jsxRuntime.jsx(CustomerAnalyticsDemo, {})
17090
+ },
17091
+ {
17092
+ id: "lgpd",
17093
+ name: "LGPD",
17094
+ icon: HeroIcons.ShieldCheckIcon,
17095
+ accent: "from-red-500 to-rose-500",
17096
+ prompt: "Auditar dados pessoais e verificar conformidade LGPD",
17097
+ agents: ["LGPD", "Privacy", "Audit", "Security"],
17098
+ workflow: lgpdWorkflow,
17099
+ dashboard: /* @__PURE__ */ jsxRuntime.jsx(LGPDComplianceDemo, {})
17100
+ }
17101
+ ];
17102
+ var MIN_ZOOM = 0.8;
17103
+ var MAX_ZOOM = 4;
17104
+ var ZOOM_STEP = 0.5;
17105
+ function useGeoMapState({
17106
+ items,
17107
+ getRegionCode,
17108
+ regionCoordinates,
17109
+ defaultCenter = [0, 0]
17110
+ }) {
17111
+ const [zoom, setZoom] = React12.useState(1);
17112
+ const [center, setCenter] = React12.useState(defaultCenter);
17113
+ const [hoveredRegion, setHoveredRegion] = React12.useState(null);
17114
+ const [animatedRegions, setAnimatedRegions] = React12.useState(/* @__PURE__ */ new Set());
17115
+ const [panOffset, setPanOffset] = React12.useState([0, 0]);
17116
+ const handleZoomIn = React12.useCallback(() => {
17117
+ setZoom((previous) => Math.min(previous + ZOOM_STEP, MAX_ZOOM));
17118
+ }, []);
17119
+ const handleZoomOut = React12.useCallback(() => {
17120
+ setZoom((previous) => Math.max(previous - ZOOM_STEP, MIN_ZOOM));
17121
+ }, []);
17122
+ const handleMoveEnd = React12.useCallback(
17123
+ (position) => {
17124
+ setCenter(position.coordinates);
17125
+ setZoom(position.zoom);
17126
+ },
17127
+ []
17128
+ );
17129
+ const handlePan = React12.useCallback((dx, dy) => {
17130
+ setPanOffset((previous) => [previous[0] + dx, previous[1] + dy]);
17131
+ }, []);
17132
+ const regionGroups = React12.useMemo(() => {
17133
+ const grouped = /* @__PURE__ */ new Map();
17134
+ items.forEach((item) => {
17135
+ const code = getRegionCode(item);
17136
+ if (!grouped.has(code)) {
17137
+ grouped.set(code, []);
17138
+ }
17139
+ grouped.get(code).push(item);
17140
+ });
17141
+ return Array.from(grouped.entries()).filter(([code]) => regionCoordinates[code]).map(([code, regionItems]) => ({
17142
+ code,
17143
+ items: regionItems,
17144
+ coordinates: regionCoordinates[code]
17145
+ })).sort((a, b) => b.items.length - a.items.length);
17146
+ }, [items, getRegionCode, regionCoordinates]);
17147
+ const animationCodes = React12.useMemo(
17148
+ () => regionGroups.map((regionData) => regionData.code),
17149
+ [regionGroups]
17150
+ );
17151
+ const animationSignature = React12.useMemo(
17152
+ () => animationCodes.join("|"),
17153
+ [animationCodes]
17154
+ );
17155
+ React12.useEffect(() => {
17156
+ if (animationCodes.length === 0) return;
17157
+ setAnimatedRegions(/* @__PURE__ */ new Set());
17158
+ const timers = [];
17159
+ animationCodes.forEach((code, index) => {
17160
+ const timer = setTimeout(() => {
17161
+ setAnimatedRegions((previous) => /* @__PURE__ */ new Set([...previous, code]));
17162
+ }, index * 100);
17163
+ timers.push(timer);
17164
+ });
17165
+ return () => timers.forEach(clearTimeout);
17166
+ }, [animationSignature]);
17167
+ const getMarkerSize = React12.useCallback(
17168
+ (count) => {
17169
+ const baseSize = count >= 10 ? 14 : count >= 5 ? 11 : count >= 2 ? 8 : 6;
17170
+ return baseSize / Math.sqrt(zoom);
17171
+ },
17172
+ [zoom]
17173
+ );
17174
+ const getFontSize = React12.useCallback(
17175
+ (markerSize) => {
17176
+ const baseSize = markerSize > 10 ? 10 : 8;
17177
+ const scaledSize = baseSize / Math.sqrt(zoom);
17178
+ return `${Math.max(scaledSize, 6)}px`;
17179
+ },
17180
+ [zoom]
17181
+ );
17182
+ return {
17183
+ zoom,
17184
+ setZoom,
17185
+ handleZoomIn,
17186
+ handleZoomOut,
17187
+ handleMoveEnd,
17188
+ MIN_ZOOM,
17189
+ MAX_ZOOM,
17190
+ center,
17191
+ setCenter,
17192
+ panOffset,
17193
+ handlePan,
17194
+ hoveredRegion,
17195
+ setHoveredRegion,
17196
+ animatedRegions,
17197
+ regionGroups,
17198
+ getMarkerSize,
17199
+ getFontSize
17200
+ };
17201
+ }
17202
+ var MAP_DEFAULT_STATE_COLOR = "rgba(100, 116, 139, 0.35)";
17203
+ var MAP_DEFAULT_MARKER_COLOR = "#6366f1";
17204
+ var VIEWBOX_WIDTH = 1e3;
17205
+ var VIEWBOX_HEIGHT = 500;
17206
+ var ALBERS_WIDTH = 960;
17207
+ var ALBERS_HEIGHT = 600;
17208
+ function GeoMapCanvasInner({
17209
+ regionGroups,
17210
+ regionColorMap,
17211
+ animatedRegions,
17212
+ zoom,
17213
+ panOffset,
17214
+ hoveredRegion,
17215
+ onPan,
17216
+ onRegionHover,
17217
+ onRegionClick,
17218
+ isRegionActive,
17219
+ getMarkerSize,
17220
+ getFontSize,
17221
+ geoJsonUrl,
17222
+ regionPropertyKey = "code",
17223
+ projectionType = "mercator",
17224
+ ariaLabel = "Interactive map"
17225
+ }, ref) {
17226
+ const [geoData, setGeoData] = React12.useState(null);
17227
+ const svgRef = React12.useRef(null);
17228
+ const dragState = React12.useRef(null);
17229
+ React12.useEffect(() => {
17230
+ let cancelled = false;
17231
+ async function loadGeoData() {
17232
+ try {
17233
+ const response = await fetch(geoJsonUrl);
17234
+ if (!response.ok) return;
17235
+ const data = await response.json();
17236
+ if (!cancelled) setGeoData(data);
17237
+ } catch {
17238
+ }
17239
+ }
17240
+ loadGeoData();
17241
+ return () => {
17242
+ cancelled = true;
17243
+ };
17244
+ }, [geoJsonUrl]);
17245
+ const handleMouseDown = React12.useCallback(
17246
+ (event) => {
17247
+ if (event.button !== 0) return;
17248
+ dragState.current = {
17249
+ active: true,
17250
+ startX: event.clientX,
17251
+ startY: event.clientY,
17252
+ lastX: event.clientX,
17253
+ lastY: event.clientY,
17254
+ didDrag: false
17255
+ };
17256
+ },
17257
+ []
17258
+ );
17259
+ const handleMouseMove = React12.useCallback(
17260
+ (event) => {
17261
+ if (!dragState.current?.active || !svgRef.current) return;
17262
+ const totalDx = event.clientX - dragState.current.startX;
17263
+ const totalDy = event.clientY - dragState.current.startY;
17264
+ if (!dragState.current.didDrag) {
17265
+ if (Math.abs(totalDx) < 5 && Math.abs(totalDy) < 5) return;
17266
+ dragState.current.didDrag = true;
17267
+ }
17268
+ const dx = event.clientX - dragState.current.lastX;
17269
+ const dy = event.clientY - dragState.current.lastY;
17270
+ const rect = svgRef.current.getBoundingClientRect();
17271
+ const viewBoxWidth = VIEWBOX_WIDTH / zoom;
17272
+ const scaleRatio = viewBoxWidth / rect.width;
17273
+ onPan(dx * scaleRatio, dy * scaleRatio);
17274
+ dragState.current.lastX = event.clientX;
17275
+ dragState.current.lastY = event.clientY;
17276
+ },
17277
+ [zoom, onPan]
17278
+ );
17279
+ const handleMouseUp = React12.useCallback(() => {
17280
+ if (dragState.current) {
17281
+ dragState.current.active = false;
17282
+ }
17283
+ }, []);
17284
+ const wasDragAction = React12.useCallback(() => {
17285
+ return dragState.current?.didDrag === true;
17286
+ }, []);
17287
+ const getLighterColor = (hexColor) => {
17288
+ const r = parseInt(hexColor.slice(1, 3), 16);
17289
+ const g = parseInt(hexColor.slice(3, 5), 16);
17290
+ const b = parseInt(hexColor.slice(5, 7), 16);
17291
+ return `rgba(${r}, ${g}, ${b}, 0.15)`;
17292
+ };
17293
+ const lighterColors = React12.useMemo(() => {
17294
+ const colors3 = /* @__PURE__ */ new Map();
17295
+ regionColorMap.forEach((color, code) => {
17296
+ colors3.set(code, getLighterColor(color));
17297
+ });
17298
+ return colors3;
17299
+ }, [regionColorMap]);
17300
+ const featureCollection = React12.useMemo(() => {
17301
+ if (!geoData) return null;
17302
+ return {
17303
+ type: "FeatureCollection",
17304
+ features: geoData.features
17305
+ };
17306
+ }, [geoData]);
17307
+ const projection = React12.useMemo(() => {
17308
+ if (!featureCollection) return null;
17309
+ if (projectionType === "albersUsa") {
17310
+ return d3Geo.geoAlbersUsa();
17311
+ }
17312
+ return d3Geo.geoMercator().fitSize([VIEWBOX_WIDTH, VIEWBOX_HEIGHT], featureCollection);
17313
+ }, [featureCollection, projectionType]);
17314
+ const pathGenerator = React12.useMemo(() => {
17315
+ if (!projection) return null;
17316
+ return d3Geo.geoPath(projection);
17317
+ }, [projection]);
17318
+ const regionsWithItems = React12.useMemo(() => {
17319
+ return new Set(regionGroups.map((regionData) => regionData.code));
17320
+ }, [regionGroups]);
17321
+ const hasAnyActiveFilter = React12.useMemo(() => {
17322
+ return regionGroups.some((regionData) => isRegionActive?.(regionData.code));
17323
+ }, [regionGroups, isRegionActive]);
17324
+ const featureBounds = React12.useMemo(() => {
17325
+ if (!pathGenerator || !geoData) return null;
17326
+ let minX = Infinity, minY = Infinity, maxX = -Infinity, maxY = -Infinity;
17327
+ for (const feature of geoData.features) {
17328
+ const bounds = pathGenerator.bounds(feature);
17329
+ if (!bounds || !isFinite(bounds[0][0])) continue;
17330
+ minX = Math.min(minX, bounds[0][0]);
17331
+ minY = Math.min(minY, bounds[0][1]);
17332
+ maxX = Math.max(maxX, bounds[1][0]);
17333
+ maxY = Math.max(maxY, bounds[1][1]);
17334
+ }
17335
+ if (!isFinite(minX)) return null;
17336
+ const pad = 15;
17337
+ return { x: minX - pad, y: minY - pad, width: maxX - minX + pad * 2, height: maxY - minY + pad * 2 };
17338
+ }, [pathGenerator, geoData]);
17339
+ const effectiveWidth = featureBounds?.width ?? (projectionType === "albersUsa" ? ALBERS_WIDTH : VIEWBOX_WIDTH);
17340
+ const effectiveHeight = featureBounds?.height ?? (projectionType === "albersUsa" ? ALBERS_HEIGHT : VIEWBOX_HEIGHT);
17341
+ const baseX = featureBounds?.x ?? 0;
17342
+ const baseY = featureBounds?.y ?? 0;
17343
+ const viewBoxParts = React12.useMemo(() => {
17344
+ const width = effectiveWidth / zoom;
17345
+ const height = effectiveHeight / zoom;
17346
+ const x = baseX + (effectiveWidth - width) / 2 - panOffset[0];
17347
+ const y = baseY + (effectiveHeight - height) / 2 - panOffset[1];
17348
+ return { x, y, width, height };
17349
+ }, [zoom, panOffset, effectiveWidth, effectiveHeight, baseX, baseY]);
17350
+ const viewBox = `${viewBoxParts.x} ${viewBoxParts.y} ${viewBoxParts.width} ${viewBoxParts.height}`;
17351
+ return /* @__PURE__ */ jsxRuntime.jsx(
17352
+ "div",
17353
+ {
17354
+ ref,
17355
+ className: "relative w-full h-full overflow-hidden rounded-2xl border border-white/20 dark:border-white/[0.12] shadow-lg shadow-black/5 dark:shadow-black/30",
17356
+ "data-testid": "map-canvas",
17357
+ children: /* @__PURE__ */ jsxRuntime.jsxs(
17358
+ "svg",
17359
+ {
17360
+ ref: svgRef,
17361
+ viewBox,
17362
+ className: "w-full h-full cursor-grab active:cursor-grabbing",
17363
+ "aria-label": ariaLabel,
17364
+ style: { touchAction: "none", background: "transparent" },
17365
+ onMouseDown: handleMouseDown,
17366
+ onMouseMove: handleMouseMove,
17367
+ onMouseUp: handleMouseUp,
17368
+ onMouseLeave: handleMouseUp,
17369
+ children: [
17370
+ /* @__PURE__ */ jsxRuntime.jsxs("defs", { children: [
17371
+ /* @__PURE__ */ jsxRuntime.jsx("filter", { id: "glow-active", x: "-20%", y: "-20%", width: "140%", height: "140%", children: /* @__PURE__ */ jsxRuntime.jsx("feDropShadow", { dx: "0", dy: "0", stdDeviation: "3", floodColor: "#fff", floodOpacity: "0.6" }) }),
17372
+ /* @__PURE__ */ jsxRuntime.jsx("filter", { id: "inactive-dim", x: "0%", y: "0%", width: "100%", height: "100%", children: /* @__PURE__ */ jsxRuntime.jsx("feColorMatrix", { type: "saturate", values: "0.3" }) }),
17373
+ /* @__PURE__ */ jsxRuntime.jsx("filter", { id: "marker-glow", x: "-50%", y: "-50%", width: "200%", height: "200%", children: /* @__PURE__ */ jsxRuntime.jsx("feDropShadow", { dx: "0", dy: "0", stdDeviation: "4", floodColor: "#fff", floodOpacity: "0.7" }) }),
17374
+ /* @__PURE__ */ jsxRuntime.jsx("clipPath", { id: "geo-inset-clip", children: /* @__PURE__ */ jsxRuntime.jsx(
17375
+ "rect",
17376
+ {
17377
+ x: viewBoxParts.x + 2,
17378
+ y: viewBoxParts.y + 2,
17379
+ width: viewBoxParts.width - 4,
17380
+ height: viewBoxParts.height - 4
17381
+ }
17382
+ ) })
17383
+ ] }),
17384
+ /* @__PURE__ */ jsxRuntime.jsx("g", { clipPath: "url(#geo-inset-clip)", children: geoData && pathGenerator ? geoData.features.map((feature, index) => {
17385
+ const regionCode = feature.properties?.[regionPropertyKey] || feature.properties?.name || "";
17386
+ const hasItems = regionsWithItems.has(regionCode);
17387
+ const regionColor = regionColorMap.get(regionCode) ?? MAP_DEFAULT_STATE_COLOR;
17388
+ const isActive = isRegionActive?.(regionCode);
17389
+ const isHovered = hoveredRegion === regionCode;
17390
+ const isDimmed = hasAnyActiveFilter && !isActive && hasItems;
17391
+ let pathData = pathGenerator(feature);
17392
+ if (pathData && projectionType === "albersUsa") {
17393
+ const subpaths = pathData.split("Z").filter(Boolean);
17394
+ const cleaned = subpaths.filter((sub) => {
17395
+ const lCount = (sub.match(/L/g) || []).length;
17396
+ if (lCount !== 3) return true;
17397
+ const nums = sub.match(/-?\d+\.?\d*/g)?.map(Number);
17398
+ if (!nums || nums.length !== 8) return true;
17399
+ const [x1, y1, x2, y2, x3, y3, x4, y4] = nums;
17400
+ const xs = /* @__PURE__ */ new Set([x1, x2, x3, x4]);
17401
+ const ys = /* @__PURE__ */ new Set([y1, y2, y3, y4]);
17402
+ return xs.size !== 2 || ys.size !== 2;
17403
+ });
17404
+ pathData = cleaned.length > 0 ? cleaned.join("Z") + "Z" : null;
17405
+ }
17406
+ if (!pathData) return null;
17407
+ return /* @__PURE__ */ jsxRuntime.jsx(
17408
+ "path",
17409
+ {
17410
+ d: pathData,
17411
+ fillRule: "evenodd",
17412
+ "data-region": hasItems ? regionCode : void 0,
17413
+ onMouseEnter: () => hasItems && onRegionHover(regionCode),
17414
+ onMouseLeave: () => onRegionHover(null),
17415
+ onClick: () => {
17416
+ if (hasItems && !wasDragAction()) {
17417
+ onRegionClick(regionCode);
17418
+ }
17419
+ },
17420
+ fill: hasItems ? isHovered ? regionColor : isActive ? regionColor : lighterColors.get(regionCode) || getLighterColor(regionColor) : MAP_DEFAULT_STATE_COLOR,
17421
+ stroke: isActive ? "#fff" : isDimmed ? "rgba(148, 163, 184, 0.15)" : "rgba(148, 163, 184, 0.40)",
17422
+ strokeWidth: (isActive ? 2.5 : 0.5) / zoom,
17423
+ filter: isActive ? "url(#glow-active)" : isDimmed ? "url(#inactive-dim)" : void 0,
17424
+ opacity: isDimmed ? 0.45 : 1,
17425
+ style: {
17426
+ transition: "fill 0.3s ease, opacity 0.3s ease",
17427
+ cursor: hasItems ? "pointer" : void 0
17428
+ }
17429
+ },
17430
+ `${regionCode}-${index}`
17431
+ );
17432
+ }) : null }),
17433
+ projection ? regionGroups.map((regionData) => {
17434
+ const point = projection(regionData.coordinates);
17435
+ if (!point) return null;
17436
+ const [x, y] = point;
17437
+ const isAnimated = animatedRegions.has(regionData.code);
17438
+ const markerSize = getMarkerSize(regionData.items.length);
17439
+ const markerColor = regionColorMap.get(regionData.code) ?? MAP_DEFAULT_MARKER_COLOR;
17440
+ const isActive = isRegionActive?.(regionData.code);
17441
+ const isDimmed = hasAnyActiveFilter && !isActive;
17442
+ return /* @__PURE__ */ jsxRuntime.jsx(
17443
+ "g",
17444
+ {
17445
+ transform: `translate(${x}, ${y})`,
17446
+ "data-region": regionData.code,
17447
+ "data-testid": `marker-${regionData.code}`,
17448
+ onMouseEnter: () => onRegionHover(regionData.code),
17449
+ onMouseLeave: () => onRegionHover(null),
17450
+ onClick: () => {
17451
+ if (!wasDragAction()) {
17452
+ onRegionClick(regionData.code);
17453
+ }
17454
+ },
17455
+ children: /* @__PURE__ */ jsxRuntime.jsxs(
17456
+ "g",
17457
+ {
17458
+ style: {
17459
+ transform: isAnimated ? "scale(1)" : "scale(0)",
17460
+ transformOrigin: "0 0",
17461
+ opacity: isAnimated ? isDimmed ? 0.35 : 1 : 0,
17462
+ transition: "all 0.4s cubic-bezier(0.34, 1.56, 0.64, 1)",
17463
+ cursor: "pointer"
17464
+ },
17465
+ filter: isActive ? "url(#marker-glow)" : void 0,
17466
+ children: [
17467
+ isActive ? /* @__PURE__ */ jsxRuntime.jsx(
17468
+ "circle",
17469
+ {
17470
+ r: markerSize + 6,
17471
+ fill: "none",
17472
+ stroke: "#fff",
17473
+ strokeWidth: 2,
17474
+ opacity: 0.8
17475
+ }
17476
+ ) : /* @__PURE__ */ jsxRuntime.jsx(
17477
+ "circle",
17478
+ {
17479
+ r: markerSize + 4,
17480
+ fill: "none",
17481
+ stroke: markerColor,
17482
+ strokeWidth: 1,
17483
+ opacity: isDimmed ? 0 : 0.4,
17484
+ className: isDimmed ? void 0 : "animate-ping",
17485
+ style: isDimmed ? void 0 : { animationDuration: "2s" }
17486
+ }
17487
+ ),
17488
+ /* @__PURE__ */ jsxRuntime.jsx(
17489
+ "circle",
17490
+ {
17491
+ r: markerSize,
17492
+ fill: markerColor,
17493
+ stroke: isActive ? "#fff" : markerColor,
17494
+ strokeWidth: isActive ? 3 : 2,
17495
+ className: "transition-colors",
17496
+ style: {
17497
+ filter: isActive ? "brightness(1.2) saturate(1.3)" : isDimmed ? "saturate(0.3) brightness(0.8)" : "none"
17498
+ }
17499
+ }
17500
+ ),
17501
+ regionData.items.length > 1 && /* @__PURE__ */ jsxRuntime.jsx(
17502
+ "text",
17503
+ {
17504
+ textAnchor: "middle",
17505
+ dominantBaseline: "central",
17506
+ style: {
17507
+ fontFamily: "system-ui",
17508
+ fontSize: getFontSize(markerSize),
17509
+ fontWeight: "bold",
17510
+ fill: "#fff",
17511
+ pointerEvents: "none",
17512
+ opacity: isDimmed ? 0.5 : 1
17513
+ },
17514
+ children: regionData.items.length
17515
+ }
17516
+ )
17517
+ ]
17518
+ }
17519
+ )
17520
+ },
17521
+ regionData.code
17522
+ );
17523
+ }) : null
17524
+ ]
17525
+ }
17526
+ )
17527
+ }
17528
+ );
18273
17529
  }
18274
- function StageChip({ label, stageIndex, mine, activeBadge }) {
18275
- const isActive = stageIndex === mine;
18276
- const isDone = stageIndex > mine;
18277
- return /* @__PURE__ */ jsxRuntime.jsxs(
17530
+ var GeoMapCanvas = React12__namespace.default.forwardRef(GeoMapCanvasInner);
17531
+ var MapZoomControls = React12__namespace.default.forwardRef(
17532
+ ({ zoom, minZoom, maxZoom, onZoomIn, onZoomOut, labels }, ref) => {
17533
+ return /* @__PURE__ */ jsxRuntime.jsxs(
17534
+ "div",
17535
+ {
17536
+ ref,
17537
+ className: "flex flex-col gap-1",
17538
+ "data-testid": "map-zoom-controls",
17539
+ children: [
17540
+ /* @__PURE__ */ jsxRuntime.jsx(
17541
+ "button",
17542
+ {
17543
+ onClick: onZoomIn,
17544
+ disabled: zoom >= maxZoom,
17545
+ className: "p-2 liquid-surface rounded-lg disabled:opacity-50 disabled:cursor-not-allowed transition-colors",
17546
+ "aria-label": labels?.zoomIn ?? "Zoom in",
17547
+ "data-testid": "zoom-in-button",
17548
+ children: /* @__PURE__ */ jsxRuntime.jsx(HeroIcons.PlusIcon, { className: "h-5 w-5 text-gray-700 dark:text-gray-300" })
17549
+ }
17550
+ ),
17551
+ /* @__PURE__ */ jsxRuntime.jsx(
17552
+ "button",
17553
+ {
17554
+ onClick: onZoomOut,
17555
+ disabled: zoom <= minZoom,
17556
+ className: "p-2 liquid-surface rounded-lg disabled:opacity-50 disabled:cursor-not-allowed transition-colors",
17557
+ "aria-label": labels?.zoomOut ?? "Zoom out",
17558
+ "data-testid": "zoom-out-button",
17559
+ children: /* @__PURE__ */ jsxRuntime.jsx(HeroIcons.MinusIcon, { className: "h-5 w-5 text-gray-700 dark:text-gray-300" })
17560
+ }
17561
+ ),
17562
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-1 px-2 py-1 liquid-surface rounded-lg text-center", children: /* @__PURE__ */ jsxRuntime.jsxs(
17563
+ "span",
17564
+ {
17565
+ className: "text-xs font-medium text-gray-600 dark:text-gray-400",
17566
+ "data-testid": "zoom-level",
17567
+ children: [
17568
+ Math.round(zoom * 100),
17569
+ "%"
17570
+ ]
17571
+ }
17572
+ ) })
17573
+ ]
17574
+ }
17575
+ );
17576
+ }
17577
+ );
17578
+ MapZoomControls.displayName = "MapZoomControls";
17579
+ function InteractiveGeoMapInner({
17580
+ items,
17581
+ getRegionCode,
17582
+ regionCoordinates,
17583
+ defaultCenter,
17584
+ geoJsonUrl,
17585
+ regionPropertyKey,
17586
+ projectionType,
17587
+ getRegionColor,
17588
+ isRegionActive,
17589
+ onRegionToggle,
17590
+ renderHoverContent,
17591
+ formatCounter,
17592
+ zoomLabels,
17593
+ ariaLabel,
17594
+ className
17595
+ }, ref) {
17596
+ const mapStateOptions = {
17597
+ items,
17598
+ getRegionCode,
17599
+ regionCoordinates,
17600
+ defaultCenter
17601
+ };
17602
+ const mapState = useGeoMapState(mapStateOptions);
17603
+ const regionColorMap = React12.useMemo(() => {
17604
+ const colorMap2 = /* @__PURE__ */ new Map();
17605
+ for (const code of Object.keys(regionCoordinates)) {
17606
+ colorMap2.set(code, getRegionColor(code));
17607
+ }
17608
+ mapState.regionGroups.forEach((regionData) => {
17609
+ if (!colorMap2.has(regionData.code)) {
17610
+ colorMap2.set(regionData.code, getRegionColor(regionData.code));
17611
+ }
17612
+ });
17613
+ return colorMap2;
17614
+ }, [regionCoordinates, mapState.regionGroups, getRegionColor]);
17615
+ const handleRegionClick = (code) => {
17616
+ onRegionToggle?.(code);
17617
+ };
17618
+ const hoveredRegionData = React12.useMemo(() => {
17619
+ if (!mapState.hoveredRegion) return null;
17620
+ return mapState.regionGroups.find(
17621
+ (regionData) => regionData.code === mapState.hoveredRegion
17622
+ ) ?? null;
17623
+ }, [mapState.hoveredRegion, mapState.regionGroups]);
17624
+ const counterText = React12.useMemo(() => {
17625
+ if (!formatCounter) return null;
17626
+ const hasActiveFilter = isRegionActive && mapState.regionGroups.some(
17627
+ (regionData) => isRegionActive(regionData.code)
17628
+ );
17629
+ if (hasActiveFilter) {
17630
+ const activeRegions = mapState.regionGroups.filter(
17631
+ (regionData) => isRegionActive(regionData.code)
17632
+ );
17633
+ const activeItemCount = activeRegions.reduce(
17634
+ (sum, regionData) => sum + regionData.items.length,
17635
+ 0
17636
+ );
17637
+ return formatCounter(items.length, mapState.regionGroups.length, activeItemCount, activeRegions.length);
17638
+ }
17639
+ return formatCounter(items.length, mapState.regionGroups.length);
17640
+ }, [formatCounter, isRegionActive, mapState.regionGroups, items.length]);
17641
+ return /* @__PURE__ */ jsxRuntime.jsx(
18278
17642
  "div",
18279
17643
  {
18280
- className: `inline-flex items-center gap-1.5 rounded-full px-2.5 py-0.5 font-semibold transition-colors ${isActive ? activeBadge : isDone ? "bg-emerald-500/10 text-emerald-600 dark:text-emerald-300" : "bg-white/5 text-gray-500 dark:text-gray-500"}`,
18281
- children: [
18282
- isDone ? /* @__PURE__ */ jsxRuntime.jsx(HeroIcons.CheckCircleIcon, { className: "h-3.5 w-3.5" }) : isActive ? /* @__PURE__ */ jsxRuntime.jsx(HeroIcons.BoltIcon, { className: "h-3.5 w-3.5 animate-pulse" }) : /* @__PURE__ */ jsxRuntime.jsx("span", { className: "h-1.5 w-1.5 rounded-full bg-current" }),
18283
- label
18284
- ]
17644
+ ref,
17645
+ className: `space-y-4 h-full ${className ?? ""}`,
17646
+ "data-testid": "interactive-geo-map-container",
17647
+ children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative h-full", children: [
17648
+ /* @__PURE__ */ jsxRuntime.jsx(
17649
+ GeoMapCanvas,
17650
+ {
17651
+ regionGroups: mapState.regionGroups,
17652
+ regionColorMap,
17653
+ animatedRegions: mapState.animatedRegions,
17654
+ zoom: mapState.zoom,
17655
+ panOffset: mapState.panOffset,
17656
+ hoveredRegion: mapState.hoveredRegion,
17657
+ onPan: mapState.handlePan,
17658
+ onRegionHover: mapState.setHoveredRegion,
17659
+ onRegionClick: handleRegionClick,
17660
+ isRegionActive,
17661
+ getMarkerSize: mapState.getMarkerSize,
17662
+ getFontSize: mapState.getFontSize,
17663
+ geoJsonUrl,
17664
+ regionPropertyKey,
17665
+ projectionType,
17666
+ ariaLabel
17667
+ }
17668
+ ),
17669
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute top-3 right-3 z-10", children: /* @__PURE__ */ jsxRuntime.jsx(
17670
+ MapZoomControls,
17671
+ {
17672
+ zoom: mapState.zoom,
17673
+ minZoom: mapState.MIN_ZOOM,
17674
+ maxZoom: mapState.MAX_ZOOM,
17675
+ onZoomIn: mapState.handleZoomIn,
17676
+ onZoomOut: mapState.handleZoomOut,
17677
+ labels: zoomLabels
17678
+ }
17679
+ ) }),
17680
+ mapState.hoveredRegion && hoveredRegionData && renderHoverContent && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute top-3 left-3 z-10 pointer-events-none", children: renderHoverContent(mapState.hoveredRegion, hoveredRegionData.items) }),
17681
+ counterText && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute bottom-3 left-3 z-10 pointer-events-none", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "liquid-surface rounded-lg px-3 py-1.5", children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs font-medium text-gray-600 dark:text-gray-300", children: counterText }) }) })
17682
+ ] })
18285
17683
  }
18286
17684
  );
18287
17685
  }
18288
- function InputStage3({
18289
- userPrompt,
18290
- assistantMessage,
18291
- phase,
18292
- assistantComplete,
18293
- department,
18294
- assistantAvatar,
18295
- assistantName,
18296
- agents,
18297
- agentAvatars,
18298
- avatarGradient,
18299
- cursorClass,
18300
- conversationLabel,
18301
- personaTagFn,
18302
- composerHint,
18303
- composerEnter
18304
- }) {
18305
- const cursor = /* @__PURE__ */ jsxRuntime.jsx("span", { className: `ml-0.5 inline-block w-[2px] h-4 align-middle ${cursorClass} animate-pulse` });
18306
- const showAssistant = phase === "assistant";
18307
- const personaName = assistantName ?? department;
18308
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex h-full flex-col px-4 py-6 sm:px-8", children: [
18309
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mb-5 flex items-center justify-center gap-2 text-[10px] font-semibold uppercase tracking-wider text-gray-400 dark:text-gray-500", children: [
18310
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "h-1 w-1 rounded-full bg-emerald-500 animate-pulse" }),
18311
- conversationLabel(personaName, department)
18312
- ] }),
18313
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mx-auto flex w-full max-w-3xl flex-1 flex-col justify-end gap-4 overflow-hidden", children: [
18314
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-end", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "liquid-surface max-w-[88%] rounded-2xl rounded-tr-md px-5 py-3.5", children: /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-base leading-relaxed text-gray-900 dark:text-white", children: [
18315
- userPrompt,
18316
- phase === "user" && cursor
18317
- ] }) }) }),
18318
- showAssistant && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-end gap-2.5", children: [
18319
- assistantAvatar ? /* @__PURE__ */ jsxRuntime.jsx(
18320
- "img",
18321
- {
18322
- src: assistantAvatar,
18323
- alt: personaName,
18324
- className: `h-11 w-11 shrink-0 rounded-2xl bg-white/40 dark:bg-white/[0.06] ring-2 ring-white/30 dark:ring-white/10 shadow-md`
18325
- }
18326
- ) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: `flex h-11 w-11 shrink-0 items-center justify-center rounded-2xl bg-gradient-to-br ${avatarGradient} shadow-md`, children: /* @__PURE__ */ jsxRuntime.jsx(HeroIcons.SparklesIcon, { className: "h-5 w-5 text-white" }) }),
18327
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "liquid-surface max-w-[88%] rounded-2xl rounded-bl-md px-5 py-3.5", children: [
18328
- assistantMessage.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mb-1 text-[10px] font-bold uppercase tracking-wider text-gray-500 dark:text-gray-400", children: personaTagFn(personaName) }),
18329
- assistantMessage.length === 0 ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1 py-1", children: [
18330
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: `h-1.5 w-1.5 rounded-full ${cursorClass} animate-pulse` }),
18331
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: `h-1.5 w-1.5 rounded-full ${cursorClass} animate-pulse`, style: { animationDelay: "150ms" } }),
18332
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: `h-1.5 w-1.5 rounded-full ${cursorClass} animate-pulse`, style: { animationDelay: "300ms" } })
18333
- ] }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
18334
- /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-base leading-relaxed text-gray-900 dark:text-white", children: [
18335
- assistantMessage,
18336
- !assistantComplete && cursor
18337
- ] }),
18338
- assistantComplete && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-3 flex flex-wrap gap-2", children: agents.map((agent) => {
18339
- const avatar = agentAvatars?.[agent];
17686
+ var InteractiveGeoMap = React12__namespace.default.forwardRef(InteractiveGeoMapInner);
17687
+ var DEFAULT_LEGEND_COLOR = "#6366f1";
17688
+ var GeoMapLegend = React12__namespace.default.forwardRef(
17689
+ ({ items, colorMap: colorMap2, getFlagUrl, getLabel, labels, maxItems = 5 }, ref) => {
17690
+ return /* @__PURE__ */ jsxRuntime.jsxs(
17691
+ "div",
17692
+ {
17693
+ ref,
17694
+ className: "liquid-surface rounded-lg p-3",
17695
+ "data-testid": "map-legend",
17696
+ children: [
17697
+ /* @__PURE__ */ jsxRuntime.jsx("h4", { className: "text-xs font-semibold text-gray-700 dark:text-gray-300 mb-2", children: labels.title }),
17698
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1.5", children: [
17699
+ items.slice(0, maxItems).map((item) => {
17700
+ const flagUrl = getFlagUrl?.(item.code);
17701
+ const regionColor = colorMap2.get(item.code) ?? DEFAULT_LEGEND_COLOR;
17702
+ const displayLabel = getLabel?.(item.code) ?? item.code;
18340
17703
  return /* @__PURE__ */ jsxRuntime.jsxs(
18341
- "span",
17704
+ "div",
18342
17705
  {
18343
- className: "inline-flex items-center gap-1.5 rounded-full bg-white/40 dark:bg-white/[0.08] py-0.5 pl-0.5 pr-3 text-[11px] font-semibold text-gray-700 dark:text-gray-200 shadow-sm",
17706
+ className: "flex items-center gap-2",
17707
+ "data-testid": `legend-item-${item.code}`,
18344
17708
  children: [
18345
- avatar ? /* @__PURE__ */ jsxRuntime.jsx("img", { src: avatar, alt: "", className: "h-6 w-6 rounded-full bg-white/40 dark:bg-white/[0.06]" }) : /* @__PURE__ */ jsxRuntime.jsx("span", { className: `flex h-6 w-6 items-center justify-center rounded-full bg-gradient-to-br ${avatarGradient}`, children: /* @__PURE__ */ jsxRuntime.jsx(HeroIcons.BoltIcon, { className: "h-3 w-3 text-white" }) }),
18346
- agent
17709
+ flagUrl ? (
17710
+ // eslint-disable-next-line @next/next/no-img-element
17711
+ /* @__PURE__ */ jsxRuntime.jsx(
17712
+ "img",
17713
+ {
17714
+ src: flagUrl,
17715
+ alt: item.code,
17716
+ className: "w-4 h-4 shadow-sm"
17717
+ }
17718
+ )
17719
+ ) : /* @__PURE__ */ jsxRuntime.jsx(
17720
+ "div",
17721
+ {
17722
+ className: "w-4 h-4 rounded-full",
17723
+ style: { backgroundColor: regionColor },
17724
+ "data-testid": `legend-color-${item.code}`
17725
+ }
17726
+ ),
17727
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-xs text-gray-600 dark:text-gray-400", children: [
17728
+ displayLabel,
17729
+ " (",
17730
+ item.count,
17731
+ ")"
17732
+ ] })
18347
17733
  ]
18348
17734
  },
18349
- agent
17735
+ item.code
18350
17736
  );
18351
- }) })
17737
+ }),
17738
+ items.length > maxItems && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-xs text-gray-500 dark:text-gray-400 italic pt-1", children: [
17739
+ "+",
17740
+ items.length - maxItems,
17741
+ " ",
17742
+ labels.more
17743
+ ] })
18352
17744
  ] })
18353
- ] })
18354
- ] })
18355
- ] }),
18356
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mx-auto mt-5 w-full max-w-3xl", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "liquid-surface flex items-center gap-3 rounded-full px-4 py-2.5 opacity-60", children: [
18357
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-xs italic text-gray-500 dark:text-gray-400", children: composerHint }),
18358
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "ml-auto flex items-center gap-1 text-[10px] text-gray-400 dark:text-gray-500", children: composerEnter })
18359
- ] }) })
18360
- ] });
18361
- }
18362
- var koriDepartmentFlows = [
18363
- {
18364
- id: "sales",
18365
- name: "Vendas",
18366
- icon: HeroIcons.ShoppingCartIcon,
18367
- accent: "from-blue-500 to-indigo-500",
18368
- prompt: "Qualificar lead empresa XPTO e preparar proposta comercial",
18369
- agents: ["Sales", "CRM", "Scoring", "Proposal"],
18370
- workflow: salesWorkflow,
18371
- dashboard: /* @__PURE__ */ jsxRuntime.jsx(SalesDemo, {})
18372
- },
18373
- {
18374
- id: "financial",
18375
- name: "Financeiro",
18376
- icon: HeroIcons.BanknotesIcon,
18377
- accent: "from-emerald-500 to-teal-500",
18378
- prompt: "Gerar relat\xF3rio financeiro e calcular impostos do trimestre",
18379
- agents: ["Finance", "Tax", "Reports", "Compliance"],
18380
- workflow: financialWorkflow,
18381
- dashboard: /* @__PURE__ */ jsxRuntime.jsx(FinancialDemo, {})
18382
- },
17745
+ ]
17746
+ }
17747
+ );
17748
+ }
17749
+ );
17750
+ GeoMapLegend.displayName = "GeoMapLegend";
17751
+
17752
+ // src/lib/themes/brazil.ts
17753
+ var BRAZIL_STATE_PALETTES = {
17754
+ AC: { primary: "#009b43", secondary: "#ffcf44", text: "light" },
17755
+ AL: { primary: "#d9251d", secondary: "#01a2ce", text: "light" },
17756
+ AM: { primary: "#213572", secondary: "#d9251d", text: "light" },
17757
+ AP: { primary: "#213572", secondary: "#009b43", text: "light" },
17758
+ BA: { primary: "#213572", secondary: "#d9251d", text: "light" },
17759
+ CE: { primary: "#009b43", secondary: "#ffcf44", text: "light" },
17760
+ DF: { primary: "#009b43", secondary: "#ffcf44", text: "light" },
17761
+ ES: { primary: "#ea5a8d", secondary: "#01a2ce", text: "light" },
17762
+ GO: { primary: "#009b43", secondary: "#213572", text: "light" },
17763
+ MA: { primary: "#213572", secondary: "#d9251d", text: "light" },
17764
+ MG: { primary: "#d9251d", secondary: "#f0f0f0", text: "light" },
17765
+ MS: { primary: "#009b43", secondary: "#01a2ce", text: "light" },
17766
+ MT: { primary: "#213572", secondary: "#009b43", text: "light" },
17767
+ PA: { primary: "#d9251d", secondary: "#213572", text: "light" },
17768
+ PB: { primary: "#d9251d", secondary: "#1d1d1b", text: "light" },
17769
+ PE: { primary: "#213572", secondary: "#ffcf44", text: "light" },
17770
+ PI: { primary: "#009b43", secondary: "#ffcf44", text: "light" },
17771
+ PR: { primary: "#009b43", secondary: "#213572", text: "light" },
17772
+ RJ: { primary: "#01a2ce", secondary: "#009b43", text: "light" },
17773
+ RN: { primary: "#009b43", secondary: "#01a2ce", text: "light" },
17774
+ RO: { primary: "#213572", secondary: "#009b43", text: "light" },
17775
+ RR: { primary: "#009b43", secondary: "#01a2ce", text: "light" },
17776
+ RS: { primary: "#009b43", secondary: "#d9251d", text: "light" },
17777
+ SC: { primary: "#d9251d", secondary: "#a6ce39", text: "light" },
17778
+ SE: { primary: "#009b43", secondary: "#213572", text: "light" },
17779
+ SP: { primary: "#1d1d1b", secondary: "#d9251d", text: "light" },
17780
+ TO: { primary: "#ef9926", secondary: "#213572", text: "dark" }
17781
+ };
17782
+ var BRAZIL_ACCENT_MAP = {
17783
+ AC: "green",
17784
+ AL: "red",
17785
+ AM: "blue",
17786
+ AP: "blue",
17787
+ BA: "blue",
17788
+ CE: "green",
17789
+ DF: "green",
17790
+ ES: "pink",
17791
+ GO: "green",
17792
+ MA: "blue",
17793
+ MG: "red",
17794
+ MS: "green",
17795
+ MT: "blue",
17796
+ PA: "red",
17797
+ PB: "red",
17798
+ PE: "blue",
17799
+ PI: "green",
17800
+ PR: "green",
17801
+ RJ: "blue",
17802
+ RN: "green",
17803
+ RO: "blue",
17804
+ RR: "green",
17805
+ RS: "green",
17806
+ SC: "red",
17807
+ SE: "green",
17808
+ SP: "black",
17809
+ TO: "yellow"
17810
+ };
17811
+ var VALID_UFS = Object.keys(BRAZIL_STATE_PALETTES);
17812
+ var BR_THEME_CONFIG = {
17813
+ palettes: BRAZIL_STATE_PALETTES,
17814
+ accents: BRAZIL_ACCENT_MAP,
17815
+ flagUrlTemplate: (code) => VALID_UFS.includes(code) ? `/flags/${code}.svg` : null
17816
+ };
17817
+ var BRAZIL_STATE_COORDINATES = {
17818
+ AC: [-70, -9],
17819
+ AL: [-36.6, -9.5],
17820
+ AM: [-64, -4],
17821
+ AP: [-51, 1],
17822
+ BA: [-41.5, -12.5],
17823
+ CE: [-39, -5],
17824
+ DF: [-47.9, -15.8],
17825
+ ES: [-40.3, -19.5],
17826
+ GO: [-49.5, -16],
17827
+ MA: [-45, -5],
17828
+ MG: [-44.5, -18.5],
17829
+ MS: [-55, -21],
17830
+ MT: [-56, -13],
17831
+ PA: [-52, -4],
17832
+ PB: [-36.8, -7.1],
17833
+ PE: [-37.5, -8.3],
17834
+ PI: [-43, -7.5],
17835
+ PR: [-51.5, -25],
17836
+ RJ: [-43.2, -22.5],
17837
+ RN: [-36.5, -5.8],
17838
+ RO: [-63, -11],
17839
+ RR: [-61, 2],
17840
+ RS: [-53, -30],
17841
+ SC: [-49.5, -27.5],
17842
+ SE: [-37, -10.5],
17843
+ SP: [-48.5, -22.5],
17844
+ TO: [-48, -10]
17845
+ };
17846
+ var BRAZIL_MAP_CENTER = [-54, -15];
17847
+ var BRAZIL_MACRO_REGIONS = [
18383
17848
  {
18384
- id: "marketing",
18385
- name: "Marketing",
18386
- icon: HeroIcons.MegaphoneIcon,
18387
- accent: "from-pink-500 to-rose-500",
18388
- prompt: "Criar campanha de Black Friday para e-commerce",
18389
- agents: ["Marketing", "Design", "E-commerce", "Email"],
18390
- workflow: marketingWorkflow,
18391
- dashboard: /* @__PURE__ */ jsxRuntime.jsx(MarketingDemo, {})
17849
+ key: "sudeste",
17850
+ label: "",
17851
+ codes: ["SP", "RJ", "MG", "ES"],
17852
+ gradient: "from-blue-500/15 to-indigo-500/10 dark:from-blue-500/20 dark:to-indigo-500/15",
17853
+ iconColor: "text-blue-600 dark:text-blue-400"
18392
17854
  },
18393
17855
  {
18394
- id: "inventory",
18395
- name: "Estoque",
18396
- icon: HeroIcons.CubeIcon,
18397
- accent: "from-orange-500 to-amber-500",
18398
- prompt: "Verificar estoque e sugerir reposi\xE7\xF5es autom\xE1ticas",
18399
- agents: ["Inventory", "Supply", "Forecast", "Logistics"],
18400
- workflow: inventoryWorkflow,
18401
- dashboard: /* @__PURE__ */ jsxRuntime.jsx(InventoryDemo, {})
17856
+ key: "sul",
17857
+ label: "",
17858
+ codes: ["PR", "SC", "RS"],
17859
+ gradient: "from-emerald-500/15 to-teal-500/10 dark:from-emerald-500/20 dark:to-teal-500/15",
17860
+ iconColor: "text-emerald-600 dark:text-emerald-400"
18402
17861
  },
18403
17862
  {
18404
- id: "hr",
18405
- name: "RH",
18406
- icon: HeroIcons.UsersIcon,
18407
- accent: "from-green-500 to-emerald-500",
18408
- prompt: "Processar candidaturas para vaga de Desenvolvedor Senior",
18409
- agents: ["HR", "Recruiter", "Skills", "Interview"],
18410
- workflow: hrWorkflow,
18411
- dashboard: /* @__PURE__ */ jsxRuntime.jsx(HRRecruitmentDemo, {})
17863
+ key: "nordeste",
17864
+ label: "",
17865
+ codes: ["BA", "PE", "CE", "MA", "PB", "RN", "AL", "SE", "PI"],
17866
+ gradient: "from-orange-500/15 to-amber-500/10 dark:from-orange-500/20 dark:to-amber-500/15",
17867
+ iconColor: "text-orange-600 dark:text-orange-400"
18412
17868
  },
18413
17869
  {
18414
- id: "analytics",
18415
- name: "Analytics",
18416
- icon: HeroIcons.DocumentTextIcon,
18417
- accent: "from-indigo-500 to-violet-500",
18418
- prompt: "Analisar comportamento dos clientes e identificar oportunidades",
18419
- agents: ["Analytics", "CRM", "Insights", "Reports"],
18420
- workflow: customerAnalyticsWorkflow,
18421
- dashboard: /* @__PURE__ */ jsxRuntime.jsx(CustomerAnalyticsDemo, {})
17870
+ key: "centroOeste",
17871
+ label: "",
17872
+ codes: ["GO", "MT", "MS", "DF"],
17873
+ gradient: "from-purple-500/15 to-fuchsia-500/10 dark:from-purple-500/20 dark:to-fuchsia-500/15",
17874
+ iconColor: "text-purple-600 dark:text-purple-400"
18422
17875
  },
18423
17876
  {
18424
- id: "lgpd",
18425
- name: "LGPD",
18426
- icon: HeroIcons.ShieldCheckIcon,
18427
- accent: "from-red-500 to-rose-500",
18428
- prompt: "Auditar dados pessoais e verificar conformidade LGPD",
18429
- agents: ["LGPD", "Privacy", "Audit", "Security"],
18430
- workflow: lgpdWorkflow,
18431
- dashboard: /* @__PURE__ */ jsxRuntime.jsx(LGPDComplianceDemo, {})
17877
+ key: "norte",
17878
+ label: "",
17879
+ codes: ["PA", "AM", "RO", "TO", "AC", "AP", "RR"],
17880
+ gradient: "from-cyan-500/15 to-sky-500/10 dark:from-cyan-500/20 dark:to-sky-500/15",
17881
+ iconColor: "text-cyan-600 dark:text-cyan-400"
18432
17882
  }
18433
17883
  ];
17884
+ var getBrazilFlagUrl = (uf) => getSubdivisionFlagUrl("BR", uf);
17885
+ var getBrazilHexColor = (uf) => getSubdivisionHexColor("BR", uf);
17886
+ var getBrazilPalette = (uf) => getSubdivisionPalette("BR", uf);
17887
+ var getBrazilGradient = (uf, direction) => getSubdivisionGradient("BR", uf, direction);
17888
+ var getBrazilColors = (uf) => getSubdivisionColors("BR", uf);
17889
+ var getBrazilAccent = (uf) => getSubdivisionAccent("BR", uf);
17890
+ var isValidBrazilState = (uf) => isValidSubdivision("BR", uf);
18434
17891
  function EntityDrawer({
18435
17892
  open,
18436
17893
  onClose,
@@ -25768,7 +25225,6 @@ exports.FRANCE_MAP_CENTER = FRANCE_MAP_CENTER;
25768
25225
  exports.FRANCE_REGION_COORDINATES = FRANCE_REGION_COORDINATES;
25769
25226
  exports.FRANCE_REGION_PALETTES = FRANCE_REGION_PALETTES;
25770
25227
  exports.FR_THEME_CONFIG = FR_THEME_CONFIG;
25771
- exports.FUEL_PRICE_LOADER = FUEL_PRICE_LOADER;
25772
25228
  exports.FavoriteSwipeAction = FavoriteSwipeAction;
25773
25229
  exports.FeatureCard = FeatureCard;
25774
25230
  exports.FeedItemCard = FeedItemCard;
@@ -25797,7 +25253,6 @@ exports.FormSection = FormSection;
25797
25253
  exports.FormSelect = FormSelect;
25798
25254
  exports.FormTextarea = FormTextarea;
25799
25255
  exports.FormToggle = FormToggle;
25800
- exports.FuelPipelineDemo = FuelPipelineDemo;
25801
25256
  exports.GB_THEME_CONFIG = GB_THEME_CONFIG;
25802
25257
  exports.GERMANY_ACCENT_MAP = GERMANY_ACCENT_MAP;
25803
25258
  exports.GERMANY_MACRO_REGIONS = GERMANY_MACRO_REGIONS;
@@ -26365,5 +25820,5 @@ exports.usePullToRefresh = usePullToRefresh;
26365
25820
  exports.validateDashboardSpec = validateDashboardSpec;
26366
25821
  exports.xScale = xScale;
26367
25822
  exports.yScale = yScale;
26368
- //# sourceMappingURL=chunk-ZKUYNCAG.js.map
26369
- //# sourceMappingURL=chunk-ZKUYNCAG.js.map
25823
+ //# sourceMappingURL=chunk-I2NZGVBG.js.map
25824
+ //# sourceMappingURL=chunk-I2NZGVBG.js.map