@react-perfscope/ui 0.5.0 → 0.7.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/index.js CHANGED
@@ -114,6 +114,9 @@ var en = {
114
114
  heapUnsupported: "heap size unavailable (Chromium only)",
115
115
  heapExtensionHint: "Heap size includes browser extensions injected into the page (e.g. React DevTools), so it can rise even while your app is idle. For app-only measurement, record in an incognito window or a profile with extensions disabled.",
116
116
  heapTrendLabel: (cls) => cls === "leak-suspected" ? "leak suspected" : cls === "growing" ? "growing" : "stable",
117
+ leaksTitle: "Suspected leaks",
118
+ leakHint: "Components whose unmounted instances stayed in memory with a count that kept climbing. Shows which component leaks and how many instances \u2014 not what retains them (a heap snapshot, unavailable in-page, is needed for that).",
119
+ leakSuspect: (component, retained, unmounted) => `${component} \u2014 ${retained} retained of ${unmounted} unmounted, climbing`,
117
120
  fpsLabel: "fps",
118
121
  fpsUnsupported: "frame timing unavailable",
119
122
  fpsBadge: (minFps, dropped) => `min ${minFps}fps \xB7 ${dropped} dropped`,
@@ -146,7 +149,8 @@ var en = {
146
149
  processingTime: "processing",
147
150
  presentation: "presentation",
148
151
  interactionThresholdHint: "Only interactions \u226540ms are shown \u2014 INP surfaces the slow ones; fast clicks are omitted.",
149
- layoutShiftHint: "Every layout shift, including ones triggered by your interactions. The CLS metric excludes input-driven shifts, so this is not a CLS score."
152
+ layoutShiftHint: "Every layout shift, including ones triggered by your interactions. The CLS metric excludes input-driven shifts, so this is not a CLS score.",
153
+ unsupportedInBrowser: (kinds) => `Not measurable in this browser (the API is missing, not that nothing happened): ${kinds}.`
150
154
  };
151
155
  var KIND_LABELS_KO = {
152
156
  render: "\uB80C\uB354",
@@ -208,6 +212,9 @@ var ko = {
208
212
  heapUnsupported: "\uD799 \uCE21\uC815 \uBBF8\uC9C0\uC6D0 (\uD06C\uB86C \uC804\uC6A9)",
209
213
  heapExtensionHint: "\uD799 \uD06C\uAE30\uC5D4 \uD398\uC774\uC9C0\uC5D0 \uC8FC\uC785\uB41C \uBE0C\uB77C\uC6B0\uC800 \uD655\uC7A5(\uC608: React DevTools) \uBA54\uBAA8\uB9AC\uB3C4 \uD3EC\uD568\uB3FC\uC694. \uADF8\uB798\uC11C \uC571\uC774 idle\uC774\uC5B4\uB3C4 \uC62C\uB77C\uAC08 \uC218 \uC788\uC5B4\uC694. \uC571\uB9CC \uC815\uD655\uD788 \uC7AC\uB824\uBA74 \uC2DC\uD06C\uB9BF \uCC3D\uC774\uB098 \uD655\uC7A5\uC774 \uAEBC\uC9C4 \uD504\uB85C\uD544\uC5D0\uC11C \uB179\uD654\uD558\uC138\uC694.",
210
214
  heapTrendLabel: (cls) => cls === "leak-suspected" ? "\uB204\uC218 \uC758\uC2EC" : cls === "growing" ? "\uC99D\uAC00 \uC911" : "\uC548\uC815",
215
+ leaksTitle: "\uB204\uC218 \uC758\uC2EC",
216
+ leakHint: "\uC5B8\uB9C8\uC6B4\uD2B8\uB410\uB294\uB370 \uBA54\uBAA8\uB9AC\uC5D0 \uB0A8\uACE0 \uADF8 \uC218\uAC00 \uACC4\uC18D \uB298\uC5B4\uB09C \uCEF4\uD3EC\uB10C\uD2B8\uC608\uC694. \uC5B4\uB5A4 \uCEF4\uD3EC\uB10C\uD2B8\uAC00 \uBA87 \uAC1C \uB204\uC218\uD558\uB294\uC9C0\uB294 \uBCF4\uC5EC\uC8FC\uC9C0\uB9CC, \uBB34\uC5C7\uC774 \uBD99\uC7A1\uACE0 \uC788\uB294\uC9C0\uB294(\uD799 \uC2A4\uB0C5\uC0F7\uC774 \uD544\uC694\uD55C\uB370 in-page\uC5D0\uC120 \uBD88\uAC00) \uC54C \uC218 \uC5C6\uC5B4\uC694.",
217
+ leakSuspect: (component, retained, unmounted) => `${component} \u2014 \uC5B8\uB9C8\uC6B4\uD2B8 ${unmounted}\uAC1C \uC911 ${retained}\uAC1C \uBCF4\uC720, \uC99D\uAC00 \uC911`,
211
218
  fpsLabel: "fps",
212
219
  fpsUnsupported: "\uD504\uB808\uC784 \uCE21\uC815 \uBBF8\uC9C0\uC6D0",
213
220
  fpsBadge: (minFps, dropped) => `\uCD5C\uC800 ${minFps}fps \xB7 \uB4DC\uB78D ${dropped}`,
@@ -240,7 +247,8 @@ var ko = {
240
247
  processingTime: "\uCC98\uB9AC",
241
248
  presentation: "\uD654\uBA74 \uBC18\uC601",
242
249
  interactionThresholdHint: "40ms \uC774\uC0C1 \uAC78\uB9B0 \uC0C1\uD638\uC791\uC6A9\uB9CC \uD45C\uC2DC\uB3FC\uC694 \u2014 \uB290\uB9B0 \uAC83\uB9CC INP\uB85C \uC7A1\uACE0, \uBE60\uB978 \uD074\uB9AD\uC740 \uC0DD\uB7B5\uD574\uC694.",
243
- layoutShiftHint: "\uC0AC\uC6A9\uC790 \uC778\uD130\uB799\uC158\uC73C\uB85C \uC0DD\uAE34 \uAC83\uAE4C\uC9C0 \uD3EC\uD568\uD55C \uBAA8\uB4E0 \uB808\uC774\uC544\uC6C3 \uC2DC\uD504\uD2B8\uC608\uC694. CLS \uC9C0\uD45C\uB294 \uC785\uB825\uC73C\uB85C \uC778\uD55C \uC2DC\uD504\uD2B8\uB97C \uC81C\uC678\uD558\uBBC0\uB85C, \uC774\uAC74 CLS \uC810\uC218\uAC00 \uC544\uB2C8\uC5D0\uC694."
250
+ layoutShiftHint: "\uC0AC\uC6A9\uC790 \uC778\uD130\uB799\uC158\uC73C\uB85C \uC0DD\uAE34 \uAC83\uAE4C\uC9C0 \uD3EC\uD568\uD55C \uBAA8\uB4E0 \uB808\uC774\uC544\uC6C3 \uC2DC\uD504\uD2B8\uC608\uC694. CLS \uC9C0\uD45C\uB294 \uC785\uB825\uC73C\uB85C \uC778\uD55C \uC2DC\uD504\uD2B8\uB97C \uC81C\uC678\uD558\uBBC0\uB85C, \uC774\uAC74 CLS \uC810\uC218\uAC00 \uC544\uB2C8\uC5D0\uC694.",
251
+ unsupportedInBrowser: (kinds) => `\uC774 \uBE0C\uB77C\uC6B0\uC800\uC5D0\uC120 \uCE21\uC815\uD560 \uC218 \uC5C6\uC5B4\uC694 (\uC544\uBB34 \uC77C\uB3C4 \uC5C6\uB358 \uAC8C \uC544\uB2C8\uB77C API\uAC00 \uC5C6\uC74C): ${kinds}.`
244
252
  };
245
253
  var STRINGS = { en, ko };
246
254
  function isLang(v) {
@@ -350,6 +358,7 @@ function Widget(props) {
350
358
 
351
359
  // src/panel.tsx
352
360
  import { useState as useState3, useMemo as useMemo3, useEffect, useRef as useRef2 } from "preact/hooks";
361
+ import { unsupportedKinds } from "@react-perfscope/core";
353
362
 
354
363
  // src/overlay.ts
355
364
  var OVERLAY_MARKER = "data-perfscope-overlay";
@@ -1762,8 +1771,39 @@ function TooltipContent({ s, startedAt }) {
1762
1771
  }
1763
1772
  }
1764
1773
 
1765
- // src/render-insights.tsx
1774
+ // src/leaks.tsx
1766
1775
  import { jsx as jsx4, jsxs as jsxs4 } from "preact/jsx-runtime";
1776
+ function LeakList({ suspects }) {
1777
+ const { t } = useI18n();
1778
+ if (!suspects || suspects.length === 0) return null;
1779
+ return /* @__PURE__ */ jsxs4("div", { "data-leaks": "", style: { padding: "8px 10px", borderBottom: "1px solid #1c1c1c" }, children: [
1780
+ /* @__PURE__ */ jsxs4(
1781
+ "div",
1782
+ {
1783
+ style: { display: "flex", alignItems: "center", gap: "6px", marginBottom: "6px" },
1784
+ children: [
1785
+ /* @__PURE__ */ jsx4("span", { style: { color: "#ef4444", fontSize: "11px", fontWeight: 600 }, children: t.leaksTitle }),
1786
+ /* @__PURE__ */ jsxs4("span", { style: { color: "#666", fontSize: "10px" }, children: [
1787
+ "\xD7",
1788
+ suspects.length
1789
+ ] })
1790
+ ]
1791
+ }
1792
+ ),
1793
+ /* @__PURE__ */ jsx4("ul", { style: { listStyle: "none", margin: 0, padding: 0 }, children: suspects.map((s) => /* @__PURE__ */ jsx4(
1794
+ "li",
1795
+ {
1796
+ style: { color: "#e6e6e6", fontSize: "11px", padding: "2px 0", fontVariantNumeric: "tabular-nums" },
1797
+ children: t.leakSuspect(s.component, s.retained, s.unmounted)
1798
+ },
1799
+ s.component
1800
+ )) }),
1801
+ /* @__PURE__ */ jsx4("p", { style: { color: "#666", fontSize: "10px", margin: "6px 0 0", lineHeight: 1.4 }, children: t.leakHint })
1802
+ ] });
1803
+ }
1804
+
1805
+ // src/render-insights.tsx
1806
+ import { jsx as jsx5, jsxs as jsxs5 } from "preact/jsx-runtime";
1767
1807
  function aggregate(signals) {
1768
1808
  const byName = /* @__PURE__ */ new Map();
1769
1809
  for (const s of signals) {
@@ -1794,7 +1834,7 @@ function RenderInsights({ signals, onSelect }) {
1794
1834
  const top = rows.slice(0, TOP_N);
1795
1835
  const max = top.length > 0 ? top[0].totalMs : 1;
1796
1836
  const hiddenCount = rows.length - top.length;
1797
- return /* @__PURE__ */ jsxs4(
1837
+ return /* @__PURE__ */ jsxs5(
1798
1838
  "div",
1799
1839
  {
1800
1840
  style: {
@@ -1805,12 +1845,12 @@ function RenderInsights({ signals, onSelect }) {
1805
1845
  borderRadius: "8px"
1806
1846
  },
1807
1847
  children: [
1808
- /* @__PURE__ */ jsx4("div", { style: { fontSize: "10px", color: "#888", textTransform: "uppercase", letterSpacing: "0.5px", marginBottom: "6px" }, children: t.topRenderers }),
1809
- /* @__PURE__ */ jsxs4("div", { style: { display: "flex", flexDirection: "column", gap: "4px" }, children: [
1848
+ /* @__PURE__ */ jsx5("div", { style: { fontSize: "10px", color: "#888", textTransform: "uppercase", letterSpacing: "0.5px", marginBottom: "6px" }, children: t.topRenderers }),
1849
+ /* @__PURE__ */ jsxs5("div", { style: { display: "flex", flexDirection: "column", gap: "4px" }, children: [
1810
1850
  top.map((a) => {
1811
1851
  const widthPct = max > 0 ? Math.max(2, a.totalMs / max * 100) : 0;
1812
1852
  const color = SEVERITY_COLOR[a.worstSeverity];
1813
- return /* @__PURE__ */ jsxs4(
1853
+ return /* @__PURE__ */ jsxs5(
1814
1854
  "div",
1815
1855
  {
1816
1856
  "data-component": a.component,
@@ -1826,8 +1866,8 @@ function RenderInsights({ signals, onSelect }) {
1826
1866
  },
1827
1867
  title: t.rendererDetail(a.component, a.count, a.totalMs, a.maxMs),
1828
1868
  children: [
1829
- /* @__PURE__ */ jsx4("strong", { style: { flex: "0 0 30%", overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }, children: a.component }),
1830
- /* @__PURE__ */ jsx4("div", { style: { flex: "1", position: "relative", height: "14px", background: "#1f1f1f", borderRadius: "2px" }, children: /* @__PURE__ */ jsx4(
1869
+ /* @__PURE__ */ jsx5("strong", { style: { flex: "0 0 30%", overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }, children: a.component }),
1870
+ /* @__PURE__ */ jsx5("div", { style: { flex: "1", position: "relative", height: "14px", background: "#1f1f1f", borderRadius: "2px" }, children: /* @__PURE__ */ jsx5(
1831
1871
  "div",
1832
1872
  {
1833
1873
  style: {
@@ -1842,11 +1882,11 @@ function RenderInsights({ signals, onSelect }) {
1842
1882
  }
1843
1883
  }
1844
1884
  ) }),
1845
- /* @__PURE__ */ jsxs4("span", { style: { flex: "0 0 auto", color, minWidth: "56px", textAlign: "right" }, children: [
1885
+ /* @__PURE__ */ jsxs5("span", { style: { flex: "0 0 auto", color, minWidth: "56px", textAlign: "right" }, children: [
1846
1886
  a.totalMs.toFixed(1),
1847
1887
  "ms"
1848
1888
  ] }),
1849
- /* @__PURE__ */ jsxs4("span", { style: { flex: "0 0 auto", color: "#888", minWidth: "32px", textAlign: "right" }, children: [
1889
+ /* @__PURE__ */ jsxs5("span", { style: { flex: "0 0 auto", color: "#888", minWidth: "32px", textAlign: "right" }, children: [
1850
1890
  "\xD7",
1851
1891
  a.count
1852
1892
  ] })
@@ -1855,7 +1895,7 @@ function RenderInsights({ signals, onSelect }) {
1855
1895
  a.component
1856
1896
  );
1857
1897
  }),
1858
- hiddenCount > 0 && /* @__PURE__ */ jsx4("div", { style: { fontSize: "10px", color: "#666", marginTop: "2px" }, children: t.moreComponents(hiddenCount) })
1898
+ hiddenCount > 0 && /* @__PURE__ */ jsx5("div", { style: { fontSize: "10px", color: "#666", marginTop: "2px" }, children: t.moreComponents(hiddenCount) })
1859
1899
  ] })
1860
1900
  ]
1861
1901
  }
@@ -1866,7 +1906,7 @@ function RenderInsights({ signals, onSelect }) {
1866
1906
  import { correlate } from "@react-perfscope/core";
1867
1907
 
1868
1908
  // src/episode-shared.tsx
1869
- import { Fragment as Fragment2, jsx as jsx5, jsxs as jsxs5 } from "preact/jsx-runtime";
1909
+ import { Fragment as Fragment2, jsx as jsx6, jsxs as jsxs6 } from "preact/jsx-runtime";
1870
1910
  function memberLabel(m) {
1871
1911
  const s = m.signal;
1872
1912
  if (s.kind === "render") return `${s.component} (${s.reason})`;
@@ -1877,18 +1917,18 @@ function memberLabel(m) {
1877
1917
  return `layout shift ${s.value.toFixed(3)}`;
1878
1918
  }
1879
1919
  function EpisodeMemberRow({ member }) {
1880
- return /* @__PURE__ */ jsxs5(
1920
+ return /* @__PURE__ */ jsxs6(
1881
1921
  "div",
1882
1922
  {
1883
1923
  "data-member-kind": member.signal.kind,
1884
1924
  style: { display: "flex", alignItems: "center", gap: "6px", padding: "1px 0", color: "#ccc" },
1885
1925
  children: [
1886
- /* @__PURE__ */ jsx5("span", { style: { overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }, children: memberLabel(member) }),
1887
- member.causedBy && /* @__PURE__ */ jsxs5("span", { style: { flex: "0 0 auto", color: "#888" }, children: [
1926
+ /* @__PURE__ */ jsx6("span", { style: { overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }, children: memberLabel(member) }),
1927
+ member.causedBy && /* @__PURE__ */ jsxs6("span", { style: { flex: "0 0 auto", color: "#888" }, children: [
1888
1928
  "\u2190 ",
1889
1929
  member.causedBy.component
1890
1930
  ] }),
1891
- member.confidence === "caused" && /* @__PURE__ */ jsx5(
1931
+ member.confidence === "caused" && /* @__PURE__ */ jsx6(
1892
1932
  "span",
1893
1933
  {
1894
1934
  style: {
@@ -1907,12 +1947,12 @@ function EpisodeMemberRow({ member }) {
1907
1947
  );
1908
1948
  }
1909
1949
  function EpisodeMemberList({ members }) {
1910
- if (members.length === 0) return /* @__PURE__ */ jsx5("span", { style: { color: "#555" }, children: "\u2014" });
1911
- return /* @__PURE__ */ jsx5(Fragment2, { children: members.map((m, i) => /* @__PURE__ */ jsx5(EpisodeMemberRow, { member: m }, i)) });
1950
+ if (members.length === 0) return /* @__PURE__ */ jsx6("span", { style: { color: "#555" }, children: "\u2014" });
1951
+ return /* @__PURE__ */ jsx6(Fragment2, { children: members.map((m, i) => /* @__PURE__ */ jsx6(EpisodeMemberRow, { member: m }, i)) });
1912
1952
  }
1913
1953
 
1914
1954
  // src/inp-episode.tsx
1915
- import { jsx as jsx6, jsxs as jsxs6 } from "preact/jsx-runtime";
1955
+ import { jsx as jsx7, jsxs as jsxs7 } from "preact/jsx-runtime";
1916
1956
  var PHASES = [
1917
1957
  { phase: "input-delay", labelKey: "inputDelay" },
1918
1958
  { phase: "processing", labelKey: "processingTime" },
@@ -1937,7 +1977,7 @@ function InpEpisode({ signals }) {
1937
1977
  if (!episode || episode.anchor.kind !== "interaction") return null;
1938
1978
  const a = episode.anchor;
1939
1979
  const target = a.target ? ` on ${a.target}` : "";
1940
- return /* @__PURE__ */ jsxs6(
1980
+ return /* @__PURE__ */ jsxs7(
1941
1981
  "div",
1942
1982
  {
1943
1983
  "data-inp-episode": true,
@@ -1951,33 +1991,33 @@ function InpEpisode({ signals }) {
1951
1991
  overflow: "hidden"
1952
1992
  },
1953
1993
  children: [
1954
- /* @__PURE__ */ jsxs6("div", { style: { padding: "6px 8px", borderBottom: "1px solid #1f1f1f", color: "#ddd" }, children: [
1955
- /* @__PURE__ */ jsx6("strong", { children: a.eventType }),
1994
+ /* @__PURE__ */ jsxs7("div", { style: { padding: "6px 8px", borderBottom: "1px solid #1f1f1f", color: "#ddd" }, children: [
1995
+ /* @__PURE__ */ jsx7("strong", { children: a.eventType }),
1956
1996
  target,
1957
1997
  " \u2014 ",
1958
- /* @__PURE__ */ jsxs6("strong", { children: [
1998
+ /* @__PURE__ */ jsxs7("strong", { children: [
1959
1999
  Math.round(a.duration),
1960
2000
  "ms"
1961
2001
  ] }),
1962
2002
  " ",
1963
- /* @__PURE__ */ jsx6("span", { style: { color: "#888" }, children: "INP" })
2003
+ /* @__PURE__ */ jsx7("span", { style: { color: "#888" }, children: "INP" })
1964
2004
  ] }),
1965
2005
  PHASES.map(({ phase, labelKey }) => {
1966
2006
  const members = episode.members.filter((m) => m.phase === phase);
1967
- return /* @__PURE__ */ jsxs6(
2007
+ return /* @__PURE__ */ jsxs7(
1968
2008
  "div",
1969
2009
  {
1970
2010
  "data-inp-phase": phase,
1971
2011
  style: { display: "flex", gap: "8px", padding: "5px 8px", borderTop: "1px solid #1a1a1a" },
1972
2012
  children: [
1973
- /* @__PURE__ */ jsxs6("div", { style: { flex: "0 0 92px", color: "#aaa" }, children: [
2013
+ /* @__PURE__ */ jsxs7("div", { style: { flex: "0 0 92px", color: "#aaa" }, children: [
1974
2014
  t[labelKey],
1975
- /* @__PURE__ */ jsxs6("div", { style: { color: "#666", fontSize: "10px" }, children: [
2015
+ /* @__PURE__ */ jsxs7("div", { style: { color: "#666", fontSize: "10px" }, children: [
1976
2016
  Math.round(phaseMs(episode, phase)),
1977
2017
  "ms"
1978
2018
  ] })
1979
2019
  ] }),
1980
- /* @__PURE__ */ jsx6("div", { style: { flex: 1, minWidth: 0 }, children: /* @__PURE__ */ jsx6(EpisodeMemberList, { members }) })
2020
+ /* @__PURE__ */ jsx7("div", { style: { flex: 1, minWidth: 0 }, children: /* @__PURE__ */ jsx7(EpisodeMemberList, { members }) })
1981
2021
  ]
1982
2022
  },
1983
2023
  phase
@@ -1990,7 +2030,7 @@ function InpEpisode({ signals }) {
1990
2030
 
1991
2031
  // src/long-task-episode.tsx
1992
2032
  import { correlate as correlate2 } from "@react-perfscope/core";
1993
- import { jsx as jsx7, jsxs as jsxs7 } from "preact/jsx-runtime";
2033
+ import { jsx as jsx8, jsxs as jsxs8 } from "preact/jsx-runtime";
1994
2034
  function worstLongTaskEpisode(signals) {
1995
2035
  let worst = null;
1996
2036
  for (const ep of correlate2(signals)) {
@@ -2005,7 +2045,7 @@ function LongTaskEpisode({ signals }) {
2005
2045
  if (!episode || episode.anchor.kind !== "long-task") return null;
2006
2046
  if (episode.members.length === 0) return null;
2007
2047
  const a = episode.anchor;
2008
- return /* @__PURE__ */ jsxs7(
2048
+ return /* @__PURE__ */ jsxs8(
2009
2049
  "div",
2010
2050
  {
2011
2051
  "data-long-task-episode": true,
@@ -2019,15 +2059,15 @@ function LongTaskEpisode({ signals }) {
2019
2059
  overflow: "hidden"
2020
2060
  },
2021
2061
  children: [
2022
- /* @__PURE__ */ jsxs7("div", { style: { padding: "6px 8px", borderBottom: "1px solid #1f1f1f", color: "#ddd" }, children: [
2023
- /* @__PURE__ */ jsx7("strong", { children: t.kindLabel("long-task") }),
2062
+ /* @__PURE__ */ jsxs8("div", { style: { padding: "6px 8px", borderBottom: "1px solid #1f1f1f", color: "#ddd" }, children: [
2063
+ /* @__PURE__ */ jsx8("strong", { children: t.kindLabel("long-task") }),
2024
2064
  " \u2014 ",
2025
- /* @__PURE__ */ jsxs7("strong", { children: [
2065
+ /* @__PURE__ */ jsxs8("strong", { children: [
2026
2066
  Math.round(a.duration),
2027
2067
  "ms"
2028
2068
  ] })
2029
2069
  ] }),
2030
- /* @__PURE__ */ jsx7("div", { style: { padding: "5px 8px" }, children: /* @__PURE__ */ jsx7(EpisodeMemberList, { members: episode.members }) })
2070
+ /* @__PURE__ */ jsx8("div", { style: { padding: "5px 8px" }, children: /* @__PURE__ */ jsx8(EpisodeMemberList, { members: episode.members }) })
2031
2071
  ]
2032
2072
  }
2033
2073
  );
@@ -2073,7 +2113,7 @@ function signalMatchesFilter(signal, query) {
2073
2113
  }
2074
2114
 
2075
2115
  // src/panel.tsx
2076
- import { Fragment as Fragment3, jsx as jsx8, jsxs as jsxs8 } from "preact/jsx-runtime";
2116
+ import { Fragment as Fragment3, jsx as jsx9, jsxs as jsxs9 } from "preact/jsx-runtime";
2077
2117
  var RENDER_REASON_COLOR = {
2078
2118
  mount: "#5ac8fa",
2079
2119
  state: "#34c759",
@@ -2097,7 +2137,7 @@ function RenderReasonTag({ reason, changedProps }) {
2097
2137
  const color = RENDER_REASON_COLOR[reason];
2098
2138
  const label = renderReasonLabel(t, reason);
2099
2139
  const keys = reason === "props" && changedProps && changedProps.length > 0 ? `: ${changedProps.join(", ")}` : "";
2100
- return /* @__PURE__ */ jsxs8(
2140
+ return /* @__PURE__ */ jsxs9(
2101
2141
  "span",
2102
2142
  {
2103
2143
  style: {
@@ -2153,7 +2193,7 @@ var WEB_VITAL_UNIT2 = {
2153
2193
  };
2154
2194
  function RatingDot({ rating }) {
2155
2195
  const { t } = useI18n();
2156
- return /* @__PURE__ */ jsx8(
2196
+ return /* @__PURE__ */ jsx9(
2157
2197
  "span",
2158
2198
  {
2159
2199
  "data-rating": rating,
@@ -2211,18 +2251,18 @@ var monoStyle = {
2211
2251
  };
2212
2252
  function LayoutShiftDetail({ s }) {
2213
2253
  const { t } = useI18n();
2214
- return /* @__PURE__ */ jsxs8("div", { style: { paddingLeft: "12px" }, children: [
2215
- /* @__PURE__ */ jsxs8("div", { style: detailRowStyle, children: [
2216
- /* @__PURE__ */ jsx8("span", { style: detailLabelStyle, children: t.value }),
2217
- /* @__PURE__ */ jsx8("span", { children: s.value.toFixed(4) })
2254
+ return /* @__PURE__ */ jsxs9("div", { style: { paddingLeft: "12px" }, children: [
2255
+ /* @__PURE__ */ jsxs9("div", { style: detailRowStyle, children: [
2256
+ /* @__PURE__ */ jsx9("span", { style: detailLabelStyle, children: t.value }),
2257
+ /* @__PURE__ */ jsx9("span", { children: s.value.toFixed(4) })
2218
2258
  ] }),
2219
- s.sources.length === 0 ? /* @__PURE__ */ jsx8("div", { style: { color: "#666" }, children: t.noSourceRects }) : s.sources.map((r, i) => /* @__PURE__ */ jsxs8("div", { style: { ...detailRowStyle, ...monoStyle }, children: [
2220
- /* @__PURE__ */ jsxs8("span", { style: { color: "#888" }, children: [
2259
+ s.sources.length === 0 ? /* @__PURE__ */ jsx9("div", { style: { color: "#666" }, children: t.noSourceRects }) : s.sources.map((r, i) => /* @__PURE__ */ jsxs9("div", { style: { ...detailRowStyle, ...monoStyle }, children: [
2260
+ /* @__PURE__ */ jsxs9("span", { style: { color: "#888" }, children: [
2221
2261
  t.rect,
2222
2262
  " ",
2223
2263
  i + 1
2224
2264
  ] }),
2225
- /* @__PURE__ */ jsxs8("span", { children: [
2265
+ /* @__PURE__ */ jsxs9("span", { children: [
2226
2266
  "x=",
2227
2267
  r.x.toFixed(0),
2228
2268
  " y=",
@@ -2237,25 +2277,25 @@ function LayoutShiftDetail({ s }) {
2237
2277
  }
2238
2278
  function NetworkDetail({ s }) {
2239
2279
  const { t } = useI18n();
2240
- return /* @__PURE__ */ jsxs8("div", { style: { paddingLeft: "12px" }, children: [
2241
- /* @__PURE__ */ jsx8("div", { style: { ...detailRowStyle, ...monoStyle, wordBreak: "break-all" }, children: /* @__PURE__ */ jsx8("span", { children: s.url }) }),
2242
- /* @__PURE__ */ jsxs8("div", { style: detailRowStyle, children: [
2243
- /* @__PURE__ */ jsx8("span", { style: detailLabelStyle, children: t.started }),
2244
- /* @__PURE__ */ jsxs8("span", { children: [
2280
+ return /* @__PURE__ */ jsxs9("div", { style: { paddingLeft: "12px" }, children: [
2281
+ /* @__PURE__ */ jsx9("div", { style: { ...detailRowStyle, ...monoStyle, wordBreak: "break-all" }, children: /* @__PURE__ */ jsx9("span", { children: s.url }) }),
2282
+ /* @__PURE__ */ jsxs9("div", { style: detailRowStyle, children: [
2283
+ /* @__PURE__ */ jsx9("span", { style: detailLabelStyle, children: t.started }),
2284
+ /* @__PURE__ */ jsxs9("span", { children: [
2245
2285
  s.startedAt.toFixed(0),
2246
2286
  "ms"
2247
2287
  ] })
2248
2288
  ] }),
2249
- /* @__PURE__ */ jsxs8("div", { style: detailRowStyle, children: [
2250
- /* @__PURE__ */ jsx8("span", { style: detailLabelStyle, children: t.duration }),
2251
- /* @__PURE__ */ jsxs8("span", { children: [
2289
+ /* @__PURE__ */ jsxs9("div", { style: detailRowStyle, children: [
2290
+ /* @__PURE__ */ jsx9("span", { style: detailLabelStyle, children: t.duration }),
2291
+ /* @__PURE__ */ jsxs9("span", { children: [
2252
2292
  s.duration.toFixed(0),
2253
2293
  "ms"
2254
2294
  ] })
2255
2295
  ] }),
2256
- /* @__PURE__ */ jsxs8("div", { style: detailRowStyle, children: [
2257
- /* @__PURE__ */ jsx8("span", { style: detailLabelStyle, children: t.size }),
2258
- /* @__PURE__ */ jsxs8("span", { children: [
2296
+ /* @__PURE__ */ jsxs9("div", { style: detailRowStyle, children: [
2297
+ /* @__PURE__ */ jsx9("span", { style: detailLabelStyle, children: t.size }),
2298
+ /* @__PURE__ */ jsxs9("span", { children: [
2259
2299
  (s.size / 1024).toFixed(2),
2260
2300
  "KB (",
2261
2301
  s.size,
@@ -2264,69 +2304,69 @@ function NetworkDetail({ s }) {
2264
2304
  ")"
2265
2305
  ] })
2266
2306
  ] }),
2267
- /* @__PURE__ */ jsxs8("div", { style: detailRowStyle, children: [
2268
- /* @__PURE__ */ jsx8("span", { style: detailLabelStyle, children: t.renderBlocking }),
2269
- /* @__PURE__ */ jsx8("span", { children: s.blocking ? t.yes : t.no })
2307
+ /* @__PURE__ */ jsxs9("div", { style: detailRowStyle, children: [
2308
+ /* @__PURE__ */ jsx9("span", { style: detailLabelStyle, children: t.renderBlocking }),
2309
+ /* @__PURE__ */ jsx9("span", { children: s.blocking ? t.yes : t.no })
2270
2310
  ] })
2271
2311
  ] });
2272
2312
  }
2273
2313
  function WebVitalDetail({ s }) {
2274
2314
  const { t } = useI18n();
2275
- return /* @__PURE__ */ jsxs8("div", { style: { paddingLeft: "12px" }, children: [
2276
- /* @__PURE__ */ jsxs8("div", { style: detailRowStyle, children: [
2277
- /* @__PURE__ */ jsx8("span", { style: detailLabelStyle, children: t.metric }),
2278
- /* @__PURE__ */ jsx8("span", { children: s.name })
2315
+ return /* @__PURE__ */ jsxs9("div", { style: { paddingLeft: "12px" }, children: [
2316
+ /* @__PURE__ */ jsxs9("div", { style: detailRowStyle, children: [
2317
+ /* @__PURE__ */ jsx9("span", { style: detailLabelStyle, children: t.metric }),
2318
+ /* @__PURE__ */ jsx9("span", { children: s.name })
2279
2319
  ] }),
2280
- /* @__PURE__ */ jsxs8("div", { style: detailRowStyle, children: [
2281
- /* @__PURE__ */ jsx8("span", { style: detailLabelStyle, children: t.value }),
2282
- /* @__PURE__ */ jsx8("span", { children: s.value.toFixed(2) })
2320
+ /* @__PURE__ */ jsxs9("div", { style: detailRowStyle, children: [
2321
+ /* @__PURE__ */ jsx9("span", { style: detailLabelStyle, children: t.value }),
2322
+ /* @__PURE__ */ jsx9("span", { children: s.value.toFixed(2) })
2283
2323
  ] })
2284
2324
  ] });
2285
2325
  }
2286
2326
  function RenderDetail({ s }) {
2287
2327
  const { t } = useI18n();
2288
2328
  if (s.members && s.members.length > 0) {
2289
- return /* @__PURE__ */ jsxs8("div", { style: { paddingLeft: "12px" }, children: [
2290
- /* @__PURE__ */ jsxs8("div", { style: detailRowStyle, children: [
2291
- /* @__PURE__ */ jsx8("span", { style: detailLabelStyle, children: t.duration }),
2292
- /* @__PURE__ */ jsxs8("span", { children: [
2329
+ return /* @__PURE__ */ jsxs9("div", { style: { paddingLeft: "12px" }, children: [
2330
+ /* @__PURE__ */ jsxs9("div", { style: detailRowStyle, children: [
2331
+ /* @__PURE__ */ jsx9("span", { style: detailLabelStyle, children: t.duration }),
2332
+ /* @__PURE__ */ jsxs9("span", { children: [
2293
2333
  s.duration.toFixed(3),
2294
2334
  "ms"
2295
2335
  ] })
2296
2336
  ] }),
2297
- /* @__PURE__ */ jsxs8("div", { style: detailRowStyle, children: [
2298
- /* @__PURE__ */ jsx8("span", { style: detailLabelStyle, children: t.at }),
2299
- /* @__PURE__ */ jsxs8("span", { children: [
2337
+ /* @__PURE__ */ jsxs9("div", { style: detailRowStyle, children: [
2338
+ /* @__PURE__ */ jsx9("span", { style: detailLabelStyle, children: t.at }),
2339
+ /* @__PURE__ */ jsxs9("span", { children: [
2300
2340
  s.at.toFixed(2),
2301
2341
  "ms"
2302
2342
  ] })
2303
2343
  ] }),
2304
- /* @__PURE__ */ jsx8("div", { style: { marginTop: "6px" }, children: /* @__PURE__ */ jsx8(CascadeMembers, { members: s.members }) })
2344
+ /* @__PURE__ */ jsx9("div", { style: { marginTop: "6px" }, children: /* @__PURE__ */ jsx9(CascadeMembers, { members: s.members }) })
2305
2345
  ] });
2306
2346
  }
2307
- return /* @__PURE__ */ jsxs8("div", { style: { paddingLeft: "12px" }, children: [
2308
- /* @__PURE__ */ jsxs8("div", { style: detailRowStyle, children: [
2309
- /* @__PURE__ */ jsx8("span", { style: detailLabelStyle, children: t.component }),
2310
- /* @__PURE__ */ jsx8("span", { children: s.component })
2347
+ return /* @__PURE__ */ jsxs9("div", { style: { paddingLeft: "12px" }, children: [
2348
+ /* @__PURE__ */ jsxs9("div", { style: detailRowStyle, children: [
2349
+ /* @__PURE__ */ jsx9("span", { style: detailLabelStyle, children: t.component }),
2350
+ /* @__PURE__ */ jsx9("span", { children: s.component })
2311
2351
  ] }),
2312
- /* @__PURE__ */ jsxs8("div", { style: detailRowStyle, children: [
2313
- /* @__PURE__ */ jsx8("span", { style: detailLabelStyle, children: t.reason }),
2314
- /* @__PURE__ */ jsx8(RenderReasonTag, { reason: s.reason, changedProps: s.changedProps })
2352
+ /* @__PURE__ */ jsxs9("div", { style: detailRowStyle, children: [
2353
+ /* @__PURE__ */ jsx9("span", { style: detailLabelStyle, children: t.reason }),
2354
+ /* @__PURE__ */ jsx9(RenderReasonTag, { reason: s.reason, changedProps: s.changedProps })
2315
2355
  ] }),
2316
- s.reason === "props" && s.changedProps && s.changedProps.length > 0 && /* @__PURE__ */ jsxs8("div", { style: { ...detailRowStyle, ...monoStyle }, children: [
2317
- /* @__PURE__ */ jsx8("span", { style: detailLabelStyle, children: t.changedProps }),
2318
- /* @__PURE__ */ jsx8("span", { children: s.changedProps.join(", ") })
2356
+ s.reason === "props" && s.changedProps && s.changedProps.length > 0 && /* @__PURE__ */ jsxs9("div", { style: { ...detailRowStyle, ...monoStyle }, children: [
2357
+ /* @__PURE__ */ jsx9("span", { style: detailLabelStyle, children: t.changedProps }),
2358
+ /* @__PURE__ */ jsx9("span", { children: s.changedProps.join(", ") })
2319
2359
  ] }),
2320
- /* @__PURE__ */ jsxs8("div", { style: detailRowStyle, children: [
2321
- /* @__PURE__ */ jsx8("span", { style: detailLabelStyle, children: t.duration }),
2322
- /* @__PURE__ */ jsxs8("span", { children: [
2360
+ /* @__PURE__ */ jsxs9("div", { style: detailRowStyle, children: [
2361
+ /* @__PURE__ */ jsx9("span", { style: detailLabelStyle, children: t.duration }),
2362
+ /* @__PURE__ */ jsxs9("span", { children: [
2323
2363
  s.duration.toFixed(3),
2324
2364
  "ms"
2325
2365
  ] })
2326
2366
  ] }),
2327
- /* @__PURE__ */ jsxs8("div", { style: detailRowStyle, children: [
2328
- /* @__PURE__ */ jsx8("span", { style: detailLabelStyle, children: t.at }),
2329
- /* @__PURE__ */ jsxs8("span", { children: [
2367
+ /* @__PURE__ */ jsxs9("div", { style: detailRowStyle, children: [
2368
+ /* @__PURE__ */ jsx9("span", { style: detailLabelStyle, children: t.at }),
2369
+ /* @__PURE__ */ jsxs9("span", { children: [
2330
2370
  s.at.toFixed(2),
2331
2371
  "ms"
2332
2372
  ] })
@@ -2356,11 +2396,11 @@ function StackFrames({
2356
2396
  cancelled = true;
2357
2397
  };
2358
2398
  }, [raw]);
2359
- return /* @__PURE__ */ jsxs8(Fragment3, { children: [
2360
- resolving && /* @__PURE__ */ jsx8("div", { style: { color: "#666", fontSize: "10px", marginBottom: "4px" }, children: t.resolvingSourceMaps }),
2361
- frames.length === 0 ? /* @__PURE__ */ jsx8("div", { style: { color: "#666" }, children: t.noStack }) : frames.map((f, i) => /* @__PURE__ */ jsxs8("div", { style: { ...detailRowStyle, ...monoStyle }, children: [
2362
- f.fnName ? /* @__PURE__ */ jsx8("span", { children: f.fnName }) : /* @__PURE__ */ jsx8("span", { style: { color: "#666" }, children: t.anonymous }),
2363
- /* @__PURE__ */ jsxs8("span", { style: { color: "#888" }, children: [
2399
+ return /* @__PURE__ */ jsxs9(Fragment3, { children: [
2400
+ resolving && /* @__PURE__ */ jsx9("div", { style: { color: "#666", fontSize: "10px", marginBottom: "4px" }, children: t.resolvingSourceMaps }),
2401
+ frames.length === 0 ? /* @__PURE__ */ jsx9("div", { style: { color: "#666" }, children: t.noStack }) : frames.map((f, i) => /* @__PURE__ */ jsxs9("div", { style: { ...detailRowStyle, ...monoStyle }, children: [
2402
+ f.fnName ? /* @__PURE__ */ jsx9("span", { children: f.fnName }) : /* @__PURE__ */ jsx9("span", { style: { color: "#666" }, children: t.anonymous }),
2403
+ /* @__PURE__ */ jsxs9("span", { style: { color: "#888" }, children: [
2364
2404
  f.file,
2365
2405
  ":",
2366
2406
  f.line,
@@ -2374,7 +2414,7 @@ function ForcedReflowDetail({
2374
2414
  s,
2375
2415
  resolveFrame
2376
2416
  }) {
2377
- return /* @__PURE__ */ jsx8("div", { style: { paddingLeft: "12px" }, children: /* @__PURE__ */ jsx8(StackFrames, { raw: s.stack, resolveFrame }) });
2417
+ return /* @__PURE__ */ jsx9("div", { style: { paddingLeft: "12px" }, children: /* @__PURE__ */ jsx9(StackFrames, { raw: s.stack, resolveFrame }) });
2378
2418
  }
2379
2419
  function HotFunctions({
2380
2420
  attribution,
@@ -2393,26 +2433,26 @@ function HotFunctions({
2393
2433
  cancelled = true;
2394
2434
  };
2395
2435
  }, [attribution]);
2396
- return /* @__PURE__ */ jsxs8("div", { style: { marginTop: "6px" }, children: [
2397
- /* @__PURE__ */ jsx8("div", { style: { ...detailLabelStyle, textTransform: "uppercase", fontSize: "10px", letterSpacing: "0.5px", marginBottom: "1px", color: "#ff9f0a" }, children: t.hotFunctions }),
2398
- /* @__PURE__ */ jsx8("div", { style: { color: "#666", fontSize: "10px", marginBottom: "4px" }, children: t.hotFunctionsHint }),
2436
+ return /* @__PURE__ */ jsxs9("div", { style: { marginTop: "6px" }, children: [
2437
+ /* @__PURE__ */ jsx9("div", { style: { ...detailLabelStyle, textTransform: "uppercase", fontSize: "10px", letterSpacing: "0.5px", marginBottom: "1px", color: "#ff9f0a" }, children: t.hotFunctions }),
2438
+ /* @__PURE__ */ jsx9("div", { style: { color: "#666", fontSize: "10px", marginBottom: "4px" }, children: t.hotFunctionsHint }),
2399
2439
  attribution.map((a, i) => {
2400
2440
  const f = frames[i] ?? a.frame;
2401
2441
  const pct = Math.round(a.selfRatio * 100);
2402
- return /* @__PURE__ */ jsxs8("div", { style: { ...monoStyle, padding: "3px 0", borderTop: i > 0 ? "1px dashed #1f1f1f" : "none" }, children: [
2403
- /* @__PURE__ */ jsxs8("div", { children: [
2404
- /* @__PURE__ */ jsx8("span", { style: { color: "#ff9f0a", fontWeight: 600 }, children: f.fnName || /* @__PURE__ */ jsx8("span", { style: { color: "#666" }, children: t.anonymous }) }),
2405
- /* @__PURE__ */ jsxs8("span", { style: { color: SEVERITY_COLOR.medium, marginLeft: "6px" }, children: [
2442
+ return /* @__PURE__ */ jsxs9("div", { style: { ...monoStyle, padding: "3px 0", borderTop: i > 0 ? "1px dashed #1f1f1f" : "none" }, children: [
2443
+ /* @__PURE__ */ jsxs9("div", { children: [
2444
+ /* @__PURE__ */ jsx9("span", { style: { color: "#ff9f0a", fontWeight: 600 }, children: f.fnName || /* @__PURE__ */ jsx9("span", { style: { color: "#666" }, children: t.anonymous }) }),
2445
+ /* @__PURE__ */ jsxs9("span", { style: { color: SEVERITY_COLOR.medium, marginLeft: "6px" }, children: [
2406
2446
  pct,
2407
2447
  "%"
2408
2448
  ] }),
2409
- /* @__PURE__ */ jsxs8("span", { style: { color: "#666", marginLeft: "6px" }, children: [
2449
+ /* @__PURE__ */ jsxs9("span", { style: { color: "#666", marginLeft: "6px" }, children: [
2410
2450
  "(",
2411
2451
  a.sampleCount,
2412
2452
  ")"
2413
2453
  ] })
2414
2454
  ] }),
2415
- /* @__PURE__ */ jsxs8("div", { style: { color: "#888", wordBreak: "break-all" }, children: [
2455
+ /* @__PURE__ */ jsxs9("div", { style: { color: "#888", wordBreak: "break-all" }, children: [
2416
2456
  f.file,
2417
2457
  ":",
2418
2458
  f.line,
@@ -2429,59 +2469,59 @@ function LongTaskDetail({
2429
2469
  }) {
2430
2470
  const { t } = useI18n();
2431
2471
  const scripts = s.scripts ? [...s.scripts].sort((a, b) => b.duration - a.duration) : [];
2432
- return /* @__PURE__ */ jsxs8("div", { style: { paddingLeft: "12px" }, children: [
2433
- /* @__PURE__ */ jsxs8("div", { style: detailRowStyle, children: [
2434
- /* @__PURE__ */ jsx8("span", { style: detailLabelStyle, children: t.started }),
2435
- /* @__PURE__ */ jsxs8("span", { children: [
2472
+ return /* @__PURE__ */ jsxs9("div", { style: { paddingLeft: "12px" }, children: [
2473
+ /* @__PURE__ */ jsxs9("div", { style: detailRowStyle, children: [
2474
+ /* @__PURE__ */ jsx9("span", { style: detailLabelStyle, children: t.started }),
2475
+ /* @__PURE__ */ jsxs9("span", { children: [
2436
2476
  s.at.toFixed(2),
2437
2477
  "ms"
2438
2478
  ] })
2439
2479
  ] }),
2440
- /* @__PURE__ */ jsxs8("div", { style: detailRowStyle, children: [
2441
- /* @__PURE__ */ jsx8("span", { style: detailLabelStyle, children: t.ended }),
2442
- /* @__PURE__ */ jsxs8("span", { children: [
2480
+ /* @__PURE__ */ jsxs9("div", { style: detailRowStyle, children: [
2481
+ /* @__PURE__ */ jsx9("span", { style: detailLabelStyle, children: t.ended }),
2482
+ /* @__PURE__ */ jsxs9("span", { children: [
2443
2483
  (s.at + s.duration).toFixed(2),
2444
2484
  "ms"
2445
2485
  ] })
2446
2486
  ] }),
2447
- /* @__PURE__ */ jsxs8("div", { style: detailRowStyle, children: [
2448
- /* @__PURE__ */ jsx8("span", { style: detailLabelStyle, children: t.duration }),
2449
- /* @__PURE__ */ jsxs8("span", { children: [
2487
+ /* @__PURE__ */ jsxs9("div", { style: detailRowStyle, children: [
2488
+ /* @__PURE__ */ jsx9("span", { style: detailLabelStyle, children: t.duration }),
2489
+ /* @__PURE__ */ jsxs9("span", { children: [
2450
2490
  s.duration.toFixed(2),
2451
2491
  "ms"
2452
2492
  ] })
2453
2493
  ] }),
2454
- typeof s.blockingDuration === "number" && /* @__PURE__ */ jsxs8("div", { style: detailRowStyle, children: [
2455
- /* @__PURE__ */ jsx8("span", { style: detailLabelStyle, children: t.blockingTime }),
2456
- /* @__PURE__ */ jsxs8("span", { children: [
2494
+ typeof s.blockingDuration === "number" && /* @__PURE__ */ jsxs9("div", { style: detailRowStyle, children: [
2495
+ /* @__PURE__ */ jsx9("span", { style: detailLabelStyle, children: t.blockingTime }),
2496
+ /* @__PURE__ */ jsxs9("span", { children: [
2457
2497
  s.blockingDuration.toFixed(2),
2458
2498
  "ms"
2459
2499
  ] })
2460
2500
  ] }),
2461
- s.attribution !== void 0 && s.attribution.length > 0 && /* @__PURE__ */ jsx8(HotFunctions, { attribution: s.attribution, resolveFrame }),
2462
- s.scripts !== void 0 && /* @__PURE__ */ jsxs8("div", { style: { marginTop: "6px" }, children: [
2463
- /* @__PURE__ */ jsx8("div", { style: { ...detailLabelStyle, textTransform: "uppercase", fontSize: "10px", letterSpacing: "0.5px", marginBottom: "4px" }, children: t.scripts }),
2464
- scripts.length === 0 ? /* @__PURE__ */ jsx8("div", { style: { color: "#666" }, children: t.noScripts }) : scripts.map((script, i) => /* @__PURE__ */ jsxs8("div", { style: { ...monoStyle, padding: "3px 0", borderTop: i > 0 ? "1px dashed #1f1f1f" : "none" }, children: [
2465
- /* @__PURE__ */ jsxs8("div", { children: [
2466
- /* @__PURE__ */ jsx8("span", { children: script.sourceFunctionName || /* @__PURE__ */ jsx8("span", { style: { color: "#666" }, children: t.anonymous }) }),
2467
- /* @__PURE__ */ jsx8("span", { style: { color: "#5ac8fa", marginLeft: "6px" }, children: script.invokerType }),
2468
- /* @__PURE__ */ jsxs8("span", { style: { color: SEVERITY_COLOR.medium, marginLeft: "6px" }, children: [
2501
+ s.attribution !== void 0 && s.attribution.length > 0 && /* @__PURE__ */ jsx9(HotFunctions, { attribution: s.attribution, resolveFrame }),
2502
+ s.scripts !== void 0 && /* @__PURE__ */ jsxs9("div", { style: { marginTop: "6px" }, children: [
2503
+ /* @__PURE__ */ jsx9("div", { style: { ...detailLabelStyle, textTransform: "uppercase", fontSize: "10px", letterSpacing: "0.5px", marginBottom: "4px" }, children: t.scripts }),
2504
+ scripts.length === 0 ? /* @__PURE__ */ jsx9("div", { style: { color: "#666" }, children: t.noScripts }) : scripts.map((script, i) => /* @__PURE__ */ jsxs9("div", { style: { ...monoStyle, padding: "3px 0", borderTop: i > 0 ? "1px dashed #1f1f1f" : "none" }, children: [
2505
+ /* @__PURE__ */ jsxs9("div", { children: [
2506
+ /* @__PURE__ */ jsx9("span", { children: script.sourceFunctionName || /* @__PURE__ */ jsx9("span", { style: { color: "#666" }, children: t.anonymous }) }),
2507
+ /* @__PURE__ */ jsx9("span", { style: { color: "#5ac8fa", marginLeft: "6px" }, children: script.invokerType }),
2508
+ /* @__PURE__ */ jsxs9("span", { style: { color: SEVERITY_COLOR.medium, marginLeft: "6px" }, children: [
2469
2509
  script.duration.toFixed(1),
2470
2510
  "ms"
2471
2511
  ] })
2472
2512
  ] }),
2473
- script.sourceURL && /* @__PURE__ */ jsxs8("div", { style: { color: "#888", wordBreak: "break-all" }, children: [
2513
+ script.sourceURL && /* @__PURE__ */ jsxs9("div", { style: { color: "#888", wordBreak: "break-all" }, children: [
2474
2514
  script.sourceURL,
2475
2515
  script.charPosition >= 0 ? `@${script.charPosition}` : ""
2476
2516
  ] }),
2477
- script.invoker && /* @__PURE__ */ jsxs8("div", { style: { color: "#666" }, children: [
2517
+ script.invoker && /* @__PURE__ */ jsxs9("div", { style: { color: "#666" }, children: [
2478
2518
  t.invoker,
2479
2519
  ": ",
2480
2520
  script.invoker
2481
2521
  ] })
2482
2522
  ] }, i))
2483
2523
  ] }),
2484
- s.scripts === void 0 && s.stack.length > 0 && /* @__PURE__ */ jsx8("div", { style: { marginTop: "4px" }, children: /* @__PURE__ */ jsx8(StackFrames, { raw: s.stack, resolveFrame, limit: 5 }) })
2524
+ s.scripts === void 0 && s.stack.length > 0 && /* @__PURE__ */ jsx9("div", { style: { marginTop: "4px" }, children: /* @__PURE__ */ jsx9(StackFrames, { raw: s.stack, resolveFrame, limit: 5 }) })
2485
2525
  ] });
2486
2526
  }
2487
2527
  var INTERACTION_PHASE_COLOR = { input: "#8e8e93", processing: "#5ac8fa", presentation: "#34c759" };
@@ -2496,33 +2536,33 @@ function InteractionDetail({
2496
2536
  { label: t.processingTime, ms: s.processing, color: INTERACTION_PHASE_COLOR.processing },
2497
2537
  { label: t.presentation, ms: s.presentation, color: INTERACTION_PHASE_COLOR.presentation }
2498
2538
  ];
2499
- return /* @__PURE__ */ jsxs8("div", { style: { paddingLeft: "12px" }, children: [
2500
- /* @__PURE__ */ jsxs8("div", { style: detailRowStyle, children: [
2501
- /* @__PURE__ */ jsx8("span", { style: detailLabelStyle, children: t.interactionEvent }),
2502
- /* @__PURE__ */ jsxs8("span", { children: [
2539
+ return /* @__PURE__ */ jsxs9("div", { style: { paddingLeft: "12px" }, children: [
2540
+ /* @__PURE__ */ jsxs9("div", { style: detailRowStyle, children: [
2541
+ /* @__PURE__ */ jsx9("span", { style: detailLabelStyle, children: t.interactionEvent }),
2542
+ /* @__PURE__ */ jsxs9("span", { children: [
2503
2543
  s.eventType,
2504
2544
  s.target ? ` \xB7 ${s.target}` : ""
2505
2545
  ] })
2506
2546
  ] }),
2507
- /* @__PURE__ */ jsxs8("div", { style: detailRowStyle, children: [
2508
- /* @__PURE__ */ jsx8("span", { style: detailLabelStyle, children: t.duration }),
2509
- /* @__PURE__ */ jsxs8("span", { children: [
2547
+ /* @__PURE__ */ jsxs9("div", { style: detailRowStyle, children: [
2548
+ /* @__PURE__ */ jsx9("span", { style: detailLabelStyle, children: t.duration }),
2549
+ /* @__PURE__ */ jsxs9("span", { children: [
2510
2550
  s.duration.toFixed(0),
2511
2551
  "ms"
2512
2552
  ] })
2513
2553
  ] }),
2514
- /* @__PURE__ */ jsx8("div", { style: { display: "flex", height: "10px", borderRadius: "3px", overflow: "hidden", margin: "5px 0 7px", background: "#1a1a1a" }, children: phases.map((p, i) => /* @__PURE__ */ jsx8("div", { style: { width: `${p.ms / total * 100}%`, background: p.color } }, i)) }),
2515
- phases.map((p, i) => /* @__PURE__ */ jsxs8("div", { style: detailRowStyle, children: [
2516
- /* @__PURE__ */ jsxs8("span", { style: { ...detailLabelStyle, display: "inline-flex", alignItems: "center", gap: "5px" }, children: [
2517
- /* @__PURE__ */ jsx8("span", { style: { width: "7px", height: "7px", borderRadius: "2px", background: p.color, flex: "0 0 7px" } }),
2554
+ /* @__PURE__ */ jsx9("div", { style: { display: "flex", height: "10px", borderRadius: "3px", overflow: "hidden", margin: "5px 0 7px", background: "#1a1a1a" }, children: phases.map((p, i) => /* @__PURE__ */ jsx9("div", { style: { width: `${p.ms / total * 100}%`, background: p.color } }, i)) }),
2555
+ phases.map((p, i) => /* @__PURE__ */ jsxs9("div", { style: detailRowStyle, children: [
2556
+ /* @__PURE__ */ jsxs9("span", { style: { ...detailLabelStyle, display: "inline-flex", alignItems: "center", gap: "5px" }, children: [
2557
+ /* @__PURE__ */ jsx9("span", { style: { width: "7px", height: "7px", borderRadius: "2px", background: p.color, flex: "0 0 7px" } }),
2518
2558
  p.label
2519
2559
  ] }),
2520
- /* @__PURE__ */ jsxs8("span", { children: [
2560
+ /* @__PURE__ */ jsxs9("span", { children: [
2521
2561
  p.ms.toFixed(0),
2522
2562
  "ms"
2523
2563
  ] })
2524
2564
  ] }, i)),
2525
- s.attribution !== void 0 && s.attribution.length > 0 && /* @__PURE__ */ jsx8(HotFunctions, { attribution: s.attribution, resolveFrame })
2565
+ s.attribution !== void 0 && s.attribution.length > 0 && /* @__PURE__ */ jsx9(HotFunctions, { attribution: s.attribution, resolveFrame })
2526
2566
  ] });
2527
2567
  }
2528
2568
  function SignalDetail({
@@ -2531,24 +2571,24 @@ function SignalDetail({
2531
2571
  }) {
2532
2572
  switch (s.kind) {
2533
2573
  case "forced-reflow":
2534
- return /* @__PURE__ */ jsx8(ForcedReflowDetail, { s, resolveFrame });
2574
+ return /* @__PURE__ */ jsx9(ForcedReflowDetail, { s, resolveFrame });
2535
2575
  case "layout-shift":
2536
- return /* @__PURE__ */ jsx8(LayoutShiftDetail, { s });
2576
+ return /* @__PURE__ */ jsx9(LayoutShiftDetail, { s });
2537
2577
  case "long-task":
2538
- return /* @__PURE__ */ jsx8(LongTaskDetail, { s, resolveFrame });
2578
+ return /* @__PURE__ */ jsx9(LongTaskDetail, { s, resolveFrame });
2539
2579
  case "interaction":
2540
- return /* @__PURE__ */ jsx8(InteractionDetail, { s, resolveFrame });
2580
+ return /* @__PURE__ */ jsx9(InteractionDetail, { s, resolveFrame });
2541
2581
  case "network":
2542
- return /* @__PURE__ */ jsx8(NetworkDetail, { s });
2582
+ return /* @__PURE__ */ jsx9(NetworkDetail, { s });
2543
2583
  case "web-vital":
2544
- return /* @__PURE__ */ jsx8(WebVitalDetail, { s });
2584
+ return /* @__PURE__ */ jsx9(WebVitalDetail, { s });
2545
2585
  case "render":
2546
- return /* @__PURE__ */ jsx8(RenderDetail, { s });
2586
+ return /* @__PURE__ */ jsx9(RenderDetail, { s });
2547
2587
  }
2548
2588
  }
2549
2589
  function SeverityDot({ sev, title }) {
2550
2590
  const { t } = useI18n();
2551
- return /* @__PURE__ */ jsx8(
2591
+ return /* @__PURE__ */ jsx9(
2552
2592
  "span",
2553
2593
  {
2554
2594
  "data-severity": sev,
@@ -2571,9 +2611,9 @@ function SummaryLine({ signal }) {
2571
2611
  if (signal.kind === "web-vital") {
2572
2612
  const rating = webVitalRating(signal.name, signal.value);
2573
2613
  const unit = WEB_VITAL_UNIT2[signal.name];
2574
- return /* @__PURE__ */ jsxs8("span", { children: [
2575
- /* @__PURE__ */ jsx8(RatingDot, { rating }),
2576
- /* @__PURE__ */ jsx8("strong", { children: signal.name }),
2614
+ return /* @__PURE__ */ jsxs9("span", { children: [
2615
+ /* @__PURE__ */ jsx9(RatingDot, { rating }),
2616
+ /* @__PURE__ */ jsx9("strong", { children: signal.name }),
2577
2617
  ": ",
2578
2618
  signal.value.toFixed(2),
2579
2619
  unit
@@ -2582,12 +2622,12 @@ function SummaryLine({ signal }) {
2582
2622
  const sev = severityForSignal(signal);
2583
2623
  const color = SEVERITY_COLOR[sev];
2584
2624
  if (signal.kind === "long-task") {
2585
- return /* @__PURE__ */ jsxs8("span", { children: [
2625
+ return /* @__PURE__ */ jsxs9("span", { children: [
2586
2626
  "@ ",
2587
2627
  signal.at.toFixed(1),
2588
2628
  "ms \u2022 duration",
2589
2629
  " ",
2590
- /* @__PURE__ */ jsxs8("span", { style: { color }, children: [
2630
+ /* @__PURE__ */ jsxs9("span", { style: { color }, children: [
2591
2631
  signal.duration.toFixed(1),
2592
2632
  "ms"
2593
2633
  ] })
@@ -2595,59 +2635,59 @@ function SummaryLine({ signal }) {
2595
2635
  }
2596
2636
  if (signal.kind === "forced-reflow") {
2597
2637
  const count = signal.count ?? 1;
2598
- return /* @__PURE__ */ jsxs8("span", { children: [
2638
+ return /* @__PURE__ */ jsxs9("span", { children: [
2599
2639
  "@ ",
2600
2640
  signal.at.toFixed(1),
2601
2641
  "ms \u2022 duration",
2602
2642
  " ",
2603
- /* @__PURE__ */ jsxs8("span", { style: { color }, children: [
2643
+ /* @__PURE__ */ jsxs9("span", { style: { color }, children: [
2604
2644
  signal.duration.toFixed(2),
2605
2645
  "ms"
2606
2646
  ] }),
2607
- count > 1 && /* @__PURE__ */ jsxs8("span", { style: { color: "#888" }, children: [
2647
+ count > 1 && /* @__PURE__ */ jsxs9("span", { style: { color: "#888" }, children: [
2608
2648
  " \u2022 ",
2609
2649
  t.coalescedReads(count)
2610
2650
  ] })
2611
2651
  ] });
2612
2652
  }
2613
2653
  if (signal.kind === "layout-shift") {
2614
- return /* @__PURE__ */ jsxs8("span", { children: [
2654
+ return /* @__PURE__ */ jsxs9("span", { children: [
2615
2655
  "@ ",
2616
2656
  signal.at.toFixed(1),
2617
2657
  "ms \u2022 value",
2618
2658
  " ",
2619
- /* @__PURE__ */ jsx8("span", { style: { color }, children: formatCls(signal.value) }),
2659
+ /* @__PURE__ */ jsx9("span", { style: { color }, children: formatCls(signal.value) }),
2620
2660
  " \u2022 ",
2621
2661
  t.sourceCount(signal.sources.length)
2622
2662
  ] });
2623
2663
  }
2624
2664
  if (signal.kind === "render") {
2625
- return /* @__PURE__ */ jsxs8("span", { style: { display: "inline-flex", alignItems: "center", gap: "6px" }, children: [
2626
- /* @__PURE__ */ jsx8("strong", { children: signal.component }),
2627
- /* @__PURE__ */ jsx8(RenderReasonTag, { reason: signal.reason, changedProps: signal.changedProps }),
2628
- /* @__PURE__ */ jsxs8("span", { style: { color }, children: [
2665
+ return /* @__PURE__ */ jsxs9("span", { style: { display: "inline-flex", alignItems: "center", gap: "6px" }, children: [
2666
+ /* @__PURE__ */ jsx9("strong", { children: signal.component }),
2667
+ /* @__PURE__ */ jsx9(RenderReasonTag, { reason: signal.reason, changedProps: signal.changedProps }),
2668
+ /* @__PURE__ */ jsxs9("span", { style: { color }, children: [
2629
2669
  signal.duration.toFixed(2),
2630
2670
  "ms"
2631
2671
  ] }),
2632
- signal.count && signal.count > 1 && /* @__PURE__ */ jsx8("span", { style: { color: "#888" }, children: t.cascadeComponents(signal.count) })
2672
+ signal.count && signal.count > 1 && /* @__PURE__ */ jsx9("span", { style: { color: "#888" }, children: t.cascadeComponents(signal.count) })
2633
2673
  ] });
2634
2674
  }
2635
2675
  if (signal.kind === "network") {
2636
2676
  const url = signal.url.length > 60 ? signal.url.slice(0, 57) + "..." : signal.url;
2637
- return /* @__PURE__ */ jsxs8("span", { children: [
2677
+ return /* @__PURE__ */ jsxs9("span", { children: [
2638
2678
  url,
2639
2679
  " \u2022 ",
2640
- /* @__PURE__ */ jsxs8("span", { style: { color }, children: [
2680
+ /* @__PURE__ */ jsxs9("span", { style: { color }, children: [
2641
2681
  signal.duration.toFixed(0),
2642
2682
  "ms"
2643
2683
  ] }),
2644
- signal.blocking && /* @__PURE__ */ jsxs8("span", { style: { color: SEVERITY_COLOR.high }, children: [
2684
+ signal.blocking && /* @__PURE__ */ jsxs9("span", { style: { color: SEVERITY_COLOR.high }, children: [
2645
2685
  " \u2022 ",
2646
2686
  t.blocking
2647
2687
  ] })
2648
2688
  ] });
2649
2689
  }
2650
- return /* @__PURE__ */ jsx8("span", { children: summary(signal) });
2690
+ return /* @__PURE__ */ jsx9("span", { children: summary(signal) });
2651
2691
  }
2652
2692
  function tabSupportsGrouping(kind) {
2653
2693
  return kind === "render" || kind === "forced-reflow";
@@ -2721,7 +2761,7 @@ function groupSignals(signals, mode, kind) {
2721
2761
  function SignalRow({ signal, expanded, onToggleExpand, onHoverGeometry, resolveFrame }) {
2722
2762
  const hasGeometry = signal.kind === "layout-shift" && signal.sources.length > 0;
2723
2763
  const sev = severityForSignal(signal);
2724
- return /* @__PURE__ */ jsxs8(
2764
+ return /* @__PURE__ */ jsxs9(
2725
2765
  "li",
2726
2766
  {
2727
2767
  "aria-expanded": expanded,
@@ -2743,22 +2783,22 @@ function SignalRow({ signal, expanded, onToggleExpand, onHoverGeometry, resolveF
2743
2783
  userSelect: "none"
2744
2784
  },
2745
2785
  children: [
2746
- /* @__PURE__ */ jsxs8("div", { style: { display: "flex", alignItems: "center", gap: "6px" }, children: [
2747
- /* @__PURE__ */ jsx8("span", { style: { color: "#888", width: "10px" }, children: expanded ? "\u25BC" : "\u25B6" }),
2748
- /* @__PURE__ */ jsx8(SeverityDot, { sev }),
2749
- /* @__PURE__ */ jsx8(SummaryLine, { signal })
2786
+ /* @__PURE__ */ jsxs9("div", { style: { display: "flex", alignItems: "center", gap: "6px" }, children: [
2787
+ /* @__PURE__ */ jsx9("span", { style: { color: "#888", width: "10px" }, children: expanded ? "\u25BC" : "\u25B6" }),
2788
+ /* @__PURE__ */ jsx9(SeverityDot, { sev }),
2789
+ /* @__PURE__ */ jsx9(SummaryLine, { signal })
2750
2790
  ] }),
2751
- expanded && /* @__PURE__ */ jsx8("div", { style: { marginTop: "6px", paddingTop: "6px", borderTop: "1px dashed #2a2a2a" }, children: /* @__PURE__ */ jsx8(SignalDetail, { s: signal, resolveFrame }) })
2791
+ expanded && /* @__PURE__ */ jsx9("div", { style: { marginTop: "6px", paddingTop: "6px", borderTop: "1px dashed #2a2a2a" }, children: /* @__PURE__ */ jsx9(SignalDetail, { s: signal, resolveFrame }) })
2752
2792
  ]
2753
2793
  }
2754
2794
  );
2755
2795
  }
2756
2796
  function CascadeMembers({ members }) {
2757
2797
  const minDepth = members.reduce((m, s) => Math.min(m, s.depth), Infinity);
2758
- return /* @__PURE__ */ jsx8("div", { children: members.map((m, i) => {
2798
+ return /* @__PURE__ */ jsx9("div", { children: members.map((m, i) => {
2759
2799
  const indent = (m.depth - minDepth) * 14;
2760
2800
  const isCascade = m.reason === "parent";
2761
- return /* @__PURE__ */ jsxs8(
2801
+ return /* @__PURE__ */ jsxs9(
2762
2802
  "div",
2763
2803
  {
2764
2804
  style: {
@@ -2769,10 +2809,10 @@ function CascadeMembers({ members }) {
2769
2809
  gap: "6px"
2770
2810
  },
2771
2811
  children: [
2772
- /* @__PURE__ */ jsx8("span", { style: { color: isCascade ? RENDER_REASON_COLOR.parent : "#555" }, children: m.depth > minDepth ? "\u2514" : "\u2022" }),
2773
- /* @__PURE__ */ jsx8("strong", { children: m.component }),
2774
- /* @__PURE__ */ jsx8(RenderReasonTag, { reason: m.reason, changedProps: m.changedProps }),
2775
- /* @__PURE__ */ jsxs8("span", { style: { color: "#888" }, children: [
2812
+ /* @__PURE__ */ jsx9("span", { style: { color: isCascade ? RENDER_REASON_COLOR.parent : "#555" }, children: m.depth > minDepth ? "\u2514" : "\u2022" }),
2813
+ /* @__PURE__ */ jsx9("strong", { children: m.component }),
2814
+ /* @__PURE__ */ jsx9(RenderReasonTag, { reason: m.reason, changedProps: m.changedProps }),
2815
+ /* @__PURE__ */ jsxs9("span", { style: { color: "#888" }, children: [
2776
2816
  m.duration.toFixed(2),
2777
2817
  "ms"
2778
2818
  ] })
@@ -2786,7 +2826,7 @@ function LanguageToggle() {
2786
2826
  const { lang, setLang, t } = useI18n();
2787
2827
  const langs = ["en", "ko"];
2788
2828
  const labels = { en: "EN", ko: "\uD55C" };
2789
- return /* @__PURE__ */ jsx8(
2829
+ return /* @__PURE__ */ jsx9(
2790
2830
  "div",
2791
2831
  {
2792
2832
  role: "group",
@@ -2799,7 +2839,7 @@ function LanguageToggle() {
2799
2839
  },
2800
2840
  children: langs.map((l) => {
2801
2841
  const active = lang === l;
2802
- return /* @__PURE__ */ jsx8(
2842
+ return /* @__PURE__ */ jsx9(
2803
2843
  "button",
2804
2844
  {
2805
2845
  type: "button",
@@ -2828,7 +2868,8 @@ function Panel(props) {
2828
2868
  const { t } = useI18n();
2829
2869
  const grouped = useMemo3(() => groupByKind(result.signals), [result.signals]);
2830
2870
  const kindsPresent = KIND_ORDER.filter((k) => grouped[k].length > 0);
2831
- const hasTimelineSignals = result.signals.some((s) => s.kind !== "web-vital") || (result.heapSamples?.length ?? 0) > 0 || (result.frames?.length ?? 0) > 0;
2871
+ const unsupported = useMemo3(() => unsupportedKinds(), []);
2872
+ const hasTimelineSignals = result.signals.some((s) => s.kind !== "web-vital") || (result.heapSamples?.length ?? 0) > 0 || (result.frames?.length ?? 0) > 0 || (result.leakSuspects?.length ?? 0) > 0;
2832
2873
  const [activeTab, setActiveTab] = useState3(
2833
2874
  kindsPresent[0] ?? "forced-reflow"
2834
2875
  );
@@ -2893,12 +2934,12 @@ function Panel(props) {
2893
2934
  flexDirection: "column",
2894
2935
  overflow: "hidden"
2895
2936
  };
2896
- return /* @__PURE__ */ jsxs8("div", { role: "region", "aria-label": t.panelRegion, style: panelStyle, children: [
2897
- /* @__PURE__ */ jsxs8("header", { style: { display: "flex", alignItems: "center", justifyContent: "space-between", marginBottom: "8px" }, children: [
2898
- /* @__PURE__ */ jsx8("strong", { children: "react-perfscope" }),
2899
- /* @__PURE__ */ jsxs8("div", { style: { display: "flex", gap: "4px", alignItems: "center" }, children: [
2900
- /* @__PURE__ */ jsx8(LanguageToggle, {}),
2901
- /* @__PURE__ */ jsx8(
2937
+ return /* @__PURE__ */ jsxs9("div", { role: "region", "aria-label": t.panelRegion, style: panelStyle, children: [
2938
+ /* @__PURE__ */ jsxs9("header", { style: { display: "flex", alignItems: "center", justifyContent: "space-between", marginBottom: "8px" }, children: [
2939
+ /* @__PURE__ */ jsx9("strong", { children: "react-perfscope" }),
2940
+ /* @__PURE__ */ jsxs9("div", { style: { display: "flex", gap: "4px", alignItems: "center" }, children: [
2941
+ /* @__PURE__ */ jsx9(LanguageToggle, {}),
2942
+ /* @__PURE__ */ jsx9(
2902
2943
  "button",
2903
2944
  {
2904
2945
  type: "button",
@@ -2917,7 +2958,7 @@ function Panel(props) {
2917
2958
  children: t.save
2918
2959
  }
2919
2960
  ),
2920
- /* @__PURE__ */ jsx8(
2961
+ /* @__PURE__ */ jsx9(
2921
2962
  "button",
2922
2963
  {
2923
2964
  type: "button",
@@ -2929,9 +2970,24 @@ function Panel(props) {
2929
2970
  )
2930
2971
  ] })
2931
2972
  ] }),
2932
- kindsPresent.length === 0 && /* @__PURE__ */ jsx8("div", { style: { color: "#888" }, children: t.noSignals }),
2933
- kindsPresent.length > 0 && /* @__PURE__ */ jsxs8(Fragment3, { children: [
2934
- /* @__PURE__ */ jsx8(
2973
+ unsupported.length > 0 && /* @__PURE__ */ jsx9(
2974
+ "div",
2975
+ {
2976
+ style: {
2977
+ padding: "6px 8px",
2978
+ marginBottom: "8px",
2979
+ fontSize: "11px",
2980
+ color: "#888",
2981
+ background: "#141414",
2982
+ border: "1px solid #1f1f1f",
2983
+ borderRadius: "6px"
2984
+ },
2985
+ children: t.unsupportedInBrowser(unsupported.map((k) => t.kindLabel(k)).join(", "))
2986
+ }
2987
+ ),
2988
+ kindsPresent.length === 0 && /* @__PURE__ */ jsx9("div", { style: { color: "#888" }, children: t.noSignals }),
2989
+ kindsPresent.length > 0 && /* @__PURE__ */ jsxs9(Fragment3, { children: [
2990
+ /* @__PURE__ */ jsx9(
2935
2991
  SummaryHeader,
2936
2992
  {
2937
2993
  signals: result.signals,
@@ -2943,8 +2999,8 @@ function Panel(props) {
2943
2999
  }
2944
3000
  }
2945
3001
  ),
2946
- /* @__PURE__ */ jsxs8("nav", { style: { display: "flex", gap: "4px", flexWrap: "wrap", marginBottom: "8px" }, children: [
2947
- hasTimelineSignals && /* @__PURE__ */ jsx8(
3002
+ /* @__PURE__ */ jsxs9("nav", { style: { display: "flex", gap: "4px", flexWrap: "wrap", marginBottom: "8px" }, children: [
3003
+ hasTimelineSignals && /* @__PURE__ */ jsx9(
2948
3004
  "button",
2949
3005
  {
2950
3006
  type: "button",
@@ -2969,7 +3025,7 @@ function Panel(props) {
2969
3025
  kindsPresent.map((kind) => {
2970
3026
  const worst = worstSeverity(grouped[kind]);
2971
3027
  const active = activeKind === kind;
2972
- return /* @__PURE__ */ jsxs8(
3028
+ return /* @__PURE__ */ jsxs9(
2973
3029
  "button",
2974
3030
  {
2975
3031
  type: "button",
@@ -2992,7 +3048,7 @@ function Panel(props) {
2992
3048
  gap: "6px"
2993
3049
  },
2994
3050
  children: [
2995
- worst !== "low" && /* @__PURE__ */ jsx8(SeverityDot, { sev: worst, title: t.worstLabel(worst) }),
3051
+ worst !== "low" && /* @__PURE__ */ jsx9(SeverityDot, { sev: worst, title: t.worstLabel(worst) }),
2996
3052
  t.kindLabel(kind),
2997
3053
  " ",
2998
3054
  grouped[kind].length
@@ -3002,10 +3058,10 @@ function Panel(props) {
3002
3058
  );
3003
3059
  })
3004
3060
  ] }),
3005
- activeKind && activeTab !== "timeline" && /* @__PURE__ */ jsxs8("div", { style: { display: "flex", alignItems: "center", gap: "12px", marginBottom: "6px", fontSize: "11px", color: "#888", flexWrap: "wrap" }, children: [
3006
- /* @__PURE__ */ jsxs8("label", { style: { display: "flex", alignItems: "center", gap: "6px" }, children: [
3061
+ activeKind && activeTab !== "timeline" && /* @__PURE__ */ jsxs9("div", { style: { display: "flex", alignItems: "center", gap: "12px", marginBottom: "6px", fontSize: "11px", color: "#888", flexWrap: "wrap" }, children: [
3062
+ /* @__PURE__ */ jsxs9("label", { style: { display: "flex", alignItems: "center", gap: "6px" }, children: [
3007
3063
  t.sort,
3008
- /* @__PURE__ */ jsxs8(
3064
+ /* @__PURE__ */ jsxs9(
3009
3065
  "select",
3010
3066
  {
3011
3067
  "aria-label": t.sort,
@@ -3017,15 +3073,15 @@ function Panel(props) {
3017
3073
  },
3018
3074
  style: { background: "#1a1a1a", color: "#e6e6e6", border: "1px solid #2a2a2a", borderRadius: "4px", padding: "2px 6px", fontSize: "11px" },
3019
3075
  children: [
3020
- /* @__PURE__ */ jsx8("option", { value: "chronological", children: t.sortChronological }),
3021
- /* @__PURE__ */ jsx8("option", { value: "severity", children: t.sortSeverity })
3076
+ /* @__PURE__ */ jsx9("option", { value: "chronological", children: t.sortChronological }),
3077
+ /* @__PURE__ */ jsx9("option", { value: "severity", children: t.sortSeverity })
3022
3078
  ]
3023
3079
  }
3024
3080
  )
3025
3081
  ] }),
3026
- tabSupportsGrouping(activeKind) && /* @__PURE__ */ jsxs8("label", { style: { display: "flex", alignItems: "center", gap: "6px" }, children: [
3082
+ tabSupportsGrouping(activeKind) && /* @__PURE__ */ jsxs9("label", { style: { display: "flex", alignItems: "center", gap: "6px" }, children: [
3027
3083
  t.groupBy,
3028
- /* @__PURE__ */ jsxs8(
3084
+ /* @__PURE__ */ jsxs9(
3029
3085
  "select",
3030
3086
  {
3031
3087
  "aria-label": t.groupBy,
@@ -3037,15 +3093,15 @@ function Panel(props) {
3037
3093
  },
3038
3094
  style: { background: "#1a1a1a", color: "#e6e6e6", border: "1px solid #2a2a2a", borderRadius: "4px", padding: "2px 6px", fontSize: "11px" },
3039
3095
  children: [
3040
- /* @__PURE__ */ jsx8("option", { value: "chronological", children: t.groupChronological }),
3041
- activeKind === "render" && /* @__PURE__ */ jsx8("option", { value: "commit", children: t.groupCommit }),
3042
- activeKind === "render" && /* @__PURE__ */ jsx8("option", { value: "component", children: t.groupComponent }),
3043
- activeKind === "forced-reflow" && /* @__PURE__ */ jsx8("option", { value: "source", children: t.groupSource })
3096
+ /* @__PURE__ */ jsx9("option", { value: "chronological", children: t.groupChronological }),
3097
+ activeKind === "render" && /* @__PURE__ */ jsx9("option", { value: "commit", children: t.groupCommit }),
3098
+ activeKind === "render" && /* @__PURE__ */ jsx9("option", { value: "component", children: t.groupComponent }),
3099
+ activeKind === "forced-reflow" && /* @__PURE__ */ jsx9("option", { value: "source", children: t.groupSource })
3044
3100
  ]
3045
3101
  }
3046
3102
  )
3047
3103
  ] }),
3048
- /* @__PURE__ */ jsx8(
3104
+ /* @__PURE__ */ jsx9(
3049
3105
  "input",
3050
3106
  {
3051
3107
  type: "text",
@@ -3060,23 +3116,26 @@ function Panel(props) {
3060
3116
  }
3061
3117
  )
3062
3118
  ] }),
3063
- activeTab === "timeline" && /* @__PURE__ */ jsx8("div", { style: { flexGrow: 1, overflowY: "auto", paddingTop: "4px", paddingBottom: "24px" }, children: /* @__PURE__ */ jsx8(
3064
- Timeline,
3065
- {
3066
- signals: result.signals,
3067
- duration: result.duration,
3068
- startedAt: result.startedAt,
3069
- heapSamples: result.heapSamples,
3070
- frames: result.frames,
3071
- onJump: (s) => {
3072
- setActiveTab(s.kind);
3073
- const inOrder = grouped[s.kind];
3074
- const idx = inOrder.indexOf(s);
3075
- if (idx >= 0) setExpandedKey(`${s.kind}-${idx}`);
3119
+ activeTab === "timeline" && /* @__PURE__ */ jsxs9("div", { style: { flexGrow: 1, overflowY: "auto", paddingTop: "4px", paddingBottom: "24px" }, children: [
3120
+ /* @__PURE__ */ jsx9(LeakList, { suspects: result.leakSuspects }),
3121
+ /* @__PURE__ */ jsx9(
3122
+ Timeline,
3123
+ {
3124
+ signals: result.signals,
3125
+ duration: result.duration,
3126
+ startedAt: result.startedAt,
3127
+ heapSamples: result.heapSamples,
3128
+ frames: result.frames,
3129
+ onJump: (s) => {
3130
+ setActiveTab(s.kind);
3131
+ const inOrder = grouped[s.kind];
3132
+ const idx = inOrder.indexOf(s);
3133
+ if (idx >= 0) setExpandedKey(`${s.kind}-${idx}`);
3134
+ }
3076
3135
  }
3077
- }
3078
- ) }),
3079
- activeKind === "render" && activeTab !== "timeline" && /* @__PURE__ */ jsx8(
3136
+ )
3137
+ ] }),
3138
+ activeKind === "render" && activeTab !== "timeline" && /* @__PURE__ */ jsx9(
3080
3139
  RenderInsights,
3081
3140
  {
3082
3141
  signals: grouped.render.flatMap((s) => s.kind === "render" ? s.members ?? [s] : []).filter((s) => signalMatchesFilter(s, filterText.render ?? "")),
@@ -3086,8 +3145,8 @@ function Panel(props) {
3086
3145
  }
3087
3146
  }
3088
3147
  ),
3089
- activeKind === "long-task" && activeTab !== "timeline" && /* @__PURE__ */ jsx8(LongTaskEpisode, { signals: result.signals }),
3090
- activeKind === "layout-shift" && activeTab !== "timeline" && /* @__PURE__ */ jsx8(
3148
+ activeKind === "long-task" && activeTab !== "timeline" && /* @__PURE__ */ jsx9(LongTaskEpisode, { signals: result.signals }),
3149
+ activeKind === "layout-shift" && activeTab !== "timeline" && /* @__PURE__ */ jsx9(
3091
3150
  "div",
3092
3151
  {
3093
3152
  style: {
@@ -3102,9 +3161,9 @@ function Panel(props) {
3102
3161
  children: t.layoutShiftHint
3103
3162
  }
3104
3163
  ),
3105
- activeKind === "interaction" && activeTab !== "timeline" && /* @__PURE__ */ jsxs8(Fragment3, { children: [
3106
- /* @__PURE__ */ jsx8(InpEpisode, { signals: result.signals }),
3107
- /* @__PURE__ */ jsx8(
3164
+ activeKind === "interaction" && activeTab !== "timeline" && /* @__PURE__ */ jsxs9(Fragment3, { children: [
3165
+ /* @__PURE__ */ jsx9(InpEpisode, { signals: result.signals }),
3166
+ /* @__PURE__ */ jsx9(
3108
3167
  "div",
3109
3168
  {
3110
3169
  style: {
@@ -3120,7 +3179,7 @@ function Panel(props) {
3120
3179
  }
3121
3180
  )
3122
3181
  ] }),
3123
- /* @__PURE__ */ jsx8("ul", { style: { listStyle: "none", margin: 0, padding: 0, overflowY: "auto", flexGrow: 1, display: activeTab === "timeline" ? "none" : void 0 }, children: activeKind && (() => {
3182
+ /* @__PURE__ */ jsx9("ul", { style: { listStyle: "none", margin: 0, padding: 0, overflowY: "auto", flexGrow: 1, display: activeTab === "timeline" ? "none" : void 0 }, children: activeKind && (() => {
3124
3183
  const filtered = grouped[activeKind].filter(
3125
3184
  (s) => signalMatchesFilter(s, filterText[activeKind] ?? "")
3126
3185
  );
@@ -3130,7 +3189,7 @@ function Panel(props) {
3130
3189
  const currentMode = groupMode[activeKind] ?? "chronological";
3131
3190
  if (currentMode === "chronological") {
3132
3191
  const key2 = `${activeKind}-${gi}`;
3133
- return /* @__PURE__ */ jsx8(
3192
+ return /* @__PURE__ */ jsx9(
3134
3193
  SignalRow,
3135
3194
  {
3136
3195
  signal: g.signals[0],
@@ -3147,7 +3206,7 @@ function Panel(props) {
3147
3206
  const isCascade = activeKind === "render" && currentMode === "commit";
3148
3207
  const renderMembers = g.signals.filter((s) => s.kind === "render");
3149
3208
  const unnecessary = isCascade ? renderMembers.filter((s) => s.reason === "parent").length : 0;
3150
- return /* @__PURE__ */ jsxs8(
3209
+ return /* @__PURE__ */ jsxs9(
3151
3210
  "li",
3152
3211
  {
3153
3212
  "aria-expanded": isOpen,
@@ -3162,34 +3221,34 @@ function Panel(props) {
3162
3221
  userSelect: "none"
3163
3222
  },
3164
3223
  children: [
3165
- /* @__PURE__ */ jsxs8("div", { style: { display: "flex", alignItems: "center", gap: "6px", flexWrap: "wrap" }, children: [
3166
- /* @__PURE__ */ jsx8("span", { style: { color: "#888", width: "10px" }, children: isOpen ? "\u25BC" : "\u25B6" }),
3167
- /* @__PURE__ */ jsxs8("span", { children: [
3168
- /* @__PURE__ */ jsx8("strong", { children: g.label }),
3224
+ /* @__PURE__ */ jsxs9("div", { style: { display: "flex", alignItems: "center", gap: "6px", flexWrap: "wrap" }, children: [
3225
+ /* @__PURE__ */ jsx9("span", { style: { color: "#888", width: "10px" }, children: isOpen ? "\u25BC" : "\u25B6" }),
3226
+ /* @__PURE__ */ jsxs9("span", { children: [
3227
+ /* @__PURE__ */ jsx9("strong", { children: g.label }),
3169
3228
  " \xD7",
3170
3229
  g.count
3171
3230
  ] }),
3172
- isCascade && unnecessary > 0 && /* @__PURE__ */ jsxs8("span", { style: { color: RENDER_REASON_COLOR.parent, fontSize: "10px" }, children: [
3231
+ isCascade && unnecessary > 0 && /* @__PURE__ */ jsxs9("span", { style: { color: RENDER_REASON_COLOR.parent, fontSize: "10px" }, children: [
3173
3232
  "\u26A0 ",
3174
3233
  t.unnecessaryRenders(unnecessary)
3175
3234
  ] })
3176
3235
  ] }),
3177
- isOpen && /* @__PURE__ */ jsx8("div", { style: { marginTop: "6px", paddingTop: "6px", borderTop: "1px dashed #2a2a2a", paddingLeft: "8px" }, children: isCascade ? /* @__PURE__ */ jsx8(CascadeMembers, { members: renderMembers }) : /* @__PURE__ */ jsxs8(Fragment3, { children: [
3178
- g.signals.slice(0, 20).map((s, si) => /* @__PURE__ */ jsx8("div", { style: { padding: "2px 0" }, children: /* @__PURE__ */ jsx8(SummaryLine, { signal: s }) }, si)),
3179
- g.signals.length > 20 && /* @__PURE__ */ jsx8("div", { style: { color: "#888", marginTop: "4px" }, children: t.moreItems(g.signals.length - 20) })
3236
+ isOpen && /* @__PURE__ */ jsx9("div", { style: { marginTop: "6px", paddingTop: "6px", borderTop: "1px dashed #2a2a2a", paddingLeft: "8px" }, children: isCascade ? /* @__PURE__ */ jsx9(CascadeMembers, { members: renderMembers }) : /* @__PURE__ */ jsxs9(Fragment3, { children: [
3237
+ g.signals.slice(0, 20).map((s, si) => /* @__PURE__ */ jsx9("div", { style: { padding: "2px 0" }, children: /* @__PURE__ */ jsx9(SummaryLine, { signal: s }) }, si)),
3238
+ g.signals.length > 20 && /* @__PURE__ */ jsx9("div", { style: { color: "#888", marginTop: "4px" }, children: t.moreItems(g.signals.length - 20) })
3180
3239
  ] }) })
3181
3240
  ]
3182
3241
  },
3183
3242
  key
3184
3243
  );
3185
3244
  }) }),
3186
- activeKind && activeTab !== "timeline" && (filterText[activeKind] ?? "").trim() !== "" && grouped[activeKind].length > 0 && grouped[activeKind].every((s) => !signalMatchesFilter(s, filterText[activeKind] ?? "")) && /* @__PURE__ */ jsx8("div", { style: { padding: "12px 8px", fontSize: "11px", color: "#888" }, children: t.filterNoMatches })
3245
+ activeKind && activeTab !== "timeline" && (filterText[activeKind] ?? "").trim() !== "" && grouped[activeKind].length > 0 && grouped[activeKind].every((s) => !signalMatchesFilter(s, filterText[activeKind] ?? "")) && /* @__PURE__ */ jsx9("div", { style: { padding: "12px 8px", fontSize: "11px", color: "#888" }, children: t.filterNoMatches })
3187
3246
  ] })
3188
3247
  ] });
3189
3248
  }
3190
3249
 
3191
3250
  // src/app.tsx
3192
- import { jsx as jsx9, jsxs as jsxs9 } from "preact/jsx-runtime";
3251
+ import { jsx as jsx10, jsxs as jsxs10 } from "preact/jsx-runtime";
3193
3252
  function App(props) {
3194
3253
  const { recorder, position = "bottom-right", resolveFrame, finalize } = props;
3195
3254
  const [recording, setRecording] = useState4(false);
@@ -3235,8 +3294,8 @@ function App(props) {
3235
3294
  function onClose() {
3236
3295
  setResult(null);
3237
3296
  }
3238
- return /* @__PURE__ */ jsxs9(I18nProvider, { children: [
3239
- result === null && /* @__PURE__ */ jsx9(
3297
+ return /* @__PURE__ */ jsxs10(I18nProvider, { children: [
3298
+ result === null && /* @__PURE__ */ jsx10(
3240
3299
  Widget,
3241
3300
  {
3242
3301
  recording,
@@ -3245,16 +3304,16 @@ function App(props) {
3245
3304
  position
3246
3305
  }
3247
3306
  ),
3248
- result !== null && /* @__PURE__ */ jsx9(Panel, { result, position, onClose, resolveFrame })
3307
+ result !== null && /* @__PURE__ */ jsx10(Panel, { result, position, onClose, resolveFrame })
3249
3308
  ] });
3250
3309
  }
3251
3310
 
3252
3311
  // src/mount.tsx
3253
- import { jsx as jsx10 } from "preact/jsx-runtime";
3312
+ import { jsx as jsx11 } from "preact/jsx-runtime";
3254
3313
  function mount(opts) {
3255
3314
  const { recorder, position = "bottom-right", host = document.body, resolveFrame, finalize } = opts;
3256
3315
  return mountShadow(
3257
- /* @__PURE__ */ jsx10(App, { recorder, position, resolveFrame, finalize }),
3316
+ /* @__PURE__ */ jsx11(App, { recorder, position, resolveFrame, finalize }),
3258
3317
  { parent: host }
3259
3318
  );
3260
3319
  }