doru 1.0.0 → 1.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.
package/dist/ui/app.js CHANGED
@@ -23406,8 +23406,8 @@ var init_formatting = __esm({
23406
23406
  };
23407
23407
  METHOD_COLORS = {
23408
23408
  GET: "#2563eb",
23409
- POST: "#16a34a",
23410
- PUT: "#d97706",
23409
+ POST: "#15803d",
23410
+ PUT: "#b45309",
23411
23411
  DELETE: "#dc2626",
23412
23412
  PATCH: "#9333ea",
23413
23413
  HEAD: "#525252",
@@ -23625,7 +23625,7 @@ var init_EmptyState2 = __esm({
23625
23625
  });
23626
23626
 
23627
23627
  // src/ui/react/components/AnalyticsDashboard/AnalyticsDashboard.tsx
23628
- var import_react3, import_jsx_runtime3, computeAnalytics, StatCardBase, StatCard, BreakdownBarBase, BreakdownBar, STATUS_COLORS, METHOD_COLORS2, AnalyticsDashboardBase, AnalyticsDashboard;
23628
+ var import_react3, import_jsx_runtime3, computeAnalytics, StatCardBase, StatCard, BreakdownBarBase, BreakdownBar, STATUS_COLORS, AnalyticsDashboardBase, AnalyticsDashboard;
23629
23629
  var init_AnalyticsDashboard = __esm({
23630
23630
  "src/ui/react/components/AnalyticsDashboard/AnalyticsDashboard.tsx"() {
23631
23631
  import_react3 = __toESM(require_react());
@@ -23703,7 +23703,7 @@ var init_AnalyticsDashboard = __esm({
23703
23703
  className: "breakdown-segment",
23704
23704
  style: {
23705
23705
  width: `${count / total * 100}%`,
23706
- backgroundColor: colorMap[key] || "#6b7280"
23706
+ backgroundColor: colorMap[key] || "var(--color-muted)"
23707
23707
  },
23708
23708
  title: `${key}: ${count} (${(count / total * 100).toFixed(1)}%)`,
23709
23709
  "aria-label": `${key}: ${count} (${(count / total * 100).toFixed(1)}%)`
@@ -23714,23 +23714,19 @@ var init_AnalyticsDashboard = __esm({
23714
23714
  BreakdownBar = (0, import_react3.memo)(BreakdownBarBase);
23715
23715
  BreakdownBar.displayName = "BreakdownBar";
23716
23716
  STATUS_COLORS = {
23717
- "2xx": "#22c55e",
23718
- "3xx": "#3b82f6",
23719
- "4xx": "#f59e0b",
23720
- "5xx": "#ef4444",
23721
- Error: "#ef4444",
23722
- Pending: "#6b7280"
23723
- };
23724
- METHOD_COLORS2 = {
23725
- GET: "#22c55e",
23726
- POST: "#3b82f6",
23727
- PUT: "#f59e0b",
23728
- DELETE: "#ef4444",
23729
- PATCH: "#8b5cf6",
23730
- HEAD: "#6b7280"
23717
+ "2xx": "var(--color-success)",
23718
+ "3xx": "var(--color-redirect)",
23719
+ "4xx": "var(--color-warning)",
23720
+ "5xx": "var(--color-error)",
23721
+ Error: "var(--color-error)",
23722
+ Pending: "var(--color-muted)"
23731
23723
  };
23732
23724
  AnalyticsDashboardBase = ({ items, onSelect }) => {
23733
23725
  const analytics = (0, import_react3.useMemo)(() => computeAnalytics(items), [items]);
23726
+ const methodColorMap = (0, import_react3.useMemo)(
23727
+ () => Object.fromEntries(Object.keys(analytics.methodBreakdown).map((m) => [m, methodHue(m)])),
23728
+ [analytics.methodBreakdown]
23729
+ );
23734
23730
  if (items.length === 0) {
23735
23731
  return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "analytics-dashboard", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
23736
23732
  EmptyState,
@@ -23759,7 +23755,7 @@ var init_AnalyticsDashboard = __esm({
23759
23755
  /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("h3", { children: "Status Breakdown" }),
23760
23756
  /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(BreakdownBar, { data: analytics.statusBreakdown, colorMap: STATUS_COLORS }),
23761
23757
  /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "breakdown-legend", children: Object.entries(analytics.statusBreakdown).map(([key, count]) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "legend-item", children: [
23762
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "legend-dot", style: { backgroundColor: STATUS_COLORS[key] || "#6b7280" } }),
23758
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "legend-dot", style: { backgroundColor: STATUS_COLORS[key] || "var(--color-muted)" } }),
23763
23759
  /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("span", { children: [
23764
23760
  key,
23765
23761
  ": ",
@@ -23769,9 +23765,9 @@ var init_AnalyticsDashboard = __esm({
23769
23765
  ] }),
23770
23766
  /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "analytics-section", children: [
23771
23767
  /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("h3", { children: "Method Breakdown" }),
23772
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(BreakdownBar, { data: analytics.methodBreakdown, colorMap: METHOD_COLORS2 }),
23768
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(BreakdownBar, { data: analytics.methodBreakdown, colorMap: methodColorMap }),
23773
23769
  /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "breakdown-legend", children: Object.entries(analytics.methodBreakdown).map(([key, count]) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "legend-item", children: [
23774
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "legend-dot", style: { backgroundColor: METHOD_COLORS2[key] || "#6b7280" } }),
23770
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "legend-dot", style: { backgroundColor: methodHue(key) } }),
23775
23771
  /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("span", { children: [
23776
23772
  key,
23777
23773
  ": ",
@@ -23931,6 +23927,31 @@ var init_generateCurl = __esm({
23931
23927
  }
23932
23928
  });
23933
23929
 
23930
+ // src/ui/react/hooks/useCopyFeedback.ts
23931
+ var import_react5, useCopyFeedback;
23932
+ var init_useCopyFeedback = __esm({
23933
+ "src/ui/react/hooks/useCopyFeedback.ts"() {
23934
+ import_react5 = __toESM(require_react());
23935
+ init_generateCurl();
23936
+ useCopyFeedback = (resetMs = 2e3) => {
23937
+ const [status, setStatus] = (0, import_react5.useState)("idle");
23938
+ const timer = (0, import_react5.useRef)(void 0);
23939
+ (0, import_react5.useEffect)(() => () => clearTimeout(timer.current), []);
23940
+ const copy = (0, import_react5.useCallback)(
23941
+ (text) => {
23942
+ void copyToClipboard(text).then((ok) => {
23943
+ setStatus(ok ? "copied" : "error");
23944
+ clearTimeout(timer.current);
23945
+ timer.current = setTimeout(() => setStatus("idle"), resetMs);
23946
+ });
23947
+ },
23948
+ [resetMs]
23949
+ );
23950
+ return [status, copy];
23951
+ };
23952
+ }
23953
+ });
23954
+
23934
23955
  // src/ui/react/utils/mask.ts
23935
23956
  var SENSITIVE_HEADERS, UUID_PATTERN, JWT_PATTERN, BEARER_PATTERN, BASIC_AUTH_PATTERN, isSensitiveHeader, maskValue, maskHeaderValue, maskUrl, maskJsonValue;
23936
23957
  var init_mask = __esm({
@@ -24060,6 +24081,21 @@ var init_Tabs2 = __esm({
24060
24081
  }
24061
24082
  });
24062
24083
 
24084
+ // src/ui/react/hooks/usePortalTarget.ts
24085
+ var import_react6, usePortalTarget;
24086
+ var init_usePortalTarget = __esm({
24087
+ "src/ui/react/hooks/usePortalTarget.ts"() {
24088
+ import_react6 = __toESM(require_react());
24089
+ usePortalTarget = (ref) => {
24090
+ const [target, setTarget] = (0, import_react6.useState)(null);
24091
+ (0, import_react6.useEffect)(() => {
24092
+ setTarget(ref?.current ?? null);
24093
+ }, [ref]);
24094
+ return target;
24095
+ };
24096
+ }
24097
+ });
24098
+
24063
24099
  // src/ui/react/utils/download.ts
24064
24100
  var b64toBlob, suggestFilename, downloadBlob;
24065
24101
  var init_download = __esm({
@@ -24089,24 +24125,25 @@ var init_download = __esm({
24089
24125
  });
24090
24126
 
24091
24127
  // src/ui/react/components/BodyRenderer/components/BinaryRenderer/BinaryRenderer.tsx
24092
- var import_react5, import_react_dom, import_jsx_runtime5, BinaryRenderer;
24128
+ var import_react7, import_react_dom, import_jsx_runtime5, BinaryRenderer;
24093
24129
  var init_BinaryRenderer = __esm({
24094
24130
  "src/ui/react/components/BodyRenderer/components/BinaryRenderer/BinaryRenderer.tsx"() {
24095
- import_react5 = __toESM(require_react());
24131
+ import_react7 = __toESM(require_react());
24096
24132
  import_react_dom = __toESM(require_react_dom());
24133
+ init_usePortalTarget();
24097
24134
  init_content();
24098
24135
  init_download();
24099
24136
  import_jsx_runtime5 = __toESM(require_jsx_runtime());
24100
24137
  BinaryRenderer = ({ bin, contentType, label, controlsRef }) => {
24101
- const mime = (0, import_react5.useMemo)(
24138
+ const mime = (0, import_react7.useMemo)(
24102
24139
  () => typeof contentType === "string" ? contentType.split(";")[0].trim() : "application/octet-stream",
24103
24140
  [contentType]
24104
24141
  );
24105
- const portalTarget = controlsRef?.current;
24142
+ const portalTarget = usePortalTarget(controlsRef);
24106
24143
  const isImage = isImageType(contentType);
24107
- const blob = (0, import_react5.useMemo)(() => b64toBlob(bin.data, mime), [bin.data, mime]);
24108
- const [objectUrl, setObjectUrl] = (0, import_react5.useState)(null);
24109
- (0, import_react5.useEffect)(() => {
24144
+ const blob = (0, import_react7.useMemo)(() => b64toBlob(bin.data, mime), [bin.data, mime]);
24145
+ const [objectUrl, setObjectUrl] = (0, import_react7.useState)(null);
24146
+ (0, import_react7.useEffect)(() => {
24110
24147
  if (!isImage) return;
24111
24148
  const url = URL.createObjectURL(blob);
24112
24149
  setObjectUrl(url);
@@ -24114,14 +24151,14 @@ var init_BinaryRenderer = __esm({
24114
24151
  URL.revokeObjectURL(url);
24115
24152
  };
24116
24153
  }, [blob, isImage]);
24117
- const handleDownload = (0, import_react5.useCallback)(() => {
24154
+ const handleDownload = (0, import_react7.useCallback)(() => {
24118
24155
  downloadBlob(blob, suggestFilename(label, contentType));
24119
24156
  }, [blob, label, contentType]);
24120
24157
  const controls = /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "controls", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("button", { className: "btn", title: "Save body to file", onClick: handleDownload, children: "Download" }) });
24121
24158
  if (isImage && objectUrl) {
24122
24159
  return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
24123
24160
  /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "img-preview", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("img", { src: objectUrl, alt: `${label} image` }) }),
24124
- portalTarget ? (0, import_react_dom.createPortal)(controls, portalTarget) : controls
24161
+ controlsRef ? portalTarget && (0, import_react_dom.createPortal)(controls, portalTarget) : controls
24125
24162
  ] });
24126
24163
  }
24127
24164
  return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
@@ -24130,7 +24167,7 @@ var init_BinaryRenderer = __esm({
24130
24167
  mime,
24131
24168
  ")"
24132
24169
  ] }),
24133
- portalTarget ? (0, import_react_dom.createPortal)(controls, portalTarget) : controls
24170
+ controlsRef ? portalTarget && (0, import_react_dom.createPortal)(controls, portalTarget) : controls
24134
24171
  ] });
24135
24172
  };
24136
24173
  }
@@ -26507,10 +26544,10 @@ var require_main = __commonJS({
26507
26544
  });
26508
26545
 
26509
26546
  // src/ui/react/hooks/useTheme.ts
26510
- var import_react6, getTheme, subscribeTheme, useTheme;
26547
+ var import_react8, getTheme, subscribeTheme, useTheme;
26511
26548
  var init_useTheme = __esm({
26512
26549
  "src/ui/react/hooks/useTheme.ts"() {
26513
- import_react6 = __toESM(require_react());
26550
+ import_react8 = __toESM(require_react());
26514
26551
  getTheme = () => document.documentElement.dataset.theme || "dark";
26515
26552
  subscribeTheme = (cb) => {
26516
26553
  const observer = new MutationObserver(cb);
@@ -26520,15 +26557,15 @@ var init_useTheme = __esm({
26520
26557
  });
26521
26558
  return () => observer.disconnect();
26522
26559
  };
26523
- useTheme = () => (0, import_react6.useSyncExternalStore)(subscribeTheme, getTheme, () => "dark");
26560
+ useTheme = () => (0, import_react8.useSyncExternalStore)(subscribeTheme, getTheme, () => "dark");
26524
26561
  }
26525
26562
  });
26526
26563
 
26527
26564
  // src/ui/react/components/BodyRenderer/components/JsonRenderer/JsonRenderer.tsx
26528
- var import_react7, import_react_json_view, import_jsx_runtime8, JsonRenderer;
26565
+ var import_react9, import_react_json_view, import_jsx_runtime8, JsonRenderer;
26529
26566
  var init_JsonRenderer = __esm({
26530
26567
  "src/ui/react/components/BodyRenderer/components/JsonRenderer/JsonRenderer.tsx"() {
26531
- import_react7 = __toESM(require_react());
26568
+ import_react9 = __toESM(require_react());
26532
26569
  import_react_json_view = __toESM(require_main());
26533
26570
  init_useMask();
26534
26571
  init_useTheme();
@@ -26537,7 +26574,7 @@ var init_JsonRenderer = __esm({
26537
26574
  JsonRenderer = ({ text }) => {
26538
26575
  const appTheme = useTheme();
26539
26576
  const { isMasked } = useMask();
26540
- const parsed = (0, import_react7.useMemo)(() => {
26577
+ const parsed = (0, import_react9.useMemo)(() => {
26541
26578
  try {
26542
26579
  const data = JSON.parse(text);
26543
26580
  return { ok: true, data: isMasked ? maskJsonValue(data) : data };
@@ -26556,7 +26593,7 @@ var init_JsonRenderer = __esm({
26556
26593
  displayObjectSize: false,
26557
26594
  quotesOnKeys: false,
26558
26595
  theme: appTheme === "light" ? "rjv-default" : "monokai",
26559
- style: { background: "transparent" },
26596
+ style: { background: "transparent", fontSize: "11px" },
26560
26597
  enableClipboard: true
26561
26598
  }
26562
26599
  ) });
@@ -26592,17 +26629,17 @@ var init_highlight = __esm({
26592
26629
  });
26593
26630
 
26594
26631
  // src/ui/react/components/BodyRenderer/components/XmlRenderer/XmlRenderer.tsx
26595
- var import_react8, import_jsx_runtime9, XmlRenderer;
26632
+ var import_react10, import_jsx_runtime9, XmlRenderer;
26596
26633
  var init_XmlRenderer = __esm({
26597
26634
  "src/ui/react/components/BodyRenderer/components/XmlRenderer/XmlRenderer.tsx"() {
26598
- import_react8 = __toESM(require_react());
26635
+ import_react10 = __toESM(require_react());
26599
26636
  init_useMask();
26600
26637
  init_highlight();
26601
26638
  init_mask();
26602
26639
  import_jsx_runtime9 = __toESM(require_jsx_runtime());
26603
26640
  XmlRenderer = ({ text, mode }) => {
26604
26641
  const { isMasked } = useMask();
26605
- const prettyContent = (0, import_react8.useMemo)(() => {
26642
+ const prettyContent = (0, import_react10.useMemo)(() => {
26606
26643
  if (mode !== "pretty") return null;
26607
26644
  try {
26608
26645
  return prettyXML(text);
@@ -26626,11 +26663,13 @@ var init_XmlRenderer2 = __esm({
26626
26663
  });
26627
26664
 
26628
26665
  // src/ui/react/components/BodyRenderer/BodyRenderer.tsx
26629
- var import_react9, import_react_dom2, import_jsx_runtime10, getInitialMode, getFileExtension, BodyRenderer;
26666
+ var import_react11, import_react_dom2, import_jsx_runtime10, getInitialMode, getFileExtension, BodyRenderer;
26630
26667
  var init_BodyRenderer = __esm({
26631
26668
  "src/ui/react/components/BodyRenderer/BodyRenderer.tsx"() {
26632
- import_react9 = __toESM(require_react());
26669
+ import_react11 = __toESM(require_react());
26633
26670
  import_react_dom2 = __toESM(require_react_dom());
26671
+ init_usePortalTarget();
26672
+ init_useCopyFeedback();
26634
26673
  init_content();
26635
26674
  init_download();
26636
26675
  init_BinaryRenderer2();
@@ -26651,13 +26690,15 @@ var init_BodyRenderer = __esm({
26651
26690
  if (isXMLType(ct2)) return "xml";
26652
26691
  return "txt";
26653
26692
  };
26654
- BodyRenderer = (0, import_react9.memo)(({ label, body, headers, controlsRef }) => {
26693
+ BodyRenderer = (0, import_react11.memo)(({ label, body, headers, controlsRef }) => {
26655
26694
  const ct2 = getHeader(headers, "content-type") || "";
26656
- const [mode, setMode] = (0, import_react9.useState)(getInitialMode(ct2));
26657
- const text = (0, import_react9.useMemo)(() => typeof body === "string" ? String(body) : null, [body]);
26658
- (0, import_react9.useEffect)(() => {
26695
+ const [mode, setMode] = (0, import_react11.useState)(getInitialMode(ct2));
26696
+ const text = (0, import_react11.useMemo)(() => typeof body === "string" ? String(body) : null, [body]);
26697
+ (0, import_react11.useEffect)(() => {
26659
26698
  setMode(getInitialMode(ct2));
26660
26699
  }, [ct2]);
26700
+ const portalTarget = usePortalTarget(controlsRef);
26701
+ const [copyStatus, copy] = useCopyFeedback();
26661
26702
  if (!body) {
26662
26703
  return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "empty", children: [
26663
26704
  "No ",
@@ -26702,11 +26743,12 @@ var init_BodyRenderer = __esm({
26702
26743
  /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
26703
26744
  "button",
26704
26745
  {
26705
- className: "btn",
26746
+ className: `btn${copyStatus === "copied" ? " copied" : copyStatus === "error" ? " error" : ""}`,
26706
26747
  title: "Copy to clipboard",
26707
- onClick: () => navigator.clipboard.writeText(text).catch(() => {
26708
- }),
26709
- children: "Copy"
26748
+ onClick: () => {
26749
+ if (text !== null) copy(text);
26750
+ },
26751
+ children: copyStatus === "copied" ? "Copied" : copyStatus === "error" ? "Failed" : "Copy"
26710
26752
  }
26711
26753
  ),
26712
26754
  /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
@@ -26724,10 +26766,9 @@ var init_BodyRenderer = __esm({
26724
26766
  )
26725
26767
  ] })
26726
26768
  ] });
26727
- const portalTarget = controlsRef?.current;
26728
26769
  return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_jsx_runtime10.Fragment, { children: [
26729
26770
  renderContent(),
26730
- portalTarget ? (0, import_react_dom2.createPortal)(controls, portalTarget) : controls
26771
+ controlsRef ? portalTarget && (0, import_react_dom2.createPortal)(controls, portalTarget) : controls
26731
26772
  ] });
26732
26773
  });
26733
26774
  }
@@ -26741,10 +26782,10 @@ var init_BodyRenderer2 = __esm({
26741
26782
  });
26742
26783
 
26743
26784
  // src/ui/react/components/DetailPanel/components/BodyTab/BodyTab.tsx
26744
- var import_react10, import_jsx_runtime11, getResBodyContent, BodyTab;
26785
+ var import_react12, import_jsx_runtime11, getResBodyContent, BodyTab;
26745
26786
  var init_BodyTab = __esm({
26746
26787
  "src/ui/react/components/DetailPanel/components/BodyTab/BodyTab.tsx"() {
26747
- import_react10 = __toESM(require_react());
26788
+ import_react12 = __toESM(require_react());
26748
26789
  init_react_resizable_panels();
26749
26790
  init_BodyRenderer2();
26750
26791
  import_jsx_runtime11 = __toESM(require_jsx_runtime());
@@ -26758,8 +26799,8 @@ var init_BodyTab = __esm({
26758
26799
  return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "empty", children: "No Response" });
26759
26800
  };
26760
26801
  BodyTab = ({ request: r, response: s, error: e }) => {
26761
- const reqBodyCtrlRef = (0, import_react10.useRef)(null);
26762
- const resBodyCtrlRef = (0, import_react10.useRef)(null);
26802
+ const reqBodyCtrlRef = (0, import_react12.useRef)(null);
26803
+ const resBodyCtrlRef = (0, import_react12.useRef)(null);
26763
26804
  const resBodyContent = getResBodyContent(r, s, e, resBodyCtrlRef);
26764
26805
  return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Gt, { orientation: "horizontal", children: [
26765
26806
  /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(_t, { defaultSize: 50, minSize: 20, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "panel", children: [
@@ -26790,10 +26831,10 @@ var init_BodyTab2 = __esm({
26790
26831
  });
26791
26832
 
26792
26833
  // src/ui/react/components/KVGrid/KVGrid.tsx
26793
- var import_react11, import_jsx_runtime12, toDisplayString, KVGrid;
26834
+ var import_react13, import_jsx_runtime12, toDisplayString, KVGrid;
26794
26835
  var init_KVGrid = __esm({
26795
26836
  "src/ui/react/components/KVGrid/KVGrid.tsx"() {
26796
- import_react11 = __toESM(require_react());
26837
+ import_react13 = __toESM(require_react());
26797
26838
  init_useMask();
26798
26839
  init_mask();
26799
26840
  import_jsx_runtime12 = __toESM(require_jsx_runtime());
@@ -26809,9 +26850,9 @@ var init_KVGrid = __esm({
26809
26850
  }
26810
26851
  return String(v);
26811
26852
  };
26812
- KVGrid = (0, import_react11.memo)(({ data, empty = "No data", isHeaders = false }) => {
26853
+ KVGrid = (0, import_react13.memo)(({ data, empty = "No data", isHeaders = false }) => {
26813
26854
  const { isMasked } = useMask();
26814
- const entries = (0, import_react11.useMemo)(() => Object.entries(data || {}), [data]);
26855
+ const entries = (0, import_react13.useMemo)(() => Object.entries(data || {}), [data]);
26815
26856
  if (entries.length === 0) return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "empty", children: empty });
26816
26857
  return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { children: entries.map(([k2, v]) => {
26817
26858
  const displayValue = toDisplayString(v);
@@ -26879,10 +26920,10 @@ var init_HeadersTab2 = __esm({
26879
26920
  });
26880
26921
 
26881
26922
  // src/ui/react/components/DetailPanel/components/OverviewTab/OverviewTab.tsx
26882
- var import_react12, import_jsx_runtime14, getResBodyContent2, renderResHeaders, OverviewTab;
26923
+ var import_react14, import_jsx_runtime14, getResBodyContent2, renderResHeaders, OverviewTab;
26883
26924
  var init_OverviewTab = __esm({
26884
26925
  "src/ui/react/components/DetailPanel/components/OverviewTab/OverviewTab.tsx"() {
26885
- import_react12 = __toESM(require_react());
26926
+ import_react14 = __toESM(require_react());
26886
26927
  init_react_resizable_panels();
26887
26928
  init_BodyRenderer2();
26888
26929
  init_KVGrid2();
@@ -26917,8 +26958,8 @@ var init_OverviewTab = __esm({
26917
26958
  resGeneral,
26918
26959
  resHeadersRest
26919
26960
  }) => {
26920
- const ovReqBodyCtrlRef = (0, import_react12.useRef)(null);
26921
- const ovResBodyCtrlRef = (0, import_react12.useRef)(null);
26961
+ const ovReqBodyCtrlRef = (0, import_react14.useRef)(null);
26962
+ const ovResBodyCtrlRef = (0, import_react14.useRef)(null);
26922
26963
  const ovResBodyContent = getResBodyContent2(r, s, e, ovResBodyCtrlRef);
26923
26964
  return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(Gt, { orientation: "horizontal", children: [
26924
26965
  /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(_t, { defaultSize: 50, minSize: 20, children: /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(Gt, { orientation: "vertical", children: [
@@ -26976,10 +27017,10 @@ var init_OverviewTab2 = __esm({
26976
27017
  });
26977
27018
 
26978
27019
  // src/ui/react/components/DetailPanel/components/QueryTab/QueryTab.tsx
26979
- var import_react13, import_jsx_runtime15, QueryTab;
27020
+ var import_react15, import_jsx_runtime15, QueryTab;
26980
27021
  var init_QueryTab = __esm({
26981
27022
  "src/ui/react/components/DetailPanel/components/QueryTab/QueryTab.tsx"() {
26982
- import_react13 = __toESM(require_react());
27023
+ import_react15 = __toESM(require_react());
26983
27024
  init_react_resizable_panels();
26984
27025
  init_useMask();
26985
27026
  init_content();
@@ -26988,8 +27029,8 @@ var init_QueryTab = __esm({
26988
27029
  import_jsx_runtime15 = __toESM(require_jsx_runtime());
26989
27030
  QueryTab = ({ request: r }) => {
26990
27031
  const { isMasked } = useMask();
26991
- const queryParams = (0, import_react13.useMemo)(() => r ? parseQuery(r.url || (r.hostname || "") + (r.path || "")) : [], [r]);
26992
- const formFields = (0, import_react13.useMemo)(() => r ? parseForm(r.body, getHeader(r.headers, "content-type")) : [], [r]);
27032
+ const queryParams = (0, import_react15.useMemo)(() => r ? parseQuery(r.url || (r.hostname || "") + (r.path || "")) : [], [r]);
27033
+ const formFields = (0, import_react15.useMemo)(() => r ? parseForm(r.body, getHeader(r.headers, "content-type")) : [], [r]);
26993
27034
  return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(Gt, { orientation: "horizontal", children: [
26994
27035
  /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(_t, { defaultSize: 50, minSize: 20, children: /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "panel", children: [
26995
27036
  /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: "title", children: "Query Params" }),
@@ -27062,13 +27103,14 @@ var init_TimingTab2 = __esm({
27062
27103
  });
27063
27104
 
27064
27105
  // src/ui/react/components/DetailPanel/DetailPanel.tsx
27065
- var import_react14, import_jsx_runtime17, REQ_HEADERS_TO_OMIT, RES_HEADERS_TO_OMIT, DetailPanelBase, DetailPanel;
27106
+ var import_react16, import_jsx_runtime17, REQ_HEADERS_TO_OMIT, RES_HEADERS_TO_OMIT, DetailPanelBase, DetailPanel;
27066
27107
  var init_DetailPanel = __esm({
27067
27108
  "src/ui/react/components/DetailPanel/DetailPanel.tsx"() {
27068
- import_react14 = __toESM(require_react());
27109
+ import_react16 = __toESM(require_react());
27069
27110
  init_useMask();
27070
27111
  init_formatting();
27071
27112
  init_generateCurl();
27113
+ init_useCopyFeedback();
27072
27114
  init_mask();
27073
27115
  init_parsing();
27074
27116
  init_EmptyState2();
@@ -27094,16 +27136,12 @@ var init_DetailPanel = __esm({
27094
27136
  const r = tx?.request;
27095
27137
  const s = tx?.response;
27096
27138
  const e = tx?.error;
27097
- const [copyStatus, setCopyStatus] = (0, import_react14.useState)("idle");
27139
+ const [copyStatus, copyCurl] = useCopyFeedback();
27098
27140
  const { isMasked } = useMask();
27099
- const handleCopyCurl = (0, import_react14.useCallback)(async () => {
27100
- if (!r) return;
27101
- const curl = generateCurl(r);
27102
- const success = await copyToClipboard(curl);
27103
- setCopyStatus(success ? "copied" : "error");
27104
- setTimeout(() => setCopyStatus("idle"), 2e3);
27105
- }, [r]);
27106
- const summary = (0, import_react14.useMemo)(() => {
27141
+ const handleCopyCurl = (0, import_react16.useCallback)(() => {
27142
+ if (r) copyCurl(generateCurl(r));
27143
+ }, [r, copyCurl]);
27144
+ const summary = (0, import_react16.useMemo)(() => {
27107
27145
  if (!r) return null;
27108
27146
  const url = r.url || (r.hostname || "") + (r.path || "");
27109
27147
  const u = safeURL(url);
@@ -27119,18 +27157,18 @@ var init_DetailPanel = __esm({
27119
27157
  else if (e) statusClass = "s-5";
27120
27158
  return { u, size, dur, code, statusClass };
27121
27159
  }, [r, s, e]);
27122
- const parsedReq = (0, import_react14.useMemo)(() => {
27160
+ const parsedReq = (0, import_react16.useMemo)(() => {
27123
27161
  const requestURL = r ? r.url || (r.hostname || "") + (r.path || "") : "";
27124
27162
  return requestURL ? safeURL(requestURL) : { href: "", host: "", path: "" };
27125
27163
  }, [r]);
27126
- const reqGeneral = (0, import_react14.useMemo)(
27164
+ const reqGeneral = (0, import_react16.useMemo)(
27127
27165
  () => r ? {
27128
27166
  "Request URL": parsedReq.href,
27129
27167
  "Request Method": r.method || ""
27130
27168
  } : {},
27131
27169
  [r, parsedReq.href]
27132
27170
  );
27133
- const resGeneral = (0, import_react14.useMemo)(
27171
+ const resGeneral = (0, import_react16.useMemo)(
27134
27172
  () => r ? {
27135
27173
  "Request URL": parsedReq.href,
27136
27174
  "Request Method": r.method || "",
@@ -27138,10 +27176,10 @@ var init_DetailPanel = __esm({
27138
27176
  } : {},
27139
27177
  [r, parsedReq.href, s]
27140
27178
  );
27141
- const reqHeaders = (0, import_react14.useMemo)(() => r?.headers || {}, [r?.headers]);
27142
- const resHeaders = (0, import_react14.useMemo)(() => s?.headers || {}, [s?.headers]);
27143
- const reqHeadersRest = (0, import_react14.useMemo)(() => omitKeysCI(reqHeaders, REQ_HEADERS_TO_OMIT), [reqHeaders]);
27144
- const resHeadersRest = (0, import_react14.useMemo)(() => omitKeysCI(resHeaders, RES_HEADERS_TO_OMIT), [resHeaders]);
27179
+ const reqHeaders = (0, import_react16.useMemo)(() => r?.headers || {}, [r?.headers]);
27180
+ const resHeaders = (0, import_react16.useMemo)(() => s?.headers || {}, [s?.headers]);
27181
+ const reqHeadersRest = (0, import_react16.useMemo)(() => omitKeysCI(reqHeaders, REQ_HEADERS_TO_OMIT), [reqHeaders]);
27182
+ const resHeadersRest = (0, import_react16.useMemo)(() => omitKeysCI(resHeaders, RES_HEADERS_TO_OMIT), [resHeaders]);
27145
27183
  if (!tx) {
27146
27184
  return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("section", { id: "detail", children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
27147
27185
  EmptyState,
@@ -27209,7 +27247,7 @@ var init_DetailPanel = __esm({
27209
27247
  ] })
27210
27248
  ] });
27211
27249
  };
27212
- DetailPanel = (0, import_react14.memo)(
27250
+ DetailPanel = (0, import_react16.memo)(
27213
27251
  DetailPanelBase,
27214
27252
  (prev, next) => prev.activeTab === next.activeTab && prev.version === next.version && prev.tx?.captureId === next.tx?.captureId
27215
27253
  );
@@ -27224,12 +27262,12 @@ var init_DetailPanel2 = __esm({
27224
27262
  });
27225
27263
 
27226
27264
  // src/ui/react/components/ErrorBoundary/ErrorBoundary.tsx
27227
- var import_react15, import_jsx_runtime18, ErrorBoundary;
27265
+ var import_react17, import_jsx_runtime18, ErrorBoundary;
27228
27266
  var init_ErrorBoundary = __esm({
27229
27267
  "src/ui/react/components/ErrorBoundary/ErrorBoundary.tsx"() {
27230
- import_react15 = __toESM(require_react());
27268
+ import_react17 = __toESM(require_react());
27231
27269
  import_jsx_runtime18 = __toESM(require_jsx_runtime());
27232
- ErrorBoundary = class extends import_react15.Component {
27270
+ ErrorBoundary = class extends import_react17.Component {
27233
27271
  constructor(props) {
27234
27272
  super(props);
27235
27273
  this.handleRetry = () => {
@@ -27322,13 +27360,13 @@ var init_ThemeSwitcher2 = __esm({
27322
27360
  });
27323
27361
 
27324
27362
  // src/ui/react/components/HeaderBar/HeaderBar.tsx
27325
- var import_react16, import_jsx_runtime20, ViewButton, HeaderBar;
27363
+ var import_react18, import_jsx_runtime20, ViewButton, HeaderBar;
27326
27364
  var init_HeaderBar = __esm({
27327
27365
  "src/ui/react/components/HeaderBar/HeaderBar.tsx"() {
27328
- import_react16 = __toESM(require_react());
27366
+ import_react18 = __toESM(require_react());
27329
27367
  init_ThemeSwitcher2();
27330
27368
  import_jsx_runtime20 = __toESM(require_jsx_runtime());
27331
- ViewButton = (0, import_react16.memo)(
27369
+ ViewButton = (0, import_react18.memo)(
27332
27370
  ({
27333
27371
  view,
27334
27372
  currentView,
@@ -27346,7 +27384,7 @@ var init_HeaderBar = __esm({
27346
27384
  )
27347
27385
  );
27348
27386
  ViewButton.displayName = "ViewButton";
27349
- HeaderBar = (0, import_react16.memo)(
27387
+ HeaderBar = (0, import_react18.memo)(
27350
27388
  ({
27351
27389
  isPaused,
27352
27390
  setPaused,
@@ -27358,10 +27396,11 @@ var init_HeaderBar = __esm({
27358
27396
  mainView,
27359
27397
  setMainView
27360
27398
  }) => /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("header", { children: [
27361
- /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "brand", children: [
27362
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "badge", children: "DORU" }),
27363
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "brand-name", children: "INTERCEPTORU" })
27364
- ] }),
27399
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className: "brand brand--term", children: /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("span", { className: "brand-term", children: [
27400
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "term-prompt", children: "\u203A" }),
27401
+ "doru",
27402
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "term-caret", "aria-hidden": "true" })
27403
+ ] }) }),
27365
27404
  /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "view-switcher", role: "group", "aria-label": "View options", children: [
27366
27405
  /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(ViewButton, { view: "list", currentView: mainView, onClick: () => setMainView("list"), children: [
27367
27406
  /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "currentColor", "aria-hidden": "true", children: [
@@ -27395,7 +27434,7 @@ var init_HeaderBar = __esm({
27395
27434
  "button",
27396
27435
  {
27397
27436
  type: "button",
27398
- className: `btn${isPaused ? " active" : ""}`,
27437
+ className: `btn pause-btn ${isPaused ? "paused" : "live"}`,
27399
27438
  title: isPaused ? "Resume auto-refresh" : "Pause auto-refresh",
27400
27439
  "aria-pressed": isPaused,
27401
27440
  onClick: () => setPaused(!isPaused),
@@ -28352,10 +28391,10 @@ var init_esm2 = __esm({
28352
28391
  });
28353
28392
 
28354
28393
  // src/ui/react/components/Skeleton/Skeleton.tsx
28355
- var import_react17, import_jsx_runtime21, SkeletonBase, Skeleton, SkeletonRowBase, SkeletonRow, SkeletonListBase, SkeletonList;
28394
+ var import_react19, import_jsx_runtime21, SkeletonBase, Skeleton, SkeletonRowBase, SkeletonRow, SkeletonListBase, SkeletonList;
28356
28395
  var init_Skeleton = __esm({
28357
28396
  "src/ui/react/components/Skeleton/Skeleton.tsx"() {
28358
- import_react17 = __toESM(require_react());
28397
+ import_react19 = __toESM(require_react());
28359
28398
  import_jsx_runtime21 = __toESM(require_jsx_runtime());
28360
28399
  SkeletonBase = ({ width = "100%", height = 16, borderRadius = 4, className = "" }) => {
28361
28400
  return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
@@ -28370,7 +28409,7 @@ var init_Skeleton = __esm({
28370
28409
  }
28371
28410
  );
28372
28411
  };
28373
- Skeleton = (0, import_react17.memo)(SkeletonBase);
28412
+ Skeleton = (0, import_react19.memo)(SkeletonBase);
28374
28413
  Skeleton.displayName = "Skeleton";
28375
28414
  SkeletonRowBase = ({ columns = 6 }) => {
28376
28415
  return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "skeleton-row", children: Array.from({ length: columns }).map((_2, i) => (
@@ -28378,7 +28417,7 @@ var init_Skeleton = __esm({
28378
28417
  /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(Skeleton, { height: 14, width: i === 2 ? "80%" : "60%" }, `col-${i}`)
28379
28418
  )) });
28380
28419
  };
28381
- SkeletonRow = (0, import_react17.memo)(SkeletonRowBase);
28420
+ SkeletonRow = (0, import_react19.memo)(SkeletonRowBase);
28382
28421
  SkeletonRow.displayName = "SkeletonRow";
28383
28422
  SkeletonListBase = ({ rows = 10, columns = 6 }) => {
28384
28423
  return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "skeleton-list", "aria-busy": "true", "aria-label": "Loading content", children: Array.from({ length: rows }).map((_2, i) => (
@@ -28386,7 +28425,7 @@ var init_Skeleton = __esm({
28386
28425
  /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(SkeletonRow, { columns }, `row-${i}`)
28387
28426
  )) });
28388
28427
  };
28389
- SkeletonList = (0, import_react17.memo)(SkeletonListBase);
28428
+ SkeletonList = (0, import_react19.memo)(SkeletonListBase);
28390
28429
  SkeletonList.displayName = "SkeletonList";
28391
28430
  }
28392
28431
  });
@@ -28399,10 +28438,10 @@ var init_Skeleton2 = __esm({
28399
28438
  });
28400
28439
 
28401
28440
  // src/ui/react/components/StatusIcon/StatusIcon.tsx
28402
- var import_react18, import_jsx_runtime22, getStatusType, STATUS_COLORS2, StatusIconBase, StatusIcon;
28441
+ var import_react20, import_jsx_runtime22, getStatusType, STATUS_COLORS2, StatusIconBase, StatusIcon;
28403
28442
  var init_StatusIcon = __esm({
28404
28443
  "src/ui/react/components/StatusIcon/StatusIcon.tsx"() {
28405
- import_react18 = __toESM(require_react());
28444
+ import_react20 = __toESM(require_react());
28406
28445
  import_jsx_runtime22 = __toESM(require_jsx_runtime());
28407
28446
  getStatusType = (status) => {
28408
28447
  if (status === "error") return "error";
@@ -28435,7 +28474,6 @@ var init_StatusIcon = __esm({
28435
28474
  "path",
28436
28475
  {
28437
28476
  d: "M3.5 3.5 L6.5 6.5 M6.5 3.5 L3.5 6.5",
28438
- stroke: "white",
28439
28477
  strokeWidth: "1.2",
28440
28478
  strokeLinecap: "round"
28441
28479
  }
@@ -28449,7 +28487,6 @@ var init_StatusIcon = __esm({
28449
28487
  {
28450
28488
  d: "M3 5 L4.5 6.5 L7 3.5",
28451
28489
  fill: "none",
28452
- stroke: "white",
28453
28490
  strokeWidth: "1.2",
28454
28491
  strokeLinecap: "round",
28455
28492
  strokeLinejoin: "round"
@@ -28460,7 +28497,6 @@ var init_StatusIcon = __esm({
28460
28497
  {
28461
28498
  d: "M4 5 L6 5 M5 3.5 L6.5 5 L5 6.5",
28462
28499
  fill: "none",
28463
- stroke: "white",
28464
28500
  strokeWidth: "1.2",
28465
28501
  strokeLinecap: "round",
28466
28502
  strokeLinejoin: "round"
@@ -28468,7 +28504,7 @@ var init_StatusIcon = __esm({
28468
28504
  )
28469
28505
  ] });
28470
28506
  };
28471
- StatusIcon = (0, import_react18.memo)(StatusIconBase);
28507
+ StatusIcon = (0, import_react20.memo)(StatusIconBase);
28472
28508
  StatusIcon.displayName = "StatusIcon";
28473
28509
  }
28474
28510
  });
@@ -28481,10 +28517,10 @@ var init_StatusIcon2 = __esm({
28481
28517
  });
28482
28518
 
28483
28519
  // src/ui/react/components/ListPanel/ListPanel.tsx
28484
- var import_react19, import_jsx_runtime23, METHODS, STATUS_FILTERS, getDuration, getArrow, getAriaSort, SortHeader, ListPanelBase, ListPanel;
28520
+ var import_react21, import_jsx_runtime23, METHODS, STATUS_FILTERS, getDuration, getArrow, getAriaSort, SortHeader, ListPanelBase, ListPanel;
28485
28521
  var init_ListPanel = __esm({
28486
28522
  "src/ui/react/components/ListPanel/ListPanel.tsx"() {
28487
- import_react19 = __toESM(require_react());
28523
+ import_react21 = __toESM(require_react());
28488
28524
  init_esm2();
28489
28525
  init_useMask();
28490
28526
  init_formatting();
@@ -28514,7 +28550,7 @@ var init_ListPanel = __esm({
28514
28550
  if (!isActive) return void 0;
28515
28551
  return direction === "asc" ? "ascending" : "descending";
28516
28552
  };
28517
- SortHeader = (0, import_react19.memo)(({ column, label, sort, onSort, className = "" }) => {
28553
+ SortHeader = (0, import_react21.memo)(({ column, label, sort, onSort, className = "" }) => {
28518
28554
  const isActive = sort.column === column;
28519
28555
  return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
28520
28556
  "div",
@@ -28549,12 +28585,12 @@ var init_ListPanel = __esm({
28549
28585
  isLoading = false,
28550
28586
  error = null
28551
28587
  }) => {
28552
- const parentRef = (0, import_react19.useRef)(null);
28588
+ const parentRef = (0, import_react21.useRef)(null);
28553
28589
  const { isMasked } = useMask();
28554
28590
  const onQ = (e) => onFilters({ ...filters, q: e.target.value });
28555
28591
  const onM = (e) => onFilters({ ...filters, m: e.target.value });
28556
28592
  const onS = (e) => onFilters({ ...filters, s: e.target.value });
28557
- const handleSort = (0, import_react19.useCallback)(
28593
+ const handleSort = (0, import_react21.useCallback)(
28558
28594
  (column) => {
28559
28595
  if (sort.column === column) {
28560
28596
  onSort({ column, direction: sort.direction === "asc" ? "desc" : "asc" });
@@ -28570,7 +28606,7 @@ var init_ListPanel = __esm({
28570
28606
  estimateSize: () => 36,
28571
28607
  overscan: 15
28572
28608
  });
28573
- (0, import_react19.useEffect)(() => {
28609
+ (0, import_react21.useEffect)(() => {
28574
28610
  const onKey = (e) => {
28575
28611
  if (!["ArrowDown", "ArrowUp", "Enter"].includes(e.key)) return;
28576
28612
  if (items.length === 0) return;
@@ -28651,7 +28687,7 @@ var init_ListPanel = __esm({
28651
28687
  let codeText = "Pending";
28652
28688
  let codeCls = "status";
28653
28689
  if (e) {
28654
- codeText = "ERROR";
28690
+ codeText = "ERR";
28655
28691
  codeCls += " s-5";
28656
28692
  } else if (s && s.statusCode) {
28657
28693
  const range = Math.floor(s.statusCode / 100);
@@ -28696,7 +28732,7 @@ var init_ListPanel = __esm({
28696
28732
  ) })
28697
28733
  ] });
28698
28734
  };
28699
- ListPanel = (0, import_react19.memo)(ListPanelBase);
28735
+ ListPanel = (0, import_react21.memo)(ListPanelBase);
28700
28736
  }
28701
28737
  });
28702
28738
 
@@ -28708,10 +28744,10 @@ var init_ListPanel2 = __esm({
28708
28744
  });
28709
28745
 
28710
28746
  // src/ui/react/components/WaterfallView/WaterfallView.tsx
28711
- var import_react20, import_jsx_runtime24, getDuration2, getTimestamp, WaterfallViewBase, WaterfallView;
28747
+ var import_react22, import_jsx_runtime24, getDuration2, getTimestamp, WaterfallViewBase, WaterfallView;
28712
28748
  var init_WaterfallView = __esm({
28713
28749
  "src/ui/react/components/WaterfallView/WaterfallView.tsx"() {
28714
- import_react20 = __toESM(require_react());
28750
+ import_react22 = __toESM(require_react());
28715
28751
  init_esm2();
28716
28752
  init_formatting();
28717
28753
  init_parsing();
@@ -28726,8 +28762,8 @@ var init_WaterfallView = __esm({
28726
28762
  return new Date(tx.request?.timestamp || 0).getTime();
28727
28763
  };
28728
28764
  WaterfallViewBase = ({ items, selectedId, onSelect }) => {
28729
- const parentRef = (0, import_react20.useRef)(null);
28730
- const handleKeyDown = (0, import_react20.useCallback)(
28765
+ const parentRef = (0, import_react22.useRef)(null);
28766
+ const handleKeyDown = (0, import_react22.useCallback)(
28731
28767
  (e, captureId) => {
28732
28768
  if (e.key === "Enter" || e.key === " ") {
28733
28769
  e.preventDefault();
@@ -28736,7 +28772,7 @@ var init_WaterfallView = __esm({
28736
28772
  },
28737
28773
  [onSelect]
28738
28774
  );
28739
- const { minTime, totalDuration } = (0, import_react20.useMemo)(() => {
28775
+ const { minTime, totalDuration } = (0, import_react22.useMemo)(() => {
28740
28776
  if (items.length === 0) return { minTime: 0, totalDuration: 1 };
28741
28777
  let min = Infinity;
28742
28778
  let max = -Infinity;
@@ -28748,7 +28784,7 @@ var init_WaterfallView = __esm({
28748
28784
  }
28749
28785
  return { minTime: min, totalDuration: Math.max(max - min, 1) };
28750
28786
  }, [items]);
28751
- const timeMarkers = (0, import_react20.useMemo)(() => {
28787
+ const timeMarkers = (0, import_react22.useMemo)(() => {
28752
28788
  const markers = [];
28753
28789
  const interval = totalDuration / 5;
28754
28790
  for (let i = 0; i <= 5; i++) {
@@ -28847,7 +28883,7 @@ var init_WaterfallView = __esm({
28847
28883
  ) })
28848
28884
  ] });
28849
28885
  };
28850
- WaterfallView = (0, import_react20.memo)(WaterfallViewBase);
28886
+ WaterfallView = (0, import_react22.memo)(WaterfallViewBase);
28851
28887
  WaterfallView.displayName = "WaterfallView";
28852
28888
  }
28853
28889
  });
@@ -28860,10 +28896,10 @@ var init_WaterfallView2 = __esm({
28860
28896
  });
28861
28897
 
28862
28898
  // src/ui/react/hooks/useCapture.ts
28863
- var import_react21, calcSize2, getDuration3, getStatus, sortTransactions, useCapture;
28899
+ var import_react23, calcSize2, getDuration3, getStatus, sortTransactions, useCapture;
28864
28900
  var init_useCapture = __esm({
28865
28901
  "src/ui/react/hooks/useCapture.ts"() {
28866
- import_react21 = __toESM(require_react());
28902
+ import_react23 = __toESM(require_react());
28867
28903
  init_parsing();
28868
28904
  calcSize2 = (tx) => {
28869
28905
  const body = tx.response?.body || tx.request?.body;
@@ -28912,18 +28948,18 @@ var init_useCapture = __esm({
28912
28948
  });
28913
28949
  };
28914
28950
  useCapture = (intervalMs = 2e3) => {
28915
- const [tx, setTx] = (0, import_react21.useState)([]);
28916
- const [filters, setFilters] = (0, import_react21.useState)({ q: "", m: "", s: "" });
28917
- const [selectedId, setSelectedId] = (0, import_react21.useState)(null);
28918
- const [paused, setPaused] = (0, import_react21.useState)(false);
28919
- const [activeTab, setActiveTab] = (0, import_react21.useState)("overview");
28920
- const [isLoading, setIsLoading] = (0, import_react21.useState)(true);
28921
- const [error, setError] = (0, import_react21.useState)(null);
28922
- const [sort, setSort] = (0, import_react21.useState)({ column: "time", direction: "desc" });
28923
- const offsetRef = (0, import_react21.useRef)(0);
28924
- const rawRecordsRef = (0, import_react21.useRef)([]);
28925
- const pendingLineRef = (0, import_react21.useRef)("");
28926
- const load = (0, import_react21.useCallback)(async () => {
28951
+ const [tx, setTx] = (0, import_react23.useState)([]);
28952
+ const [filters, setFilters] = (0, import_react23.useState)({ q: "", m: "", s: "" });
28953
+ const [selectedId, setSelectedId] = (0, import_react23.useState)(null);
28954
+ const [paused, setPaused] = (0, import_react23.useState)(false);
28955
+ const [activeTab, setActiveTab] = (0, import_react23.useState)("overview");
28956
+ const [isLoading, setIsLoading] = (0, import_react23.useState)(true);
28957
+ const [error, setError] = (0, import_react23.useState)(null);
28958
+ const [sort, setSort] = (0, import_react23.useState)({ column: "time", direction: "desc" });
28959
+ const offsetRef = (0, import_react23.useRef)(0);
28960
+ const rawRecordsRef = (0, import_react23.useRef)([]);
28961
+ const pendingLineRef = (0, import_react23.useRef)("");
28962
+ const load = (0, import_react23.useCallback)(async () => {
28927
28963
  if (paused) return;
28928
28964
  try {
28929
28965
  setError(null);
@@ -28976,7 +29012,7 @@ var init_useCapture = __esm({
28976
29012
  setIsLoading(false);
28977
29013
  }
28978
29014
  }, [paused]);
28979
- (0, import_react21.useEffect)(() => {
29015
+ (0, import_react23.useEffect)(() => {
28980
29016
  const initialLoad = async () => {
28981
29017
  try {
28982
29018
  setIsLoading(true);
@@ -29007,12 +29043,12 @@ var init_useCapture = __esm({
29007
29043
  };
29008
29044
  initialLoad();
29009
29045
  }, []);
29010
- (0, import_react21.useEffect)(() => {
29046
+ (0, import_react23.useEffect)(() => {
29011
29047
  if (isLoading) return;
29012
29048
  const id = setInterval(load, intervalMs);
29013
29049
  return () => clearInterval(id);
29014
29050
  }, [load, intervalMs, isLoading]);
29015
- const filtered = (0, import_react21.useMemo)(() => {
29051
+ const filtered = (0, import_react23.useMemo)(() => {
29016
29052
  const q = filters.q.toLowerCase();
29017
29053
  const m = filters.m;
29018
29054
  const s = filters.s;
@@ -29026,8 +29062,8 @@ var init_useCapture = __esm({
29026
29062
  return true;
29027
29063
  });
29028
29064
  }, [tx, filters]);
29029
- const sorted = (0, import_react21.useMemo)(() => sortTransactions(filtered, sort), [filtered, sort]);
29030
- const stats = (0, import_react21.useMemo)(() => {
29065
+ const sorted = (0, import_react23.useMemo)(() => sortTransactions(filtered, sort), [filtered, sort]);
29066
+ const stats = (0, import_react23.useMemo)(() => {
29031
29067
  const total = sorted.length;
29032
29068
  const ok = sorted.filter((t) => (t.response && t.response.statusCode || 0) < 400).length;
29033
29069
  const errors = sorted.filter(
@@ -29035,12 +29071,12 @@ var init_useCapture = __esm({
29035
29071
  ).length;
29036
29072
  return { total, ok, errors };
29037
29073
  }, [sorted]);
29038
- const selected = (0, import_react21.useMemo)(
29074
+ const selected = (0, import_react23.useMemo)(
29039
29075
  () => sorted.find((t) => t.captureId === selectedId) || tx.find((t) => t.captureId === selectedId) || null,
29040
29076
  [sorted, tx, selectedId]
29041
29077
  );
29042
- const selectedVersion = (0, import_react21.useMemo)(() => getTxVersion(selected), [selected]);
29043
- (0, import_react21.useEffect)(() => {
29078
+ const selectedVersion = (0, import_react23.useMemo)(() => getTxVersion(selected), [selected]);
29079
+ (0, import_react23.useEffect)(() => {
29044
29080
  if (!selectedId && sorted.length > 0) {
29045
29081
  setSelectedId(sorted[0].captureId);
29046
29082
  }
@@ -29068,12 +29104,12 @@ var init_useCapture = __esm({
29068
29104
  });
29069
29105
 
29070
29106
  // src/ui/react/hooks/useFavicon.ts
29071
- var import_react22, useFavicon;
29107
+ var import_react24, useFavicon;
29072
29108
  var init_useFavicon = __esm({
29073
29109
  "src/ui/react/hooks/useFavicon.ts"() {
29074
- import_react22 = __toESM(require_react());
29110
+ import_react24 = __toESM(require_react());
29075
29111
  useFavicon = (isRecording) => {
29076
- (0, import_react22.useEffect)(() => {
29112
+ (0, import_react24.useEffect)(() => {
29077
29113
  const link = document.querySelector('link[rel="icon"]');
29078
29114
  if (link) {
29079
29115
  link.href = isRecording ? "./favicon.svg" : "./favicon-paused.svg";
@@ -29085,7 +29121,7 @@ var init_useFavicon = __esm({
29085
29121
 
29086
29122
  // src/ui/react/hooks/useLocalStorage.ts
29087
29123
  function useLocalStorage(key, initialValue) {
29088
- const [storedValue, setStoredValue] = (0, import_react23.useState)(() => {
29124
+ const [storedValue, setStoredValue] = (0, import_react25.useState)(() => {
29089
29125
  if (typeof window === "undefined") return initialValue;
29090
29126
  try {
29091
29127
  const item = localStorage.getItem(key);
@@ -29094,7 +29130,7 @@ function useLocalStorage(key, initialValue) {
29094
29130
  return initialValue;
29095
29131
  }
29096
29132
  });
29097
- const setValue = (0, import_react23.useCallback)(
29133
+ const setValue = (0, import_react25.useCallback)(
29098
29134
  (value) => {
29099
29135
  setStoredValue(value);
29100
29136
  if (typeof window !== "undefined") {
@@ -29108,18 +29144,18 @@ function useLocalStorage(key, initialValue) {
29108
29144
  );
29109
29145
  return [storedValue, setValue];
29110
29146
  }
29111
- var import_react23;
29147
+ var import_react25;
29112
29148
  var init_useLocalStorage = __esm({
29113
29149
  "src/ui/react/hooks/useLocalStorage.ts"() {
29114
- import_react23 = __toESM(require_react());
29150
+ import_react25 = __toESM(require_react());
29115
29151
  }
29116
29152
  });
29117
29153
 
29118
29154
  // src/ui/react/App.tsx
29119
- var import_react24, import_jsx_runtime25, MainContent, App;
29155
+ var import_react26, import_jsx_runtime25, MainContent, App;
29120
29156
  var init_App = __esm({
29121
29157
  "src/ui/react/App.tsx"() {
29122
- import_react24 = __toESM(require_react());
29158
+ import_react26 = __toESM(require_react());
29123
29159
  init_react_resizable_panels();
29124
29160
  init_AnalyticsDashboard2();
29125
29161
  init_DetailPanel2();
@@ -29181,8 +29217,8 @@ var init_App = __esm({
29181
29217
  App = () => {
29182
29218
  const [theme, setTheme] = useLocalStorage("doru-theme", "dark");
29183
29219
  const [isMasked, setMasked] = useLocalStorage("doru-mask", false);
29184
- const [mainView, setMainView] = (0, import_react24.useState)("list");
29185
- (0, import_react24.useEffect)(() => {
29220
+ const [mainView, setMainView] = (0, import_react26.useState)("list");
29221
+ (0, import_react26.useEffect)(() => {
29186
29222
  document.documentElement.dataset.theme = theme;
29187
29223
  }, [theme]);
29188
29224
  const {
@@ -29204,10 +29240,10 @@ var init_App = __esm({
29204
29240
  setSort
29205
29241
  } = useCapture(2e3);
29206
29242
  useFavicon(!paused);
29207
- const txMap = (0, import_react24.useMemo)(() => new Map(tx.map((t) => [t.captureId, t])), [tx]);
29208
- const selected = (0, import_react24.useMemo)(() => selectedId ? txMap.get(selectedId) ?? null : null, [txMap, selectedId]);
29243
+ const txMap = (0, import_react26.useMemo)(() => new Map(tx.map((t) => [t.captureId, t])), [tx]);
29244
+ const selected = (0, import_react26.useMemo)(() => selectedId ? txMap.get(selectedId) ?? null : null, [txMap, selectedId]);
29209
29245
  const statsText = `${stats.total} reqs \u2022 ${stats.ok} ok \u2022 ${stats.errors} err`;
29210
- const maskContextValue = (0, import_react24.useMemo)(() => ({ isMasked, setMasked }), [isMasked, setMasked]);
29246
+ const maskContextValue = (0, import_react26.useMemo)(() => ({ isMasked, setMasked }), [isMasked, setMasked]);
29211
29247
  return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(ErrorBoundary, { children: /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(MaskContext.Provider, { value: maskContextValue, children: [
29212
29248
  /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
29213
29249
  HeaderBar,