@react-perfscope/ui 0.6.0 → 0.7.1

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.cjs CHANGED
@@ -90,7 +90,7 @@ function mountShadow(vnode, opts = {}) {
90
90
  }
91
91
 
92
92
  // src/app.tsx
93
- var import_hooks4 = require("preact/hooks");
93
+ var import_hooks6 = require("preact/hooks");
94
94
 
95
95
  // src/i18n.ts
96
96
  var import_preact2 = require("preact");
@@ -147,6 +147,9 @@ var en = {
147
147
  heapUnsupported: "heap size unavailable (Chromium only)",
148
148
  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.",
149
149
  heapTrendLabel: (cls) => cls === "leak-suspected" ? "leak suspected" : cls === "growing" ? "growing" : "stable",
150
+ leaksTitle: "Suspected leaks",
151
+ 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).",
152
+ leakSuspect: (component, retained, unmounted) => `${component} \u2014 ${retained} retained of ${unmounted} unmounted, climbing`,
150
153
  fpsLabel: "fps",
151
154
  fpsUnsupported: "frame timing unavailable",
152
155
  fpsBadge: (minFps, dropped) => `min ${minFps}fps \xB7 ${dropped} dropped`,
@@ -242,6 +245,9 @@ var ko = {
242
245
  heapUnsupported: "\uD799 \uCE21\uC815 \uBBF8\uC9C0\uC6D0 (\uD06C\uB86C \uC804\uC6A9)",
243
246
  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.",
244
247
  heapTrendLabel: (cls) => cls === "leak-suspected" ? "\uB204\uC218 \uC758\uC2EC" : cls === "growing" ? "\uC99D\uAC00 \uC911" : "\uC548\uC815",
248
+ leaksTitle: "\uB204\uC218 \uC758\uC2EC",
249
+ 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.",
250
+ leakSuspect: (component, retained, unmounted) => `${component} \u2014 \uC5B8\uB9C8\uC6B4\uD2B8 ${unmounted}\uAC1C \uC911 ${retained}\uAC1C \uBCF4\uC720, \uC99D\uAC00 \uC911`,
245
251
  fpsLabel: "fps",
246
252
  fpsUnsupported: "\uD504\uB808\uC784 \uCE21\uC815 \uBBF8\uC9C0\uC6D0",
247
253
  fpsBadge: (minFps, dropped) => `\uCD5C\uC800 ${minFps}fps \xB7 \uB4DC\uB78D ${dropped}`,
@@ -384,7 +390,7 @@ function Widget(props) {
384
390
  }
385
391
 
386
392
  // src/panel.tsx
387
- var import_hooks3 = require("preact/hooks");
393
+ var import_hooks5 = require("preact/hooks");
388
394
  var import_core4 = require("@react-perfscope/core");
389
395
 
390
396
  // src/overlay.ts
@@ -1798,8 +1804,39 @@ function TooltipContent({ s, startedAt }) {
1798
1804
  }
1799
1805
  }
1800
1806
 
1801
- // src/render-insights.tsx
1807
+ // src/leaks.tsx
1802
1808
  var import_jsx_runtime4 = require("preact/jsx-runtime");
1809
+ function LeakList({ suspects }) {
1810
+ const { t } = useI18n();
1811
+ if (!suspects || suspects.length === 0) return null;
1812
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { "data-leaks": "", style: { padding: "8px 10px", borderBottom: "1px solid #1c1c1c" }, children: [
1813
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
1814
+ "div",
1815
+ {
1816
+ style: { display: "flex", alignItems: "center", gap: "6px", marginBottom: "6px" },
1817
+ children: [
1818
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { style: { color: "#ef4444", fontSize: "11px", fontWeight: 600 }, children: t.leaksTitle }),
1819
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("span", { style: { color: "#666", fontSize: "10px" }, children: [
1820
+ "\xD7",
1821
+ suspects.length
1822
+ ] })
1823
+ ]
1824
+ }
1825
+ ),
1826
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("ul", { style: { listStyle: "none", margin: 0, padding: 0 }, children: suspects.map((s) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1827
+ "li",
1828
+ {
1829
+ style: { color: "#e6e6e6", fontSize: "11px", padding: "2px 0", fontVariantNumeric: "tabular-nums" },
1830
+ children: t.leakSuspect(s.component, s.retained, s.unmounted)
1831
+ },
1832
+ s.component
1833
+ )) }),
1834
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { style: { color: "#666", fontSize: "10px", margin: "6px 0 0", lineHeight: 1.4 }, children: t.leakHint })
1835
+ ] });
1836
+ }
1837
+
1838
+ // src/render-insights.tsx
1839
+ var import_jsx_runtime5 = require("preact/jsx-runtime");
1803
1840
  function aggregate(signals) {
1804
1841
  const byName = /* @__PURE__ */ new Map();
1805
1842
  for (const s of signals) {
@@ -1830,7 +1867,7 @@ function RenderInsights({ signals, onSelect }) {
1830
1867
  const top = rows.slice(0, TOP_N);
1831
1868
  const max = top.length > 0 ? top[0].totalMs : 1;
1832
1869
  const hiddenCount = rows.length - top.length;
1833
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
1870
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
1834
1871
  "div",
1835
1872
  {
1836
1873
  style: {
@@ -1841,12 +1878,12 @@ function RenderInsights({ signals, onSelect }) {
1841
1878
  borderRadius: "8px"
1842
1879
  },
1843
1880
  children: [
1844
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { style: { fontSize: "10px", color: "#888", textTransform: "uppercase", letterSpacing: "0.5px", marginBottom: "6px" }, children: t.topRenderers }),
1845
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { style: { display: "flex", flexDirection: "column", gap: "4px" }, children: [
1881
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { style: { fontSize: "10px", color: "#888", textTransform: "uppercase", letterSpacing: "0.5px", marginBottom: "6px" }, children: t.topRenderers }),
1882
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { style: { display: "flex", flexDirection: "column", gap: "4px" }, children: [
1846
1883
  top.map((a) => {
1847
1884
  const widthPct = max > 0 ? Math.max(2, a.totalMs / max * 100) : 0;
1848
1885
  const color = SEVERITY_COLOR[a.worstSeverity];
1849
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
1886
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
1850
1887
  "div",
1851
1888
  {
1852
1889
  "data-component": a.component,
@@ -1862,8 +1899,8 @@ function RenderInsights({ signals, onSelect }) {
1862
1899
  },
1863
1900
  title: t.rendererDetail(a.component, a.count, a.totalMs, a.maxMs),
1864
1901
  children: [
1865
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("strong", { style: { flex: "0 0 30%", overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }, children: a.component }),
1866
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { style: { flex: "1", position: "relative", height: "14px", background: "#1f1f1f", borderRadius: "2px" }, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1902
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("strong", { style: { flex: "0 0 30%", overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }, children: a.component }),
1903
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { style: { flex: "1", position: "relative", height: "14px", background: "#1f1f1f", borderRadius: "2px" }, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
1867
1904
  "div",
1868
1905
  {
1869
1906
  style: {
@@ -1878,11 +1915,11 @@ function RenderInsights({ signals, onSelect }) {
1878
1915
  }
1879
1916
  }
1880
1917
  ) }),
1881
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("span", { style: { flex: "0 0 auto", color, minWidth: "56px", textAlign: "right" }, children: [
1918
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("span", { style: { flex: "0 0 auto", color, minWidth: "56px", textAlign: "right" }, children: [
1882
1919
  a.totalMs.toFixed(1),
1883
1920
  "ms"
1884
1921
  ] }),
1885
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("span", { style: { flex: "0 0 auto", color: "#888", minWidth: "32px", textAlign: "right" }, children: [
1922
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("span", { style: { flex: "0 0 auto", color: "#888", minWidth: "32px", textAlign: "right" }, children: [
1886
1923
  "\xD7",
1887
1924
  a.count
1888
1925
  ] })
@@ -1891,7 +1928,7 @@ function RenderInsights({ signals, onSelect }) {
1891
1928
  a.component
1892
1929
  );
1893
1930
  }),
1894
- hiddenCount > 0 && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { style: { fontSize: "10px", color: "#666", marginTop: "2px" }, children: t.moreComponents(hiddenCount) })
1931
+ hiddenCount > 0 && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { style: { fontSize: "10px", color: "#666", marginTop: "2px" }, children: t.moreComponents(hiddenCount) })
1895
1932
  ] })
1896
1933
  ]
1897
1934
  }
@@ -1899,10 +1936,11 @@ function RenderInsights({ signals, onSelect }) {
1899
1936
  }
1900
1937
 
1901
1938
  // src/inp-episode.tsx
1939
+ var import_hooks3 = require("preact/hooks");
1902
1940
  var import_core2 = require("@react-perfscope/core");
1903
1941
 
1904
1942
  // src/episode-shared.tsx
1905
- var import_jsx_runtime5 = require("preact/jsx-runtime");
1943
+ var import_jsx_runtime6 = require("preact/jsx-runtime");
1906
1944
  function memberLabel(m) {
1907
1945
  const s = m.signal;
1908
1946
  if (s.kind === "render") return `${s.component} (${s.reason})`;
@@ -1913,18 +1951,18 @@ function memberLabel(m) {
1913
1951
  return `layout shift ${s.value.toFixed(3)}`;
1914
1952
  }
1915
1953
  function EpisodeMemberRow({ member }) {
1916
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
1954
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
1917
1955
  "div",
1918
1956
  {
1919
1957
  "data-member-kind": member.signal.kind,
1920
1958
  style: { display: "flex", alignItems: "center", gap: "6px", padding: "1px 0", color: "#ccc" },
1921
1959
  children: [
1922
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { style: { overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }, children: memberLabel(member) }),
1923
- member.causedBy && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("span", { style: { flex: "0 0 auto", color: "#888" }, children: [
1960
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { style: { overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }, children: memberLabel(member) }),
1961
+ member.causedBy && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { style: { flex: "0 0 auto", color: "#888" }, children: [
1924
1962
  "\u2190 ",
1925
1963
  member.causedBy.component
1926
1964
  ] }),
1927
- member.confidence === "caused" && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
1965
+ member.confidence === "caused" && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1928
1966
  "span",
1929
1967
  {
1930
1968
  style: {
@@ -1943,12 +1981,12 @@ function EpisodeMemberRow({ member }) {
1943
1981
  );
1944
1982
  }
1945
1983
  function EpisodeMemberList({ members }) {
1946
- if (members.length === 0) return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { style: { color: "#555" }, children: "\u2014" });
1947
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_jsx_runtime5.Fragment, { children: members.map((m, i) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(EpisodeMemberRow, { member: m }, i)) });
1984
+ if (members.length === 0) return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { style: { color: "#555" }, children: "\u2014" });
1985
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_jsx_runtime6.Fragment, { children: members.map((m, i) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(EpisodeMemberRow, { member: m }, i)) });
1948
1986
  }
1949
1987
 
1950
1988
  // src/inp-episode.tsx
1951
- var import_jsx_runtime6 = require("preact/jsx-runtime");
1989
+ var import_jsx_runtime7 = require("preact/jsx-runtime");
1952
1990
  var PHASES = [
1953
1991
  { phase: "input-delay", labelKey: "inputDelay" },
1954
1992
  { phase: "processing", labelKey: "processingTime" },
@@ -1969,11 +2007,11 @@ function phaseMs(episode, phase) {
1969
2007
  }
1970
2008
  function InpEpisode({ signals }) {
1971
2009
  const { t } = useI18n();
1972
- const episode = worstInteractionEpisode(signals);
2010
+ const episode = (0, import_hooks3.useMemo)(() => worstInteractionEpisode(signals), [signals]);
1973
2011
  if (!episode || episode.anchor.kind !== "interaction") return null;
1974
2012
  const a = episode.anchor;
1975
2013
  const target = a.target ? ` on ${a.target}` : "";
1976
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
2014
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
1977
2015
  "div",
1978
2016
  {
1979
2017
  "data-inp-episode": true,
@@ -1987,33 +2025,33 @@ function InpEpisode({ signals }) {
1987
2025
  overflow: "hidden"
1988
2026
  },
1989
2027
  children: [
1990
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { style: { padding: "6px 8px", borderBottom: "1px solid #1f1f1f", color: "#ddd" }, children: [
1991
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("strong", { children: a.eventType }),
2028
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { style: { padding: "6px 8px", borderBottom: "1px solid #1f1f1f", color: "#ddd" }, children: [
2029
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("strong", { children: a.eventType }),
1992
2030
  target,
1993
2031
  " \u2014 ",
1994
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("strong", { children: [
2032
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("strong", { children: [
1995
2033
  Math.round(a.duration),
1996
2034
  "ms"
1997
2035
  ] }),
1998
2036
  " ",
1999
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { style: { color: "#888" }, children: "INP" })
2037
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { style: { color: "#888" }, children: "INP" })
2000
2038
  ] }),
2001
2039
  PHASES.map(({ phase, labelKey }) => {
2002
2040
  const members = episode.members.filter((m) => m.phase === phase);
2003
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
2041
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
2004
2042
  "div",
2005
2043
  {
2006
2044
  "data-inp-phase": phase,
2007
2045
  style: { display: "flex", gap: "8px", padding: "5px 8px", borderTop: "1px solid #1a1a1a" },
2008
2046
  children: [
2009
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { style: { flex: "0 0 92px", color: "#aaa" }, children: [
2047
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { style: { flex: "0 0 92px", color: "#aaa" }, children: [
2010
2048
  t[labelKey],
2011
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { style: { color: "#666", fontSize: "10px" }, children: [
2049
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { style: { color: "#666", fontSize: "10px" }, children: [
2012
2050
  Math.round(phaseMs(episode, phase)),
2013
2051
  "ms"
2014
2052
  ] })
2015
2053
  ] }),
2016
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { style: { flex: 1, minWidth: 0 }, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(EpisodeMemberList, { members }) })
2054
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { style: { flex: 1, minWidth: 0 }, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(EpisodeMemberList, { members }) })
2017
2055
  ]
2018
2056
  },
2019
2057
  phase
@@ -2025,8 +2063,9 @@ function InpEpisode({ signals }) {
2025
2063
  }
2026
2064
 
2027
2065
  // src/long-task-episode.tsx
2066
+ var import_hooks4 = require("preact/hooks");
2028
2067
  var import_core3 = require("@react-perfscope/core");
2029
- var import_jsx_runtime7 = require("preact/jsx-runtime");
2068
+ var import_jsx_runtime8 = require("preact/jsx-runtime");
2030
2069
  function worstLongTaskEpisode(signals) {
2031
2070
  let worst = null;
2032
2071
  for (const ep of (0, import_core3.correlate)(signals)) {
@@ -2037,11 +2076,11 @@ function worstLongTaskEpisode(signals) {
2037
2076
  }
2038
2077
  function LongTaskEpisode({ signals }) {
2039
2078
  const { t } = useI18n();
2040
- const episode = worstLongTaskEpisode(signals);
2079
+ const episode = (0, import_hooks4.useMemo)(() => worstLongTaskEpisode(signals), [signals]);
2041
2080
  if (!episode || episode.anchor.kind !== "long-task") return null;
2042
2081
  if (episode.members.length === 0) return null;
2043
2082
  const a = episode.anchor;
2044
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
2083
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
2045
2084
  "div",
2046
2085
  {
2047
2086
  "data-long-task-episode": true,
@@ -2055,15 +2094,15 @@ function LongTaskEpisode({ signals }) {
2055
2094
  overflow: "hidden"
2056
2095
  },
2057
2096
  children: [
2058
- /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { style: { padding: "6px 8px", borderBottom: "1px solid #1f1f1f", color: "#ddd" }, children: [
2059
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("strong", { children: t.kindLabel("long-task") }),
2097
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { style: { padding: "6px 8px", borderBottom: "1px solid #1f1f1f", color: "#ddd" }, children: [
2098
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("strong", { children: t.kindLabel("long-task") }),
2060
2099
  " \u2014 ",
2061
- /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("strong", { children: [
2100
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("strong", { children: [
2062
2101
  Math.round(a.duration),
2063
2102
  "ms"
2064
2103
  ] })
2065
2104
  ] }),
2066
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { style: { padding: "5px 8px" }, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(EpisodeMemberList, { members: episode.members }) })
2105
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { style: { padding: "5px 8px" }, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(EpisodeMemberList, { members: episode.members }) })
2067
2106
  ]
2068
2107
  }
2069
2108
  );
@@ -2109,7 +2148,7 @@ function signalMatchesFilter(signal, query) {
2109
2148
  }
2110
2149
 
2111
2150
  // src/panel.tsx
2112
- var import_jsx_runtime8 = require("preact/jsx-runtime");
2151
+ var import_jsx_runtime9 = require("preact/jsx-runtime");
2113
2152
  var RENDER_REASON_COLOR = {
2114
2153
  mount: "#5ac8fa",
2115
2154
  state: "#34c759",
@@ -2133,7 +2172,7 @@ function RenderReasonTag({ reason, changedProps }) {
2133
2172
  const color = RENDER_REASON_COLOR[reason];
2134
2173
  const label = renderReasonLabel(t, reason);
2135
2174
  const keys = reason === "props" && changedProps && changedProps.length > 0 ? `: ${changedProps.join(", ")}` : "";
2136
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
2175
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
2137
2176
  "span",
2138
2177
  {
2139
2178
  style: {
@@ -2189,7 +2228,7 @@ var WEB_VITAL_UNIT2 = {
2189
2228
  };
2190
2229
  function RatingDot({ rating }) {
2191
2230
  const { t } = useI18n();
2192
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
2231
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
2193
2232
  "span",
2194
2233
  {
2195
2234
  "data-rating": rating,
@@ -2247,18 +2286,18 @@ var monoStyle = {
2247
2286
  };
2248
2287
  function LayoutShiftDetail({ s }) {
2249
2288
  const { t } = useI18n();
2250
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { style: { paddingLeft: "12px" }, children: [
2251
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { style: detailRowStyle, children: [
2252
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { style: detailLabelStyle, children: t.value }),
2253
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { children: s.value.toFixed(4) })
2289
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { style: { paddingLeft: "12px" }, children: [
2290
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { style: detailRowStyle, children: [
2291
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { style: detailLabelStyle, children: t.value }),
2292
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { children: s.value.toFixed(4) })
2254
2293
  ] }),
2255
- s.sources.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { style: { color: "#666" }, children: t.noSourceRects }) : s.sources.map((r, i) => /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { style: { ...detailRowStyle, ...monoStyle }, children: [
2256
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("span", { style: { color: "#888" }, children: [
2294
+ s.sources.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { style: { color: "#666" }, children: t.noSourceRects }) : s.sources.map((r, i) => /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { style: { ...detailRowStyle, ...monoStyle }, children: [
2295
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("span", { style: { color: "#888" }, children: [
2257
2296
  t.rect,
2258
2297
  " ",
2259
2298
  i + 1
2260
2299
  ] }),
2261
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("span", { children: [
2300
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("span", { children: [
2262
2301
  "x=",
2263
2302
  r.x.toFixed(0),
2264
2303
  " y=",
@@ -2273,25 +2312,25 @@ function LayoutShiftDetail({ s }) {
2273
2312
  }
2274
2313
  function NetworkDetail({ s }) {
2275
2314
  const { t } = useI18n();
2276
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { style: { paddingLeft: "12px" }, children: [
2277
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { style: { ...detailRowStyle, ...monoStyle, wordBreak: "break-all" }, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { children: s.url }) }),
2278
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { style: detailRowStyle, children: [
2279
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { style: detailLabelStyle, children: t.started }),
2280
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("span", { children: [
2315
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { style: { paddingLeft: "12px" }, children: [
2316
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { style: { ...detailRowStyle, ...monoStyle, wordBreak: "break-all" }, children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { children: s.url }) }),
2317
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { style: detailRowStyle, children: [
2318
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { style: detailLabelStyle, children: t.started }),
2319
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("span", { children: [
2281
2320
  s.startedAt.toFixed(0),
2282
2321
  "ms"
2283
2322
  ] })
2284
2323
  ] }),
2285
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { style: detailRowStyle, children: [
2286
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { style: detailLabelStyle, children: t.duration }),
2287
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("span", { children: [
2324
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { style: detailRowStyle, children: [
2325
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { style: detailLabelStyle, children: t.duration }),
2326
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("span", { children: [
2288
2327
  s.duration.toFixed(0),
2289
2328
  "ms"
2290
2329
  ] })
2291
2330
  ] }),
2292
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { style: detailRowStyle, children: [
2293
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { style: detailLabelStyle, children: t.size }),
2294
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("span", { children: [
2331
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { style: detailRowStyle, children: [
2332
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { style: detailLabelStyle, children: t.size }),
2333
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("span", { children: [
2295
2334
  (s.size / 1024).toFixed(2),
2296
2335
  "KB (",
2297
2336
  s.size,
@@ -2300,69 +2339,69 @@ function NetworkDetail({ s }) {
2300
2339
  ")"
2301
2340
  ] })
2302
2341
  ] }),
2303
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { style: detailRowStyle, children: [
2304
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { style: detailLabelStyle, children: t.renderBlocking }),
2305
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { children: s.blocking ? t.yes : t.no })
2342
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { style: detailRowStyle, children: [
2343
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { style: detailLabelStyle, children: t.renderBlocking }),
2344
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { children: s.blocking ? t.yes : t.no })
2306
2345
  ] })
2307
2346
  ] });
2308
2347
  }
2309
2348
  function WebVitalDetail({ s }) {
2310
2349
  const { t } = useI18n();
2311
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { style: { paddingLeft: "12px" }, children: [
2312
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { style: detailRowStyle, children: [
2313
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { style: detailLabelStyle, children: t.metric }),
2314
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { children: s.name })
2350
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { style: { paddingLeft: "12px" }, children: [
2351
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { style: detailRowStyle, children: [
2352
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { style: detailLabelStyle, children: t.metric }),
2353
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { children: s.name })
2315
2354
  ] }),
2316
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { style: detailRowStyle, children: [
2317
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { style: detailLabelStyle, children: t.value }),
2318
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { children: s.value.toFixed(2) })
2355
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { style: detailRowStyle, children: [
2356
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { style: detailLabelStyle, children: t.value }),
2357
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { children: s.value.toFixed(2) })
2319
2358
  ] })
2320
2359
  ] });
2321
2360
  }
2322
2361
  function RenderDetail({ s }) {
2323
2362
  const { t } = useI18n();
2324
2363
  if (s.members && s.members.length > 0) {
2325
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { style: { paddingLeft: "12px" }, children: [
2326
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { style: detailRowStyle, children: [
2327
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { style: detailLabelStyle, children: t.duration }),
2328
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("span", { children: [
2364
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { style: { paddingLeft: "12px" }, children: [
2365
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { style: detailRowStyle, children: [
2366
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { style: detailLabelStyle, children: t.duration }),
2367
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("span", { children: [
2329
2368
  s.duration.toFixed(3),
2330
2369
  "ms"
2331
2370
  ] })
2332
2371
  ] }),
2333
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { style: detailRowStyle, children: [
2334
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { style: detailLabelStyle, children: t.at }),
2335
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("span", { children: [
2372
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { style: detailRowStyle, children: [
2373
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { style: detailLabelStyle, children: t.at }),
2374
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("span", { children: [
2336
2375
  s.at.toFixed(2),
2337
2376
  "ms"
2338
2377
  ] })
2339
2378
  ] }),
2340
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { style: { marginTop: "6px" }, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(CascadeMembers, { members: s.members }) })
2379
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { style: { marginTop: "6px" }, children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(CascadeMembers, { members: s.members }) })
2341
2380
  ] });
2342
2381
  }
2343
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { style: { paddingLeft: "12px" }, children: [
2344
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { style: detailRowStyle, children: [
2345
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { style: detailLabelStyle, children: t.component }),
2346
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { children: s.component })
2382
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { style: { paddingLeft: "12px" }, children: [
2383
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { style: detailRowStyle, children: [
2384
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { style: detailLabelStyle, children: t.component }),
2385
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { children: s.component })
2347
2386
  ] }),
2348
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { style: detailRowStyle, children: [
2349
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { style: detailLabelStyle, children: t.reason }),
2350
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(RenderReasonTag, { reason: s.reason, changedProps: s.changedProps })
2387
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { style: detailRowStyle, children: [
2388
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { style: detailLabelStyle, children: t.reason }),
2389
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(RenderReasonTag, { reason: s.reason, changedProps: s.changedProps })
2351
2390
  ] }),
2352
- s.reason === "props" && s.changedProps && s.changedProps.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { style: { ...detailRowStyle, ...monoStyle }, children: [
2353
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { style: detailLabelStyle, children: t.changedProps }),
2354
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { children: s.changedProps.join(", ") })
2391
+ s.reason === "props" && s.changedProps && s.changedProps.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { style: { ...detailRowStyle, ...monoStyle }, children: [
2392
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { style: detailLabelStyle, children: t.changedProps }),
2393
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { children: s.changedProps.join(", ") })
2355
2394
  ] }),
2356
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { style: detailRowStyle, children: [
2357
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { style: detailLabelStyle, children: t.duration }),
2358
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("span", { children: [
2395
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { style: detailRowStyle, children: [
2396
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { style: detailLabelStyle, children: t.duration }),
2397
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("span", { children: [
2359
2398
  s.duration.toFixed(3),
2360
2399
  "ms"
2361
2400
  ] })
2362
2401
  ] }),
2363
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { style: detailRowStyle, children: [
2364
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { style: detailLabelStyle, children: t.at }),
2365
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("span", { children: [
2402
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { style: detailRowStyle, children: [
2403
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { style: detailLabelStyle, children: t.at }),
2404
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("span", { children: [
2366
2405
  s.at.toFixed(2),
2367
2406
  "ms"
2368
2407
  ] })
@@ -2376,9 +2415,9 @@ function StackFrames({
2376
2415
  }) {
2377
2416
  const { t } = useI18n();
2378
2417
  const original = raw.slice(0, limit);
2379
- const [frames, setFrames] = (0, import_hooks3.useState)(original);
2380
- const [resolving, setResolving] = (0, import_hooks3.useState)(false);
2381
- (0, import_hooks3.useEffect)(() => {
2418
+ const [frames, setFrames] = (0, import_hooks5.useState)(original);
2419
+ const [resolving, setResolving] = (0, import_hooks5.useState)(false);
2420
+ (0, import_hooks5.useEffect)(() => {
2382
2421
  if (!resolveFrame || original.length === 0) return;
2383
2422
  let cancelled = false;
2384
2423
  setResolving(true);
@@ -2392,11 +2431,11 @@ function StackFrames({
2392
2431
  cancelled = true;
2393
2432
  };
2394
2433
  }, [raw]);
2395
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_jsx_runtime8.Fragment, { children: [
2396
- resolving && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { style: { color: "#666", fontSize: "10px", marginBottom: "4px" }, children: t.resolvingSourceMaps }),
2397
- frames.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { style: { color: "#666" }, children: t.noStack }) : frames.map((f, i) => /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { style: { ...detailRowStyle, ...monoStyle }, children: [
2398
- f.fnName ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { children: f.fnName }) : /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { style: { color: "#666" }, children: t.anonymous }),
2399
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("span", { style: { color: "#888" }, children: [
2434
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_jsx_runtime9.Fragment, { children: [
2435
+ resolving && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { style: { color: "#666", fontSize: "10px", marginBottom: "4px" }, children: t.resolvingSourceMaps }),
2436
+ frames.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { style: { color: "#666" }, children: t.noStack }) : frames.map((f, i) => /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { style: { ...detailRowStyle, ...monoStyle }, children: [
2437
+ f.fnName ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { children: f.fnName }) : /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { style: { color: "#666" }, children: t.anonymous }),
2438
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("span", { style: { color: "#888" }, children: [
2400
2439
  f.file,
2401
2440
  ":",
2402
2441
  f.line,
@@ -2410,15 +2449,15 @@ function ForcedReflowDetail({
2410
2449
  s,
2411
2450
  resolveFrame
2412
2451
  }) {
2413
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { style: { paddingLeft: "12px" }, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(StackFrames, { raw: s.stack, resolveFrame }) });
2452
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { style: { paddingLeft: "12px" }, children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(StackFrames, { raw: s.stack, resolveFrame }) });
2414
2453
  }
2415
2454
  function HotFunctions({
2416
2455
  attribution,
2417
2456
  resolveFrame
2418
2457
  }) {
2419
2458
  const { t } = useI18n();
2420
- const [frames, setFrames] = (0, import_hooks3.useState)(attribution.map((a) => a.frame));
2421
- (0, import_hooks3.useEffect)(() => {
2459
+ const [frames, setFrames] = (0, import_hooks5.useState)(attribution.map((a) => a.frame));
2460
+ (0, import_hooks5.useEffect)(() => {
2422
2461
  if (!resolveFrame) return;
2423
2462
  let cancelled = false;
2424
2463
  Promise.all(attribution.map((a) => resolveFrame(a.frame))).then((resolved) => {
@@ -2429,26 +2468,26 @@ function HotFunctions({
2429
2468
  cancelled = true;
2430
2469
  };
2431
2470
  }, [attribution]);
2432
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { style: { marginTop: "6px" }, children: [
2433
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { style: { ...detailLabelStyle, textTransform: "uppercase", fontSize: "10px", letterSpacing: "0.5px", marginBottom: "1px", color: "#ff9f0a" }, children: t.hotFunctions }),
2434
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { style: { color: "#666", fontSize: "10px", marginBottom: "4px" }, children: t.hotFunctionsHint }),
2471
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { style: { marginTop: "6px" }, children: [
2472
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { style: { ...detailLabelStyle, textTransform: "uppercase", fontSize: "10px", letterSpacing: "0.5px", marginBottom: "1px", color: "#ff9f0a" }, children: t.hotFunctions }),
2473
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { style: { color: "#666", fontSize: "10px", marginBottom: "4px" }, children: t.hotFunctionsHint }),
2435
2474
  attribution.map((a, i) => {
2436
2475
  const f = frames[i] ?? a.frame;
2437
2476
  const pct = Math.round(a.selfRatio * 100);
2438
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { style: { ...monoStyle, padding: "3px 0", borderTop: i > 0 ? "1px dashed #1f1f1f" : "none" }, children: [
2439
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { children: [
2440
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { style: { color: "#ff9f0a", fontWeight: 600 }, children: f.fnName || /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { style: { color: "#666" }, children: t.anonymous }) }),
2441
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("span", { style: { color: SEVERITY_COLOR.medium, marginLeft: "6px" }, children: [
2477
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { style: { ...monoStyle, padding: "3px 0", borderTop: i > 0 ? "1px dashed #1f1f1f" : "none" }, children: [
2478
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { children: [
2479
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { style: { color: "#ff9f0a", fontWeight: 600 }, children: f.fnName || /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { style: { color: "#666" }, children: t.anonymous }) }),
2480
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("span", { style: { color: SEVERITY_COLOR.medium, marginLeft: "6px" }, children: [
2442
2481
  pct,
2443
2482
  "%"
2444
2483
  ] }),
2445
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("span", { style: { color: "#666", marginLeft: "6px" }, children: [
2484
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("span", { style: { color: "#666", marginLeft: "6px" }, children: [
2446
2485
  "(",
2447
2486
  a.sampleCount,
2448
2487
  ")"
2449
2488
  ] })
2450
2489
  ] }),
2451
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { style: { color: "#888", wordBreak: "break-all" }, children: [
2490
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { style: { color: "#888", wordBreak: "break-all" }, children: [
2452
2491
  f.file,
2453
2492
  ":",
2454
2493
  f.line,
@@ -2465,59 +2504,59 @@ function LongTaskDetail({
2465
2504
  }) {
2466
2505
  const { t } = useI18n();
2467
2506
  const scripts = s.scripts ? [...s.scripts].sort((a, b) => b.duration - a.duration) : [];
2468
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { style: { paddingLeft: "12px" }, children: [
2469
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { style: detailRowStyle, children: [
2470
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { style: detailLabelStyle, children: t.started }),
2471
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("span", { children: [
2507
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { style: { paddingLeft: "12px" }, children: [
2508
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { style: detailRowStyle, children: [
2509
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { style: detailLabelStyle, children: t.started }),
2510
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("span", { children: [
2472
2511
  s.at.toFixed(2),
2473
2512
  "ms"
2474
2513
  ] })
2475
2514
  ] }),
2476
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { style: detailRowStyle, children: [
2477
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { style: detailLabelStyle, children: t.ended }),
2478
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("span", { children: [
2515
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { style: detailRowStyle, children: [
2516
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { style: detailLabelStyle, children: t.ended }),
2517
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("span", { children: [
2479
2518
  (s.at + s.duration).toFixed(2),
2480
2519
  "ms"
2481
2520
  ] })
2482
2521
  ] }),
2483
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { style: detailRowStyle, children: [
2484
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { style: detailLabelStyle, children: t.duration }),
2485
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("span", { children: [
2522
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { style: detailRowStyle, children: [
2523
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { style: detailLabelStyle, children: t.duration }),
2524
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("span", { children: [
2486
2525
  s.duration.toFixed(2),
2487
2526
  "ms"
2488
2527
  ] })
2489
2528
  ] }),
2490
- typeof s.blockingDuration === "number" && /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { style: detailRowStyle, children: [
2491
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { style: detailLabelStyle, children: t.blockingTime }),
2492
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("span", { children: [
2529
+ typeof s.blockingDuration === "number" && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { style: detailRowStyle, children: [
2530
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { style: detailLabelStyle, children: t.blockingTime }),
2531
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("span", { children: [
2493
2532
  s.blockingDuration.toFixed(2),
2494
2533
  "ms"
2495
2534
  ] })
2496
2535
  ] }),
2497
- s.attribution !== void 0 && s.attribution.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(HotFunctions, { attribution: s.attribution, resolveFrame }),
2498
- s.scripts !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { style: { marginTop: "6px" }, children: [
2499
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { style: { ...detailLabelStyle, textTransform: "uppercase", fontSize: "10px", letterSpacing: "0.5px", marginBottom: "4px" }, children: t.scripts }),
2500
- scripts.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { style: { color: "#666" }, children: t.noScripts }) : scripts.map((script, i) => /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { style: { ...monoStyle, padding: "3px 0", borderTop: i > 0 ? "1px dashed #1f1f1f" : "none" }, children: [
2501
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { children: [
2502
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { children: script.sourceFunctionName || /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { style: { color: "#666" }, children: t.anonymous }) }),
2503
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { style: { color: "#5ac8fa", marginLeft: "6px" }, children: script.invokerType }),
2504
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("span", { style: { color: SEVERITY_COLOR.medium, marginLeft: "6px" }, children: [
2536
+ s.attribution !== void 0 && s.attribution.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(HotFunctions, { attribution: s.attribution, resolveFrame }),
2537
+ s.scripts !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { style: { marginTop: "6px" }, children: [
2538
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { style: { ...detailLabelStyle, textTransform: "uppercase", fontSize: "10px", letterSpacing: "0.5px", marginBottom: "4px" }, children: t.scripts }),
2539
+ scripts.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { style: { color: "#666" }, children: t.noScripts }) : scripts.map((script, i) => /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { style: { ...monoStyle, padding: "3px 0", borderTop: i > 0 ? "1px dashed #1f1f1f" : "none" }, children: [
2540
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { children: [
2541
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { children: script.sourceFunctionName || /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { style: { color: "#666" }, children: t.anonymous }) }),
2542
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { style: { color: "#5ac8fa", marginLeft: "6px" }, children: script.invokerType }),
2543
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("span", { style: { color: SEVERITY_COLOR.medium, marginLeft: "6px" }, children: [
2505
2544
  script.duration.toFixed(1),
2506
2545
  "ms"
2507
2546
  ] })
2508
2547
  ] }),
2509
- script.sourceURL && /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { style: { color: "#888", wordBreak: "break-all" }, children: [
2548
+ script.sourceURL && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { style: { color: "#888", wordBreak: "break-all" }, children: [
2510
2549
  script.sourceURL,
2511
2550
  script.charPosition >= 0 ? `@${script.charPosition}` : ""
2512
2551
  ] }),
2513
- script.invoker && /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { style: { color: "#666" }, children: [
2552
+ script.invoker && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { style: { color: "#666" }, children: [
2514
2553
  t.invoker,
2515
2554
  ": ",
2516
2555
  script.invoker
2517
2556
  ] })
2518
2557
  ] }, i))
2519
2558
  ] }),
2520
- s.scripts === void 0 && s.stack.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { style: { marginTop: "4px" }, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(StackFrames, { raw: s.stack, resolveFrame, limit: 5 }) })
2559
+ s.scripts === void 0 && s.stack.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { style: { marginTop: "4px" }, children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(StackFrames, { raw: s.stack, resolveFrame, limit: 5 }) })
2521
2560
  ] });
2522
2561
  }
2523
2562
  var INTERACTION_PHASE_COLOR = { input: "#8e8e93", processing: "#5ac8fa", presentation: "#34c759" };
@@ -2532,33 +2571,33 @@ function InteractionDetail({
2532
2571
  { label: t.processingTime, ms: s.processing, color: INTERACTION_PHASE_COLOR.processing },
2533
2572
  { label: t.presentation, ms: s.presentation, color: INTERACTION_PHASE_COLOR.presentation }
2534
2573
  ];
2535
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { style: { paddingLeft: "12px" }, children: [
2536
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { style: detailRowStyle, children: [
2537
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { style: detailLabelStyle, children: t.interactionEvent }),
2538
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("span", { children: [
2574
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { style: { paddingLeft: "12px" }, children: [
2575
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { style: detailRowStyle, children: [
2576
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { style: detailLabelStyle, children: t.interactionEvent }),
2577
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("span", { children: [
2539
2578
  s.eventType,
2540
2579
  s.target ? ` \xB7 ${s.target}` : ""
2541
2580
  ] })
2542
2581
  ] }),
2543
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { style: detailRowStyle, children: [
2544
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { style: detailLabelStyle, children: t.duration }),
2545
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("span", { children: [
2582
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { style: detailRowStyle, children: [
2583
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { style: detailLabelStyle, children: t.duration }),
2584
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("span", { children: [
2546
2585
  s.duration.toFixed(0),
2547
2586
  "ms"
2548
2587
  ] })
2549
2588
  ] }),
2550
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { style: { display: "flex", height: "10px", borderRadius: "3px", overflow: "hidden", margin: "5px 0 7px", background: "#1a1a1a" }, children: phases.map((p, i) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { style: { width: `${p.ms / total * 100}%`, background: p.color } }, i)) }),
2551
- phases.map((p, i) => /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { style: detailRowStyle, children: [
2552
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("span", { style: { ...detailLabelStyle, display: "inline-flex", alignItems: "center", gap: "5px" }, children: [
2553
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { style: { width: "7px", height: "7px", borderRadius: "2px", background: p.color, flex: "0 0 7px" } }),
2589
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { style: { display: "flex", height: "10px", borderRadius: "3px", overflow: "hidden", margin: "5px 0 7px", background: "#1a1a1a" }, children: phases.map((p, i) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { style: { width: `${p.ms / total * 100}%`, background: p.color } }, i)) }),
2590
+ phases.map((p, i) => /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { style: detailRowStyle, children: [
2591
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("span", { style: { ...detailLabelStyle, display: "inline-flex", alignItems: "center", gap: "5px" }, children: [
2592
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { style: { width: "7px", height: "7px", borderRadius: "2px", background: p.color, flex: "0 0 7px" } }),
2554
2593
  p.label
2555
2594
  ] }),
2556
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("span", { children: [
2595
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("span", { children: [
2557
2596
  p.ms.toFixed(0),
2558
2597
  "ms"
2559
2598
  ] })
2560
2599
  ] }, i)),
2561
- s.attribution !== void 0 && s.attribution.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(HotFunctions, { attribution: s.attribution, resolveFrame })
2600
+ s.attribution !== void 0 && s.attribution.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(HotFunctions, { attribution: s.attribution, resolveFrame })
2562
2601
  ] });
2563
2602
  }
2564
2603
  function SignalDetail({
@@ -2567,24 +2606,24 @@ function SignalDetail({
2567
2606
  }) {
2568
2607
  switch (s.kind) {
2569
2608
  case "forced-reflow":
2570
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(ForcedReflowDetail, { s, resolveFrame });
2609
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(ForcedReflowDetail, { s, resolveFrame });
2571
2610
  case "layout-shift":
2572
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(LayoutShiftDetail, { s });
2611
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(LayoutShiftDetail, { s });
2573
2612
  case "long-task":
2574
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(LongTaskDetail, { s, resolveFrame });
2613
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(LongTaskDetail, { s, resolveFrame });
2575
2614
  case "interaction":
2576
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(InteractionDetail, { s, resolveFrame });
2615
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(InteractionDetail, { s, resolveFrame });
2577
2616
  case "network":
2578
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(NetworkDetail, { s });
2617
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(NetworkDetail, { s });
2579
2618
  case "web-vital":
2580
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(WebVitalDetail, { s });
2619
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(WebVitalDetail, { s });
2581
2620
  case "render":
2582
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(RenderDetail, { s });
2621
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(RenderDetail, { s });
2583
2622
  }
2584
2623
  }
2585
2624
  function SeverityDot({ sev, title }) {
2586
2625
  const { t } = useI18n();
2587
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
2626
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
2588
2627
  "span",
2589
2628
  {
2590
2629
  "data-severity": sev,
@@ -2607,9 +2646,9 @@ function SummaryLine({ signal }) {
2607
2646
  if (signal.kind === "web-vital") {
2608
2647
  const rating = webVitalRating(signal.name, signal.value);
2609
2648
  const unit = WEB_VITAL_UNIT2[signal.name];
2610
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("span", { children: [
2611
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(RatingDot, { rating }),
2612
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("strong", { children: signal.name }),
2649
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("span", { children: [
2650
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(RatingDot, { rating }),
2651
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("strong", { children: signal.name }),
2613
2652
  ": ",
2614
2653
  signal.value.toFixed(2),
2615
2654
  unit
@@ -2618,12 +2657,12 @@ function SummaryLine({ signal }) {
2618
2657
  const sev = severityForSignal(signal);
2619
2658
  const color = SEVERITY_COLOR[sev];
2620
2659
  if (signal.kind === "long-task") {
2621
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("span", { children: [
2660
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("span", { children: [
2622
2661
  "@ ",
2623
2662
  signal.at.toFixed(1),
2624
2663
  "ms \u2022 duration",
2625
2664
  " ",
2626
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("span", { style: { color }, children: [
2665
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("span", { style: { color }, children: [
2627
2666
  signal.duration.toFixed(1),
2628
2667
  "ms"
2629
2668
  ] })
@@ -2631,59 +2670,59 @@ function SummaryLine({ signal }) {
2631
2670
  }
2632
2671
  if (signal.kind === "forced-reflow") {
2633
2672
  const count = signal.count ?? 1;
2634
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("span", { children: [
2673
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("span", { children: [
2635
2674
  "@ ",
2636
2675
  signal.at.toFixed(1),
2637
2676
  "ms \u2022 duration",
2638
2677
  " ",
2639
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("span", { style: { color }, children: [
2678
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("span", { style: { color }, children: [
2640
2679
  signal.duration.toFixed(2),
2641
2680
  "ms"
2642
2681
  ] }),
2643
- count > 1 && /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("span", { style: { color: "#888" }, children: [
2682
+ count > 1 && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("span", { style: { color: "#888" }, children: [
2644
2683
  " \u2022 ",
2645
2684
  t.coalescedReads(count)
2646
2685
  ] })
2647
2686
  ] });
2648
2687
  }
2649
2688
  if (signal.kind === "layout-shift") {
2650
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("span", { children: [
2689
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("span", { children: [
2651
2690
  "@ ",
2652
2691
  signal.at.toFixed(1),
2653
2692
  "ms \u2022 value",
2654
2693
  " ",
2655
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { style: { color }, children: formatCls(signal.value) }),
2694
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { style: { color }, children: formatCls(signal.value) }),
2656
2695
  " \u2022 ",
2657
2696
  t.sourceCount(signal.sources.length)
2658
2697
  ] });
2659
2698
  }
2660
2699
  if (signal.kind === "render") {
2661
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("span", { style: { display: "inline-flex", alignItems: "center", gap: "6px" }, children: [
2662
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("strong", { children: signal.component }),
2663
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(RenderReasonTag, { reason: signal.reason, changedProps: signal.changedProps }),
2664
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("span", { style: { color }, children: [
2700
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("span", { style: { display: "inline-flex", alignItems: "center", gap: "6px" }, children: [
2701
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("strong", { children: signal.component }),
2702
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(RenderReasonTag, { reason: signal.reason, changedProps: signal.changedProps }),
2703
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("span", { style: { color }, children: [
2665
2704
  signal.duration.toFixed(2),
2666
2705
  "ms"
2667
2706
  ] }),
2668
- signal.count && signal.count > 1 && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { style: { color: "#888" }, children: t.cascadeComponents(signal.count) })
2707
+ signal.count && signal.count > 1 && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { style: { color: "#888" }, children: t.cascadeComponents(signal.count) })
2669
2708
  ] });
2670
2709
  }
2671
2710
  if (signal.kind === "network") {
2672
2711
  const url = signal.url.length > 60 ? signal.url.slice(0, 57) + "..." : signal.url;
2673
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("span", { children: [
2712
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("span", { children: [
2674
2713
  url,
2675
2714
  " \u2022 ",
2676
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("span", { style: { color }, children: [
2715
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("span", { style: { color }, children: [
2677
2716
  signal.duration.toFixed(0),
2678
2717
  "ms"
2679
2718
  ] }),
2680
- signal.blocking && /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("span", { style: { color: SEVERITY_COLOR.high }, children: [
2719
+ signal.blocking && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("span", { style: { color: SEVERITY_COLOR.high }, children: [
2681
2720
  " \u2022 ",
2682
2721
  t.blocking
2683
2722
  ] })
2684
2723
  ] });
2685
2724
  }
2686
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { children: summary(signal) });
2725
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { children: summary(signal) });
2687
2726
  }
2688
2727
  function tabSupportsGrouping(kind) {
2689
2728
  return kind === "render" || kind === "forced-reflow";
@@ -2757,7 +2796,7 @@ function groupSignals(signals, mode, kind) {
2757
2796
  function SignalRow({ signal, expanded, onToggleExpand, onHoverGeometry, resolveFrame }) {
2758
2797
  const hasGeometry = signal.kind === "layout-shift" && signal.sources.length > 0;
2759
2798
  const sev = severityForSignal(signal);
2760
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
2799
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
2761
2800
  "li",
2762
2801
  {
2763
2802
  "aria-expanded": expanded,
@@ -2779,22 +2818,22 @@ function SignalRow({ signal, expanded, onToggleExpand, onHoverGeometry, resolveF
2779
2818
  userSelect: "none"
2780
2819
  },
2781
2820
  children: [
2782
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: "6px" }, children: [
2783
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { style: { color: "#888", width: "10px" }, children: expanded ? "\u25BC" : "\u25B6" }),
2784
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(SeverityDot, { sev }),
2785
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(SummaryLine, { signal })
2821
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: "6px" }, children: [
2822
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { style: { color: "#888", width: "10px" }, children: expanded ? "\u25BC" : "\u25B6" }),
2823
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(SeverityDot, { sev }),
2824
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(SummaryLine, { signal })
2786
2825
  ] }),
2787
- expanded && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { style: { marginTop: "6px", paddingTop: "6px", borderTop: "1px dashed #2a2a2a" }, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(SignalDetail, { s: signal, resolveFrame }) })
2826
+ expanded && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { style: { marginTop: "6px", paddingTop: "6px", borderTop: "1px dashed #2a2a2a" }, children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(SignalDetail, { s: signal, resolveFrame }) })
2788
2827
  ]
2789
2828
  }
2790
2829
  );
2791
2830
  }
2792
2831
  function CascadeMembers({ members }) {
2793
2832
  const minDepth = members.reduce((m, s) => Math.min(m, s.depth), Infinity);
2794
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { children: members.map((m, i) => {
2833
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { children: members.map((m, i) => {
2795
2834
  const indent = (m.depth - minDepth) * 14;
2796
2835
  const isCascade = m.reason === "parent";
2797
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
2836
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
2798
2837
  "div",
2799
2838
  {
2800
2839
  style: {
@@ -2805,10 +2844,10 @@ function CascadeMembers({ members }) {
2805
2844
  gap: "6px"
2806
2845
  },
2807
2846
  children: [
2808
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { style: { color: isCascade ? RENDER_REASON_COLOR.parent : "#555" }, children: m.depth > minDepth ? "\u2514" : "\u2022" }),
2809
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("strong", { children: m.component }),
2810
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(RenderReasonTag, { reason: m.reason, changedProps: m.changedProps }),
2811
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("span", { style: { color: "#888" }, children: [
2847
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { style: { color: isCascade ? RENDER_REASON_COLOR.parent : "#555" }, children: m.depth > minDepth ? "\u2514" : "\u2022" }),
2848
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("strong", { children: m.component }),
2849
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(RenderReasonTag, { reason: m.reason, changedProps: m.changedProps }),
2850
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("span", { style: { color: "#888" }, children: [
2812
2851
  m.duration.toFixed(2),
2813
2852
  "ms"
2814
2853
  ] })
@@ -2822,7 +2861,7 @@ function LanguageToggle() {
2822
2861
  const { lang, setLang, t } = useI18n();
2823
2862
  const langs = ["en", "ko"];
2824
2863
  const labels = { en: "EN", ko: "\uD55C" };
2825
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
2864
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
2826
2865
  "div",
2827
2866
  {
2828
2867
  role: "group",
@@ -2835,7 +2874,7 @@ function LanguageToggle() {
2835
2874
  },
2836
2875
  children: langs.map((l) => {
2837
2876
  const active = lang === l;
2838
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
2877
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
2839
2878
  "button",
2840
2879
  {
2841
2880
  type: "button",
@@ -2862,21 +2901,21 @@ function LanguageToggle() {
2862
2901
  function Panel(props) {
2863
2902
  const { result, onClose, position = "bottom-right", resolveFrame } = props;
2864
2903
  const { t } = useI18n();
2865
- const grouped = (0, import_hooks3.useMemo)(() => groupByKind(result.signals), [result.signals]);
2904
+ const grouped = (0, import_hooks5.useMemo)(() => groupByKind(result.signals), [result.signals]);
2866
2905
  const kindsPresent = KIND_ORDER.filter((k) => grouped[k].length > 0);
2867
- const unsupported = (0, import_hooks3.useMemo)(() => (0, import_core4.unsupportedKinds)(), []);
2868
- const hasTimelineSignals = result.signals.some((s) => s.kind !== "web-vital") || (result.heapSamples?.length ?? 0) > 0 || (result.frames?.length ?? 0) > 0;
2869
- const [activeTab, setActiveTab] = (0, import_hooks3.useState)(
2906
+ const unsupported = (0, import_hooks5.useMemo)(() => (0, import_core4.unsupportedKinds)(), []);
2907
+ 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;
2908
+ const [activeTab, setActiveTab] = (0, import_hooks5.useState)(
2870
2909
  kindsPresent[0] ?? "forced-reflow"
2871
2910
  );
2872
2911
  const activeKind = activeTab === "timeline" ? null : activeTab;
2873
2912
  const setActiveKind = (k) => setActiveTab(k);
2874
- const [expandedKey, setExpandedKey] = (0, import_hooks3.useState)(null);
2875
- const [groupMode, setGroupMode] = (0, import_hooks3.useState)({});
2876
- const [sortMode, setSortMode] = (0, import_hooks3.useState)({});
2877
- const [filterText, setFilterText] = (0, import_hooks3.useState)({});
2878
- const activeOverlayCount = (0, import_hooks3.useRef)(0);
2879
- (0, import_hooks3.useEffect)(() => () => hideAllOverlays(), []);
2913
+ const [expandedKey, setExpandedKey] = (0, import_hooks5.useState)(null);
2914
+ const [groupMode, setGroupMode] = (0, import_hooks5.useState)({});
2915
+ const [sortMode, setSortMode] = (0, import_hooks5.useState)({});
2916
+ const [filterText, setFilterText] = (0, import_hooks5.useState)({});
2917
+ const activeOverlayCount = (0, import_hooks5.useRef)(0);
2918
+ (0, import_hooks5.useEffect)(() => () => hideAllOverlays(), []);
2880
2919
  function handleHover(signal) {
2881
2920
  if (!signal) {
2882
2921
  for (let i = 0; i < activeOverlayCount.current; i++) {
@@ -2930,12 +2969,12 @@ function Panel(props) {
2930
2969
  flexDirection: "column",
2931
2970
  overflow: "hidden"
2932
2971
  };
2933
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { role: "region", "aria-label": t.panelRegion, style: panelStyle, children: [
2934
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("header", { style: { display: "flex", alignItems: "center", justifyContent: "space-between", marginBottom: "8px" }, children: [
2935
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("strong", { children: "react-perfscope" }),
2936
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { style: { display: "flex", gap: "4px", alignItems: "center" }, children: [
2937
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(LanguageToggle, {}),
2938
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
2972
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { role: "region", "aria-label": t.panelRegion, style: panelStyle, children: [
2973
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("header", { style: { display: "flex", alignItems: "center", justifyContent: "space-between", marginBottom: "8px" }, children: [
2974
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("strong", { children: "react-perfscope" }),
2975
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { style: { display: "flex", gap: "4px", alignItems: "center" }, children: [
2976
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(LanguageToggle, {}),
2977
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
2939
2978
  "button",
2940
2979
  {
2941
2980
  type: "button",
@@ -2954,7 +2993,7 @@ function Panel(props) {
2954
2993
  children: t.save
2955
2994
  }
2956
2995
  ),
2957
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
2996
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
2958
2997
  "button",
2959
2998
  {
2960
2999
  type: "button",
@@ -2966,7 +3005,7 @@ function Panel(props) {
2966
3005
  )
2967
3006
  ] })
2968
3007
  ] }),
2969
- unsupported.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
3008
+ unsupported.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
2970
3009
  "div",
2971
3010
  {
2972
3011
  style: {
@@ -2981,9 +3020,9 @@ function Panel(props) {
2981
3020
  children: t.unsupportedInBrowser(unsupported.map((k) => t.kindLabel(k)).join(", "))
2982
3021
  }
2983
3022
  ),
2984
- kindsPresent.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { style: { color: "#888" }, children: t.noSignals }),
2985
- kindsPresent.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_jsx_runtime8.Fragment, { children: [
2986
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
3023
+ kindsPresent.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { style: { color: "#888" }, children: t.noSignals }),
3024
+ kindsPresent.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_jsx_runtime9.Fragment, { children: [
3025
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
2987
3026
  SummaryHeader,
2988
3027
  {
2989
3028
  signals: result.signals,
@@ -2995,8 +3034,8 @@ function Panel(props) {
2995
3034
  }
2996
3035
  }
2997
3036
  ),
2998
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("nav", { style: { display: "flex", gap: "4px", flexWrap: "wrap", marginBottom: "8px" }, children: [
2999
- hasTimelineSignals && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
3037
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("nav", { style: { display: "flex", gap: "4px", flexWrap: "wrap", marginBottom: "8px" }, children: [
3038
+ hasTimelineSignals && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
3000
3039
  "button",
3001
3040
  {
3002
3041
  type: "button",
@@ -3021,7 +3060,7 @@ function Panel(props) {
3021
3060
  kindsPresent.map((kind) => {
3022
3061
  const worst = worstSeverity(grouped[kind]);
3023
3062
  const active = activeKind === kind;
3024
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
3063
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
3025
3064
  "button",
3026
3065
  {
3027
3066
  type: "button",
@@ -3044,7 +3083,7 @@ function Panel(props) {
3044
3083
  gap: "6px"
3045
3084
  },
3046
3085
  children: [
3047
- worst !== "low" && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(SeverityDot, { sev: worst, title: t.worstLabel(worst) }),
3086
+ worst !== "low" && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(SeverityDot, { sev: worst, title: t.worstLabel(worst) }),
3048
3087
  t.kindLabel(kind),
3049
3088
  " ",
3050
3089
  grouped[kind].length
@@ -3054,10 +3093,10 @@ function Panel(props) {
3054
3093
  );
3055
3094
  })
3056
3095
  ] }),
3057
- activeKind && activeTab !== "timeline" && /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: "12px", marginBottom: "6px", fontSize: "11px", color: "#888", flexWrap: "wrap" }, children: [
3058
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("label", { style: { display: "flex", alignItems: "center", gap: "6px" }, children: [
3096
+ activeKind && activeTab !== "timeline" && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: "12px", marginBottom: "6px", fontSize: "11px", color: "#888", flexWrap: "wrap" }, children: [
3097
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("label", { style: { display: "flex", alignItems: "center", gap: "6px" }, children: [
3059
3098
  t.sort,
3060
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
3099
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
3061
3100
  "select",
3062
3101
  {
3063
3102
  "aria-label": t.sort,
@@ -3069,15 +3108,15 @@ function Panel(props) {
3069
3108
  },
3070
3109
  style: { background: "#1a1a1a", color: "#e6e6e6", border: "1px solid #2a2a2a", borderRadius: "4px", padding: "2px 6px", fontSize: "11px" },
3071
3110
  children: [
3072
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("option", { value: "chronological", children: t.sortChronological }),
3073
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("option", { value: "severity", children: t.sortSeverity })
3111
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("option", { value: "chronological", children: t.sortChronological }),
3112
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("option", { value: "severity", children: t.sortSeverity })
3074
3113
  ]
3075
3114
  }
3076
3115
  )
3077
3116
  ] }),
3078
- tabSupportsGrouping(activeKind) && /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("label", { style: { display: "flex", alignItems: "center", gap: "6px" }, children: [
3117
+ tabSupportsGrouping(activeKind) && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("label", { style: { display: "flex", alignItems: "center", gap: "6px" }, children: [
3079
3118
  t.groupBy,
3080
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
3119
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
3081
3120
  "select",
3082
3121
  {
3083
3122
  "aria-label": t.groupBy,
@@ -3089,15 +3128,15 @@ function Panel(props) {
3089
3128
  },
3090
3129
  style: { background: "#1a1a1a", color: "#e6e6e6", border: "1px solid #2a2a2a", borderRadius: "4px", padding: "2px 6px", fontSize: "11px" },
3091
3130
  children: [
3092
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("option", { value: "chronological", children: t.groupChronological }),
3093
- activeKind === "render" && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("option", { value: "commit", children: t.groupCommit }),
3094
- activeKind === "render" && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("option", { value: "component", children: t.groupComponent }),
3095
- activeKind === "forced-reflow" && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("option", { value: "source", children: t.groupSource })
3131
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("option", { value: "chronological", children: t.groupChronological }),
3132
+ activeKind === "render" && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("option", { value: "commit", children: t.groupCommit }),
3133
+ activeKind === "render" && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("option", { value: "component", children: t.groupComponent }),
3134
+ activeKind === "forced-reflow" && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("option", { value: "source", children: t.groupSource })
3096
3135
  ]
3097
3136
  }
3098
3137
  )
3099
3138
  ] }),
3100
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
3139
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
3101
3140
  "input",
3102
3141
  {
3103
3142
  type: "text",
@@ -3112,23 +3151,26 @@ function Panel(props) {
3112
3151
  }
3113
3152
  )
3114
3153
  ] }),
3115
- activeTab === "timeline" && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { style: { flexGrow: 1, overflowY: "auto", paddingTop: "4px", paddingBottom: "24px" }, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
3116
- Timeline,
3117
- {
3118
- signals: result.signals,
3119
- duration: result.duration,
3120
- startedAt: result.startedAt,
3121
- heapSamples: result.heapSamples,
3122
- frames: result.frames,
3123
- onJump: (s) => {
3124
- setActiveTab(s.kind);
3125
- const inOrder = grouped[s.kind];
3126
- const idx = inOrder.indexOf(s);
3127
- if (idx >= 0) setExpandedKey(`${s.kind}-${idx}`);
3154
+ activeTab === "timeline" && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { style: { flexGrow: 1, overflowY: "auto", paddingTop: "4px", paddingBottom: "24px" }, children: [
3155
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(LeakList, { suspects: result.leakSuspects }),
3156
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
3157
+ Timeline,
3158
+ {
3159
+ signals: result.signals,
3160
+ duration: result.duration,
3161
+ startedAt: result.startedAt,
3162
+ heapSamples: result.heapSamples,
3163
+ frames: result.frames,
3164
+ onJump: (s) => {
3165
+ setActiveTab(s.kind);
3166
+ const inOrder = grouped[s.kind];
3167
+ const idx = inOrder.indexOf(s);
3168
+ if (idx >= 0) setExpandedKey(`${s.kind}-${idx}`);
3169
+ }
3128
3170
  }
3129
- }
3130
- ) }),
3131
- activeKind === "render" && activeTab !== "timeline" && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
3171
+ )
3172
+ ] }),
3173
+ activeKind === "render" && activeTab !== "timeline" && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
3132
3174
  RenderInsights,
3133
3175
  {
3134
3176
  signals: grouped.render.flatMap((s) => s.kind === "render" ? s.members ?? [s] : []).filter((s) => signalMatchesFilter(s, filterText.render ?? "")),
@@ -3138,8 +3180,8 @@ function Panel(props) {
3138
3180
  }
3139
3181
  }
3140
3182
  ),
3141
- activeKind === "long-task" && activeTab !== "timeline" && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(LongTaskEpisode, { signals: result.signals }),
3142
- activeKind === "layout-shift" && activeTab !== "timeline" && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
3183
+ activeKind === "long-task" && activeTab !== "timeline" && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(LongTaskEpisode, { signals: result.signals }),
3184
+ activeKind === "layout-shift" && activeTab !== "timeline" && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
3143
3185
  "div",
3144
3186
  {
3145
3187
  style: {
@@ -3154,9 +3196,9 @@ function Panel(props) {
3154
3196
  children: t.layoutShiftHint
3155
3197
  }
3156
3198
  ),
3157
- activeKind === "interaction" && activeTab !== "timeline" && /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_jsx_runtime8.Fragment, { children: [
3158
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(InpEpisode, { signals: result.signals }),
3159
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
3199
+ activeKind === "interaction" && activeTab !== "timeline" && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_jsx_runtime9.Fragment, { children: [
3200
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(InpEpisode, { signals: result.signals }),
3201
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
3160
3202
  "div",
3161
3203
  {
3162
3204
  style: {
@@ -3172,7 +3214,7 @@ function Panel(props) {
3172
3214
  }
3173
3215
  )
3174
3216
  ] }),
3175
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("ul", { style: { listStyle: "none", margin: 0, padding: 0, overflowY: "auto", flexGrow: 1, display: activeTab === "timeline" ? "none" : void 0 }, children: activeKind && (() => {
3217
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("ul", { style: { listStyle: "none", margin: 0, padding: 0, overflowY: "auto", flexGrow: 1, display: activeTab === "timeline" ? "none" : void 0 }, children: activeKind && (() => {
3176
3218
  const filtered = grouped[activeKind].filter(
3177
3219
  (s) => signalMatchesFilter(s, filterText[activeKind] ?? "")
3178
3220
  );
@@ -3182,7 +3224,7 @@ function Panel(props) {
3182
3224
  const currentMode = groupMode[activeKind] ?? "chronological";
3183
3225
  if (currentMode === "chronological") {
3184
3226
  const key2 = `${activeKind}-${gi}`;
3185
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
3227
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
3186
3228
  SignalRow,
3187
3229
  {
3188
3230
  signal: g.signals[0],
@@ -3199,7 +3241,7 @@ function Panel(props) {
3199
3241
  const isCascade = activeKind === "render" && currentMode === "commit";
3200
3242
  const renderMembers = g.signals.filter((s) => s.kind === "render");
3201
3243
  const unnecessary = isCascade ? renderMembers.filter((s) => s.reason === "parent").length : 0;
3202
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
3244
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
3203
3245
  "li",
3204
3246
  {
3205
3247
  "aria-expanded": isOpen,
@@ -3214,49 +3256,50 @@ function Panel(props) {
3214
3256
  userSelect: "none"
3215
3257
  },
3216
3258
  children: [
3217
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: "6px", flexWrap: "wrap" }, children: [
3218
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { style: { color: "#888", width: "10px" }, children: isOpen ? "\u25BC" : "\u25B6" }),
3219
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("span", { children: [
3220
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("strong", { children: g.label }),
3259
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: "6px", flexWrap: "wrap" }, children: [
3260
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { style: { color: "#888", width: "10px" }, children: isOpen ? "\u25BC" : "\u25B6" }),
3261
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("span", { children: [
3262
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("strong", { children: g.label }),
3221
3263
  " \xD7",
3222
3264
  g.count
3223
3265
  ] }),
3224
- isCascade && unnecessary > 0 && /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("span", { style: { color: RENDER_REASON_COLOR.parent, fontSize: "10px" }, children: [
3266
+ isCascade && unnecessary > 0 && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("span", { style: { color: RENDER_REASON_COLOR.parent, fontSize: "10px" }, children: [
3225
3267
  "\u26A0 ",
3226
3268
  t.unnecessaryRenders(unnecessary)
3227
3269
  ] })
3228
3270
  ] }),
3229
- isOpen && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { style: { marginTop: "6px", paddingTop: "6px", borderTop: "1px dashed #2a2a2a", paddingLeft: "8px" }, children: isCascade ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(CascadeMembers, { members: renderMembers }) : /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_jsx_runtime8.Fragment, { children: [
3230
- g.signals.slice(0, 20).map((s, si) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { style: { padding: "2px 0" }, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(SummaryLine, { signal: s }) }, si)),
3231
- g.signals.length > 20 && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { style: { color: "#888", marginTop: "4px" }, children: t.moreItems(g.signals.length - 20) })
3271
+ isOpen && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { style: { marginTop: "6px", paddingTop: "6px", borderTop: "1px dashed #2a2a2a", paddingLeft: "8px" }, children: isCascade ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(CascadeMembers, { members: renderMembers }) : /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_jsx_runtime9.Fragment, { children: [
3272
+ g.signals.slice(0, 20).map((s, si) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { style: { padding: "2px 0" }, children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(SummaryLine, { signal: s }) }, si)),
3273
+ g.signals.length > 20 && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { style: { color: "#888", marginTop: "4px" }, children: t.moreItems(g.signals.length - 20) })
3232
3274
  ] }) })
3233
3275
  ]
3234
3276
  },
3235
3277
  key
3236
3278
  );
3237
3279
  }) }),
3238
- activeKind && activeTab !== "timeline" && (filterText[activeKind] ?? "").trim() !== "" && grouped[activeKind].length > 0 && grouped[activeKind].every((s) => !signalMatchesFilter(s, filterText[activeKind] ?? "")) && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { style: { padding: "12px 8px", fontSize: "11px", color: "#888" }, children: t.filterNoMatches })
3280
+ activeKind && activeTab !== "timeline" && (filterText[activeKind] ?? "").trim() !== "" && grouped[activeKind].length > 0 && grouped[activeKind].every((s) => !signalMatchesFilter(s, filterText[activeKind] ?? "")) && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { style: { padding: "12px 8px", fontSize: "11px", color: "#888" }, children: t.filterNoMatches })
3239
3281
  ] })
3240
3282
  ] });
3241
3283
  }
3242
3284
 
3243
3285
  // src/app.tsx
3244
- var import_jsx_runtime9 = require("preact/jsx-runtime");
3286
+ var import_jsx_runtime10 = require("preact/jsx-runtime");
3245
3287
  function App(props) {
3246
3288
  const { recorder, position = "bottom-right", resolveFrame, finalize } = props;
3247
- const [recording, setRecording] = (0, import_hooks4.useState)(false);
3248
- const [result, setResult] = (0, import_hooks4.useState)(null);
3249
- const [elapsedMs, setElapsedMs] = (0, import_hooks4.useState)(0);
3250
- const startedAtRef = (0, import_hooks4.useRef)(0);
3251
- const rafRef = (0, import_hooks4.useRef)(null);
3252
- const resultTokenRef = (0, import_hooks4.useRef)(0);
3253
- (0, import_hooks4.useEffect)(() => {
3289
+ const [recording, setRecording] = (0, import_hooks6.useState)(false);
3290
+ const [result, setResult] = (0, import_hooks6.useState)(null);
3291
+ const [elapsedMs, setElapsedMs] = (0, import_hooks6.useState)(0);
3292
+ const startedAtRef = (0, import_hooks6.useRef)(0);
3293
+ const rafRef = (0, import_hooks6.useRef)(null);
3294
+ const resultTokenRef = (0, import_hooks6.useRef)(0);
3295
+ (0, import_hooks6.useEffect)(() => {
3254
3296
  if (!recording) {
3255
3297
  if (rafRef.current !== null) cancelAnimationFrame(rafRef.current);
3256
3298
  return;
3257
3299
  }
3258
3300
  const tick = () => {
3259
- setElapsedMs(performance.now() - startedAtRef.current);
3301
+ const elapsed = performance.now() - startedAtRef.current;
3302
+ setElapsedMs(Math.floor(elapsed / 1e3) * 1e3);
3260
3303
  rafRef.current = requestAnimationFrame(tick);
3261
3304
  };
3262
3305
  rafRef.current = requestAnimationFrame(tick);
@@ -3287,8 +3330,8 @@ function App(props) {
3287
3330
  function onClose() {
3288
3331
  setResult(null);
3289
3332
  }
3290
- return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(I18nProvider, { children: [
3291
- result === null && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
3333
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(I18nProvider, { children: [
3334
+ result === null && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
3292
3335
  Widget,
3293
3336
  {
3294
3337
  recording,
@@ -3297,16 +3340,21 @@ function App(props) {
3297
3340
  position
3298
3341
  }
3299
3342
  ),
3300
- result !== null && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Panel, { result, position, onClose, resolveFrame })
3343
+ result !== null && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Panel, { result, position, onClose, resolveFrame })
3301
3344
  ] });
3302
3345
  }
3303
3346
 
3304
3347
  // src/mount.tsx
3305
- var import_jsx_runtime10 = require("preact/jsx-runtime");
3348
+ var import_jsx_runtime11 = require("preact/jsx-runtime");
3306
3349
  function mount(opts) {
3307
3350
  const { recorder, position = "bottom-right", host = document.body, resolveFrame, finalize } = opts;
3351
+ if (host.querySelector("[data-perfscope-host]")) {
3352
+ console.warn("[react-perfscope] mount(): a widget is already mounted here \u2014 ignoring this call");
3353
+ return () => {
3354
+ };
3355
+ }
3308
3356
  return mountShadow(
3309
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(App, { recorder, position, resolveFrame, finalize }),
3357
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(App, { recorder, position, resolveFrame, finalize }),
3310
3358
  { parent: host }
3311
3359
  );
3312
3360
  }