r3f-frame-profiler 1.0.1 → 1.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (128) hide show
  1. package/dist/cjs/index.js +1 -2
  2. package/dist/cjs/index.js.map +1 -1
  3. package/dist/esm/index.js +7 -12485
  4. package/dist/esm/index.js.map +1 -1
  5. package/dist/index-D_LaF0YP.cjs +2 -0
  6. package/dist/index-D_LaF0YP.cjs.map +1 -0
  7. package/dist/index-o5zvhDta.js +4406 -0
  8. package/dist/index-o5zvhDta.js.map +1 -0
  9. package/dist/report-generator-BCq_enQo.js +283 -0
  10. package/dist/report-generator-BCq_enQo.js.map +1 -0
  11. package/dist/report-generator-BsoP53qp.cjs +61 -0
  12. package/dist/report-generator-BsoP53qp.cjs.map +1 -0
  13. package/dist/types/FrameProfiler.d.ts +2 -0
  14. package/dist/types/FrameProfiler.d.ts.map +1 -0
  15. package/dist/types/collectors/frame-time-collector.d.ts +41 -0
  16. package/dist/types/collectors/frame-time-collector.d.ts.map +1 -0
  17. package/dist/types/collectors/gpu-collector.d.ts +32 -0
  18. package/dist/types/collectors/gpu-collector.d.ts.map +1 -0
  19. package/dist/types/collectors/hot-path-detector.d.ts +42 -0
  20. package/dist/types/collectors/hot-path-detector.d.ts.map +1 -0
  21. package/dist/types/collectors/index.d.ts +7 -0
  22. package/dist/types/collectors/index.d.ts.map +1 -0
  23. package/dist/types/collectors/memory-collector.d.ts +49 -0
  24. package/dist/types/collectors/memory-collector.d.ts.map +1 -0
  25. package/dist/types/collectors/scene-collector.d.ts +47 -0
  26. package/dist/types/collectors/scene-collector.d.ts.map +1 -0
  27. package/dist/types/components/ReactProfiler.d.ts +12 -0
  28. package/dist/types/components/ReactProfiler.d.ts.map +1 -0
  29. package/dist/types/core/alert-system.d.ts +37 -0
  30. package/dist/types/core/alert-system.d.ts.map +1 -0
  31. package/dist/types/core/auto-instrumentation.d.ts +33 -0
  32. package/dist/types/core/auto-instrumentation.d.ts.map +1 -0
  33. package/dist/types/core/budget-manager.d.ts +78 -0
  34. package/dist/types/core/budget-manager.d.ts.map +1 -0
  35. package/dist/types/core/data-export.d.ts +24 -0
  36. package/dist/types/core/data-export.d.ts.map +1 -0
  37. package/dist/types/core/index.d.ts +4 -0
  38. package/dist/types/core/index.d.ts.map +1 -0
  39. package/dist/types/core/monitor-state.d.ts +21 -0
  40. package/dist/types/core/monitor-state.d.ts.map +1 -0
  41. package/dist/types/core/profiler.d.ts +83 -0
  42. package/dist/types/core/profiler.d.ts.map +1 -0
  43. package/dist/types/core/react-monitor.d.ts +51 -0
  44. package/dist/types/core/react-monitor.d.ts.map +1 -0
  45. package/dist/types/core/report-generator.d.ts +83 -0
  46. package/dist/types/core/report-generator.d.ts.map +1 -0
  47. package/dist/types/hooks/index.d.ts +17 -0
  48. package/dist/types/hooks/index.d.ts.map +1 -0
  49. package/dist/types/hooks/useAlerts.d.ts +11 -0
  50. package/dist/types/hooks/useAlerts.d.ts.map +1 -0
  51. package/dist/types/hooks/useBudgetChecker.d.ts +6 -0
  52. package/dist/types/hooks/useBudgetChecker.d.ts.map +1 -0
  53. package/dist/types/hooks/useFrameHistory.d.ts +2 -0
  54. package/dist/types/hooks/useFrameHistory.d.ts.map +1 -0
  55. package/dist/types/hooks/useFrameTime.d.ts +3 -0
  56. package/dist/types/hooks/useFrameTime.d.ts.map +1 -0
  57. package/dist/types/hooks/useGPUStats.d.ts +3 -0
  58. package/dist/types/hooks/useGPUStats.d.ts.map +1 -0
  59. package/dist/types/hooks/useHotPath.d.ts +3 -0
  60. package/dist/types/hooks/useHotPath.d.ts.map +1 -0
  61. package/dist/types/hooks/useMemoryHistory.d.ts +5 -0
  62. package/dist/types/hooks/useMemoryHistory.d.ts.map +1 -0
  63. package/dist/types/hooks/useMemoryStats.d.ts +3 -0
  64. package/dist/types/hooks/useMemoryStats.d.ts.map +1 -0
  65. package/dist/types/hooks/useMetricsCollector.d.ts +31 -0
  66. package/dist/types/hooks/useMetricsCollector.d.ts.map +1 -0
  67. package/dist/types/hooks/usePerformanceBudget.d.ts +20 -0
  68. package/dist/types/hooks/usePerformanceBudget.d.ts.map +1 -0
  69. package/dist/types/hooks/useProfiler.d.ts +5 -0
  70. package/dist/types/hooks/useProfiler.d.ts.map +1 -0
  71. package/dist/types/hooks/useR3FProfiler.d.ts +2 -0
  72. package/dist/types/hooks/useR3FProfiler.d.ts.map +1 -0
  73. package/dist/types/hooks/useR3FProfilerCollector.d.ts +2 -0
  74. package/dist/types/hooks/useR3FProfilerCollector.d.ts.map +1 -0
  75. package/dist/types/hooks/useR3FStatsCollector.d.ts +2 -0
  76. package/dist/types/hooks/useR3FStatsCollector.d.ts.map +1 -0
  77. package/dist/types/hooks/useReactProfiler.d.ts +3 -0
  78. package/dist/types/hooks/useReactProfiler.d.ts.map +1 -0
  79. package/dist/types/hooks/useReportMetric.d.ts +19 -0
  80. package/dist/types/hooks/useReportMetric.d.ts.map +1 -0
  81. package/dist/types/hooks/useSceneStats.d.ts +3 -0
  82. package/dist/types/hooks/useSceneStats.d.ts.map +1 -0
  83. package/dist/types/index.d.ts +5 -0
  84. package/dist/types/index.d.ts.map +1 -0
  85. package/dist/types/ui/PerformanceMonitor.d.ts +7 -0
  86. package/dist/types/ui/PerformanceMonitor.d.ts.map +1 -0
  87. package/dist/types/ui/components/AlertBadge.d.ts +9 -0
  88. package/dist/types/ui/components/AlertBadge.d.ts.map +1 -0
  89. package/dist/types/ui/components/MetricCard.d.ts +14 -0
  90. package/dist/types/ui/components/MetricCard.d.ts.map +1 -0
  91. package/dist/types/ui/components/SimpleChart.d.ts +13 -0
  92. package/dist/types/ui/components/SimpleChart.d.ts.map +1 -0
  93. package/dist/types/ui/components/Tabs.d.ts +15 -0
  94. package/dist/types/ui/components/Tabs.d.ts.map +1 -0
  95. package/dist/types/ui/components/index.d.ts +5 -0
  96. package/dist/types/ui/components/index.d.ts.map +1 -0
  97. package/dist/types/ui/panels/BudgetPanel.d.ts +2 -0
  98. package/dist/types/ui/panels/BudgetPanel.d.ts.map +1 -0
  99. package/dist/types/ui/panels/FramePanel.d.ts +2 -0
  100. package/dist/types/ui/panels/FramePanel.d.ts.map +1 -0
  101. package/dist/types/ui/panels/FrameTimePanel.d.ts +2 -0
  102. package/dist/types/ui/panels/FrameTimePanel.d.ts.map +1 -0
  103. package/dist/types/ui/panels/GPUPanel.d.ts +2 -0
  104. package/dist/types/ui/panels/GPUPanel.d.ts.map +1 -0
  105. package/dist/types/ui/panels/HotPathPanel.d.ts +2 -0
  106. package/dist/types/ui/panels/HotPathPanel.d.ts.map +1 -0
  107. package/dist/types/ui/panels/MemoryPanel.d.ts +2 -0
  108. package/dist/types/ui/panels/MemoryPanel.d.ts.map +1 -0
  109. package/dist/types/ui/panels/ReactPanel.d.ts +2 -0
  110. package/dist/types/ui/panels/ReactPanel.d.ts.map +1 -0
  111. package/dist/types/ui/panels/ScenePanel.d.ts +2 -0
  112. package/dist/types/ui/panels/ScenePanel.d.ts.map +1 -0
  113. package/dist/types/ui/panels/index.d.ts +9 -0
  114. package/dist/types/ui/panels/index.d.ts.map +1 -0
  115. package/dist/types/ui/styles/theme.d.ts +76 -0
  116. package/dist/types/ui/styles/theme.d.ts.map +1 -0
  117. package/dist/types/ui/visualizations/FrameGraph.d.ts +10 -0
  118. package/dist/types/ui/visualizations/FrameGraph.d.ts.map +1 -0
  119. package/dist/types/ui/visualizations/MemoryChart.d.ts +10 -0
  120. package/dist/types/ui/visualizations/MemoryChart.d.ts.map +1 -0
  121. package/dist/types/ui/visualizations/PerformanceChart.d.ts +16 -0
  122. package/dist/types/ui/visualizations/PerformanceChart.d.ts.map +1 -0
  123. package/dist/types/ui/visualizations/TimelineView.d.ts +7 -0
  124. package/dist/types/ui/visualizations/TimelineView.d.ts.map +1 -0
  125. package/dist/types/ui/visualizations/index.d.ts +5 -0
  126. package/dist/types/ui/visualizations/index.d.ts.map +1 -0
  127. package/package.json +14 -7
  128. package/README.md +0 -60
@@ -0,0 +1,4406 @@
1
+ import { useRef as I, useEffect as A, useState as B, useMemo as L, useCallback as Z } from "react";
2
+ import { useFrame as le, useThree as he } from "@react-three/fiber";
3
+ import { Mesh as oe, Texture as ne, Light as se, Camera as fe } from "three";
4
+ import { jsxs as c, jsx as s, Fragment as N } from "react/jsx-runtime";
5
+ class ye {
6
+ data = /* @__PURE__ */ new Map();
7
+ frameCount = 0;
8
+ enabled = !1;
9
+ maxHistorySize = 240;
10
+ listeners = /* @__PURE__ */ new Set();
11
+ reportGenerator = null;
12
+ constructor() {
13
+ this.updateEnabledState(), typeof window < "u" && (window.addEventListener("storage", () => {
14
+ this.updateEnabledState();
15
+ }), import("./report-generator-BCq_enQo.js").then(({ reportGenerator: e }) => {
16
+ this.reportGenerator = e;
17
+ }));
18
+ }
19
+ updateEnabledState() {
20
+ if (typeof window > "u") {
21
+ this.enabled = !1;
22
+ return;
23
+ }
24
+ const e = new URLSearchParams(window.location.search);
25
+ this.enabled = e.get("debug") === "1" || localStorage.getItem("debug") === "true";
26
+ }
27
+ isEnabled() {
28
+ return this.enabled;
29
+ }
30
+ profile(e, t) {
31
+ if (!this.enabled)
32
+ return t();
33
+ const r = performance.now(), o = t(), d = performance.now() - r;
34
+ return this.record(e, d), o;
35
+ }
36
+ async profileAsync(e, t) {
37
+ if (!this.enabled)
38
+ return t();
39
+ const r = performance.now(), o = await t(), d = performance.now() - r;
40
+ return this.record(e, d), o;
41
+ }
42
+ record(e, t) {
43
+ if (!this.enabled) return;
44
+ this.data.has(e) || this.data.set(e, {
45
+ total: 0,
46
+ calls: 0,
47
+ max: 0,
48
+ times: []
49
+ });
50
+ const r = this.data.get(e);
51
+ if (r.total += t, r.calls += 1, r.max = Math.max(r.max, t), r.times.push(t), typeof window < "u" && window.__hotPathDetector)
52
+ try {
53
+ window.__hotPathDetector.recordCall(e, t);
54
+ } catch {
55
+ }
56
+ if (r.times.length > this.maxHistorySize) {
57
+ const o = r.times.shift();
58
+ r.total -= o, r.calls -= 1;
59
+ }
60
+ this.frameCount += 1, this.frameCount > this.maxHistorySize && (this.frameCount = this.maxHistorySize);
61
+ }
62
+ wrap(e, t) {
63
+ if (!this.enabled)
64
+ return t;
65
+ const r = this;
66
+ return ((...o) => r.profile(e, () => t(...o)));
67
+ }
68
+ wrapAsync(e, t) {
69
+ if (!this.enabled)
70
+ return t;
71
+ const r = this;
72
+ return (async (...o) => r.profileAsync(e, () => t(...o)));
73
+ }
74
+ getData() {
75
+ if (!this.enabled) return null;
76
+ const e = Array.from(this.data.entries()).map(([o, a]) => ({
77
+ name: o,
78
+ total: a.total,
79
+ avg: a.calls > 0 ? a.total / a.calls : 0,
80
+ max: a.max,
81
+ calls: a.calls
82
+ })), t = e.reduce((o, a) => o + a.total, 0);
83
+ return {
84
+ entries: e.map((o) => ({
85
+ ...o,
86
+ percentage: t > 0 ? o.total / t * 100 : 0,
87
+ avg: isFinite(o.avg) ? o.avg : 0
88
+ // Ensure safe number
89
+ })),
90
+ totalTime: t,
91
+ calls: Math.max(...e.map((o) => o.calls), 0),
92
+ frames: this.frameCount
93
+ };
94
+ }
95
+ /**
96
+ * Get raw profiler data including individual timing samples for percentile analysis
97
+ */
98
+ getRawData() {
99
+ return this.enabled ? this.data : null;
100
+ }
101
+ reset() {
102
+ this.data.clear(), this.frameCount = 0, this.notifyListeners();
103
+ }
104
+ subscribe(e) {
105
+ return this.listeners.add(e), () => {
106
+ this.listeners.delete(e);
107
+ };
108
+ }
109
+ /**
110
+ * Notifie tous les listeners
111
+ */
112
+ notifyListeners() {
113
+ const e = this.getData();
114
+ this.listeners.forEach((t) => t(e));
115
+ }
116
+ /**
117
+ * Force une notification aux listeners
118
+ */
119
+ notify() {
120
+ this.notifyListeners();
121
+ }
122
+ /**
123
+ * Configure la taille maximale de l'historique
124
+ */
125
+ setMaxHistorySize(e) {
126
+ this.maxHistorySize = e;
127
+ }
128
+ /**
129
+ * Génère un rapport de performance markdown
130
+ * Optimisé pour être analysé par une IA
131
+ */
132
+ async generateReport() {
133
+ const { reportGenerator: e } = await import("./report-generator-BCq_enQo.js");
134
+ return e.generateMarkdownReport();
135
+ }
136
+ /**
137
+ * Copie le rapport dans le clipboard
138
+ */
139
+ async copyReportToClipboard() {
140
+ const { reportGenerator: e } = await import("./report-generator-BCq_enQo.js");
141
+ await e.copyReportToClipboard();
142
+ }
143
+ /**
144
+ * Enregistre une frame pour les statistiques du rapport
145
+ */
146
+ recordFrameStats(e, t, r) {
147
+ !isFinite(e) || !isFinite(t) || e > 1e3 || t <= 0 || (this.reportGenerator ? this.reportGenerator.recordFrame(e, t, r) : import("./report-generator-BCq_enQo.js").then(({ reportGenerator: o }) => {
148
+ this.reportGenerator = o, this.reportGenerator.recordFrame(e, t, r);
149
+ }));
150
+ }
151
+ /**
152
+ * Enregistre une métrique custom pour le rapport
153
+ */
154
+ recordMetricForReport(e, t) {
155
+ import("./report-generator-BCq_enQo.js").then(({ reportGenerator: r }) => {
156
+ r.recordMetric(e, t);
157
+ });
158
+ }
159
+ }
160
+ const E = new ye();
161
+ typeof window < "u" && Promise.resolve().then(async () => {
162
+ try {
163
+ const { hotPathDetector: n } = await Promise.resolve().then(() => Ke);
164
+ window.__hotPathDetector = n;
165
+ } catch {
166
+ }
167
+ });
168
+ const be = (n, e) => E.profile(n, e), ce = () => E.isEnabled(), xe = (n, e) => {
169
+ E.recordMetricForReport(n, e);
170
+ }, ve = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
171
+ __proto__: null,
172
+ isProfilerEnabled: ce,
173
+ profile: be,
174
+ profiler: E,
175
+ reportMetric: xe
176
+ }, Symbol.toStringTag, { value: "Module" })), ot = () => {
177
+ const n = I(performance.now());
178
+ return le(() => {
179
+ if (E.isEnabled()) {
180
+ const e = performance.now(), t = e - n.current;
181
+ n.current = e, E.record("Frame", t), E.notify();
182
+ } else
183
+ n.current = performance.now();
184
+ }), null;
185
+ };
186
+ class Se {
187
+ renderer = null;
188
+ lastStats = null;
189
+ frameStartTime = 0;
190
+ setRenderer(e) {
191
+ this.renderer = e;
192
+ }
193
+ getStats() {
194
+ if (!this.renderer)
195
+ return null;
196
+ const e = this.renderer.info, t = e.memory, r = e.render, o = "points" in r ? r.points : 0, a = "lines" in r ? r.lines : 0;
197
+ let d = 0, l = 0;
198
+ if (t.textures && this.renderer)
199
+ try {
200
+ d = t.textures * 2 * 1024 * 1024;
201
+ } catch {
202
+ d = t.textures * 1024 * 1024;
203
+ }
204
+ if (t.geometries && this.renderer)
205
+ try {
206
+ l = (this.renderer.info.render.triangles || 0) * 100, l += t.geometries * 10 * 1024;
207
+ } catch {
208
+ l = t.geometries * 100 * 1024;
209
+ }
210
+ const g = {
211
+ drawCalls: r.calls || 0,
212
+ triangles: r.triangles || 0,
213
+ points: o || 0,
214
+ lines: a || 0,
215
+ textures: t.textures || 0,
216
+ geometries: t.geometries || 0,
217
+ programs: e.programs?.length || 0,
218
+ memory: {
219
+ textures: d,
220
+ geometries: l,
221
+ programs: 0,
222
+ // Not available in memory object
223
+ total: d + l
224
+ },
225
+ frameTime: performance.now() - this.frameStartTime,
226
+ timestamp: performance.now()
227
+ };
228
+ return this.lastStats = g, g;
229
+ }
230
+ startFrame() {
231
+ this.frameStartTime = performance.now();
232
+ }
233
+ endFrame() {
234
+ }
235
+ getLastStats() {
236
+ return this.lastStats;
237
+ }
238
+ reset() {
239
+ this.lastStats = null;
240
+ }
241
+ }
242
+ const O = new Se();
243
+ class we {
244
+ scene = null;
245
+ setScene(e) {
246
+ this.scene = e;
247
+ }
248
+ getStats() {
249
+ if (!this.scene)
250
+ return null;
251
+ const e = {
252
+ total: 0,
253
+ meshes: 0,
254
+ lights: 0,
255
+ cameras: 0,
256
+ groups: 0,
257
+ other: 0
258
+ }, t = {
259
+ total: 0,
260
+ byType: {}
261
+ }, r = {
262
+ total: 0,
263
+ totalSize: 0,
264
+ byFormat: {},
265
+ environment: 0,
266
+ system: 0
267
+ }, o = {
268
+ total: 0,
269
+ vertices: 0,
270
+ faces: 0
271
+ }, a = {
272
+ meshes: 0,
273
+ total: 0
274
+ }, d = /* @__PURE__ */ new Set(), l = /* @__PURE__ */ new Set(), g = /* @__PURE__ */ new Set(), i = /* @__PURE__ */ new Set(), w = (h) => {
275
+ if (!h || h.userData && (h.userData.rapier || h.userData.physics || h.userData.type === "RigidBody" || h.userData.__r3f || h.userData.__reactInternalInstance || h.userData.internal === !0 || h.userData.helper === !0))
276
+ return !0;
277
+ if (h.name) {
278
+ const m = h.name.toLowerCase();
279
+ if (m.includes("__rapier") || m.includes("__physics") || m.includes("__r3f") || m.includes("__internal") || m.startsWith("_helper") || m.startsWith("_internal") || m.includes("__internal") || m.startsWith("_") || m.includes("collider") || m.includes("rigidbody") || m.includes("helper") || m.includes("debug"))
280
+ return !0;
281
+ }
282
+ return !!(h.type === "RigidBody" || h.isRigidBody || h.type && h.type.includes("Helper"));
283
+ }, y = (h) => {
284
+ if (!(h instanceof oe || h.isMesh)) return !1;
285
+ const m = h;
286
+ return !(!m.geometry || !m.material || w(h));
287
+ }, u = (h) => !(!(h instanceof se || h.isLight) || w(h) || h.type && h.type.includes("Helper")), f = (h, m = 0, S = !1) => {
288
+ if (!h) return;
289
+ const z = w(h) || S;
290
+ if (h instanceof oe || h.isMesh) {
291
+ const p = h;
292
+ if (y(h) && !i.has(p)) {
293
+ if (i.add(p), e.meshes++, h.visible && a.meshes++, z || (e.total++, h.visible && a.total++), p.geometry && !g.has(p.geometry)) {
294
+ g.add(p.geometry), o.total++;
295
+ const T = p.geometry;
296
+ if (T.attributes && T.attributes.position) {
297
+ const P = T.attributes.position.count || 0;
298
+ o.vertices += P, T.index ? o.faces += Math.floor(T.index.count / 3) : o.faces += Math.floor(P / 3);
299
+ }
300
+ }
301
+ p.material && (Array.isArray(p.material) ? p.material : [p.material]).forEach((P) => {
302
+ if (P && !d.has(P)) {
303
+ d.add(P), t.total++;
304
+ const D = P.type || P.constructor.name || "Unknown";
305
+ t.byType[D] = (t.byType[D] || 0) + 1, [
306
+ "map",
307
+ "normalMap",
308
+ "roughnessMap",
309
+ "metalnessMap",
310
+ "aoMap",
311
+ "emissiveMap",
312
+ "bumpMap",
313
+ "displacementMap",
314
+ "alphaMap",
315
+ "envMap",
316
+ "lightMap",
317
+ "specularMap",
318
+ "clearcoatMap",
319
+ "clearcoatNormalMap",
320
+ "clearcoatRoughnessMap",
321
+ "sheenColorMap",
322
+ "sheenRoughnessMap",
323
+ "transmissionMap",
324
+ "thicknessMap",
325
+ "iridescenceMap",
326
+ "iridescenceThicknessMap"
327
+ ].forEach((b) => {
328
+ const R = P[b];
329
+ if (R && R instanceof ne && !l.has(R)) {
330
+ l.add(R), r.total++;
331
+ const $ = this.estimateTextureSize(R);
332
+ r.totalSize += $;
333
+ const G = R.format?.toString() || "unknown";
334
+ r.byFormat[G] = (r.byFormat[G] || 0) + 1, (b === "envMap" || R.name?.toLowerCase().includes("env") || R.name?.toLowerCase().includes("environment")) && r.environment++, (b === "lightMap" || R.name?.toLowerCase().includes("lightmap") || R.name?.toLowerCase().includes("system")) && r.system++;
335
+ }
336
+ }), Object.keys(P).forEach((b) => {
337
+ const R = P[b];
338
+ if (R && R instanceof ne && !l.has(R)) {
339
+ l.add(R), r.total++;
340
+ const $ = this.estimateTextureSize(R);
341
+ r.totalSize += $;
342
+ const G = R.format?.toString() || "unknown";
343
+ r.byFormat[G] = (r.byFormat[G] || 0) + 1, (b === "envMap" || R.name?.toLowerCase().includes("env") || R.name?.toLowerCase().includes("environment")) && r.environment++, (b === "lightMap" || R.name?.toLowerCase().includes("lightmap") || R.name?.toLowerCase().includes("system")) && r.system++;
344
+ }
345
+ });
346
+ }
347
+ });
348
+ }
349
+ } else h instanceof se || h.isLight ? u(h) && e.lights++ : h instanceof fe || h.isCamera ? !z && !h.type?.includes("Helper") && e.cameras++ : h.type === "Group" || h.isGroup ? z || e.groups++ : z || e.other++;
350
+ m < 20 && h.children && h.children.length > 0 && h.children.forEach((p) => {
351
+ p && f(p, m + 1, z);
352
+ });
353
+ };
354
+ this.scene.children.forEach((h) => {
355
+ h && f(h, 0, !1);
356
+ });
357
+ const M = e.meshes > 0 ? o.vertices / e.meshes : 0, C = e.meshes > 0 ? o.faces / e.meshes : 0;
358
+ return {
359
+ objects: e,
360
+ materials: t,
361
+ textures: r,
362
+ geometries: o,
363
+ visible: a,
364
+ complexity: {
365
+ averageVerticesPerMesh: M,
366
+ averageFacesPerMesh: C,
367
+ totalDrawCalls: e.meshes
368
+ // Simplified estimate
369
+ },
370
+ timestamp: performance.now()
371
+ };
372
+ }
373
+ estimateTextureSize(e) {
374
+ if (!e.image) return 0;
375
+ const t = e.image;
376
+ if (!t) return 0;
377
+ const r = t.width || 1, o = t.height || 1;
378
+ let a = 4;
379
+ try {
380
+ const d = Number(e.format);
381
+ isNaN(d) || (d === 1022 && (a = 3), d === 1021 && (a = 1), d === 1020 && (a = 1));
382
+ } catch {
383
+ }
384
+ return r * o * a;
385
+ }
386
+ reset() {
387
+ }
388
+ }
389
+ const de = new we();
390
+ class Re {
391
+ renderer = null;
392
+ lastStats = null;
393
+ history = [];
394
+ historySize = 60;
395
+ // Keep last 60 samples (1 minute at 1 sample/sec)
396
+ startTime = 0;
397
+ warmupPeriod = 1e4;
398
+ // 10 seconds warmup before leak detection
399
+ setRenderer(e) {
400
+ this.renderer = e, this.startTime === 0 && (this.startTime = performance.now());
401
+ }
402
+ getStats() {
403
+ const e = this.getJSHeapStats(), t = this.getGPUMemoryStats(), r = this.detectLeaks();
404
+ if (!e && !t)
405
+ return null;
406
+ const o = {
407
+ jsHeap: e || {
408
+ used: 0,
409
+ total: 0,
410
+ limit: 0,
411
+ percentage: 0
412
+ },
413
+ gpuMemory: t || {
414
+ textures: 0,
415
+ geometries: 0,
416
+ total: 0
417
+ },
418
+ leaks: r,
419
+ timestamp: performance.now()
420
+ };
421
+ return this.lastStats = o, o;
422
+ }
423
+ getJSHeapStats() {
424
+ if (typeof performance > "u" || !performance.memory)
425
+ return null;
426
+ const e = performance.memory, t = e.usedJSHeapSize, r = e.totalJSHeapSize, o = e.jsHeapSizeLimit, a = o > 0 ? t / o * 100 : 0;
427
+ return this.addToHistory(t), {
428
+ used: t,
429
+ total: r,
430
+ limit: o,
431
+ percentage: Math.min(100, Math.max(0, a))
432
+ };
433
+ }
434
+ getGPUMemoryStats() {
435
+ if (!this.renderer)
436
+ return null;
437
+ const e = this.renderer.info, t = e.memory, r = e.render;
438
+ let o = 0, a = 0;
439
+ if (t.textures && this.renderer)
440
+ try {
441
+ o = t.textures * 2 * 1024 * 1024;
442
+ } catch {
443
+ o = t.textures * 1024 * 1024;
444
+ }
445
+ if (t.geometries && this.renderer)
446
+ try {
447
+ a = (r.triangles || 0) * 100, a += t.geometries * 10 * 1024;
448
+ } catch {
449
+ a = t.geometries * 100 * 1024;
450
+ }
451
+ return {
452
+ textures: o,
453
+ geometries: a,
454
+ total: o + a
455
+ };
456
+ }
457
+ addToHistory(e) {
458
+ const t = performance.now();
459
+ this.history.push({ timestamp: t, used: e }), this.history.length > this.historySize && this.history.shift();
460
+ }
461
+ detectLeaks() {
462
+ if (performance.now() - this.startTime < this.warmupPeriod)
463
+ return {
464
+ detected: !1,
465
+ growthRate: 0,
466
+ trend: "stable"
467
+ };
468
+ if (this.history.length < 20)
469
+ return {
470
+ detected: !1,
471
+ growthRate: 0,
472
+ trend: "stable"
473
+ };
474
+ const t = this.history.slice(-10), r = this.history.slice(-30), o = t[0], a = t[t.length - 1], d = (a.timestamp - o.timestamp) / 1e3, l = a.used - o.used, g = d > 0 ? l / d : 0, i = r[0], w = r[r.length - 1], y = (w.timestamp - i.timestamp) / 1e3, u = w.used - i.used, f = y > 0 ? u / y : 0, M = (g + f) / 2, C = 33 * 1024, h = g > 0 && f > 0, m = M > C && h;
475
+ let S = "stable";
476
+ return Math.abs(M) < 2048 ? S = "stable" : M > 0 ? S = "increasing" : S = "decreasing", {
477
+ detected: m,
478
+ growthRate: M,
479
+ trend: S
480
+ };
481
+ }
482
+ getLastStats() {
483
+ return this.lastStats;
484
+ }
485
+ reset() {
486
+ this.lastStats = null, this.history = [], this.startTime = 0;
487
+ }
488
+ }
489
+ const Y = new Re();
490
+ class ze {
491
+ phases = /* @__PURE__ */ new Map();
492
+ timeline = [];
493
+ frameStartTime = 0;
494
+ lastFrameTime = 0;
495
+ currentInterval = 0;
496
+ lastBreakdown = null;
497
+ maxTimelineEntries = 100;
498
+ startFrame() {
499
+ const e = performance.now();
500
+ this.lastFrameTime > 0 && (this.currentInterval = e - this.lastFrameTime), this.lastFrameTime = e, this.frameStartTime = e, this.phases.clear(), this.timeline = [];
501
+ }
502
+ startPhase(e) {
503
+ const t = performance.now();
504
+ this.phases.set(e, { start: t });
505
+ }
506
+ endPhase(e) {
507
+ const t = this.phases.get(e);
508
+ if (!t)
509
+ return;
510
+ const r = performance.now();
511
+ t.end = r;
512
+ const o = r - t.start;
513
+ this.timeline.push({
514
+ name: e,
515
+ start: t.start,
516
+ end: r,
517
+ duration: o
518
+ });
519
+ }
520
+ endFrame() {
521
+ const t = performance.now() - this.frameStartTime, r = this.currentInterval > 0 ? this.currentInterval : t > 0 ? t : 16.66, o = {
522
+ react: this.getPhaseDuration("react"),
523
+ update: this.getPhaseDuration("update"),
524
+ physics: this.getPhaseDuration("physics"),
525
+ render: this.getPhaseDuration("render"),
526
+ postProcess: this.getPhaseDuration("postProcess"),
527
+ other: 0
528
+ }, a = Object.values(o).reduce((l, g) => l + g, 0);
529
+ o.other = Math.max(0, t - a);
530
+ const d = {
531
+ total: t,
532
+ interval: r,
533
+ phases: o,
534
+ timeline: [...this.timeline].slice(-this.maxTimelineEntries),
535
+ // Keep last N entries
536
+ timestamp: this.frameStartTime
537
+ };
538
+ return this.lastBreakdown = d, d;
539
+ }
540
+ getPhaseDuration(e) {
541
+ const t = this.phases.get(e);
542
+ return !t || t.end === void 0 ? 0 : t.end - t.start;
543
+ }
544
+ // Helper method to measure a function execution
545
+ measure(e, t) {
546
+ this.startPhase(e);
547
+ try {
548
+ return t();
549
+ } finally {
550
+ this.endPhase(e);
551
+ }
552
+ }
553
+ // Helper method to measure async function execution
554
+ async measureAsync(e, t) {
555
+ this.startPhase(e);
556
+ try {
557
+ return await t();
558
+ } finally {
559
+ this.endPhase(e);
560
+ }
561
+ }
562
+ getLastBreakdown() {
563
+ return this.lastBreakdown;
564
+ }
565
+ reset() {
566
+ this.phases.clear(), this.timeline = [], this.lastBreakdown = null;
567
+ }
568
+ }
569
+ const H = new ze();
570
+ class Ce {
571
+ enabled = !1;
572
+ reactPhaseStart = 0;
573
+ isReactRendering = !1;
574
+ isUpdating = !1;
575
+ isPhysicsRunning = !1;
576
+ isRendering = !1;
577
+ mutationObserver = null;
578
+ enable() {
579
+ this.enabled || (this.enabled = !0, this.setupReactInstrumentation(), this.setupThreeJSInstrumentation(), this.setupPhysicsInstrumentation());
580
+ }
581
+ disable() {
582
+ this.enabled && (this.enabled = !1, this.cleanup());
583
+ }
584
+ setupReactInstrumentation() {
585
+ if (typeof window > "u") return;
586
+ const e = document.getElementById("root") || document.body;
587
+ if (e && (this.mutationObserver = new MutationObserver(() => {
588
+ this.isReactRendering || this.startReactPhase();
589
+ }), this.mutationObserver.observe(e, {
590
+ childList: !0,
591
+ subtree: !0,
592
+ attributes: !0,
593
+ attributeOldValue: !1
594
+ })), performance.mark) {
595
+ const t = performance.mark;
596
+ performance.mark = ((r, o) => ((r.includes("react") || r.includes("React")) && (this.isReactRendering || this.startReactPhase()), t.call(performance, r, o)));
597
+ }
598
+ }
599
+ setupThreeJSInstrumentation() {
600
+ }
601
+ setupPhysicsInstrumentation() {
602
+ }
603
+ startFrame() {
604
+ this.enabled && H.startFrame();
605
+ }
606
+ startReactPhase() {
607
+ !this.enabled || this.isReactRendering || (this.isReactRendering = !0, this.reactPhaseStart = performance.now(), H.startPhase("react"));
608
+ }
609
+ endReactPhase() {
610
+ !this.enabled || !this.isReactRendering || (this.isReactRendering = !1, H.endPhase("react"));
611
+ }
612
+ // Called by ReactMonitor when a component renders
613
+ onReactRender(e) {
614
+ this.enabled && (this.isReactRendering || this.startReactPhase(), setTimeout(() => {
615
+ this.isReactRendering && performance.now() - this.reactPhaseStart > e && this.endReactPhase();
616
+ }, 0));
617
+ }
618
+ startUpdatePhase() {
619
+ !this.enabled || this.isUpdating || (this.isUpdating = !0, H.startPhase("update"));
620
+ }
621
+ endUpdatePhase() {
622
+ !this.enabled || !this.isUpdating || (this.isUpdating = !1, H.endPhase("update"));
623
+ }
624
+ startPhysicsPhase() {
625
+ !this.enabled || this.isPhysicsRunning || (this.isPhysicsRunning = !0, H.startPhase("physics"));
626
+ }
627
+ endPhysicsPhase() {
628
+ !this.enabled || !this.isPhysicsRunning || (this.isPhysicsRunning = !1, H.endPhase("physics"));
629
+ }
630
+ startRenderPhase() {
631
+ !this.enabled || this.isRendering || (this.isRendering = !0, H.startPhase("render"));
632
+ }
633
+ endRenderPhase() {
634
+ !this.enabled || !this.isRendering || (this.isRendering = !1, H.endPhase("render"), H.endFrame());
635
+ }
636
+ cleanup() {
637
+ this.isReactRendering = !1, this.isUpdating = !1, this.isPhysicsRunning = !1, this.isRendering = !1, this.mutationObserver && (this.mutationObserver.disconnect(), this.mutationObserver = null);
638
+ }
639
+ isActive() {
640
+ return this.enabled;
641
+ }
642
+ }
643
+ const _ = new Ce();
644
+ class Te {
645
+ isPaused = !1;
646
+ listeners = /* @__PURE__ */ new Set();
647
+ STORAGE_KEY = "r3f-profiler-paused";
648
+ constructor() {
649
+ this.loadPauseState();
650
+ }
651
+ loadPauseState() {
652
+ try {
653
+ const e = localStorage.getItem(this.STORAGE_KEY);
654
+ e !== null && (this.isPaused = e === "true");
655
+ } catch (e) {
656
+ console.warn("Failed to load pause state:", e);
657
+ }
658
+ }
659
+ savePauseState() {
660
+ try {
661
+ localStorage.setItem(this.STORAGE_KEY, String(this.isPaused));
662
+ } catch (e) {
663
+ console.warn("Failed to save pause state:", e);
664
+ }
665
+ }
666
+ pause() {
667
+ this.isPaused || (this.isPaused = !0, this.savePauseState(), this.notifyListeners());
668
+ }
669
+ resume() {
670
+ this.isPaused && (this.isPaused = !1, this.savePauseState(), this.notifyListeners());
671
+ }
672
+ toggle() {
673
+ this.isPaused ? this.resume() : this.pause();
674
+ }
675
+ getPaused() {
676
+ return this.isPaused;
677
+ }
678
+ subscribe(e) {
679
+ return this.listeners.add(e), () => {
680
+ this.listeners.delete(e);
681
+ };
682
+ }
683
+ notifyListeners() {
684
+ this.listeners.forEach((e) => {
685
+ try {
686
+ e(this.isPaused);
687
+ } catch (t) {
688
+ console.error("Error in monitor state listener:", t);
689
+ }
690
+ });
691
+ }
692
+ }
693
+ const k = new Te(), nt = () => {
694
+ const { gl: n, scene: e } = he();
695
+ return A(() => {
696
+ n && (O.setRenderer(n), Y.setRenderer(n));
697
+ }, [n]), A(() => {
698
+ e && de.setScene(e);
699
+ }, [e]), A(() => (_.enable(), () => {
700
+ _.disable();
701
+ }), []), le((t, r) => {
702
+ n && !k.getPaused() && (H.startFrame(), _.startUpdatePhase(), _.endUpdatePhase(), _.startRenderPhase(), O.startFrame(), requestAnimationFrame(() => {
703
+ if (!k.getPaused()) {
704
+ _.endRenderPhase();
705
+ const o = H.endFrame();
706
+ if (O.endFrame(), O.getStats(), Y.getStats(), o) {
707
+ const a = o.interval || o.total, d = Math.max(a, 1e-3), l = 1e3 / d, g = l > 500 && o.total < 16 ? 0 : l;
708
+ let i;
709
+ typeof performance < "u" && performance.memory && (i = performance.memory.usedJSHeapSize / (1024 * 1024)), E.isEnabled() && E.recordFrameStats(g, d, i);
710
+ }
711
+ }
712
+ }));
713
+ }), null;
714
+ }, Me = {
715
+ colors: {
716
+ background: "rgba(15, 15, 15, 0.95)",
717
+ surface: "rgba(26, 26, 26, 0.98)",
718
+ surfaceElevated: "rgba(35, 35, 35, 0.98)",
719
+ text: "#ffffff",
720
+ textSecondary: "rgba(255, 255, 255, 0.7)",
721
+ textTertiary: "rgba(255, 255, 255, 0.5)",
722
+ border: "rgba(255, 255, 255, 0.1)",
723
+ borderLight: "rgba(255, 255, 255, 0.05)",
724
+ primary: "#3b82f6",
725
+ primaryHover: "#2563eb",
726
+ success: "#10b981",
727
+ warning: "#f59e0b",
728
+ error: "#ef4444",
729
+ info: "#06b6d4",
730
+ accent: "#8b5cf6"
731
+ },
732
+ shadows: {
733
+ md: "0 4px 6px rgba(0, 0, 0, 0.4)",
734
+ xl: "0 20px 25px rgba(0, 0, 0, 0.6)"
735
+ },
736
+ borderRadius: {
737
+ sm: "4px",
738
+ md: "8px",
739
+ lg: "12px"
740
+ },
741
+ spacing: {
742
+ xs: "4px",
743
+ sm: "8px",
744
+ md: "16px",
745
+ lg: "24px"
746
+ },
747
+ typography: {
748
+ fontFamilyMono: '"SF Mono", "Monaco", "Inconsolata", "Roboto Mono", "Source Code Pro", monospace',
749
+ fontSize: {
750
+ xs: "10px",
751
+ sm: "12px",
752
+ md: "14px",
753
+ lg: "16px"
754
+ }
755
+ },
756
+ transitions: {
757
+ fast: "150ms ease",
758
+ normal: "250ms ease"
759
+ },
760
+ zIndex: {
761
+ base: 1e4
762
+ }
763
+ }, F = Me;
764
+ function ie(n, e) {
765
+ return n <= e.good ? F.colors.success : n <= e.warning ? F.colors.warning : F.colors.error;
766
+ }
767
+ function v(n, e = 2) {
768
+ return n.toFixed(e);
769
+ }
770
+ const x = ({
771
+ label: n,
772
+ value: e,
773
+ unit: t,
774
+ trend: r,
775
+ status: o,
776
+ color: a,
777
+ icon: d,
778
+ onClick: l,
779
+ className: g = ""
780
+ }) => {
781
+ const i = F;
782
+ let w = a;
783
+ !w && o && (w = o === "good" ? i.colors.success : o === "warning" ? i.colors.warning : i.colors.error);
784
+ const y = typeof e == "number" ? e.toLocaleString() : e, u = t ? ` ${t}` : "";
785
+ return /* @__PURE__ */ c(
786
+ "div",
787
+ {
788
+ onClick: l,
789
+ className: g,
790
+ style: {
791
+ backgroundColor: i.colors.surface,
792
+ border: `1px solid ${i.colors.border}`,
793
+ borderRadius: i.borderRadius.md,
794
+ padding: i.spacing.md,
795
+ cursor: l ? "pointer" : "default",
796
+ transition: i.transitions.fast,
797
+ position: "relative",
798
+ overflow: "hidden"
799
+ },
800
+ onMouseEnter: (f) => {
801
+ l && (f.currentTarget.style.backgroundColor = i.colors.surfaceElevated, f.currentTarget.style.transform = "translateY(-2px)", f.currentTarget.style.boxShadow = i.shadows.md);
802
+ },
803
+ onMouseLeave: (f) => {
804
+ l && (f.currentTarget.style.backgroundColor = i.colors.surface, f.currentTarget.style.transform = "translateY(0)", f.currentTarget.style.boxShadow = "none");
805
+ },
806
+ children: [
807
+ d && /* @__PURE__ */ s("div", { style: {
808
+ position: "absolute",
809
+ top: i.spacing.sm,
810
+ right: i.spacing.sm,
811
+ opacity: 0.3
812
+ }, children: d }),
813
+ /* @__PURE__ */ s("div", { style: {
814
+ fontSize: i.typography.fontSize.sm,
815
+ color: i.colors.textSecondary,
816
+ marginBottom: i.spacing.xs,
817
+ fontWeight: 500
818
+ }, children: n }),
819
+ /* @__PURE__ */ c("div", { style: {
820
+ display: "flex",
821
+ alignItems: "baseline",
822
+ gap: i.spacing.xs
823
+ }, children: [
824
+ /* @__PURE__ */ s("div", { style: {
825
+ fontSize: i.typography.fontSize.lg,
826
+ fontWeight: "bold",
827
+ color: w || i.colors.text,
828
+ fontFamily: i.typography.fontFamilyMono
829
+ }, children: y }),
830
+ t && /* @__PURE__ */ s("div", { style: {
831
+ fontSize: i.typography.fontSize.sm,
832
+ color: i.colors.textTertiary
833
+ }, children: u }),
834
+ r && /* @__PURE__ */ s("div", { style: {
835
+ fontSize: i.typography.fontSize.xs,
836
+ color: r === "up" ? i.colors.error : r === "down" ? i.colors.success : i.colors.textTertiary,
837
+ marginLeft: "auto"
838
+ }, children: r === "up" ? "↑" : r === "down" ? "↓" : "→" })
839
+ ] }),
840
+ w && /* @__PURE__ */ s("div", { style: {
841
+ position: "absolute",
842
+ bottom: 0,
843
+ left: 0,
844
+ right: 0,
845
+ height: "2px",
846
+ backgroundColor: w
847
+ } })
848
+ ]
849
+ }
850
+ );
851
+ }, Pe = ({ tabs: n, activeTab: e, onTabChange: t, className: r = "" }) => {
852
+ const o = F;
853
+ return /* @__PURE__ */ s("div", { className: r, style: { position: "relative" }, children: /* @__PURE__ */ s("div", { style: {
854
+ display: "flex",
855
+ gap: o.spacing.xs,
856
+ borderBottom: `1px solid ${o.colors.border}`,
857
+ paddingBottom: o.spacing.xs
858
+ }, children: n.map((a) => {
859
+ const d = a.id === e;
860
+ return /* @__PURE__ */ c(
861
+ "button",
862
+ {
863
+ onClick: () => t(a.id),
864
+ style: {
865
+ display: "flex",
866
+ alignItems: "center",
867
+ gap: o.spacing.xs,
868
+ padding: `${o.spacing.sm} ${o.spacing.md}`,
869
+ backgroundColor: "transparent",
870
+ border: "none",
871
+ color: d ? o.colors.primary : o.colors.textSecondary,
872
+ fontSize: o.typography.fontSize.sm,
873
+ fontWeight: d ? 600 : 400,
874
+ cursor: "pointer",
875
+ position: "relative",
876
+ transition: o.transitions.fast,
877
+ borderRadius: `${o.borderRadius.sm} ${o.borderRadius.sm} 0 0`
878
+ },
879
+ onMouseEnter: (l) => {
880
+ d || (l.currentTarget.style.color = o.colors.text, l.currentTarget.style.backgroundColor = o.colors.surfaceElevated);
881
+ },
882
+ onMouseLeave: (l) => {
883
+ d || (l.currentTarget.style.color = o.colors.textSecondary, l.currentTarget.style.backgroundColor = "transparent");
884
+ },
885
+ children: [
886
+ a.icon && /* @__PURE__ */ s("span", { style: { display: "flex", alignItems: "center" }, children: a.icon }),
887
+ /* @__PURE__ */ s("span", { children: a.label }),
888
+ a.badge !== void 0 && /* @__PURE__ */ s("span", { style: {
889
+ backgroundColor: d ? o.colors.primary : o.colors.surfaceElevated,
890
+ color: d ? o.colors.text : o.colors.textSecondary,
891
+ borderRadius: o.borderRadius.sm,
892
+ padding: `2px ${o.spacing.xs}`,
893
+ fontSize: o.typography.fontSize.xs,
894
+ fontWeight: 600,
895
+ minWidth: "18px",
896
+ textAlign: "center"
897
+ }, children: a.badge }),
898
+ d && /* @__PURE__ */ s("div", { style: {
899
+ position: "absolute",
900
+ bottom: -1,
901
+ left: 0,
902
+ right: 0,
903
+ height: "2px",
904
+ backgroundColor: o.colors.primary
905
+ } })
906
+ ]
907
+ },
908
+ a.id
909
+ );
910
+ }) }) });
911
+ }, V = ({ severity: n, count: e, children: t, onClick: r }) => {
912
+ const o = F, d = {
913
+ info: o.colors.info,
914
+ warning: o.colors.warning,
915
+ error: o.colors.error
916
+ }[n];
917
+ return /* @__PURE__ */ c(
918
+ "div",
919
+ {
920
+ onClick: r,
921
+ style: {
922
+ display: "inline-flex",
923
+ alignItems: "center",
924
+ gap: o.spacing.xs,
925
+ padding: `${o.spacing.xs} ${o.spacing.sm}`,
926
+ backgroundColor: `${d}20`,
927
+ color: d,
928
+ borderRadius: o.borderRadius.md,
929
+ fontSize: o.typography.fontSize.xs,
930
+ fontWeight: 600,
931
+ cursor: r ? "pointer" : "default",
932
+ border: `1px solid ${d}40`,
933
+ transition: o.transitions.fast
934
+ },
935
+ onMouseEnter: (l) => {
936
+ r && (l.currentTarget.style.backgroundColor = `${d}30`);
937
+ },
938
+ onMouseLeave: (l) => {
939
+ r && (l.currentTarget.style.backgroundColor = `${d}20`);
940
+ },
941
+ children: [
942
+ /* @__PURE__ */ s("div", { style: {
943
+ width: "8px",
944
+ height: "8px",
945
+ borderRadius: "50%",
946
+ backgroundColor: d
947
+ } }),
948
+ e !== void 0 && e > 0 && /* @__PURE__ */ s("span", { children: e }),
949
+ t
950
+ ]
951
+ }
952
+ );
953
+ };
954
+ function J() {
955
+ const [n, e] = B(null);
956
+ return A(() => {
957
+ const t = () => {
958
+ if (!k.getPaused()) {
959
+ const d = E.getData();
960
+ e(d);
961
+ }
962
+ }, r = E.subscribe((d) => {
963
+ k.getPaused() || e(d);
964
+ });
965
+ t();
966
+ const o = setInterval(() => {
967
+ E.isEnabled() && !k.getPaused() && t();
968
+ }, 100), a = k.subscribe((d) => {
969
+ d || t();
970
+ });
971
+ return () => {
972
+ r(), a(), clearInterval(o);
973
+ };
974
+ }, []), n;
975
+ }
976
+ const U = 120;
977
+ function j() {
978
+ const n = J(), [e, t] = B([]), r = I(0), o = I(null);
979
+ return A(() => {
980
+ if (!n || n.frames === 0) {
981
+ t([]), r.current = 0;
982
+ return;
983
+ }
984
+ const a = () => {
985
+ if (k.getPaused()) return;
986
+ const l = H.getLastBreakdown();
987
+ if (l && l.total > 0) {
988
+ t((g) => {
989
+ const i = g.length > 0 ? g[g.length - 1] : null;
990
+ if (i === null || Math.abs(l.total - i) > 0.1) {
991
+ const w = [...g, l.total];
992
+ return w.length > U ? w.slice(-U) : w;
993
+ }
994
+ return g;
995
+ });
996
+ return;
997
+ }
998
+ if (n && n.frames > 0) {
999
+ const g = n.totalTime / n.frames;
1000
+ if (n.frames > r.current) {
1001
+ const i = n.frames - r.current;
1002
+ r.current = n.frames, t((w) => {
1003
+ const y = [...w], u = Math.min(i, 10);
1004
+ for (let f = 0; f < u; f++)
1005
+ y.push(g);
1006
+ return y.length > U ? y.slice(-U) : y;
1007
+ });
1008
+ }
1009
+ }
1010
+ };
1011
+ o.current = window.setInterval(a, 16);
1012
+ const d = k.subscribe((l) => {
1013
+ !l && n && n.frames > 0 && a();
1014
+ });
1015
+ return () => {
1016
+ o.current !== null && clearInterval(o.current), d();
1017
+ };
1018
+ }, [n]), e;
1019
+ }
1020
+ function ue() {
1021
+ const [n, e] = B(null), t = I(null);
1022
+ return A(() => {
1023
+ const r = () => {
1024
+ if (!k.getPaused()) {
1025
+ const a = H.getLastBreakdown();
1026
+ a && e(a);
1027
+ }
1028
+ };
1029
+ r(), t.current = window.setInterval(r, 100);
1030
+ const o = k.subscribe((a) => {
1031
+ a || r();
1032
+ });
1033
+ return () => {
1034
+ t.current !== null && clearInterval(t.current), o();
1035
+ };
1036
+ }, []), n;
1037
+ }
1038
+ const ke = ({
1039
+ width: n = 600,
1040
+ height: e = 200,
1041
+ showGrid: t = !0,
1042
+ showLabels: r = !0,
1043
+ maxValue: o,
1044
+ minValue: a
1045
+ }) => {
1046
+ const d = j(), l = F, g = typeof n == "string" && n.includes("%"), i = g ? "100%" : typeof n == "number" ? n : 600, { normalizedData: w, chartMax: y, chartMin: u } = L(() => {
1047
+ if (d.length === 0)
1048
+ return {
1049
+ normalizedData: [],
1050
+ chartMax: 0,
1051
+ chartMin: 0
1052
+ };
1053
+ const p = o ?? Math.max(...d), T = a ?? Math.min(...d), P = p - T || 1;
1054
+ return {
1055
+ normalizedData: d.map((q) => {
1056
+ const b = (q - T) / P * e;
1057
+ return Math.max(0, Math.min(e, b));
1058
+ }),
1059
+ chartMax: p,
1060
+ chartMin: T
1061
+ };
1062
+ }, [d, o, a, e]);
1063
+ if (d.length === 0)
1064
+ return /* @__PURE__ */ s("div", { style: {
1065
+ width: i,
1066
+ height: e,
1067
+ display: "flex",
1068
+ alignItems: "center",
1069
+ justifyContent: "center",
1070
+ color: l.colors.textTertiary,
1071
+ fontSize: l.typography.fontSize.sm,
1072
+ border: `1px solid ${l.colors.border}`,
1073
+ borderRadius: l.borderRadius.md
1074
+ }, children: "No frame data available" });
1075
+ const f = g ? 600 : typeof i == "number" ? i : 600, M = f / (d.length - 1 || 1), C = w.map((p, T) => {
1076
+ const P = T * M;
1077
+ return `${T === 0 ? "M" : "L"} ${P} ${e - p}`;
1078
+ }).join(" "), h = `${C} L ${f} ${e} L 0 ${e} Z`, S = e - (16.67 - u) / (y - u || 1) * e;
1079
+ return /* @__PURE__ */ s("div", { style: { position: "relative", width: i }, children: /* @__PURE__ */ c(
1080
+ "svg",
1081
+ {
1082
+ width: g ? "100%" : i,
1083
+ height: e,
1084
+ style: { display: "block" },
1085
+ viewBox: g ? `0 0 600 ${e}` : void 0,
1086
+ preserveAspectRatio: g ? "none" : void 0,
1087
+ children: [
1088
+ t && /* @__PURE__ */ s("g", { opacity: 0.2, children: [0, 0.25, 0.5, 0.75, 1].map((p) => {
1089
+ const T = e * p;
1090
+ return /* @__PURE__ */ s(
1091
+ "line",
1092
+ {
1093
+ x1: 0,
1094
+ y1: T,
1095
+ x2: f,
1096
+ y2: T,
1097
+ stroke: l.colors.border,
1098
+ strokeWidth: 1
1099
+ },
1100
+ p
1101
+ );
1102
+ }) }),
1103
+ S >= 0 && S <= e && /* @__PURE__ */ s(
1104
+ "line",
1105
+ {
1106
+ x1: 0,
1107
+ y1: S,
1108
+ x2: f,
1109
+ y2: S,
1110
+ stroke: l.colors.success,
1111
+ strokeWidth: 2,
1112
+ strokeDasharray: "4 4",
1113
+ opacity: 0.5
1114
+ }
1115
+ ),
1116
+ /* @__PURE__ */ s(
1117
+ "path",
1118
+ {
1119
+ d: h,
1120
+ fill: l.colors.primary,
1121
+ fillOpacity: 0.2
1122
+ }
1123
+ ),
1124
+ /* @__PURE__ */ s(
1125
+ "path",
1126
+ {
1127
+ d: C,
1128
+ fill: "none",
1129
+ stroke: l.colors.primary,
1130
+ strokeWidth: 2,
1131
+ strokeLinecap: "round",
1132
+ strokeLinejoin: "round"
1133
+ }
1134
+ ),
1135
+ w.map((p, T) => {
1136
+ const D = d[T] > 16.67;
1137
+ return /* @__PURE__ */ s(
1138
+ "circle",
1139
+ {
1140
+ cx: T * M,
1141
+ cy: e - p,
1142
+ r: D ? 3 : 2,
1143
+ fill: D ? l.colors.error : l.colors.primary
1144
+ },
1145
+ T
1146
+ );
1147
+ }),
1148
+ r && /* @__PURE__ */ c("g", { children: [
1149
+ /* @__PURE__ */ c(
1150
+ "text",
1151
+ {
1152
+ x: f - 4,
1153
+ y: 12,
1154
+ fill: l.colors.textSecondary,
1155
+ fontSize: l.typography.fontSize.xs,
1156
+ textAnchor: "end",
1157
+ children: [
1158
+ v(y, 2),
1159
+ "ms"
1160
+ ]
1161
+ }
1162
+ ),
1163
+ /* @__PURE__ */ c(
1164
+ "text",
1165
+ {
1166
+ x: f - 4,
1167
+ y: e - 4,
1168
+ fill: l.colors.textSecondary,
1169
+ fontSize: l.typography.fontSize.xs,
1170
+ textAnchor: "end",
1171
+ children: [
1172
+ v(u, 2),
1173
+ "ms"
1174
+ ]
1175
+ }
1176
+ ),
1177
+ S >= 0 && S <= e && /* @__PURE__ */ s(
1178
+ "text",
1179
+ {
1180
+ x: 4,
1181
+ y: S - 4,
1182
+ fill: l.colors.success,
1183
+ fontSize: l.typography.fontSize.xs,
1184
+ fontWeight: 600,
1185
+ children: "60 FPS"
1186
+ }
1187
+ )
1188
+ ] })
1189
+ ]
1190
+ }
1191
+ ) });
1192
+ }, $e = ({
1193
+ width: n = 800,
1194
+ height: e = 300,
1195
+ timeWindow: t = 10
1196
+ // 10 seconds
1197
+ }) => {
1198
+ const r = j(), o = F, a = typeof n == "string" && n.includes("%"), d = a ? "100%" : typeof n == "number" ? n : 800, l = L(() => {
1199
+ const S = performance.now(), z = r.slice(-Math.floor(t * 60));
1200
+ return z.map((T, P) => ({
1201
+ timestamp: S - (z.length - P) * 16.666666666666668,
1202
+ frameTime: T,
1203
+ fps: T > 0 ? 1e3 / T : 0
1204
+ }));
1205
+ }, [r, t]);
1206
+ if (l.length === 0)
1207
+ return /* @__PURE__ */ s("div", { style: {
1208
+ width: d,
1209
+ height: e,
1210
+ display: "flex",
1211
+ alignItems: "center",
1212
+ justifyContent: "center",
1213
+ color: o.colors.textTertiary,
1214
+ fontSize: o.typography.fontSize.sm,
1215
+ border: `1px solid ${o.colors.border}`,
1216
+ borderRadius: o.borderRadius.md,
1217
+ backgroundColor: o.colors.surface
1218
+ }, children: "No timeline data available" });
1219
+ const g = Math.max(...l.map((S) => S.frameTime), 50), i = Math.min(...l.map((S) => S.frameTime), 0), w = Math.max(...l.map((S) => S.fps), 60), y = Math.min(...l.map((S) => S.fps), 0), u = e / 2, f = a ? 800 : typeof d == "number" ? d : 800, M = f / (l.length - 1 || 1), C = l.map((S, z) => {
1220
+ const p = u - (S.frameTime - i) / (g - i || 1) * u, T = z * M;
1221
+ return `${z === 0 ? "M" : "L"} ${T} ${p}`;
1222
+ }).join(" "), h = l.map((S, z) => {
1223
+ const p = u - (S.fps - y) / (w - y || 1) * u, T = z * M;
1224
+ return `${z === 0 ? "M" : "L"} ${T} ${p + u}`;
1225
+ }).join(" "), m = a ? "100%" : d;
1226
+ return /* @__PURE__ */ c("div", { style: {
1227
+ width: d,
1228
+ height: e,
1229
+ backgroundColor: "transparent",
1230
+ borderRadius: o.borderRadius.md
1231
+ }, children: [
1232
+ /* @__PURE__ */ c("div", { style: {
1233
+ fontSize: o.typography.fontSize.sm,
1234
+ fontWeight: 600,
1235
+ color: o.colors.text,
1236
+ marginBottom: o.spacing.sm
1237
+ }, children: [
1238
+ "Timeline (",
1239
+ t,
1240
+ "s window)"
1241
+ ] }),
1242
+ /* @__PURE__ */ s("div", { style: {
1243
+ width: "100%",
1244
+ height: e,
1245
+ position: "relative",
1246
+ overflow: "hidden"
1247
+ }, children: /* @__PURE__ */ c("svg", { width: m, height: e, style: { display: "block" }, viewBox: a ? `0 0 800 ${e}` : void 0, preserveAspectRatio: a ? "none" : void 0, children: [
1248
+ /* @__PURE__ */ s("g", { opacity: 0.1, children: [0, 0.25, 0.5, 0.75, 1].map((S) => {
1249
+ const z = e * S;
1250
+ return /* @__PURE__ */ s(
1251
+ "line",
1252
+ {
1253
+ x1: 0,
1254
+ y1: z,
1255
+ x2: f,
1256
+ y2: z,
1257
+ stroke: o.colors.border,
1258
+ strokeWidth: 1
1259
+ },
1260
+ S
1261
+ );
1262
+ }) }),
1263
+ /* @__PURE__ */ s(
1264
+ "line",
1265
+ {
1266
+ x1: 0,
1267
+ y1: u,
1268
+ x2: f,
1269
+ y2: u,
1270
+ stroke: o.colors.border,
1271
+ strokeWidth: 2
1272
+ }
1273
+ ),
1274
+ /* @__PURE__ */ c("g", { children: [
1275
+ /* @__PURE__ */ s(
1276
+ "text",
1277
+ {
1278
+ x: 4,
1279
+ y: 12,
1280
+ fill: o.colors.textSecondary,
1281
+ fontSize: o.typography.fontSize.xs,
1282
+ fontWeight: 600,
1283
+ children: "Frame Time (ms)"
1284
+ }
1285
+ ),
1286
+ /* @__PURE__ */ s(
1287
+ "path",
1288
+ {
1289
+ d: C,
1290
+ fill: "none",
1291
+ stroke: o.colors.error,
1292
+ strokeWidth: 2,
1293
+ strokeLinecap: "round",
1294
+ strokeLinejoin: "round"
1295
+ }
1296
+ ),
1297
+ /* @__PURE__ */ s(
1298
+ "line",
1299
+ {
1300
+ x1: 0,
1301
+ y1: u - (16.67 - i) / (g - i || 1) * u,
1302
+ x2: f,
1303
+ y2: u - (16.67 - i) / (g - i || 1) * u,
1304
+ stroke: o.colors.success,
1305
+ strokeWidth: 1,
1306
+ strokeDasharray: "2 2",
1307
+ opacity: 0.5
1308
+ }
1309
+ )
1310
+ ] }),
1311
+ /* @__PURE__ */ c("g", { children: [
1312
+ /* @__PURE__ */ s(
1313
+ "text",
1314
+ {
1315
+ x: 4,
1316
+ y: u + 12,
1317
+ fill: o.colors.textSecondary,
1318
+ fontSize: o.typography.fontSize.xs,
1319
+ fontWeight: 600,
1320
+ children: "FPS"
1321
+ }
1322
+ ),
1323
+ /* @__PURE__ */ s(
1324
+ "path",
1325
+ {
1326
+ d: h,
1327
+ fill: "none",
1328
+ stroke: o.colors.success,
1329
+ strokeWidth: 2,
1330
+ strokeLinecap: "round",
1331
+ strokeLinejoin: "round"
1332
+ }
1333
+ ),
1334
+ /* @__PURE__ */ s(
1335
+ "line",
1336
+ {
1337
+ x1: 0,
1338
+ y1: u + u - (60 - y) / (w - y || 1) * u,
1339
+ x2: f,
1340
+ y2: u + u - (60 - y) / (w - y || 1) * u,
1341
+ stroke: o.colors.success,
1342
+ strokeWidth: 1,
1343
+ strokeDasharray: "2 2",
1344
+ opacity: 0.5
1345
+ }
1346
+ )
1347
+ ] }),
1348
+ /* @__PURE__ */ c("g", { children: [
1349
+ /* @__PURE__ */ c(
1350
+ "text",
1351
+ {
1352
+ x: f - 4,
1353
+ y: 12,
1354
+ fill: o.colors.textTertiary,
1355
+ fontSize: o.typography.fontSize.xs,
1356
+ textAnchor: "end",
1357
+ children: [
1358
+ v(g, 1),
1359
+ "ms"
1360
+ ]
1361
+ }
1362
+ ),
1363
+ /* @__PURE__ */ c(
1364
+ "text",
1365
+ {
1366
+ x: f - 4,
1367
+ y: u - 4,
1368
+ fill: o.colors.textTertiary,
1369
+ fontSize: o.typography.fontSize.xs,
1370
+ textAnchor: "end",
1371
+ children: [
1372
+ v(i, 1),
1373
+ "ms"
1374
+ ]
1375
+ }
1376
+ ),
1377
+ /* @__PURE__ */ c(
1378
+ "text",
1379
+ {
1380
+ x: f - 4,
1381
+ y: u + 12,
1382
+ fill: o.colors.textTertiary,
1383
+ fontSize: o.typography.fontSize.xs,
1384
+ textAnchor: "end",
1385
+ children: [
1386
+ v(w, 0),
1387
+ " FPS"
1388
+ ]
1389
+ }
1390
+ ),
1391
+ /* @__PURE__ */ c(
1392
+ "text",
1393
+ {
1394
+ x: f - 4,
1395
+ y: e - 4,
1396
+ fill: o.colors.textTertiary,
1397
+ fontSize: o.typography.fontSize.xs,
1398
+ textAnchor: "end",
1399
+ children: [
1400
+ v(y, 0),
1401
+ " FPS"
1402
+ ]
1403
+ }
1404
+ )
1405
+ ] })
1406
+ ] }) })
1407
+ ] });
1408
+ };
1409
+ function Be() {
1410
+ const [n, e] = B([]);
1411
+ return A(() => {
1412
+ const t = () => {
1413
+ if (!k.getPaused()) {
1414
+ const a = Y.getStats();
1415
+ a && e((d) => [...d, { ...a, time: Date.now() }].slice(-120));
1416
+ }
1417
+ };
1418
+ t();
1419
+ const r = setInterval(t, 1e3), o = k.subscribe((a) => {
1420
+ a || t();
1421
+ });
1422
+ return () => {
1423
+ clearInterval(r), o();
1424
+ };
1425
+ }, []), n;
1426
+ }
1427
+ const Fe = ({
1428
+ width: n = "100%",
1429
+ height: e = 200,
1430
+ showGrid: t = !0,
1431
+ showLabels: r = !0,
1432
+ timeWindow: o = 60,
1433
+ // 60 seconds default
1434
+ metric: a = "both"
1435
+ }) => {
1436
+ const d = Be(), l = F, g = L(() => {
1437
+ const h = Date.now() - o * 1e3, m = d.filter((D) => D.time >= h);
1438
+ if (m.length === 0)
1439
+ return {
1440
+ jsHeapData: [],
1441
+ gpuMemoryData: [],
1442
+ maxValue: 0,
1443
+ minValue: 0
1444
+ };
1445
+ const S = m.map((D) => D.jsHeap.used), z = m.map((D) => D.gpuMemory.total), p = [...S, ...z].filter((D) => D > 0), T = p.length > 0 ? Math.max(...p) : 0, P = p.length > 0 ? Math.min(...p) : 0;
1446
+ return {
1447
+ jsHeapData: S,
1448
+ gpuMemoryData: z,
1449
+ maxValue: T || 1,
1450
+ minValue: P
1451
+ };
1452
+ }, [d, o]);
1453
+ if (g.jsHeapData.length === 0 && g.gpuMemoryData.length === 0)
1454
+ return /* @__PURE__ */ s("div", { style: {
1455
+ width: n,
1456
+ height: e,
1457
+ display: "flex",
1458
+ alignItems: "center",
1459
+ justifyContent: "center",
1460
+ color: l.colors.textTertiary,
1461
+ fontSize: l.typography.fontSize.sm,
1462
+ border: `1px solid ${l.colors.border}`,
1463
+ borderRadius: l.borderRadius.md,
1464
+ backgroundColor: l.colors.surface
1465
+ }, children: "No memory data available" });
1466
+ const i = 800, w = i / (Math.max(g.jsHeapData.length, g.gpuMemoryData.length) - 1 || 1), y = g.maxValue - g.minValue || 1, u = g.jsHeapData.map((C, h) => {
1467
+ const m = e - (C - g.minValue) / y * e, S = h * w;
1468
+ return `${h === 0 ? "M" : "L"} ${S} ${m}`;
1469
+ }).join(" "), f = g.gpuMemoryData.map((C, h) => {
1470
+ const m = e - (C - g.minValue) / y * e, S = h * w;
1471
+ return `${h === 0 ? "M" : "L"} ${S} ${m}`;
1472
+ }).join(" "), M = (C) => C < 1024 ? `${v(C, 0)} B` : C < 1024 * 1024 ? `${v(C / 1024, 1)} KB` : C < 1024 * 1024 * 1024 ? `${v(C / (1024 * 1024), 1)} MB` : `${v(C / (1024 * 1024 * 1024), 2)} GB`;
1473
+ return /* @__PURE__ */ s("div", { style: { position: "relative", width: n, height: e }, children: /* @__PURE__ */ c("svg", { width: "100%", height: e, viewBox: `0 0 ${i} ${e}`, preserveAspectRatio: "none", style: { display: "block" }, children: [
1474
+ t && /* @__PURE__ */ s("g", { opacity: 0.2, children: [0, 0.25, 0.5, 0.75, 1].map((C) => {
1475
+ const h = e * C;
1476
+ return /* @__PURE__ */ s(
1477
+ "line",
1478
+ {
1479
+ x1: 0,
1480
+ y1: h,
1481
+ x2: i,
1482
+ y2: h,
1483
+ stroke: l.colors.border,
1484
+ strokeWidth: 1
1485
+ },
1486
+ C
1487
+ );
1488
+ }) }),
1489
+ a === "jsHeap" || a === "both" ? /* @__PURE__ */ c(N, { children: [
1490
+ /* @__PURE__ */ s(
1491
+ "path",
1492
+ {
1493
+ d: `${u} L ${i} ${e} L 0 ${e} Z`,
1494
+ fill: l.colors.primary,
1495
+ fillOpacity: 0.1
1496
+ }
1497
+ ),
1498
+ /* @__PURE__ */ s(
1499
+ "path",
1500
+ {
1501
+ d: u,
1502
+ fill: "none",
1503
+ stroke: l.colors.primary,
1504
+ strokeWidth: 2,
1505
+ strokeLinecap: "round",
1506
+ strokeLinejoin: "round"
1507
+ }
1508
+ )
1509
+ ] }) : null,
1510
+ a === "gpuMemory" || a === "both" ? /* @__PURE__ */ c(N, { children: [
1511
+ /* @__PURE__ */ s(
1512
+ "path",
1513
+ {
1514
+ d: `${f} L ${i} ${e} L 0 ${e} Z`,
1515
+ fill: l.colors.accent,
1516
+ fillOpacity: 0.1
1517
+ }
1518
+ ),
1519
+ /* @__PURE__ */ s(
1520
+ "path",
1521
+ {
1522
+ d: f,
1523
+ fill: "none",
1524
+ stroke: l.colors.accent,
1525
+ strokeWidth: 2,
1526
+ strokeLinecap: "round",
1527
+ strokeLinejoin: "round"
1528
+ }
1529
+ )
1530
+ ] }) : null,
1531
+ r && /* @__PURE__ */ c("g", { children: [
1532
+ /* @__PURE__ */ s(
1533
+ "text",
1534
+ {
1535
+ x: i - 4,
1536
+ y: 12,
1537
+ fill: l.colors.textSecondary,
1538
+ fontSize: l.typography.fontSize.xs,
1539
+ textAnchor: "end",
1540
+ children: M(g.maxValue)
1541
+ }
1542
+ ),
1543
+ /* @__PURE__ */ s(
1544
+ "text",
1545
+ {
1546
+ x: i - 4,
1547
+ y: e - 4,
1548
+ fill: l.colors.textSecondary,
1549
+ fontSize: l.typography.fontSize.xs,
1550
+ textAnchor: "end",
1551
+ children: M(g.minValue)
1552
+ }
1553
+ ),
1554
+ a === "both" && /* @__PURE__ */ c(N, { children: [
1555
+ /* @__PURE__ */ s(
1556
+ "text",
1557
+ {
1558
+ x: 4,
1559
+ y: 12,
1560
+ fill: l.colors.primary,
1561
+ fontSize: l.typography.fontSize.xs,
1562
+ children: "JS Heap"
1563
+ }
1564
+ ),
1565
+ /* @__PURE__ */ s(
1566
+ "text",
1567
+ {
1568
+ x: 4,
1569
+ y: e - 4,
1570
+ fill: l.colors.accent,
1571
+ fontSize: l.typography.fontSize.xs,
1572
+ children: "GPU Memory"
1573
+ }
1574
+ )
1575
+ ] })
1576
+ ] })
1577
+ ] }) });
1578
+ }, De = () => {
1579
+ const n = J(), e = j(), t = ue(), r = F, o = L(() => !n || !n.entries ? [] : [...n.entries].sort((y, u) => u.total - y.total), [n]), a = L(() => t ? t.interval || t.total : !n || n.totalTime || n.frames === 0 ? 0 : n.totalTime / n.frames, [t, n]), d = L(() => t ? t.total : !n || n.frames === 0 ? 0 : n.totalTime / n.frames, [t, n]), l = L(() => a > 0 ? 1e3 / a : 0, [a]), g = L(() => d <= 16.67 ? "good" : d <= 33.33 ? "warning" : "error", [d]), i = L(() => e.length > 0 ? e : d > 0 ? [d] : [], [e, d]), w = L(() => i.length === 0 ? 33 : Math.max(...i, 20), [i]);
1580
+ return !n || n.entries.length === 0 ? /* @__PURE__ */ s("div", { style: {
1581
+ padding: r.spacing.lg,
1582
+ textAlign: "center",
1583
+ color: r.colors.textSecondary,
1584
+ fontSize: r.typography.fontSize.sm
1585
+ }, children: "Aucune donnée profilée pour le moment." }) : /* @__PURE__ */ c("div", { style: { padding: r.spacing.md }, children: [
1586
+ /* @__PURE__ */ c("div", { style: {
1587
+ display: "grid",
1588
+ gridTemplateColumns: "repeat(auto-fit, minmax(150px, 1fr))",
1589
+ gap: r.spacing.md,
1590
+ marginBottom: r.spacing.lg
1591
+ }, children: [
1592
+ /* @__PURE__ */ s(
1593
+ x,
1594
+ {
1595
+ label: "FPS",
1596
+ value: v(l, 1),
1597
+ status: l >= 60 ? "good" : l >= 30 ? "warning" : "error"
1598
+ }
1599
+ ),
1600
+ /* @__PURE__ */ s(
1601
+ x,
1602
+ {
1603
+ label: "Frame Time",
1604
+ value: v(d, 2),
1605
+ unit: "ms",
1606
+ status: g
1607
+ }
1608
+ ),
1609
+ /* @__PURE__ */ s(
1610
+ x,
1611
+ {
1612
+ label: "Total Time",
1613
+ value: v(n.totalTime, 2),
1614
+ unit: "ms"
1615
+ }
1616
+ ),
1617
+ /* @__PURE__ */ s(
1618
+ x,
1619
+ {
1620
+ label: "Frames",
1621
+ value: n.frames
1622
+ }
1623
+ )
1624
+ ] }),
1625
+ /* @__PURE__ */ c("div", { style: {
1626
+ backgroundColor: r.colors.surface,
1627
+ borderRadius: r.borderRadius.md,
1628
+ padding: r.spacing.md,
1629
+ marginBottom: r.spacing.lg,
1630
+ border: `1px solid ${r.colors.border}`,
1631
+ overflow: "hidden"
1632
+ }, children: [
1633
+ /* @__PURE__ */ c("div", { style: {
1634
+ display: "flex",
1635
+ justifyContent: "space-between",
1636
+ alignItems: "center",
1637
+ marginBottom: r.spacing.sm
1638
+ }, children: [
1639
+ /* @__PURE__ */ s("div", { style: {
1640
+ fontSize: r.typography.fontSize.sm,
1641
+ fontWeight: 600,
1642
+ color: r.colors.text
1643
+ }, children: "Frame Time History" }),
1644
+ /* @__PURE__ */ c("div", { style: {
1645
+ fontSize: r.typography.fontSize.xs,
1646
+ color: r.colors.textSecondary,
1647
+ fontFamily: r.typography.fontFamilyMono
1648
+ }, children: [
1649
+ i.length,
1650
+ " frames"
1651
+ ] })
1652
+ ] }),
1653
+ /* @__PURE__ */ s(
1654
+ ke,
1655
+ {
1656
+ width: "100%",
1657
+ height: 100,
1658
+ showGrid: !0,
1659
+ showLabels: !0,
1660
+ maxValue: w
1661
+ }
1662
+ ),
1663
+ /* @__PURE__ */ c("div", { style: {
1664
+ display: "flex",
1665
+ justifyContent: "space-between",
1666
+ marginTop: r.spacing.xs,
1667
+ fontSize: r.typography.fontSize.xs,
1668
+ color: r.colors.textTertiary
1669
+ }, children: [
1670
+ /* @__PURE__ */ s("div", { children: "Target: <16.67ms (60 FPS)" }),
1671
+ /* @__PURE__ */ c("div", { style: {
1672
+ color: ie(d, { good: 16.67, warning: 33.33 })
1673
+ }, children: [
1674
+ "Current: ",
1675
+ v(d, 2),
1676
+ "ms (work)"
1677
+ ] })
1678
+ ] })
1679
+ ] }),
1680
+ /* @__PURE__ */ s("div", { style: {
1681
+ backgroundColor: r.colors.surface,
1682
+ borderRadius: r.borderRadius.md,
1683
+ padding: r.spacing.md,
1684
+ marginBottom: r.spacing.lg,
1685
+ border: `1px solid ${r.colors.border}`,
1686
+ overflow: "hidden"
1687
+ }, children: /* @__PURE__ */ s($e, { width: "100%", height: 200, timeWindow: 10 }) }),
1688
+ /* @__PURE__ */ s("div", { style: {
1689
+ backgroundColor: r.colors.surface,
1690
+ borderRadius: r.borderRadius.md,
1691
+ border: `1px solid ${r.colors.border}`,
1692
+ overflow: "hidden"
1693
+ }, children: /* @__PURE__ */ c("table", { style: {
1694
+ width: "100%",
1695
+ borderCollapse: "collapse"
1696
+ }, children: [
1697
+ /* @__PURE__ */ s("thead", { children: /* @__PURE__ */ c("tr", { style: {
1698
+ backgroundColor: r.colors.surfaceElevated,
1699
+ borderBottom: `1px solid ${r.colors.border}`
1700
+ }, children: [
1701
+ /* @__PURE__ */ s("th", { style: {
1702
+ textAlign: "left",
1703
+ padding: r.spacing.md,
1704
+ color: r.colors.textSecondary,
1705
+ fontSize: r.typography.fontSize.sm,
1706
+ fontWeight: 600
1707
+ }, children: "Hook" }),
1708
+ /* @__PURE__ */ s("th", { style: {
1709
+ textAlign: "right",
1710
+ padding: r.spacing.md,
1711
+ color: r.colors.textSecondary,
1712
+ fontSize: r.typography.fontSize.sm,
1713
+ fontWeight: 600
1714
+ }, children: "Total (ms)" }),
1715
+ /* @__PURE__ */ s("th", { style: {
1716
+ textAlign: "right",
1717
+ padding: r.spacing.md,
1718
+ color: r.colors.textSecondary,
1719
+ fontSize: r.typography.fontSize.sm,
1720
+ fontWeight: 600
1721
+ }, children: "Avg (ms)" }),
1722
+ /* @__PURE__ */ s("th", { style: {
1723
+ textAlign: "right",
1724
+ padding: r.spacing.md,
1725
+ color: r.colors.textSecondary,
1726
+ fontSize: r.typography.fontSize.sm,
1727
+ fontWeight: 600
1728
+ }, children: "Max (ms)" }),
1729
+ /* @__PURE__ */ s("th", { style: {
1730
+ textAlign: "right",
1731
+ padding: r.spacing.md,
1732
+ color: r.colors.textSecondary,
1733
+ fontSize: r.typography.fontSize.sm,
1734
+ fontWeight: 600
1735
+ }, children: "%" })
1736
+ ] }) }),
1737
+ /* @__PURE__ */ s("tbody", { children: o.map((y, u) => {
1738
+ const f = ie(y.avg, { good: 5, warning: 10 });
1739
+ return /* @__PURE__ */ c(
1740
+ "tr",
1741
+ {
1742
+ style: {
1743
+ borderBottom: u < o.length - 1 ? `1px solid ${r.colors.borderLight}` : "none",
1744
+ transition: r.transitions.fast
1745
+ },
1746
+ onMouseEnter: (M) => {
1747
+ M.currentTarget.style.backgroundColor = r.colors.surfaceElevated;
1748
+ },
1749
+ onMouseLeave: (M) => {
1750
+ M.currentTarget.style.backgroundColor = "transparent";
1751
+ },
1752
+ children: [
1753
+ /* @__PURE__ */ s("td", { style: {
1754
+ padding: r.spacing.md,
1755
+ color: r.colors.text,
1756
+ fontFamily: r.typography.fontFamilyMono,
1757
+ fontSize: r.typography.fontSize.sm
1758
+ }, children: y.name }),
1759
+ /* @__PURE__ */ s("td", { style: {
1760
+ textAlign: "right",
1761
+ padding: r.spacing.md,
1762
+ color: r.colors.text,
1763
+ fontFamily: r.typography.fontFamilyMono,
1764
+ fontSize: r.typography.fontSize.sm
1765
+ }, children: v(y.total, 2) }),
1766
+ /* @__PURE__ */ s("td", { style: {
1767
+ textAlign: "right",
1768
+ padding: r.spacing.md,
1769
+ color: f,
1770
+ fontFamily: r.typography.fontFamilyMono,
1771
+ fontSize: r.typography.fontSize.sm,
1772
+ fontWeight: 600
1773
+ }, children: v(y.avg, 3) }),
1774
+ /* @__PURE__ */ s("td", { style: {
1775
+ textAlign: "right",
1776
+ padding: r.spacing.md,
1777
+ color: r.colors.text,
1778
+ fontFamily: r.typography.fontFamilyMono,
1779
+ fontSize: r.typography.fontSize.sm
1780
+ }, children: v(y.max, 3) }),
1781
+ /* @__PURE__ */ c("td", { style: {
1782
+ textAlign: "right",
1783
+ padding: r.spacing.md,
1784
+ color: r.colors.textSecondary,
1785
+ fontFamily: r.typography.fontFamilyMono,
1786
+ fontSize: r.typography.fontSize.sm
1787
+ }, children: [
1788
+ v(y.percentage, 1),
1789
+ "%"
1790
+ ] })
1791
+ ]
1792
+ },
1793
+ y.name
1794
+ );
1795
+ }) })
1796
+ ] }) })
1797
+ ] });
1798
+ };
1799
+ function Q() {
1800
+ const [n, e] = B(null), t = I(null);
1801
+ return A(() => {
1802
+ const r = () => {
1803
+ if (!k.getPaused()) {
1804
+ const a = O.getStats();
1805
+ a && e(a);
1806
+ }
1807
+ };
1808
+ r(), t.current = window.setInterval(r, 100);
1809
+ const o = k.subscribe((a) => {
1810
+ a || r();
1811
+ });
1812
+ return () => {
1813
+ t.current !== null && clearInterval(t.current), o();
1814
+ };
1815
+ }, []), n;
1816
+ }
1817
+ const Le = () => {
1818
+ const n = Q(), e = F, t = L(() => n ? n.drawCalls <= 100 ? "good" : n.drawCalls <= 500 ? "warning" : "error" : "neutral", [n]), r = L(() => n ? n.triangles <= 1e5 ? "good" : n.triangles <= 5e5 ? "warning" : "error" : "neutral", [n]);
1819
+ if (!n)
1820
+ return /* @__PURE__ */ s("div", { style: {
1821
+ padding: e.spacing.lg,
1822
+ textAlign: "center",
1823
+ color: e.colors.textSecondary,
1824
+ fontSize: e.typography.fontSize.sm
1825
+ }, children: "Aucune donnée GPU disponible. Assurez-vous que le composant est à l'intérieur d'un Canvas R3F." });
1826
+ const o = (a) => a === 0 ? "0 B" : a < 1024 ? `${v(a, 0)} B` : a < 1024 * 1024 ? `${v(a / 1024, 2)} KB` : `${v(a / (1024 * 1024), 2)} MB`;
1827
+ return /* @__PURE__ */ c("div", { style: { padding: e.spacing.md }, children: [
1828
+ /* @__PURE__ */ c("div", { style: {
1829
+ display: "grid",
1830
+ gridTemplateColumns: "repeat(auto-fit, minmax(150px, 1fr))",
1831
+ gap: e.spacing.md,
1832
+ marginBottom: e.spacing.lg
1833
+ }, children: [
1834
+ /* @__PURE__ */ s(
1835
+ x,
1836
+ {
1837
+ label: "Draw Calls",
1838
+ value: n.drawCalls.toLocaleString(),
1839
+ status: t
1840
+ }
1841
+ ),
1842
+ /* @__PURE__ */ s(
1843
+ x,
1844
+ {
1845
+ label: "Triangles",
1846
+ value: n.triangles.toLocaleString(),
1847
+ status: r
1848
+ }
1849
+ ),
1850
+ /* @__PURE__ */ s(
1851
+ x,
1852
+ {
1853
+ label: "Points",
1854
+ value: n.points.toLocaleString()
1855
+ }
1856
+ ),
1857
+ /* @__PURE__ */ s(
1858
+ x,
1859
+ {
1860
+ label: "Lines",
1861
+ value: n.lines.toLocaleString()
1862
+ }
1863
+ )
1864
+ ] }),
1865
+ /* @__PURE__ */ c("div", { style: {
1866
+ backgroundColor: e.colors.surface,
1867
+ borderRadius: e.borderRadius.md,
1868
+ padding: e.spacing.md,
1869
+ marginBottom: e.spacing.lg,
1870
+ border: `1px solid ${e.colors.border}`
1871
+ }, children: [
1872
+ /* @__PURE__ */ s("div", { style: {
1873
+ fontSize: e.typography.fontSize.md,
1874
+ fontWeight: 600,
1875
+ color: e.colors.text,
1876
+ marginBottom: e.spacing.md
1877
+ }, children: "GPU Memory" }),
1878
+ /* @__PURE__ */ c("div", { style: {
1879
+ display: "grid",
1880
+ gridTemplateColumns: "repeat(auto-fit, minmax(120px, 1fr))",
1881
+ gap: e.spacing.md
1882
+ }, children: [
1883
+ /* @__PURE__ */ s(
1884
+ x,
1885
+ {
1886
+ label: "Textures",
1887
+ value: o(n.memory.textures)
1888
+ }
1889
+ ),
1890
+ /* @__PURE__ */ s(
1891
+ x,
1892
+ {
1893
+ label: "Geometries",
1894
+ value: o(n.memory.geometries)
1895
+ }
1896
+ ),
1897
+ /* @__PURE__ */ s(
1898
+ x,
1899
+ {
1900
+ label: "Programs",
1901
+ value: o(n.memory.programs)
1902
+ }
1903
+ ),
1904
+ /* @__PURE__ */ s(
1905
+ x,
1906
+ {
1907
+ label: "Total",
1908
+ value: o(n.memory.total),
1909
+ color: n.memory.total > 100 * 1024 * 1024 ? e.colors.warning : e.colors.success
1910
+ }
1911
+ )
1912
+ ] })
1913
+ ] }),
1914
+ /* @__PURE__ */ c("div", { style: {
1915
+ backgroundColor: e.colors.surface,
1916
+ borderRadius: e.borderRadius.md,
1917
+ padding: e.spacing.md,
1918
+ border: `1px solid ${e.colors.border}`
1919
+ }, children: [
1920
+ /* @__PURE__ */ s("div", { style: {
1921
+ fontSize: e.typography.fontSize.md,
1922
+ fontWeight: 600,
1923
+ color: e.colors.text,
1924
+ marginBottom: e.spacing.md
1925
+ }, children: "Resources" }),
1926
+ /* @__PURE__ */ c("div", { style: {
1927
+ display: "grid",
1928
+ gridTemplateColumns: "repeat(auto-fit, minmax(120px, 1fr))",
1929
+ gap: e.spacing.md
1930
+ }, children: [
1931
+ /* @__PURE__ */ s(
1932
+ x,
1933
+ {
1934
+ label: "Textures",
1935
+ value: n.textures
1936
+ }
1937
+ ),
1938
+ /* @__PURE__ */ s(
1939
+ x,
1940
+ {
1941
+ label: "Geometries",
1942
+ value: n.geometries
1943
+ }
1944
+ ),
1945
+ /* @__PURE__ */ s(
1946
+ x,
1947
+ {
1948
+ label: "Programs",
1949
+ value: n.programs
1950
+ }
1951
+ )
1952
+ ] })
1953
+ ] })
1954
+ ] });
1955
+ };
1956
+ function Ae() {
1957
+ const [n, e] = B(null), t = I(null);
1958
+ return A(() => {
1959
+ const r = () => {
1960
+ if (!k.getPaused()) {
1961
+ const a = de.getStats();
1962
+ a && e(a);
1963
+ }
1964
+ };
1965
+ r(), t.current = window.setInterval(r, 500);
1966
+ const o = k.subscribe((a) => {
1967
+ a || r();
1968
+ });
1969
+ return () => {
1970
+ t.current !== null && clearInterval(t.current), o();
1971
+ };
1972
+ }, []), n;
1973
+ }
1974
+ const He = () => {
1975
+ const n = Ae(), e = F;
1976
+ if (!n)
1977
+ return /* @__PURE__ */ s("div", { style: {
1978
+ padding: e.spacing.lg,
1979
+ textAlign: "center",
1980
+ color: e.colors.textSecondary,
1981
+ fontSize: e.typography.fontSize.sm
1982
+ }, children: "Aucune donnée de scène disponible. Assurez-vous que le composant est à l'intérieur d'un Canvas R3F." });
1983
+ const t = (r) => r < 1024 ? `${v(r, 0)} B` : r < 1024 * 1024 ? `${v(r / 1024, 2)} KB` : `${v(r / (1024 * 1024), 2)} MB`;
1984
+ return /* @__PURE__ */ c("div", { style: { padding: e.spacing.md }, children: [
1985
+ /* @__PURE__ */ c("div", { style: {
1986
+ backgroundColor: e.colors.surface,
1987
+ borderRadius: e.borderRadius.md,
1988
+ padding: e.spacing.md,
1989
+ marginBottom: e.spacing.lg,
1990
+ border: `1px solid ${e.colors.border}`
1991
+ }, children: [
1992
+ /* @__PURE__ */ s("div", { style: {
1993
+ fontSize: e.typography.fontSize.md,
1994
+ fontWeight: 600,
1995
+ color: e.colors.text,
1996
+ marginBottom: e.spacing.md
1997
+ }, children: "Objects" }),
1998
+ /* @__PURE__ */ c("div", { style: {
1999
+ display: "grid",
2000
+ gridTemplateColumns: "repeat(auto-fit, minmax(120px, 1fr))",
2001
+ gap: e.spacing.md
2002
+ }, children: [
2003
+ /* @__PURE__ */ s(
2004
+ x,
2005
+ {
2006
+ label: "Total",
2007
+ value: n.objects.total.toLocaleString()
2008
+ }
2009
+ ),
2010
+ /* @__PURE__ */ s(
2011
+ x,
2012
+ {
2013
+ label: "Meshes",
2014
+ value: n.objects.meshes.toLocaleString()
2015
+ }
2016
+ ),
2017
+ /* @__PURE__ */ s(
2018
+ x,
2019
+ {
2020
+ label: "Lights",
2021
+ value: n.objects.lights.toLocaleString()
2022
+ }
2023
+ ),
2024
+ /* @__PURE__ */ s(
2025
+ x,
2026
+ {
2027
+ label: "Cameras",
2028
+ value: n.objects.cameras.toLocaleString()
2029
+ }
2030
+ ),
2031
+ /* @__PURE__ */ s(
2032
+ x,
2033
+ {
2034
+ label: "Groups",
2035
+ value: n.objects.groups.toLocaleString()
2036
+ }
2037
+ ),
2038
+ /* @__PURE__ */ s(
2039
+ x,
2040
+ {
2041
+ label: "Visible",
2042
+ value: n.visible.total.toLocaleString(),
2043
+ color: n.visible.total === n.objects.total ? e.colors.success : e.colors.warning
2044
+ }
2045
+ )
2046
+ ] })
2047
+ ] }),
2048
+ /* @__PURE__ */ c("div", { style: {
2049
+ backgroundColor: e.colors.surface,
2050
+ borderRadius: e.borderRadius.md,
2051
+ padding: e.spacing.md,
2052
+ marginBottom: e.spacing.lg,
2053
+ border: `1px solid ${e.colors.border}`
2054
+ }, children: [
2055
+ /* @__PURE__ */ c("div", { style: {
2056
+ fontSize: e.typography.fontSize.md,
2057
+ fontWeight: 600,
2058
+ color: e.colors.text,
2059
+ marginBottom: e.spacing.md
2060
+ }, children: [
2061
+ "Materials (",
2062
+ n.materials.total,
2063
+ ")"
2064
+ ] }),
2065
+ /* @__PURE__ */ s("div", { style: {
2066
+ display: "flex",
2067
+ flexWrap: "wrap",
2068
+ gap: e.spacing.sm
2069
+ }, children: Object.entries(n.materials.byType).map(([r, o]) => /* @__PURE__ */ c(
2070
+ "div",
2071
+ {
2072
+ style: {
2073
+ backgroundColor: e.colors.surfaceElevated,
2074
+ padding: `${e.spacing.xs} ${e.spacing.sm}`,
2075
+ borderRadius: e.borderRadius.sm,
2076
+ fontSize: e.typography.fontSize.xs,
2077
+ color: e.colors.textSecondary,
2078
+ fontFamily: e.typography.fontFamilyMono
2079
+ },
2080
+ children: [
2081
+ r,
2082
+ ": ",
2083
+ o
2084
+ ]
2085
+ },
2086
+ r
2087
+ )) })
2088
+ ] }),
2089
+ n.textures.total > 0 && /* @__PURE__ */ c("div", { style: {
2090
+ backgroundColor: e.colors.surface,
2091
+ borderRadius: e.borderRadius.md,
2092
+ padding: e.spacing.md,
2093
+ marginBottom: e.spacing.lg,
2094
+ border: `1px solid ${e.colors.border}`
2095
+ }, children: [
2096
+ /* @__PURE__ */ s("div", { style: {
2097
+ fontSize: e.typography.fontSize.md,
2098
+ fontWeight: 600,
2099
+ color: e.colors.text,
2100
+ marginBottom: e.spacing.md
2101
+ }, children: "Textures" }),
2102
+ /* @__PURE__ */ c("div", { style: {
2103
+ display: "grid",
2104
+ gridTemplateColumns: "repeat(auto-fit, minmax(150px, 1fr))",
2105
+ gap: e.spacing.md
2106
+ }, children: [
2107
+ /* @__PURE__ */ s(
2108
+ x,
2109
+ {
2110
+ label: "Total",
2111
+ value: n.textures.total.toLocaleString()
2112
+ }
2113
+ ),
2114
+ /* @__PURE__ */ s(
2115
+ x,
2116
+ {
2117
+ label: "Total Size",
2118
+ value: t(n.textures.totalSize)
2119
+ }
2120
+ ),
2121
+ n.textures.environment > 0 && /* @__PURE__ */ s(
2122
+ x,
2123
+ {
2124
+ label: "Environment",
2125
+ value: n.textures.environment.toLocaleString(),
2126
+ color: e.colors.info
2127
+ }
2128
+ ),
2129
+ n.textures.system > 0 && /* @__PURE__ */ s(
2130
+ x,
2131
+ {
2132
+ label: "System",
2133
+ value: n.textures.system.toLocaleString(),
2134
+ color: e.colors.warning
2135
+ }
2136
+ )
2137
+ ] })
2138
+ ] }),
2139
+ /* @__PURE__ */ c("div", { style: {
2140
+ backgroundColor: e.colors.surface,
2141
+ borderRadius: e.borderRadius.md,
2142
+ padding: e.spacing.md,
2143
+ marginBottom: e.spacing.lg,
2144
+ border: `1px solid ${e.colors.border}`
2145
+ }, children: [
2146
+ /* @__PURE__ */ s("div", { style: {
2147
+ fontSize: e.typography.fontSize.md,
2148
+ fontWeight: 600,
2149
+ color: e.colors.text,
2150
+ marginBottom: e.spacing.md
2151
+ }, children: "Geometries" }),
2152
+ /* @__PURE__ */ c("div", { style: {
2153
+ display: "grid",
2154
+ gridTemplateColumns: "repeat(auto-fit, minmax(150px, 1fr))",
2155
+ gap: e.spacing.md
2156
+ }, children: [
2157
+ /* @__PURE__ */ s(
2158
+ x,
2159
+ {
2160
+ label: "Total",
2161
+ value: n.geometries.total.toLocaleString()
2162
+ }
2163
+ ),
2164
+ /* @__PURE__ */ s(
2165
+ x,
2166
+ {
2167
+ label: "Vertices",
2168
+ value: n.geometries.vertices.toLocaleString()
2169
+ }
2170
+ ),
2171
+ /* @__PURE__ */ s(
2172
+ x,
2173
+ {
2174
+ label: "Faces",
2175
+ value: n.geometries.faces.toLocaleString()
2176
+ }
2177
+ )
2178
+ ] })
2179
+ ] }),
2180
+ /* @__PURE__ */ c("div", { style: {
2181
+ backgroundColor: e.colors.surface,
2182
+ borderRadius: e.borderRadius.md,
2183
+ padding: e.spacing.md,
2184
+ border: `1px solid ${e.colors.border}`
2185
+ }, children: [
2186
+ /* @__PURE__ */ s("div", { style: {
2187
+ fontSize: e.typography.fontSize.md,
2188
+ fontWeight: 600,
2189
+ color: e.colors.text,
2190
+ marginBottom: e.spacing.md
2191
+ }, children: "Complexity" }),
2192
+ /* @__PURE__ */ c("div", { style: {
2193
+ display: "grid",
2194
+ gridTemplateColumns: "repeat(auto-fit, minmax(150px, 1fr))",
2195
+ gap: e.spacing.md
2196
+ }, children: [
2197
+ /* @__PURE__ */ s(
2198
+ x,
2199
+ {
2200
+ label: "Avg Vertices/Mesh",
2201
+ value: v(n.complexity.averageVerticesPerMesh, 0)
2202
+ }
2203
+ ),
2204
+ /* @__PURE__ */ s(
2205
+ x,
2206
+ {
2207
+ label: "Avg Faces/Mesh",
2208
+ value: v(n.complexity.averageFacesPerMesh, 0)
2209
+ }
2210
+ ),
2211
+ /* @__PURE__ */ s(
2212
+ x,
2213
+ {
2214
+ label: "Est. Draw Calls",
2215
+ value: n.complexity.totalDrawCalls.toLocaleString()
2216
+ }
2217
+ )
2218
+ ] })
2219
+ ] })
2220
+ ] });
2221
+ };
2222
+ function ee() {
2223
+ const [n, e] = B(null), t = I(null);
2224
+ return A(() => {
2225
+ const r = () => {
2226
+ if (!k.getPaused()) {
2227
+ const a = Y.getStats();
2228
+ a && e(a);
2229
+ }
2230
+ };
2231
+ r(), t.current = window.setInterval(r, 1e3);
2232
+ const o = k.subscribe((a) => {
2233
+ a || r();
2234
+ });
2235
+ return () => {
2236
+ t.current !== null && clearInterval(t.current), o();
2237
+ };
2238
+ }, []), n;
2239
+ }
2240
+ const Ee = () => {
2241
+ const n = ee(), e = F, t = (a) => a === 0 ? "0 B" : a < 1024 ? `${v(a, 0)} B` : a < 1024 * 1024 ? `${v(a / 1024, 2)} KB` : a < 1024 * 1024 * 1024 ? `${v(a / (1024 * 1024), 2)} MB` : `${v(a / (1024 * 1024 * 1024), 2)} GB`, r = L(() => {
2242
+ if (!n) return "neutral";
2243
+ const a = n.jsHeap.percentage;
2244
+ return a < 50 ? "good" : a < 80 ? "warning" : "error";
2245
+ }, [n]), o = L(() => n ? n.leaks.detected ? "error" : "good" : "neutral", [n]);
2246
+ return n ? /* @__PURE__ */ c("div", { style: { padding: e.spacing.md }, children: [
2247
+ n.jsHeap.limit > 0 && /* @__PURE__ */ c("div", { style: {
2248
+ backgroundColor: e.colors.surface,
2249
+ borderRadius: e.borderRadius.md,
2250
+ padding: e.spacing.md,
2251
+ marginBottom: e.spacing.lg,
2252
+ border: `1px solid ${e.colors.border}`
2253
+ }, children: [
2254
+ /* @__PURE__ */ s("div", { style: {
2255
+ fontSize: e.typography.fontSize.sm,
2256
+ fontWeight: 600,
2257
+ color: e.colors.text,
2258
+ marginBottom: e.spacing.sm
2259
+ }, children: "JavaScript Heap Memory" }),
2260
+ /* @__PURE__ */ c("div", { style: {
2261
+ display: "grid",
2262
+ gridTemplateColumns: "repeat(auto-fit, minmax(150px, 1fr))",
2263
+ gap: e.spacing.md,
2264
+ marginBottom: e.spacing.md
2265
+ }, children: [
2266
+ /* @__PURE__ */ s(
2267
+ x,
2268
+ {
2269
+ label: "Used",
2270
+ value: t(n.jsHeap.used),
2271
+ status: r
2272
+ }
2273
+ ),
2274
+ /* @__PURE__ */ s(
2275
+ x,
2276
+ {
2277
+ label: "Total",
2278
+ value: t(n.jsHeap.total)
2279
+ }
2280
+ ),
2281
+ /* @__PURE__ */ s(
2282
+ x,
2283
+ {
2284
+ label: "Limit",
2285
+ value: t(n.jsHeap.limit)
2286
+ }
2287
+ ),
2288
+ /* @__PURE__ */ s(
2289
+ x,
2290
+ {
2291
+ label: "Usage",
2292
+ value: `${v(n.jsHeap.percentage, 1)}%`,
2293
+ status: r
2294
+ }
2295
+ )
2296
+ ] }),
2297
+ /* @__PURE__ */ s("div", { style: {
2298
+ width: "100%",
2299
+ height: "8px",
2300
+ backgroundColor: e.colors.border,
2301
+ borderRadius: e.borderRadius.sm,
2302
+ overflow: "hidden",
2303
+ marginTop: e.spacing.sm
2304
+ }, children: /* @__PURE__ */ s("div", { style: {
2305
+ width: `${Math.min(100, n.jsHeap.percentage)}%`,
2306
+ height: "100%",
2307
+ backgroundColor: n.jsHeap.percentage <= 50 ? e.colors.success : n.jsHeap.percentage <= 80 ? e.colors.warning : e.colors.error,
2308
+ transition: e.transitions.normal
2309
+ } }) })
2310
+ ] }),
2311
+ n.gpuMemory.total > 0 && /* @__PURE__ */ c("div", { style: {
2312
+ backgroundColor: e.colors.surface,
2313
+ borderRadius: e.borderRadius.md,
2314
+ padding: e.spacing.md,
2315
+ marginBottom: e.spacing.lg,
2316
+ border: `1px solid ${e.colors.border}`
2317
+ }, children: [
2318
+ /* @__PURE__ */ s("div", { style: {
2319
+ fontSize: e.typography.fontSize.sm,
2320
+ fontWeight: 600,
2321
+ color: e.colors.text,
2322
+ marginBottom: e.spacing.sm
2323
+ }, children: "GPU Memory (Estimated)" }),
2324
+ /* @__PURE__ */ c("div", { style: {
2325
+ display: "grid",
2326
+ gridTemplateColumns: "repeat(auto-fit, minmax(120px, 1fr))",
2327
+ gap: e.spacing.sm
2328
+ }, children: [
2329
+ /* @__PURE__ */ s(
2330
+ x,
2331
+ {
2332
+ label: "Textures",
2333
+ value: t(n.gpuMemory.textures)
2334
+ }
2335
+ ),
2336
+ /* @__PURE__ */ s(
2337
+ x,
2338
+ {
2339
+ label: "Geometries",
2340
+ value: t(n.gpuMemory.geometries)
2341
+ }
2342
+ ),
2343
+ /* @__PURE__ */ s(
2344
+ x,
2345
+ {
2346
+ label: "Total",
2347
+ value: t(n.gpuMemory.total)
2348
+ }
2349
+ )
2350
+ ] }),
2351
+ /* @__PURE__ */ s("div", { style: {
2352
+ fontSize: e.typography.fontSize.xs,
2353
+ color: e.colors.textTertiary,
2354
+ marginTop: e.spacing.sm
2355
+ }, children: "Note: GPU memory is an estimation based on resource counts. Actual usage may vary." })
2356
+ ] }),
2357
+ /* @__PURE__ */ c("div", { style: {
2358
+ backgroundColor: e.colors.surface,
2359
+ borderRadius: e.borderRadius.md,
2360
+ padding: e.spacing.md,
2361
+ marginBottom: e.spacing.lg,
2362
+ border: `1px solid ${e.colors.border}`,
2363
+ overflow: "hidden"
2364
+ }, children: [
2365
+ /* @__PURE__ */ s("div", { style: {
2366
+ fontSize: e.typography.fontSize.sm,
2367
+ fontWeight: 600,
2368
+ color: e.colors.text,
2369
+ marginBottom: e.spacing.sm
2370
+ }, children: "Memory Evolution (Last 60s)" }),
2371
+ /* @__PURE__ */ s(
2372
+ Fe,
2373
+ {
2374
+ width: "100%",
2375
+ height: 150,
2376
+ timeWindow: 60,
2377
+ metric: "both",
2378
+ showGrid: !0,
2379
+ showLabels: !0
2380
+ }
2381
+ )
2382
+ ] }),
2383
+ /* @__PURE__ */ c("div", { style: {
2384
+ backgroundColor: e.colors.surface,
2385
+ borderRadius: e.borderRadius.md,
2386
+ padding: e.spacing.md,
2387
+ border: `1px solid ${e.colors.border}`
2388
+ }, children: [
2389
+ /* @__PURE__ */ s("div", { style: {
2390
+ fontSize: e.typography.fontSize.sm,
2391
+ fontWeight: 600,
2392
+ color: e.colors.text,
2393
+ marginBottom: e.spacing.sm
2394
+ }, children: "Memory Leak Detection" }),
2395
+ /* @__PURE__ */ c("div", { style: {
2396
+ display: "flex",
2397
+ alignItems: "center",
2398
+ gap: e.spacing.sm,
2399
+ marginBottom: e.spacing.sm
2400
+ }, children: [
2401
+ /* @__PURE__ */ s("div", { style: {
2402
+ width: "12px",
2403
+ height: "12px",
2404
+ borderRadius: "50%",
2405
+ backgroundColor: o === "good" ? e.colors.success : e.colors.error
2406
+ } }),
2407
+ /* @__PURE__ */ s("div", { style: {
2408
+ color: e.colors.text,
2409
+ fontSize: e.typography.fontSize.sm
2410
+ }, children: n.leaks.detected ? "Potential leak detected" : "No leaks detected" })
2411
+ ] }),
2412
+ /* @__PURE__ */ c("div", { style: {
2413
+ fontSize: e.typography.fontSize.xs,
2414
+ color: e.colors.textSecondary,
2415
+ fontFamily: e.typography.fontFamilyMono
2416
+ }, children: [
2417
+ /* @__PURE__ */ c("div", { children: [
2418
+ "Growth Rate: ",
2419
+ t(Math.abs(n.leaks.growthRate)),
2420
+ "/s"
2421
+ ] }),
2422
+ /* @__PURE__ */ c("div", { children: [
2423
+ "Trend: ",
2424
+ n.leaks.trend
2425
+ ] })
2426
+ ] })
2427
+ ] })
2428
+ ] }) : /* @__PURE__ */ s("div", { style: {
2429
+ padding: e.spacing.lg,
2430
+ textAlign: "center",
2431
+ color: e.colors.textSecondary,
2432
+ fontSize: e.typography.fontSize.sm
2433
+ }, children: "Aucune donnée de mémoire disponible. Les stats de mémoire JS nécessitent Chrome." });
2434
+ }, We = () => {
2435
+ const n = ue(), e = F, t = (l) => l < 0.1 ? `${v(l * 1e3, 0)} μs` : l < 1 ? `${v(l, 2)} ms` : `${v(l, 2)} ms`, r = (l, g) => g === 0 ? "0%" : `${v(l / g * 100, 1)}%`, o = L(() => n ? n.total <= 16.67 ? "good" : n.total <= 33.33 ? "warning" : "error" : "neutral", [n]);
2436
+ if (!n)
2437
+ return /* @__PURE__ */ s("div", { style: {
2438
+ padding: e.spacing.lg,
2439
+ textAlign: "center",
2440
+ color: e.colors.textSecondary,
2441
+ fontSize: e.typography.fontSize.sm
2442
+ }, children: "Aucune donnée de breakdown de frame disponible. Le frame breakdown nécessite une instrumentation du code." });
2443
+ const a = [
2444
+ { name: "React", value: n.phases.react, color: e.colors.primary },
2445
+ { name: "Update", value: n.phases.update, color: e.colors.info },
2446
+ { name: "Physics", value: n.phases.physics, color: e.colors.warning },
2447
+ { name: "Render", value: n.phases.render, color: e.colors.success },
2448
+ { name: "Post-Process", value: n.phases.postProcess, color: e.colors.accent },
2449
+ { name: "Other", value: n.phases.other, color: e.colors.textSecondary }
2450
+ ].filter((l) => l.value > 0), d = Math.max(...a.map((l) => l.value), n.total);
2451
+ return /* @__PURE__ */ c("div", { style: { padding: e.spacing.md }, children: [
2452
+ /* @__PURE__ */ c("div", { style: {
2453
+ backgroundColor: e.colors.surface,
2454
+ borderRadius: e.borderRadius.md,
2455
+ padding: e.spacing.md,
2456
+ marginBottom: e.spacing.lg,
2457
+ border: `1px solid ${e.colors.border}`
2458
+ }, children: [
2459
+ /* @__PURE__ */ s("div", { style: {
2460
+ fontSize: e.typography.fontSize.sm,
2461
+ fontWeight: 600,
2462
+ color: e.colors.text,
2463
+ marginBottom: e.spacing.sm
2464
+ }, children: "Total Frame Time" }),
2465
+ /* @__PURE__ */ c("div", { style: {
2466
+ display: "flex",
2467
+ alignItems: "baseline",
2468
+ gap: e.spacing.sm,
2469
+ marginBottom: e.spacing.sm
2470
+ }, children: [
2471
+ /* @__PURE__ */ s(
2472
+ x,
2473
+ {
2474
+ label: "Frame Time",
2475
+ value: t(n.total),
2476
+ status: o
2477
+ }
2478
+ ),
2479
+ /* @__PURE__ */ c("div", { style: {
2480
+ fontSize: e.typography.fontSize.xs,
2481
+ color: e.colors.textSecondary
2482
+ }, children: [
2483
+ "(",
2484
+ v(1e3 / n.total, 1),
2485
+ " FPS)"
2486
+ ] })
2487
+ ] })
2488
+ ] }),
2489
+ /* @__PURE__ */ c("div", { style: {
2490
+ backgroundColor: e.colors.surface,
2491
+ borderRadius: e.borderRadius.md,
2492
+ padding: e.spacing.md,
2493
+ marginBottom: e.spacing.lg,
2494
+ border: `1px solid ${e.colors.border}`
2495
+ }, children: [
2496
+ /* @__PURE__ */ s("div", { style: {
2497
+ fontSize: e.typography.fontSize.sm,
2498
+ fontWeight: 600,
2499
+ color: e.colors.text,
2500
+ marginBottom: e.spacing.sm
2501
+ }, children: "Phase Breakdown" }),
2502
+ /* @__PURE__ */ s("div", { style: {
2503
+ display: "grid",
2504
+ gridTemplateColumns: "repeat(auto-fit, minmax(120px, 1fr))",
2505
+ gap: e.spacing.sm,
2506
+ marginBottom: e.spacing.md
2507
+ }, children: a.map((l) => /* @__PURE__ */ s(
2508
+ x,
2509
+ {
2510
+ label: l.name,
2511
+ value: t(l.value)
2512
+ },
2513
+ l.name
2514
+ )) }),
2515
+ /* @__PURE__ */ c("div", { style: {
2516
+ marginTop: e.spacing.md
2517
+ }, children: [
2518
+ /* @__PURE__ */ s("div", { style: {
2519
+ fontSize: e.typography.fontSize.xs,
2520
+ color: e.colors.textSecondary,
2521
+ marginBottom: e.spacing.sm
2522
+ }, children: "Timeline (Waterfall)" }),
2523
+ /* @__PURE__ */ s("div", { style: {
2524
+ position: "relative",
2525
+ height: "200px",
2526
+ backgroundColor: e.colors.background,
2527
+ borderRadius: e.borderRadius.sm,
2528
+ border: `1px solid ${e.colors.border}`,
2529
+ padding: e.spacing.xs
2530
+ }, children: a.map((l, g) => {
2531
+ const i = l.value / d * 100, w = a.slice(0, g).reduce((y, u) => y + u.value / d * 100, 0);
2532
+ return /* @__PURE__ */ s(
2533
+ "div",
2534
+ {
2535
+ style: {
2536
+ position: "absolute",
2537
+ left: `${w}%`,
2538
+ width: `${i}%`,
2539
+ height: "30px",
2540
+ backgroundColor: l.color,
2541
+ borderRadius: e.borderRadius.sm,
2542
+ display: "flex",
2543
+ alignItems: "center",
2544
+ justifyContent: "center",
2545
+ fontSize: e.typography.fontSize.xs,
2546
+ color: e.colors.background,
2547
+ fontWeight: 600,
2548
+ marginTop: `${g * 35}px`,
2549
+ opacity: 0.8,
2550
+ border: `1px solid ${e.colors.border}`
2551
+ },
2552
+ title: `${l.name}: ${t(l.value)} (${r(l.value, n.total)})`,
2553
+ children: i > 5 && `${l.name}: ${t(l.value)}`
2554
+ },
2555
+ l.name
2556
+ );
2557
+ }) })
2558
+ ] })
2559
+ ] }),
2560
+ n.timeline.length > 0 && /* @__PURE__ */ c("div", { style: {
2561
+ backgroundColor: e.colors.surface,
2562
+ borderRadius: e.borderRadius.md,
2563
+ padding: e.spacing.md,
2564
+ border: `1px solid ${e.colors.border}`
2565
+ }, children: [
2566
+ /* @__PURE__ */ s("div", { style: {
2567
+ fontSize: e.typography.fontSize.sm,
2568
+ fontWeight: 600,
2569
+ color: e.colors.text,
2570
+ marginBottom: e.spacing.sm
2571
+ }, children: "Timeline Details" }),
2572
+ /* @__PURE__ */ s("div", { style: {
2573
+ maxHeight: "200px",
2574
+ overflowY: "auto",
2575
+ fontSize: e.typography.fontSize.xs,
2576
+ fontFamily: e.typography.fontFamilyMono,
2577
+ color: e.colors.textSecondary
2578
+ }, children: n.timeline.slice(-20).reverse().map((l, g) => /* @__PURE__ */ c(
2579
+ "div",
2580
+ {
2581
+ style: {
2582
+ padding: e.spacing.xs,
2583
+ borderBottom: `1px solid ${e.colors.border}`,
2584
+ display: "flex",
2585
+ justifyContent: "space-between"
2586
+ },
2587
+ children: [
2588
+ /* @__PURE__ */ s("span", { children: l.name }),
2589
+ /* @__PURE__ */ s("span", { children: t(l.duration) })
2590
+ ]
2591
+ },
2592
+ g
2593
+ )) })
2594
+ ] })
2595
+ ] });
2596
+ };
2597
+ class Ie {
2598
+ budget = null;
2599
+ violations = [];
2600
+ maxHistorySize = 100;
2601
+ listeners = /* @__PURE__ */ new Set();
2602
+ STORAGE_KEY = "r3f-profiler-budget";
2603
+ constructor() {
2604
+ this.loadBudget();
2605
+ }
2606
+ loadBudget() {
2607
+ try {
2608
+ const e = localStorage.getItem(this.STORAGE_KEY);
2609
+ if (e) {
2610
+ const t = JSON.parse(e);
2611
+ this.isValidBudget(t) && (this.budget = t);
2612
+ }
2613
+ } catch (e) {
2614
+ console.warn("Failed to load saved budget from localStorage:", e);
2615
+ }
2616
+ }
2617
+ saveBudget() {
2618
+ try {
2619
+ this.budget ? localStorage.setItem(this.STORAGE_KEY, JSON.stringify(this.budget)) : localStorage.removeItem(this.STORAGE_KEY);
2620
+ } catch (e) {
2621
+ console.warn("Failed to save budget to localStorage:", e);
2622
+ }
2623
+ }
2624
+ isValidBudget(e) {
2625
+ return !e || typeof e != "object" ? !1 : e.fps && typeof e.fps.min == "number" || e.frameTime && typeof e.frameTime.max == "number" || e.memory && (typeof e.memory.max == "number" || e.memory.jsHeap) || e.gpu && (e.gpu.drawCalls || e.gpu.triangles);
2626
+ }
2627
+ setBudget(e) {
2628
+ !e || !e.fps && !e.frameTime && !e.memory && !e.gpu ? this.budget = null : this.budget = e, this.violations = [], this.saveBudget(), this.notifyListeners();
2629
+ }
2630
+ getBudget() {
2631
+ return this.budget;
2632
+ }
2633
+ checkBudget(e) {
2634
+ if (!this.budget)
2635
+ return [];
2636
+ const t = [];
2637
+ return this.budget.fps?.min !== void 0 && e.fps !== void 0 && e.fps < this.budget.fps.min && t.push({
2638
+ id: `fps-${Date.now()}-${Math.random()}`,
2639
+ metric: "fps",
2640
+ current: e.fps,
2641
+ budget: this.budget.fps.min,
2642
+ severity: e.fps < this.budget.fps.min * 0.7 ? "error" : "warning",
2643
+ timestamp: performance.now(),
2644
+ message: `FPS is ${e.fps.toFixed(1)} (budget: ${this.budget.fps.min} FPS)`
2645
+ }), this.budget.frameTime?.max !== void 0 && e.frameTime !== void 0 && e.frameTime > this.budget.frameTime.max && t.push({
2646
+ id: `frameTime-${Date.now()}-${Math.random()}`,
2647
+ metric: "frameTime",
2648
+ current: e.frameTime,
2649
+ budget: this.budget.frameTime.max,
2650
+ severity: e.frameTime > this.budget.frameTime.max * 1.5 ? "error" : "warning",
2651
+ timestamp: performance.now(),
2652
+ message: `Frame time is ${e.frameTime.toFixed(2)}ms (budget: ${this.budget.frameTime.max}ms)`
2653
+ }), this.budget.memory && (this.budget.memory.max !== void 0 && e.memory?.used !== void 0 && e.memory.used > this.budget.memory.max && t.push({
2654
+ id: `memory-${Date.now()}-${Math.random()}`,
2655
+ metric: "memory",
2656
+ current: e.memory.used,
2657
+ budget: this.budget.memory.max,
2658
+ severity: e.memory.used > this.budget.memory.max * 1.2 ? "error" : "warning",
2659
+ timestamp: performance.now(),
2660
+ message: `Memory usage is ${(e.memory.used / (1024 * 1024)).toFixed(2)}MB (budget: ${(this.budget.memory.max / (1024 * 1024)).toFixed(2)}MB)`
2661
+ }), this.budget.memory.jsHeap?.maxPercentage !== void 0 && e.memory?.jsHeapPercentage !== void 0 && e.memory.jsHeapPercentage > this.budget.memory.jsHeap.maxPercentage && t.push({
2662
+ id: `jsHeap-${Date.now()}-${Math.random()}`,
2663
+ metric: "jsHeap",
2664
+ current: e.memory.jsHeapPercentage,
2665
+ budget: this.budget.memory.jsHeap.maxPercentage,
2666
+ severity: e.memory.jsHeapPercentage > this.budget.memory.jsHeap.maxPercentage * 1.1 ? "error" : "warning",
2667
+ timestamp: performance.now(),
2668
+ message: `JS Heap usage is ${e.memory.jsHeapPercentage.toFixed(1)}% (budget: ${this.budget.memory.jsHeap.maxPercentage}%)`
2669
+ })), this.budget.gpu && (this.budget.gpu.drawCalls?.max !== void 0 && e.gpu?.drawCalls !== void 0 && e.gpu.drawCalls > this.budget.gpu.drawCalls.max && t.push({
2670
+ id: `drawCalls-${Date.now()}-${Math.random()}`,
2671
+ metric: "drawCalls",
2672
+ current: e.gpu.drawCalls,
2673
+ budget: this.budget.gpu.drawCalls.max,
2674
+ severity: e.gpu.drawCalls > this.budget.gpu.drawCalls.max * 1.5 ? "error" : "warning",
2675
+ timestamp: performance.now(),
2676
+ message: `Draw calls: ${e.gpu.drawCalls} (budget: ${this.budget.gpu.drawCalls.max})`
2677
+ }), this.budget.gpu.triangles?.max !== void 0 && e.gpu?.triangles !== void 0 && e.gpu.triangles > this.budget.gpu.triangles.max && t.push({
2678
+ id: `triangles-${Date.now()}-${Math.random()}`,
2679
+ metric: "triangles",
2680
+ current: e.gpu.triangles,
2681
+ budget: this.budget.gpu.triangles.max,
2682
+ severity: e.gpu.triangles > this.budget.gpu.triangles.max * 1.5 ? "error" : "warning",
2683
+ timestamp: performance.now(),
2684
+ message: `Triangles: ${e.gpu.triangles.toLocaleString()} (budget: ${this.budget.gpu.triangles.max.toLocaleString()})`
2685
+ })), t.length > 0 && (this.violations.push(...t), this.violations.length > this.maxHistorySize && (this.violations = this.violations.slice(-this.maxHistorySize)), this.notifyListeners()), t;
2686
+ }
2687
+ getViolations() {
2688
+ return [...this.violations];
2689
+ }
2690
+ getRecentViolations(e = 60) {
2691
+ const t = performance.now() - e * 1e3;
2692
+ return this.violations.filter((r) => r.timestamp >= t);
2693
+ }
2694
+ getViolationsByMetric(e) {
2695
+ return this.violations.filter((t) => t.metric === e);
2696
+ }
2697
+ clearViolations() {
2698
+ this.violations = [], this.notifyListeners();
2699
+ }
2700
+ // Get default budget recommendations based on current metrics
2701
+ getRecommendedBudget(e) {
2702
+ const t = {};
2703
+ return e.fps !== void 0 && (t.fps = {
2704
+ min: Math.max(30, Math.floor(e.fps * 0.9))
2705
+ }), e.frameTime !== void 0 && (t.frameTime = {
2706
+ max: Math.ceil(e.frameTime * 1.1)
2707
+ }), e.memory?.used !== void 0 && (t.memory = {
2708
+ max: Math.ceil(e.memory.used * 1.2),
2709
+ jsHeap: {
2710
+ maxPercentage: 80
2711
+ // Default 80% of heap limit
2712
+ }
2713
+ }), e.gpu && (t.gpu = {}, e.gpu.drawCalls !== void 0 && (t.gpu.drawCalls = {
2714
+ max: Math.ceil(e.gpu.drawCalls * 1.2)
2715
+ }), e.gpu.triangles !== void 0 && (t.gpu.triangles = {
2716
+ max: Math.ceil(e.gpu.triangles * 1.2)
2717
+ })), t;
2718
+ }
2719
+ // Subscribe to violation changes
2720
+ subscribe(e) {
2721
+ return this.listeners.add(e), () => {
2722
+ this.listeners.delete(e);
2723
+ };
2724
+ }
2725
+ notifyListeners() {
2726
+ const e = this.getRecentViolations(60);
2727
+ this.listeners.forEach((t) => {
2728
+ try {
2729
+ t(e);
2730
+ } catch (r) {
2731
+ console.error("Error in budget violation listener:", r);
2732
+ }
2733
+ });
2734
+ }
2735
+ reset() {
2736
+ this.budget = null, this.violations = [], this.listeners.clear(), localStorage.removeItem(this.STORAGE_KEY);
2737
+ }
2738
+ }
2739
+ const W = new Ie();
2740
+ function Ge() {
2741
+ const [n, e] = B(null), [t, r] = B([]);
2742
+ return A(() => {
2743
+ e(W.getBudget()), r(W.getRecentViolations(60));
2744
+ const g = W.subscribe((i) => {
2745
+ r(i), e(W.getBudget());
2746
+ });
2747
+ return () => {
2748
+ g();
2749
+ };
2750
+ }, []), {
2751
+ budget: n,
2752
+ violations: t,
2753
+ setBudget: (g) => {
2754
+ W.setBudget(g), e(g), r([]);
2755
+ },
2756
+ clearViolations: () => {
2757
+ W.clearViolations(), r([]);
2758
+ },
2759
+ clearBudget: () => {
2760
+ W.setBudget({}), e(null), r([]);
2761
+ },
2762
+ getRecommendedBudget: (g) => W.getRecommendedBudget(g)
2763
+ };
2764
+ }
2765
+ class Ve {
2766
+ alerts = [];
2767
+ maxAlerts = 50;
2768
+ listeners = /* @__PURE__ */ new Set();
2769
+ soundEnabled = !1;
2770
+ // Create alert from budget violation
2771
+ createFromViolation(e) {
2772
+ return {
2773
+ id: `alert-${e.id}`,
2774
+ type: "budget",
2775
+ severity: e.severity,
2776
+ title: `Budget Violation: ${e.metric}`,
2777
+ message: e.message,
2778
+ timestamp: e.timestamp,
2779
+ dismissed: !1,
2780
+ data: {
2781
+ violation: e
2782
+ }
2783
+ };
2784
+ }
2785
+ // Create custom alert
2786
+ createAlert(e, t, r, o, a) {
2787
+ const d = {
2788
+ id: `alert-${Date.now()}-${Math.random()}`,
2789
+ type: e,
2790
+ severity: t,
2791
+ title: r,
2792
+ message: o,
2793
+ timestamp: performance.now(),
2794
+ dismissed: !1,
2795
+ data: a
2796
+ };
2797
+ return this.addAlert(d), d;
2798
+ }
2799
+ addAlert(e) {
2800
+ if (e.type === "budget" && e.data?.violation) {
2801
+ const t = e.data.violation;
2802
+ this.alerts = this.alerts.filter(
2803
+ (r) => !(r.type === "budget" && r.data?.violation && r.data.violation.metric === t.metric)
2804
+ );
2805
+ }
2806
+ this.alerts.push(e), this.alerts.length > this.maxAlerts && (this.alerts = this.alerts.slice(-this.maxAlerts)), this.soundEnabled && e.severity === "error" && this.playAlertSound(), this.notifyListeners();
2807
+ }
2808
+ getAlerts(e = !1) {
2809
+ return e ? [...this.alerts] : this.alerts.filter((t) => !t.dismissed);
2810
+ }
2811
+ getActiveAlerts() {
2812
+ return this.alerts.filter((e) => !e.dismissed);
2813
+ }
2814
+ getAlertsBySeverity(e) {
2815
+ return this.alerts.filter((t) => !t.dismissed && t.severity === e);
2816
+ }
2817
+ getAlertsByType(e) {
2818
+ return this.alerts.filter((t) => !t.dismissed && t.type === e);
2819
+ }
2820
+ dismissAlert(e) {
2821
+ const t = this.alerts.find((r) => r.id === e);
2822
+ t && (t.dismissed = !0, this.notifyListeners());
2823
+ }
2824
+ dismissAll() {
2825
+ this.alerts.forEach((e) => {
2826
+ e.dismissed = !0;
2827
+ }), this.notifyListeners();
2828
+ }
2829
+ removeAlert(e) {
2830
+ this.alerts = this.alerts.filter((t) => t.id !== e), this.notifyListeners();
2831
+ }
2832
+ clearAlerts() {
2833
+ this.alerts = [], this.notifyListeners();
2834
+ }
2835
+ setSoundEnabled(e) {
2836
+ this.soundEnabled = e;
2837
+ }
2838
+ isSoundEnabled() {
2839
+ return this.soundEnabled;
2840
+ }
2841
+ playAlertSound() {
2842
+ try {
2843
+ const e = new (window.AudioContext || window.webkitAudioContext)(), t = e.createOscillator(), r = e.createGain();
2844
+ t.connect(r), r.connect(e.destination), t.frequency.value = 800, t.type = "sine", r.gain.setValueAtTime(0.3, e.currentTime), r.gain.exponentialRampToValueAtTime(0.01, e.currentTime + 0.1), t.start(e.currentTime), t.stop(e.currentTime + 0.1);
2845
+ } catch (e) {
2846
+ console.debug("Could not play alert sound:", e);
2847
+ }
2848
+ }
2849
+ // Subscribe to alert changes
2850
+ subscribe(e) {
2851
+ return this.listeners.add(e), () => {
2852
+ this.listeners.delete(e);
2853
+ };
2854
+ }
2855
+ notifyListeners() {
2856
+ const e = this.getActiveAlerts();
2857
+ this.listeners.forEach((t) => {
2858
+ try {
2859
+ t(e);
2860
+ } catch (r) {
2861
+ console.error("Error in alert listener:", r);
2862
+ }
2863
+ });
2864
+ }
2865
+ reset() {
2866
+ this.alerts = [], this.listeners.clear(), this.soundEnabled = !1;
2867
+ }
2868
+ }
2869
+ const ae = new Ve();
2870
+ function _e() {
2871
+ const n = j(), e = J(), t = Q(), r = ee(), o = I(null);
2872
+ A(() => {
2873
+ const a = () => {
2874
+ if (!W.getBudget())
2875
+ return;
2876
+ let l = 0, g = 0;
2877
+ e && e.totalTime > 0 && e.frames > 0 ? (g = e.totalTime / e.frames, l = 1e3 / g) : n.length > 0 ? (g = n.reduce((y, u) => y + u, 0) / n.length, l = g > 0 ? 1e3 / g : 0) : t && t.frameTime > 0 && (g = t.frameTime, l = g > 0 ? 1e3 / g : 0);
2878
+ const i = {
2879
+ fps: l,
2880
+ frameTime: g,
2881
+ memory: r ? {
2882
+ used: r.jsHeap.used,
2883
+ jsHeapPercentage: r.jsHeap.percentage
2884
+ } : void 0,
2885
+ gpu: t ? {
2886
+ drawCalls: t.drawCalls,
2887
+ triangles: t.triangles
2888
+ } : void 0
2889
+ };
2890
+ W.checkBudget(i).forEach((y) => {
2891
+ ae.getAlerts().find(
2892
+ (f) => f.type === "budget" && f.data?.violation && f.data.violation.id === y.id
2893
+ ) || ae.createFromViolation(y);
2894
+ });
2895
+ };
2896
+ return o.current = window.setInterval(a, 1e3), a(), () => {
2897
+ o.current !== null && clearInterval(o.current);
2898
+ };
2899
+ }, [n, e, t, r]);
2900
+ }
2901
+ const Oe = () => {
2902
+ const { budget: n, violations: e, setBudget: t, clearViolations: r, clearBudget: o, getRecommendedBudget: a } = Ge(), d = j(), l = Q(), g = ee(), i = F;
2903
+ _e();
2904
+ const [w, y] = B(!1), [u, f] = B(n || {}), M = L(() => {
2905
+ const p = d.length > 0 ? d.reduce((P, D) => P + D, 0) / d.length : 0;
2906
+ return {
2907
+ fps: p > 0 ? 1e3 / p : 0,
2908
+ frameTime: p,
2909
+ memory: g ? {
2910
+ used: g.jsHeap.used,
2911
+ jsHeapPercentage: g.jsHeap.percentage
2912
+ } : void 0,
2913
+ gpu: l ? {
2914
+ drawCalls: l.drawCalls,
2915
+ triangles: l.triangles
2916
+ } : void 0
2917
+ };
2918
+ }, [d, l, g]), C = (p) => p === 0 ? "0 B" : p < 1024 ? `${v(p, 0)} B` : p < 1024 * 1024 ? `${v(p / 1024, 2)} KB` : p < 1024 * 1024 * 1024 ? `${v(p / (1024 * 1024), 2)} MB` : `${v(p / (1024 * 1024 * 1024), 2)} GB`, h = () => {
2919
+ t(u), y(!1);
2920
+ }, m = () => {
2921
+ const p = a(M);
2922
+ f(p), t(p), y(!1);
2923
+ }, S = () => {
2924
+ f(n || {}), y(!1);
2925
+ }, z = L(() => {
2926
+ const p = e.filter((P) => P.severity === "error").length, T = e.filter((P) => P.severity === "warning").length;
2927
+ return { errors: p, warnings: T };
2928
+ }, [e]);
2929
+ return /* @__PURE__ */ c("div", { style: { padding: i.spacing.md }, children: [
2930
+ /* @__PURE__ */ c("div", { style: {
2931
+ backgroundColor: i.colors.surface,
2932
+ borderRadius: i.borderRadius.md,
2933
+ padding: i.spacing.md,
2934
+ marginBottom: i.spacing.lg,
2935
+ border: `1px solid ${i.colors.border}`
2936
+ }, children: [
2937
+ /* @__PURE__ */ c("div", { style: {
2938
+ display: "flex",
2939
+ alignItems: "center",
2940
+ justifyContent: "space-between",
2941
+ marginBottom: i.spacing.md
2942
+ }, children: [
2943
+ /* @__PURE__ */ s("div", { style: {
2944
+ fontSize: i.typography.fontSize.sm,
2945
+ fontWeight: 600,
2946
+ color: i.colors.text
2947
+ }, children: "Budget Status" }),
2948
+ /* @__PURE__ */ c("div", { style: {
2949
+ display: "flex",
2950
+ gap: i.spacing.sm,
2951
+ alignItems: "center"
2952
+ }, children: [
2953
+ z.errors > 0 && /* @__PURE__ */ s(V, { severity: "error", count: z.errors }),
2954
+ z.warnings > 0 && /* @__PURE__ */ s(V, { severity: "warning", count: z.warnings }),
2955
+ !n && /* @__PURE__ */ s("div", { style: {
2956
+ fontSize: i.typography.fontSize.xs,
2957
+ color: i.colors.textSecondary
2958
+ }, children: "No budget configured" })
2959
+ ] })
2960
+ ] }),
2961
+ n ? /* @__PURE__ */ c("div", { style: {
2962
+ display: "grid",
2963
+ gridTemplateColumns: "repeat(auto-fit, minmax(150px, 1fr))",
2964
+ gap: i.spacing.sm
2965
+ }, children: [
2966
+ n.fps && /* @__PURE__ */ s(
2967
+ x,
2968
+ {
2969
+ label: "FPS Min",
2970
+ value: n.fps.min,
2971
+ unit: "FPS"
2972
+ }
2973
+ ),
2974
+ n.frameTime && /* @__PURE__ */ s(
2975
+ x,
2976
+ {
2977
+ label: "Frame Time Max",
2978
+ value: `${n.frameTime.max.toFixed(2)}ms`
2979
+ }
2980
+ ),
2981
+ n.memory?.max && /* @__PURE__ */ s(
2982
+ x,
2983
+ {
2984
+ label: "Memory Max",
2985
+ value: C(n.memory.max)
2986
+ }
2987
+ ),
2988
+ n.gpu?.drawCalls?.max && /* @__PURE__ */ s(
2989
+ x,
2990
+ {
2991
+ label: "Draw Calls Max",
2992
+ value: n.gpu.drawCalls.max.toLocaleString()
2993
+ }
2994
+ ),
2995
+ n.gpu?.triangles?.max && /* @__PURE__ */ s(
2996
+ x,
2997
+ {
2998
+ label: "Triangles Max",
2999
+ value: n.gpu.triangles.max.toLocaleString()
3000
+ }
3001
+ )
3002
+ ] }) : /* @__PURE__ */ s("div", { style: {
3003
+ padding: i.spacing.md,
3004
+ textAlign: "center",
3005
+ color: i.colors.textSecondary,
3006
+ fontSize: i.typography.fontSize.sm
3007
+ }, children: "Configure a budget to start monitoring performance thresholds" })
3008
+ ] }),
3009
+ /* @__PURE__ */ c("div", { style: {
3010
+ backgroundColor: i.colors.surface,
3011
+ borderRadius: i.borderRadius.md,
3012
+ padding: i.spacing.md,
3013
+ marginBottom: i.spacing.lg,
3014
+ border: `1px solid ${i.colors.border}`
3015
+ }, children: [
3016
+ /* @__PURE__ */ s("div", { style: {
3017
+ fontSize: i.typography.fontSize.sm,
3018
+ fontWeight: 600,
3019
+ color: i.colors.text,
3020
+ marginBottom: i.spacing.md
3021
+ }, children: "Budget Configuration" }),
3022
+ w ? /* @__PURE__ */ c("div", { children: [
3023
+ /* @__PURE__ */ c("div", { style: {
3024
+ display: "grid",
3025
+ gap: i.spacing.sm,
3026
+ marginBottom: i.spacing.md
3027
+ }, children: [
3028
+ /* @__PURE__ */ c("div", { children: [
3029
+ /* @__PURE__ */ s("label", { style: {
3030
+ display: "block",
3031
+ fontSize: i.typography.fontSize.xs,
3032
+ color: i.colors.textSecondary,
3033
+ marginBottom: i.spacing.xs
3034
+ }, children: "FPS Minimum" }),
3035
+ /* @__PURE__ */ s(
3036
+ "input",
3037
+ {
3038
+ type: "number",
3039
+ value: u.fps?.min || "",
3040
+ onChange: (p) => f({
3041
+ ...u,
3042
+ fps: { min: parseInt(p.target.value) || 0 }
3043
+ }),
3044
+ placeholder: "60",
3045
+ style: {
3046
+ width: "100%",
3047
+ padding: i.spacing.sm,
3048
+ backgroundColor: i.colors.background,
3049
+ border: `1px solid ${i.colors.border}`,
3050
+ borderRadius: i.borderRadius.sm,
3051
+ color: i.colors.text,
3052
+ fontSize: i.typography.fontSize.sm
3053
+ }
3054
+ }
3055
+ )
3056
+ ] }),
3057
+ /* @__PURE__ */ c("div", { children: [
3058
+ /* @__PURE__ */ s("label", { style: {
3059
+ display: "block",
3060
+ fontSize: i.typography.fontSize.xs,
3061
+ color: i.colors.textSecondary,
3062
+ marginBottom: i.spacing.xs
3063
+ }, children: "Frame Time Maximum (ms)" }),
3064
+ /* @__PURE__ */ s(
3065
+ "input",
3066
+ {
3067
+ type: "number",
3068
+ value: u.frameTime?.max || "",
3069
+ onChange: (p) => f({
3070
+ ...u,
3071
+ frameTime: { max: parseFloat(p.target.value) || 0 }
3072
+ }),
3073
+ placeholder: "16.67",
3074
+ step: "0.1",
3075
+ style: {
3076
+ width: "100%",
3077
+ padding: i.spacing.sm,
3078
+ backgroundColor: i.colors.background,
3079
+ border: `1px solid ${i.colors.border}`,
3080
+ borderRadius: i.borderRadius.sm,
3081
+ color: i.colors.text,
3082
+ fontSize: i.typography.fontSize.sm
3083
+ }
3084
+ }
3085
+ )
3086
+ ] }),
3087
+ /* @__PURE__ */ c("div", { children: [
3088
+ /* @__PURE__ */ s("label", { style: {
3089
+ display: "block",
3090
+ fontSize: i.typography.fontSize.xs,
3091
+ color: i.colors.textSecondary,
3092
+ marginBottom: i.spacing.xs
3093
+ }, children: "Memory Maximum (MB)" }),
3094
+ /* @__PURE__ */ s(
3095
+ "input",
3096
+ {
3097
+ type: "number",
3098
+ value: u.memory?.max ? u.memory.max / (1024 * 1024) : "",
3099
+ onChange: (p) => f({
3100
+ ...u,
3101
+ memory: {
3102
+ ...u.memory,
3103
+ max: (parseFloat(p.target.value) || 0) * 1024 * 1024
3104
+ }
3105
+ }),
3106
+ placeholder: "512",
3107
+ step: "1",
3108
+ style: {
3109
+ width: "100%",
3110
+ padding: i.spacing.sm,
3111
+ backgroundColor: i.colors.background,
3112
+ border: `1px solid ${i.colors.border}`,
3113
+ borderRadius: i.borderRadius.sm,
3114
+ color: i.colors.text,
3115
+ fontSize: i.typography.fontSize.sm
3116
+ }
3117
+ }
3118
+ )
3119
+ ] }),
3120
+ /* @__PURE__ */ c("div", { children: [
3121
+ /* @__PURE__ */ s("label", { style: {
3122
+ display: "block",
3123
+ fontSize: i.typography.fontSize.xs,
3124
+ color: i.colors.textSecondary,
3125
+ marginBottom: i.spacing.xs
3126
+ }, children: "Draw Calls Maximum" }),
3127
+ /* @__PURE__ */ s(
3128
+ "input",
3129
+ {
3130
+ type: "number",
3131
+ value: u.gpu?.drawCalls?.max || "",
3132
+ onChange: (p) => f({
3133
+ ...u,
3134
+ gpu: {
3135
+ ...u.gpu,
3136
+ drawCalls: { max: parseInt(p.target.value) || 0 }
3137
+ }
3138
+ }),
3139
+ placeholder: "100",
3140
+ style: {
3141
+ width: "100%",
3142
+ padding: i.spacing.sm,
3143
+ backgroundColor: i.colors.background,
3144
+ border: `1px solid ${i.colors.border}`,
3145
+ borderRadius: i.borderRadius.sm,
3146
+ color: i.colors.text,
3147
+ fontSize: i.typography.fontSize.sm
3148
+ }
3149
+ }
3150
+ )
3151
+ ] }),
3152
+ /* @__PURE__ */ c("div", { children: [
3153
+ /* @__PURE__ */ s("label", { style: {
3154
+ display: "block",
3155
+ fontSize: i.typography.fontSize.xs,
3156
+ color: i.colors.textSecondary,
3157
+ marginBottom: i.spacing.xs
3158
+ }, children: "Triangles Maximum" }),
3159
+ /* @__PURE__ */ s(
3160
+ "input",
3161
+ {
3162
+ type: "number",
3163
+ value: u.gpu?.triangles?.max || "",
3164
+ onChange: (p) => f({
3165
+ ...u,
3166
+ gpu: {
3167
+ ...u.gpu,
3168
+ triangles: { max: parseInt(p.target.value) || 0 }
3169
+ }
3170
+ }),
3171
+ placeholder: "100000",
3172
+ style: {
3173
+ width: "100%",
3174
+ padding: i.spacing.sm,
3175
+ backgroundColor: i.colors.background,
3176
+ border: `1px solid ${i.colors.border}`,
3177
+ borderRadius: i.borderRadius.sm,
3178
+ color: i.colors.text,
3179
+ fontSize: i.typography.fontSize.sm
3180
+ }
3181
+ }
3182
+ )
3183
+ ] })
3184
+ ] }),
3185
+ /* @__PURE__ */ c("div", { style: {
3186
+ display: "flex",
3187
+ gap: i.spacing.sm
3188
+ }, children: [
3189
+ /* @__PURE__ */ s(
3190
+ "button",
3191
+ {
3192
+ onClick: h,
3193
+ style: {
3194
+ padding: `${i.spacing.sm} ${i.spacing.md}`,
3195
+ backgroundColor: i.colors.success,
3196
+ color: i.colors.background,
3197
+ border: "none",
3198
+ borderRadius: i.borderRadius.sm,
3199
+ cursor: "pointer",
3200
+ fontSize: i.typography.fontSize.sm,
3201
+ fontWeight: 600
3202
+ },
3203
+ children: "Save"
3204
+ }
3205
+ ),
3206
+ /* @__PURE__ */ s(
3207
+ "button",
3208
+ {
3209
+ onClick: S,
3210
+ style: {
3211
+ padding: `${i.spacing.sm} ${i.spacing.md}`,
3212
+ backgroundColor: "transparent",
3213
+ color: i.colors.textSecondary,
3214
+ border: `1px solid ${i.colors.border}`,
3215
+ borderRadius: i.borderRadius.sm,
3216
+ cursor: "pointer",
3217
+ fontSize: i.typography.fontSize.sm,
3218
+ fontWeight: 600
3219
+ },
3220
+ children: "Cancel"
3221
+ }
3222
+ )
3223
+ ] })
3224
+ ] }) : /* @__PURE__ */ c("div", { style: {
3225
+ display: "flex",
3226
+ gap: i.spacing.sm,
3227
+ flexWrap: "wrap"
3228
+ }, children: [
3229
+ /* @__PURE__ */ s(
3230
+ "button",
3231
+ {
3232
+ onClick: () => y(!0),
3233
+ style: {
3234
+ padding: `${i.spacing.sm} ${i.spacing.md}`,
3235
+ backgroundColor: i.colors.primary,
3236
+ color: i.colors.background,
3237
+ border: "none",
3238
+ borderRadius: i.borderRadius.sm,
3239
+ cursor: "pointer",
3240
+ fontSize: i.typography.fontSize.sm,
3241
+ fontWeight: 600,
3242
+ transition: i.transitions.fast
3243
+ },
3244
+ onMouseEnter: (p) => {
3245
+ p.currentTarget.style.backgroundColor = i.colors.primaryHover;
3246
+ },
3247
+ onMouseLeave: (p) => {
3248
+ p.currentTarget.style.backgroundColor = i.colors.primary;
3249
+ },
3250
+ children: n ? "Edit Budget" : "Set Budget"
3251
+ }
3252
+ ),
3253
+ !n && /* @__PURE__ */ s(
3254
+ "button",
3255
+ {
3256
+ onClick: m,
3257
+ style: {
3258
+ padding: `${i.spacing.sm} ${i.spacing.md}`,
3259
+ backgroundColor: "transparent",
3260
+ color: i.colors.primary,
3261
+ border: `1px solid ${i.colors.primary}`,
3262
+ borderRadius: i.borderRadius.sm,
3263
+ cursor: "pointer",
3264
+ fontSize: i.typography.fontSize.sm,
3265
+ fontWeight: 600,
3266
+ transition: i.transitions.fast
3267
+ },
3268
+ onMouseEnter: (p) => {
3269
+ p.currentTarget.style.backgroundColor = `${i.colors.primary}20`;
3270
+ },
3271
+ onMouseLeave: (p) => {
3272
+ p.currentTarget.style.backgroundColor = "transparent";
3273
+ },
3274
+ children: "Use Recommended"
3275
+ }
3276
+ ),
3277
+ n && /* @__PURE__ */ s(
3278
+ "button",
3279
+ {
3280
+ onClick: () => {
3281
+ window.confirm("Are you sure you want to delete the current budget?") && o();
3282
+ },
3283
+ style: {
3284
+ padding: `${i.spacing.sm} ${i.spacing.md}`,
3285
+ backgroundColor: "transparent",
3286
+ color: i.colors.error,
3287
+ border: `1px solid ${i.colors.error}`,
3288
+ borderRadius: i.borderRadius.sm,
3289
+ cursor: "pointer",
3290
+ fontSize: i.typography.fontSize.sm,
3291
+ fontWeight: 600,
3292
+ transition: i.transitions.fast
3293
+ },
3294
+ onMouseEnter: (p) => {
3295
+ p.currentTarget.style.backgroundColor = `${i.colors.error}20`;
3296
+ },
3297
+ onMouseLeave: (p) => {
3298
+ p.currentTarget.style.backgroundColor = "transparent";
3299
+ },
3300
+ children: "Delete Budget"
3301
+ }
3302
+ )
3303
+ ] })
3304
+ ] }),
3305
+ e.length > 0 && /* @__PURE__ */ c("div", { style: {
3306
+ backgroundColor: i.colors.surface,
3307
+ borderRadius: i.borderRadius.md,
3308
+ padding: i.spacing.md,
3309
+ border: `1px solid ${i.colors.border}`
3310
+ }, children: [
3311
+ /* @__PURE__ */ c("div", { style: {
3312
+ display: "flex",
3313
+ alignItems: "center",
3314
+ justifyContent: "space-between",
3315
+ marginBottom: i.spacing.md
3316
+ }, children: [
3317
+ /* @__PURE__ */ c("div", { style: {
3318
+ fontSize: i.typography.fontSize.sm,
3319
+ fontWeight: 600,
3320
+ color: i.colors.text
3321
+ }, children: [
3322
+ "Recent Violations (",
3323
+ e.length,
3324
+ ")"
3325
+ ] }),
3326
+ /* @__PURE__ */ s(
3327
+ "button",
3328
+ {
3329
+ onClick: r,
3330
+ style: {
3331
+ padding: `${i.spacing.xs} ${i.spacing.sm}`,
3332
+ backgroundColor: "transparent",
3333
+ color: i.colors.textSecondary,
3334
+ border: "none",
3335
+ cursor: "pointer",
3336
+ fontSize: i.typography.fontSize.xs
3337
+ },
3338
+ children: "Clear"
3339
+ }
3340
+ )
3341
+ ] }),
3342
+ /* @__PURE__ */ s("div", { style: {
3343
+ maxHeight: "200px",
3344
+ overflowY: "auto",
3345
+ fontSize: i.typography.fontSize.xs,
3346
+ fontFamily: i.typography.fontFamilyMono
3347
+ }, children: e.slice(-10).reverse().map((p) => /* @__PURE__ */ c(
3348
+ "div",
3349
+ {
3350
+ style: {
3351
+ padding: i.spacing.sm,
3352
+ borderBottom: `1px solid ${i.colors.border}`,
3353
+ display: "flex",
3354
+ justifyContent: "space-between",
3355
+ alignItems: "center"
3356
+ },
3357
+ children: [
3358
+ /* @__PURE__ */ c("div", { children: [
3359
+ /* @__PURE__ */ s("div", { style: {
3360
+ color: p.severity === "error" ? i.colors.error : i.colors.warning,
3361
+ fontWeight: 600
3362
+ }, children: p.metric }),
3363
+ /* @__PURE__ */ s("div", { style: {
3364
+ color: i.colors.textSecondary,
3365
+ marginTop: i.spacing.xs
3366
+ }, children: p.message })
3367
+ ] }),
3368
+ /* @__PURE__ */ s(V, { severity: p.severity })
3369
+ ]
3370
+ },
3371
+ p.id
3372
+ )) })
3373
+ ] })
3374
+ ] });
3375
+ };
3376
+ class je {
3377
+ componentStats = /* @__PURE__ */ new Map();
3378
+ recentRenders = [];
3379
+ totalRenders = 0;
3380
+ maxRecentRenders = 100;
3381
+ slowThreshold = 16;
3382
+ // ms (1 frame at 60fps)
3383
+ frequentThreshold = 10;
3384
+ // renders per second
3385
+ // React Profiler callback
3386
+ onRenderCallback = (e, t, r, o, a, d) => {
3387
+ const l = this.getComponentName(e), g = performance.now(), i = {
3388
+ id: e,
3389
+ name: l,
3390
+ phase: t,
3391
+ actualDuration: r,
3392
+ baseDuration: o,
3393
+ startTime: a,
3394
+ commitTime: d,
3395
+ timestamp: g
3396
+ };
3397
+ this.recentRenders.push(i), this.recentRenders.length > this.maxRecentRenders && this.recentRenders.shift(), this.updateComponentStats(l, i), _.onReactRender(r), this.totalRenders++;
3398
+ };
3399
+ getComponentName(e) {
3400
+ return e.split(":")[0] || e;
3401
+ }
3402
+ updateComponentStats(e, t) {
3403
+ let r = this.componentStats.get(e);
3404
+ r || (r = {
3405
+ name: e,
3406
+ renderCount: 0,
3407
+ totalDuration: 0,
3408
+ averageDuration: 0,
3409
+ maxDuration: 0,
3410
+ minDuration: 1 / 0,
3411
+ lastRenderTime: 0,
3412
+ phases: {
3413
+ mount: 0,
3414
+ update: 0
3415
+ }
3416
+ }, this.componentStats.set(e, r)), r.renderCount++, r.totalDuration += t.actualDuration, r.averageDuration = r.totalDuration / r.renderCount, r.maxDuration = Math.max(r.maxDuration, t.actualDuration), r.minDuration = Math.min(r.minDuration, t.actualDuration), r.lastRenderTime = t.timestamp, t.phase === "mount" ? r.phases.mount++ : r.phases.update++;
3417
+ }
3418
+ getPerformanceData() {
3419
+ const e = new Map(this.componentStats), t = Array.from(e.values()).filter((d) => d.averageDuration > this.slowThreshold).sort((d, l) => l.averageDuration - d.averageDuration), r = performance.now(), o = 1e3, a = Array.from(e.values()).filter((d) => r - d.lastRenderTime > o ? !1 : d.renderCount / (o / 1e3) > this.frequentThreshold).sort((d, l) => l.renderCount - d.renderCount);
3420
+ return {
3421
+ components: e,
3422
+ recentRenders: [...this.recentRenders],
3423
+ totalRenders: this.totalRenders,
3424
+ slowComponents: t,
3425
+ frequentRenders: a,
3426
+ timestamp: performance.now()
3427
+ };
3428
+ }
3429
+ getComponentStats(e) {
3430
+ return this.componentStats.get(e) || null;
3431
+ }
3432
+ getSlowComponents() {
3433
+ return this.getPerformanceData().slowComponents;
3434
+ }
3435
+ getFrequentRenders() {
3436
+ return this.getPerformanceData().frequentRenders;
3437
+ }
3438
+ reset() {
3439
+ this.componentStats.clear(), this.recentRenders = [], this.totalRenders = 0;
3440
+ }
3441
+ }
3442
+ const qe = new je();
3443
+ function Ue() {
3444
+ const [n, e] = B(null);
3445
+ return A(() => {
3446
+ const t = () => {
3447
+ if (!k.getPaused()) {
3448
+ const a = qe.getPerformanceData();
3449
+ e(a);
3450
+ }
3451
+ };
3452
+ t();
3453
+ const r = setInterval(t, 500), o = k.subscribe((a) => {
3454
+ a || t();
3455
+ });
3456
+ return () => {
3457
+ clearInterval(r), o();
3458
+ };
3459
+ }, []), n;
3460
+ }
3461
+ const Ne = () => {
3462
+ const n = Ue(), e = F, t = (o) => o < 0.1 ? `${v(o * 1e3, 0)} μs` : o < 1 ? `${v(o, 2)} ms` : `${v(o, 2)} ms`, r = L(() => n ? Array.from(n.components.values()).sort((o, a) => a.totalDuration - o.totalDuration) : [], [n]);
3463
+ return n ? /* @__PURE__ */ c("div", { style: { padding: e.spacing.md }, children: [
3464
+ /* @__PURE__ */ c("div", { style: {
3465
+ backgroundColor: e.colors.surface,
3466
+ borderRadius: e.borderRadius.md,
3467
+ padding: e.spacing.md,
3468
+ marginBottom: e.spacing.lg,
3469
+ border: `1px solid ${e.colors.border}`
3470
+ }, children: [
3471
+ /* @__PURE__ */ s("div", { style: {
3472
+ fontSize: e.typography.fontSize.sm,
3473
+ fontWeight: 600,
3474
+ color: e.colors.text,
3475
+ marginBottom: e.spacing.sm
3476
+ }, children: "Overview" }),
3477
+ /* @__PURE__ */ c("div", { style: {
3478
+ display: "grid",
3479
+ gridTemplateColumns: "repeat(auto-fit, minmax(120px, 1fr))",
3480
+ gap: e.spacing.sm
3481
+ }, children: [
3482
+ /* @__PURE__ */ s(
3483
+ x,
3484
+ {
3485
+ label: "Total Renders",
3486
+ value: n.totalRenders.toLocaleString()
3487
+ }
3488
+ ),
3489
+ /* @__PURE__ */ s(
3490
+ x,
3491
+ {
3492
+ label: "Components",
3493
+ value: n.components.size.toLocaleString()
3494
+ }
3495
+ ),
3496
+ /* @__PURE__ */ s(
3497
+ x,
3498
+ {
3499
+ label: "Slow Components",
3500
+ value: n.slowComponents.length.toLocaleString(),
3501
+ status: n.slowComponents.length > 0 ? "warning" : "good"
3502
+ }
3503
+ ),
3504
+ /* @__PURE__ */ s(
3505
+ x,
3506
+ {
3507
+ label: "Frequent Renders",
3508
+ value: n.frequentRenders.length.toLocaleString(),
3509
+ status: n.frequentRenders.length > 0 ? "warning" : "good"
3510
+ }
3511
+ )
3512
+ ] })
3513
+ ] }),
3514
+ n.slowComponents.length > 0 && /* @__PURE__ */ c("div", { style: {
3515
+ backgroundColor: e.colors.surface,
3516
+ borderRadius: e.borderRadius.md,
3517
+ padding: e.spacing.md,
3518
+ marginBottom: e.spacing.lg,
3519
+ border: `1px solid ${e.colors.warning}40`
3520
+ }, children: [
3521
+ /* @__PURE__ */ c("div", { style: {
3522
+ display: "flex",
3523
+ alignItems: "center",
3524
+ gap: e.spacing.sm,
3525
+ marginBottom: e.spacing.sm
3526
+ }, children: [
3527
+ /* @__PURE__ */ s(V, { severity: "warning", count: n.slowComponents.length }),
3528
+ /* @__PURE__ */ s("div", { style: {
3529
+ fontSize: e.typography.fontSize.sm,
3530
+ fontWeight: 600,
3531
+ color: e.colors.text
3532
+ }, children: "Slow Components (avg > 16ms)" })
3533
+ ] }),
3534
+ /* @__PURE__ */ s("div", { style: {
3535
+ fontSize: e.typography.fontSize.xs,
3536
+ color: e.colors.textSecondary,
3537
+ fontFamily: e.typography.fontFamilyMono
3538
+ }, children: n.slowComponents.slice(0, 5).map((o) => /* @__PURE__ */ c("div", { style: { marginBottom: e.spacing.xs }, children: [
3539
+ o.name,
3540
+ ": ",
3541
+ t(o.averageDuration),
3542
+ " avg (",
3543
+ o.renderCount,
3544
+ " renders)"
3545
+ ] }, o.name)) })
3546
+ ] }),
3547
+ n.frequentRenders.length > 0 && /* @__PURE__ */ c("div", { style: {
3548
+ backgroundColor: e.colors.surface,
3549
+ borderRadius: e.borderRadius.md,
3550
+ padding: e.spacing.md,
3551
+ marginBottom: e.spacing.lg,
3552
+ border: `1px solid ${e.colors.warning}40`
3553
+ }, children: [
3554
+ /* @__PURE__ */ c("div", { style: {
3555
+ display: "flex",
3556
+ alignItems: "center",
3557
+ gap: e.spacing.sm,
3558
+ marginBottom: e.spacing.sm
3559
+ }, children: [
3560
+ /* @__PURE__ */ s(V, { severity: "warning", count: n.frequentRenders.length }),
3561
+ /* @__PURE__ */ s("div", { style: {
3562
+ fontSize: e.typography.fontSize.sm,
3563
+ fontWeight: 600,
3564
+ color: e.colors.text
3565
+ }, children: "Frequent Renders (> 10 renders/sec)" })
3566
+ ] }),
3567
+ /* @__PURE__ */ s("div", { style: {
3568
+ fontSize: e.typography.fontSize.xs,
3569
+ color: e.colors.textSecondary,
3570
+ fontFamily: e.typography.fontFamilyMono
3571
+ }, children: n.frequentRenders.slice(0, 5).map((o) => /* @__PURE__ */ c("div", { style: { marginBottom: e.spacing.xs }, children: [
3572
+ o.name,
3573
+ ": ",
3574
+ o.renderCount,
3575
+ " renders"
3576
+ ] }, o.name)) })
3577
+ ] }),
3578
+ /* @__PURE__ */ c("div", { style: {
3579
+ backgroundColor: e.colors.surface,
3580
+ borderRadius: e.borderRadius.md,
3581
+ padding: e.spacing.md,
3582
+ border: `1px solid ${e.colors.border}`
3583
+ }, children: [
3584
+ /* @__PURE__ */ c("div", { style: {
3585
+ fontSize: e.typography.fontSize.sm,
3586
+ fontWeight: 600,
3587
+ color: e.colors.text,
3588
+ marginBottom: e.spacing.sm
3589
+ }, children: [
3590
+ "Components (",
3591
+ r.length,
3592
+ ")"
3593
+ ] }),
3594
+ /* @__PURE__ */ s("div", { style: {
3595
+ maxHeight: "400px",
3596
+ overflowY: "auto"
3597
+ }, children: r.length === 0 ? /* @__PURE__ */ s("div", { style: {
3598
+ padding: e.spacing.md,
3599
+ textAlign: "center",
3600
+ color: e.colors.textSecondary,
3601
+ fontSize: e.typography.fontSize.sm
3602
+ }, children: "No components profiled yet" }) : /* @__PURE__ */ s(Ye, { components: r, formatTime: t }) })
3603
+ ] })
3604
+ ] }) : /* @__PURE__ */ s("div", { style: {
3605
+ padding: e.spacing.lg,
3606
+ textAlign: "center",
3607
+ color: e.colors.textSecondary,
3608
+ fontSize: e.typography.fontSize.sm
3609
+ }, children: "Aucune donnée React disponible. Enveloppez vos composants avec <ReactProfiler> pour commencer le monitoring." });
3610
+ }, Ye = ({ components: n, formatTime: e }) => {
3611
+ const t = F;
3612
+ return /* @__PURE__ */ c("table", { style: {
3613
+ width: "100%",
3614
+ borderCollapse: "collapse",
3615
+ fontSize: t.typography.fontSize.xs,
3616
+ fontFamily: t.typography.fontFamilyMono
3617
+ }, children: [
3618
+ /* @__PURE__ */ s("thead", { children: /* @__PURE__ */ c("tr", { style: {
3619
+ borderBottom: `1px solid ${t.colors.border}`
3620
+ }, children: [
3621
+ /* @__PURE__ */ s("th", { style: {
3622
+ textAlign: "left",
3623
+ padding: t.spacing.sm,
3624
+ color: t.colors.textSecondary,
3625
+ fontWeight: 600
3626
+ }, children: "Component" }),
3627
+ /* @__PURE__ */ s("th", { style: {
3628
+ textAlign: "right",
3629
+ padding: t.spacing.sm,
3630
+ color: t.colors.textSecondary,
3631
+ fontWeight: 600
3632
+ }, children: "Renders" }),
3633
+ /* @__PURE__ */ s("th", { style: {
3634
+ textAlign: "right",
3635
+ padding: t.spacing.sm,
3636
+ color: t.colors.textSecondary,
3637
+ fontWeight: 600
3638
+ }, children: "Avg Time" }),
3639
+ /* @__PURE__ */ s("th", { style: {
3640
+ textAlign: "right",
3641
+ padding: t.spacing.sm,
3642
+ color: t.colors.textSecondary,
3643
+ fontWeight: 600
3644
+ }, children: "Max Time" }),
3645
+ /* @__PURE__ */ s("th", { style: {
3646
+ textAlign: "right",
3647
+ padding: t.spacing.sm,
3648
+ color: t.colors.textSecondary,
3649
+ fontWeight: 600
3650
+ }, children: "Total Time" })
3651
+ ] }) }),
3652
+ /* @__PURE__ */ s("tbody", { children: n.map((r) => {
3653
+ const o = r.averageDuration > 16, a = r.renderCount > 10;
3654
+ return /* @__PURE__ */ c(
3655
+ "tr",
3656
+ {
3657
+ style: {
3658
+ borderBottom: `1px solid ${t.colors.border}`,
3659
+ backgroundColor: o || a ? `${t.colors.warning}10` : "transparent"
3660
+ },
3661
+ children: [
3662
+ /* @__PURE__ */ s("td", { style: {
3663
+ padding: t.spacing.sm,
3664
+ color: t.colors.text,
3665
+ fontWeight: o || a ? 600 : 400
3666
+ }, children: r.name }),
3667
+ /* @__PURE__ */ s("td", { style: {
3668
+ textAlign: "right",
3669
+ padding: t.spacing.sm,
3670
+ color: t.colors.textSecondary
3671
+ }, children: r.renderCount.toLocaleString() }),
3672
+ /* @__PURE__ */ s("td", { style: {
3673
+ textAlign: "right",
3674
+ padding: t.spacing.sm,
3675
+ color: o ? t.colors.warning : t.colors.textSecondary,
3676
+ fontWeight: o ? 600 : 400
3677
+ }, children: e(r.averageDuration) }),
3678
+ /* @__PURE__ */ s("td", { style: {
3679
+ textAlign: "right",
3680
+ padding: t.spacing.sm,
3681
+ color: t.colors.textSecondary
3682
+ }, children: e(r.maxDuration) }),
3683
+ /* @__PURE__ */ s("td", { style: {
3684
+ textAlign: "right",
3685
+ padding: t.spacing.sm,
3686
+ color: t.colors.textSecondary
3687
+ }, children: e(r.totalDuration) })
3688
+ ]
3689
+ },
3690
+ r.name
3691
+ );
3692
+ }) })
3693
+ ] });
3694
+ };
3695
+ class Je {
3696
+ functionCalls = /* @__PURE__ */ new Map();
3697
+ callHistory = [];
3698
+ maxHistorySize = 1e3;
3699
+ hotPathThreshold = 5;
3700
+ // ms - functions taking longer than this are considered hot
3701
+ frequencyThreshold = 10;
3702
+ // calls per second
3703
+ recordCall(e, t, r) {
3704
+ const o = performance.now();
3705
+ let a = this.functionCalls.get(e);
3706
+ a || (a = {
3707
+ name: e,
3708
+ duration: 0,
3709
+ timestamp: o,
3710
+ callCount: 0,
3711
+ averageDuration: 0,
3712
+ maxDuration: 0,
3713
+ stack: r || []
3714
+ }, this.functionCalls.set(e, a)), a.callCount++, a.duration += t, a.averageDuration = a.duration / a.callCount, a.maxDuration = Math.max(a.maxDuration, t), a.timestamp = o, this.callHistory.push({ name: e, duration: t, timestamp: o }), this.callHistory.length > this.maxHistorySize && this.callHistory.shift();
3715
+ }
3716
+ analyze(e) {
3717
+ const t = performance.now(), r = 5e3, o = t - r, a = this.callHistory.filter((u) => u.timestamp >= o), d = /* @__PURE__ */ new Map();
3718
+ a.forEach((u) => {
3719
+ const f = d.get(u.name) || 0;
3720
+ d.set(u.name, f + 1);
3721
+ });
3722
+ const l = /* @__PURE__ */ new Map();
3723
+ d.forEach((u, f) => {
3724
+ l.set(f, u / r * 1e3);
3725
+ });
3726
+ const g = [], i = [], w = [];
3727
+ this.functionCalls.forEach((u, f) => {
3728
+ const M = l.get(f) || 0, C = u.averageDuration > this.hotPathThreshold, h = M > this.frequencyThreshold;
3729
+ if (C || h) {
3730
+ const S = u.averageDuration > 16 ? "high" : u.averageDuration > 8 ? "medium" : "low", z = [];
3731
+ C && z.push(`Optimize ${f} - average duration: ${u.averageDuration.toFixed(2)}ms`), h && z.push(`Reduce calls to ${f} - ${M.toFixed(1)} calls/sec`), u.maxDuration > u.averageDuration * 2 && z.push(`Investigate performance spikes in ${f} - max: ${u.maxDuration.toFixed(2)}ms`);
3732
+ const p = {
3733
+ id: `hotpath-${f}-${Date.now()}`,
3734
+ path: [f],
3735
+ totalDuration: u.duration,
3736
+ averageDuration: u.averageDuration,
3737
+ callCount: u.callCount,
3738
+ frequency: M,
3739
+ impact: S,
3740
+ recommendations: z
3741
+ };
3742
+ g.push(p), C && w.push(p);
3743
+ }
3744
+ i.push(u);
3745
+ }), i.sort((u, f) => f.duration - u.duration);
3746
+ const y = [];
3747
+ return w.length > 0 && y.push(`Found ${w.length} performance bottlenecks`), g.length > 5 && y.push("Consider optimizing multiple hot paths simultaneously"), e && e.forEach((u) => {
3748
+ u.avg > this.hotPathThreshold && y.push(`Hook "${u.name}" takes ${u.avg.toFixed(2)}ms on average`);
3749
+ }), {
3750
+ hotPaths: g.sort((u, f) => f.averageDuration - u.averageDuration),
3751
+ topFunctions: i.slice(0, 10),
3752
+ // Top 10
3753
+ bottlenecks: w.sort((u, f) => f.averageDuration - u.averageDuration),
3754
+ recommendations: y,
3755
+ timestamp: t
3756
+ };
3757
+ }
3758
+ detectCallChain(e) {
3759
+ const t = /* @__PURE__ */ new Map();
3760
+ this.callHistory.forEach((o) => {
3761
+ const a = o.name;
3762
+ let d = t.get(a);
3763
+ d || (d = { path: [o.name], duration: 0, count: 0 }, t.set(a, d)), d.duration += o.duration, d.count++;
3764
+ });
3765
+ const r = [];
3766
+ return t.forEach((o, a) => {
3767
+ const d = o.duration / o.count;
3768
+ d > this.hotPathThreshold && r.push({
3769
+ id: `chain-${a}-${Date.now()}`,
3770
+ path: o.path,
3771
+ totalDuration: o.duration,
3772
+ averageDuration: d,
3773
+ callCount: o.count,
3774
+ frequency: o.count / 5,
3775
+ // Approximate
3776
+ impact: d > 16 ? "high" : d > 8 ? "medium" : "low",
3777
+ recommendations: [`Optimize call chain: ${o.path.join(" -> ")}`]
3778
+ });
3779
+ }), r;
3780
+ }
3781
+ reset() {
3782
+ this.functionCalls.clear(), this.callHistory = [];
3783
+ }
3784
+ getTopFunctions(e = 10) {
3785
+ return Array.from(this.functionCalls.values()).sort((t, r) => r.duration - t.duration).slice(0, e);
3786
+ }
3787
+ }
3788
+ const me = new Je(), Ke = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
3789
+ __proto__: null,
3790
+ hotPathDetector: me
3791
+ }, Symbol.toStringTag, { value: "Module" }));
3792
+ function Xe() {
3793
+ const [n, e] = B(null), t = J();
3794
+ return A(() => {
3795
+ const r = () => {
3796
+ if (!k.getPaused()) {
3797
+ const d = me.analyze(t?.entries);
3798
+ e(d);
3799
+ }
3800
+ };
3801
+ r();
3802
+ const o = setInterval(r, 2e3), a = k.subscribe((d) => {
3803
+ d || r();
3804
+ });
3805
+ return () => {
3806
+ clearInterval(o), a();
3807
+ };
3808
+ }, [t]), n;
3809
+ }
3810
+ const Ze = () => {
3811
+ const n = Xe(), e = F, t = (o) => o < 0.1 ? `${v(o * 1e3, 0)} μs` : o < 1 ? `${v(o, 2)} ms` : `${v(o, 2)} ms`, r = {
3812
+ high: e.colors.error,
3813
+ medium: e.colors.warning,
3814
+ low: e.colors.info
3815
+ };
3816
+ return n ? /* @__PURE__ */ c("div", { style: { padding: e.spacing.md }, children: [
3817
+ /* @__PURE__ */ c("div", { style: {
3818
+ backgroundColor: e.colors.surface,
3819
+ borderRadius: e.borderRadius.md,
3820
+ padding: e.spacing.md,
3821
+ marginBottom: e.spacing.lg,
3822
+ border: `1px solid ${e.colors.border}`
3823
+ }, children: [
3824
+ /* @__PURE__ */ s("div", { style: {
3825
+ fontSize: e.typography.fontSize.sm,
3826
+ fontWeight: 600,
3827
+ color: e.colors.text,
3828
+ marginBottom: e.spacing.sm
3829
+ }, children: "Overview" }),
3830
+ /* @__PURE__ */ c("div", { style: {
3831
+ display: "grid",
3832
+ gridTemplateColumns: "repeat(auto-fit, minmax(120px, 1fr))",
3833
+ gap: e.spacing.sm
3834
+ }, children: [
3835
+ /* @__PURE__ */ s(
3836
+ x,
3837
+ {
3838
+ label: "Hot Paths",
3839
+ value: n.hotPaths.length.toLocaleString(),
3840
+ status: n.hotPaths.length > 0 ? "warning" : "good"
3841
+ }
3842
+ ),
3843
+ /* @__PURE__ */ s(
3844
+ x,
3845
+ {
3846
+ label: "Bottlenecks",
3847
+ value: n.bottlenecks.length.toLocaleString(),
3848
+ status: n.bottlenecks.length > 0 ? "error" : "good"
3849
+ }
3850
+ ),
3851
+ /* @__PURE__ */ s(
3852
+ x,
3853
+ {
3854
+ label: "Top Functions",
3855
+ value: n.topFunctions.length.toLocaleString()
3856
+ }
3857
+ )
3858
+ ] })
3859
+ ] }),
3860
+ n.recommendations.length > 0 && /* @__PURE__ */ c("div", { style: {
3861
+ backgroundColor: e.colors.surface,
3862
+ borderRadius: e.borderRadius.md,
3863
+ padding: e.spacing.md,
3864
+ marginBottom: e.spacing.lg,
3865
+ border: `1px solid ${e.colors.warning}40`
3866
+ }, children: [
3867
+ /* @__PURE__ */ c("div", { style: {
3868
+ display: "flex",
3869
+ alignItems: "center",
3870
+ gap: e.spacing.sm,
3871
+ marginBottom: e.spacing.sm
3872
+ }, children: [
3873
+ /* @__PURE__ */ s(V, { severity: "warning" }),
3874
+ /* @__PURE__ */ s("div", { style: {
3875
+ fontSize: e.typography.fontSize.sm,
3876
+ fontWeight: 600,
3877
+ color: e.colors.text
3878
+ }, children: "Recommendations" })
3879
+ ] }),
3880
+ /* @__PURE__ */ s("div", { style: {
3881
+ fontSize: e.typography.fontSize.xs,
3882
+ color: e.colors.textSecondary,
3883
+ fontFamily: e.typography.fontFamilyMono
3884
+ }, children: n.recommendations.map((o, a) => /* @__PURE__ */ c("div", { style: { marginBottom: e.spacing.xs }, children: [
3885
+ "• ",
3886
+ o
3887
+ ] }, a)) })
3888
+ ] }),
3889
+ n.bottlenecks.length > 0 && /* @__PURE__ */ c("div", { style: {
3890
+ backgroundColor: e.colors.surface,
3891
+ borderRadius: e.borderRadius.md,
3892
+ padding: e.spacing.md,
3893
+ marginBottom: e.spacing.lg,
3894
+ border: `1px solid ${e.colors.error}40`
3895
+ }, children: [
3896
+ /* @__PURE__ */ c("div", { style: {
3897
+ display: "flex",
3898
+ alignItems: "center",
3899
+ gap: e.spacing.sm,
3900
+ marginBottom: e.spacing.sm
3901
+ }, children: [
3902
+ /* @__PURE__ */ s(V, { severity: "error", count: n.bottlenecks.length }),
3903
+ /* @__PURE__ */ s("div", { style: {
3904
+ fontSize: e.typography.fontSize.sm,
3905
+ fontWeight: 600,
3906
+ color: e.colors.text
3907
+ }, children: "Performance Bottlenecks" })
3908
+ ] }),
3909
+ /* @__PURE__ */ s("div", { style: {
3910
+ maxHeight: "300px",
3911
+ overflowY: "auto"
3912
+ }, children: n.bottlenecks.map((o) => /* @__PURE__ */ c(
3913
+ "div",
3914
+ {
3915
+ style: {
3916
+ padding: e.spacing.sm,
3917
+ borderBottom: `1px solid ${e.colors.border}`,
3918
+ backgroundColor: `${r[o.impact]}10`
3919
+ },
3920
+ children: [
3921
+ /* @__PURE__ */ c("div", { style: {
3922
+ display: "flex",
3923
+ justifyContent: "space-between",
3924
+ alignItems: "center",
3925
+ marginBottom: e.spacing.xs
3926
+ }, children: [
3927
+ /* @__PURE__ */ s("div", { style: {
3928
+ fontSize: e.typography.fontSize.sm,
3929
+ fontWeight: 600,
3930
+ color: r[o.impact],
3931
+ fontFamily: e.typography.fontFamilyMono
3932
+ }, children: o.path.join(" -> ") }),
3933
+ /* @__PURE__ */ c("div", { style: {
3934
+ fontSize: e.typography.fontSize.xs,
3935
+ color: e.colors.textSecondary
3936
+ }, children: [
3937
+ t(o.averageDuration),
3938
+ " avg"
3939
+ ] })
3940
+ ] }),
3941
+ /* @__PURE__ */ c("div", { style: {
3942
+ fontSize: e.typography.fontSize.xs,
3943
+ color: e.colors.textSecondary,
3944
+ marginBottom: e.spacing.xs
3945
+ }, children: [
3946
+ o.callCount.toLocaleString(),
3947
+ " calls • ",
3948
+ o.frequency.toFixed(1),
3949
+ " calls/sec"
3950
+ ] }),
3951
+ o.recommendations.length > 0 && /* @__PURE__ */ s("div", { style: {
3952
+ fontSize: e.typography.fontSize.xs,
3953
+ color: e.colors.textTertiary,
3954
+ fontStyle: "italic"
3955
+ }, children: o.recommendations[0] })
3956
+ ]
3957
+ },
3958
+ o.id
3959
+ )) })
3960
+ ] }),
3961
+ n.hotPaths.length > 0 && /* @__PURE__ */ c("div", { style: {
3962
+ backgroundColor: e.colors.surface,
3963
+ borderRadius: e.borderRadius.md,
3964
+ padding: e.spacing.md,
3965
+ marginBottom: e.spacing.lg,
3966
+ border: `1px solid ${e.colors.border}`
3967
+ }, children: [
3968
+ /* @__PURE__ */ c("div", { style: {
3969
+ fontSize: e.typography.fontSize.sm,
3970
+ fontWeight: 600,
3971
+ color: e.colors.text,
3972
+ marginBottom: e.spacing.sm
3973
+ }, children: [
3974
+ "Hot Paths (",
3975
+ n.hotPaths.length,
3976
+ ")"
3977
+ ] }),
3978
+ /* @__PURE__ */ s("div", { style: {
3979
+ maxHeight: "400px",
3980
+ overflowY: "auto"
3981
+ }, children: /* @__PURE__ */ c("table", { style: {
3982
+ width: "100%",
3983
+ borderCollapse: "collapse",
3984
+ fontSize: e.typography.fontSize.xs,
3985
+ fontFamily: e.typography.fontFamilyMono
3986
+ }, children: [
3987
+ /* @__PURE__ */ s("thead", { children: /* @__PURE__ */ c("tr", { style: {
3988
+ borderBottom: `1px solid ${e.colors.border}`
3989
+ }, children: [
3990
+ /* @__PURE__ */ s("th", { style: {
3991
+ textAlign: "left",
3992
+ padding: e.spacing.sm,
3993
+ color: e.colors.textSecondary,
3994
+ fontWeight: 600
3995
+ }, children: "Path" }),
3996
+ /* @__PURE__ */ s("th", { style: {
3997
+ textAlign: "right",
3998
+ padding: e.spacing.sm,
3999
+ color: e.colors.textSecondary,
4000
+ fontWeight: 600
4001
+ }, children: "Avg Time" }),
4002
+ /* @__PURE__ */ s("th", { style: {
4003
+ textAlign: "right",
4004
+ padding: e.spacing.sm,
4005
+ color: e.colors.textSecondary,
4006
+ fontWeight: 600
4007
+ }, children: "Calls" }),
4008
+ /* @__PURE__ */ s("th", { style: {
4009
+ textAlign: "right",
4010
+ padding: e.spacing.sm,
4011
+ color: e.colors.textSecondary,
4012
+ fontWeight: 600
4013
+ }, children: "Freq/sec" }),
4014
+ /* @__PURE__ */ s("th", { style: {
4015
+ textAlign: "center",
4016
+ padding: e.spacing.sm,
4017
+ color: e.colors.textSecondary,
4018
+ fontWeight: 600
4019
+ }, children: "Impact" })
4020
+ ] }) }),
4021
+ /* @__PURE__ */ s("tbody", { children: n.hotPaths.map((o) => /* @__PURE__ */ c(
4022
+ "tr",
4023
+ {
4024
+ style: {
4025
+ borderBottom: `1px solid ${e.colors.border}`,
4026
+ backgroundColor: `${r[o.impact]}10`
4027
+ },
4028
+ children: [
4029
+ /* @__PURE__ */ s("td", { style: {
4030
+ padding: e.spacing.sm,
4031
+ color: e.colors.text
4032
+ }, children: o.path.join(" -> ") }),
4033
+ /* @__PURE__ */ s("td", { style: {
4034
+ textAlign: "right",
4035
+ padding: e.spacing.sm,
4036
+ color: r[o.impact],
4037
+ fontWeight: 600
4038
+ }, children: t(o.averageDuration) }),
4039
+ /* @__PURE__ */ s("td", { style: {
4040
+ textAlign: "right",
4041
+ padding: e.spacing.sm,
4042
+ color: e.colors.textSecondary
4043
+ }, children: o.callCount.toLocaleString() }),
4044
+ /* @__PURE__ */ s("td", { style: {
4045
+ textAlign: "right",
4046
+ padding: e.spacing.sm,
4047
+ color: e.colors.textSecondary
4048
+ }, children: v(o.frequency, 1) }),
4049
+ /* @__PURE__ */ s("td", { style: {
4050
+ textAlign: "center",
4051
+ padding: e.spacing.sm
4052
+ }, children: /* @__PURE__ */ s(V, { severity: o.impact === "high" ? "error" : o.impact === "medium" ? "warning" : "info" }) })
4053
+ ]
4054
+ },
4055
+ o.id
4056
+ )) })
4057
+ ] }) })
4058
+ ] }),
4059
+ n.topFunctions.length > 0 && /* @__PURE__ */ c("div", { style: {
4060
+ backgroundColor: e.colors.surface,
4061
+ borderRadius: e.borderRadius.md,
4062
+ padding: e.spacing.md,
4063
+ border: `1px solid ${e.colors.border}`
4064
+ }, children: [
4065
+ /* @__PURE__ */ s("div", { style: {
4066
+ fontSize: e.typography.fontSize.sm,
4067
+ fontWeight: 600,
4068
+ color: e.colors.text,
4069
+ marginBottom: e.spacing.sm
4070
+ }, children: "Top Functions (by total duration)" }),
4071
+ /* @__PURE__ */ s("div", { style: {
4072
+ maxHeight: "300px",
4073
+ overflowY: "auto",
4074
+ fontSize: e.typography.fontSize.xs,
4075
+ fontFamily: e.typography.fontFamilyMono,
4076
+ color: e.colors.textSecondary
4077
+ }, children: n.topFunctions.map((o, a) => /* @__PURE__ */ c(
4078
+ "div",
4079
+ {
4080
+ style: {
4081
+ padding: e.spacing.sm,
4082
+ borderBottom: `1px solid ${e.colors.border}`,
4083
+ display: "flex",
4084
+ justifyContent: "space-between"
4085
+ },
4086
+ children: [
4087
+ /* @__PURE__ */ c("span", { children: [
4088
+ a + 1,
4089
+ ". ",
4090
+ o.name
4091
+ ] }),
4092
+ /* @__PURE__ */ c("span", { children: [
4093
+ t(o.averageDuration),
4094
+ " avg (",
4095
+ o.callCount.toLocaleString(),
4096
+ " calls)"
4097
+ ] })
4098
+ ]
4099
+ },
4100
+ o.name
4101
+ )) })
4102
+ ] })
4103
+ ] }) : /* @__PURE__ */ s("div", { style: {
4104
+ padding: e.spacing.lg,
4105
+ textAlign: "center",
4106
+ color: e.colors.textSecondary,
4107
+ fontSize: e.typography.fontSize.sm
4108
+ }, children: "Aucune analyse de hot path disponible. Les hot paths sont détectés automatiquement à partir des données du profiler." });
4109
+ }, st = ({
4110
+ position: n = "top-right",
4111
+ defaultTab: e = "frames",
4112
+ collapsed: t = !1
4113
+ }) => {
4114
+ const [r, o] = B(!1), [a, d] = B(e), [l, g] = B(t), [i, w] = B(k.getPaused()), [y, u] = B(!1), [f, M] = B(null), C = I(null), h = I(null), m = F, S = "r3f-profiler-state";
4115
+ A(() => {
4116
+ const b = localStorage.getItem(S);
4117
+ if (b)
4118
+ try {
4119
+ const $ = JSON.parse(b);
4120
+ $.position && typeof $.position.x == "number" && typeof $.position.y == "number" && M({ x: $.position.x, y: $.position.y }), typeof $.collapsed == "boolean" && g($.collapsed), typeof $.activeTab == "string" && $.activeTab && d($.activeTab);
4121
+ } catch ($) {
4122
+ console.warn("Failed to load saved profiler state:", $);
4123
+ }
4124
+ const R = k.subscribe(($) => {
4125
+ w($);
4126
+ });
4127
+ return () => {
4128
+ R();
4129
+ };
4130
+ }, []);
4131
+ const z = Z((b) => {
4132
+ try {
4133
+ const R = localStorage.getItem(S), G = {
4134
+ ...R ? JSON.parse(R) : {},
4135
+ ...b
4136
+ };
4137
+ localStorage.setItem(S, JSON.stringify(G));
4138
+ } catch (R) {
4139
+ console.warn("Failed to save profiler state:", R);
4140
+ }
4141
+ }, []), p = Z((b, R) => {
4142
+ z({ position: { x: b, y: R } });
4143
+ }, [z]), T = Z((b) => {
4144
+ if (!b.target.closest("button") && (u(!0), h.current)) {
4145
+ const R = h.current.getBoundingClientRect();
4146
+ C.current = {
4147
+ x: b.clientX - R.left,
4148
+ y: b.clientY - R.top
4149
+ };
4150
+ }
4151
+ }, []);
4152
+ if (A(() => {
4153
+ if (!y) return;
4154
+ const b = ($) => {
4155
+ if (!C.current || !h.current) return;
4156
+ const te = h.current.getBoundingClientRect(), ge = window.innerWidth, pe = window.innerHeight;
4157
+ let K = $.clientX - C.current.x, X = $.clientY - C.current.y;
4158
+ K = Math.max(0, Math.min(K, ge - te.width)), X = Math.max(0, Math.min(X, pe - te.height));
4159
+ const re = { x: K, y: X };
4160
+ M(re), z({ position: re });
4161
+ }, R = () => {
4162
+ u(!1), C.current = null;
4163
+ };
4164
+ return window.addEventListener("mousemove", b), window.addEventListener("mouseup", R), () => {
4165
+ window.removeEventListener("mousemove", b), window.removeEventListener("mouseup", R);
4166
+ };
4167
+ }, [y, p]), A(() => {
4168
+ const b = () => ce();
4169
+ o(b());
4170
+ const R = () => {
4171
+ o(b());
4172
+ };
4173
+ return window.addEventListener("storage", R), () => {
4174
+ window.removeEventListener("storage", R);
4175
+ };
4176
+ }, []), !r)
4177
+ return null;
4178
+ const P = [
4179
+ { id: "frames", label: "Frames" },
4180
+ { id: "gpu", label: "GPU" },
4181
+ { id: "scene", label: "Scene" },
4182
+ { id: "memory", label: "Memory" },
4183
+ { id: "frame-time", label: "Frame Time" },
4184
+ { id: "budget", label: "Budget" },
4185
+ { id: "react", label: "React" },
4186
+ { id: "hot-path", label: "Hot Path" }
4187
+ ], q = f ? {
4188
+ left: `${f.x}px`,
4189
+ top: `${f.y}px`,
4190
+ right: "auto",
4191
+ bottom: "auto"
4192
+ } : {
4193
+ "top-left": { top: m.spacing.md, left: m.spacing.md, right: "auto", bottom: "auto" },
4194
+ "top-right": { top: m.spacing.md, right: m.spacing.md, left: "auto", bottom: "auto" },
4195
+ "bottom-left": { bottom: m.spacing.md, left: m.spacing.md, right: "auto", top: "auto" },
4196
+ "bottom-right": { bottom: m.spacing.md, right: m.spacing.md, left: "auto", top: "auto" }
4197
+ }[n];
4198
+ return /* @__PURE__ */ c(
4199
+ "div",
4200
+ {
4201
+ ref: h,
4202
+ style: {
4203
+ position: "fixed",
4204
+ ...q,
4205
+ width: l ? "auto" : "600px",
4206
+ maxWidth: l ? "auto" : "90vw",
4207
+ maxHeight: "80vh",
4208
+ backgroundColor: m.colors.background,
4209
+ backdropFilter: "blur(10px)",
4210
+ borderRadius: m.borderRadius.lg,
4211
+ boxShadow: m.shadows.xl,
4212
+ border: `1px solid ${m.colors.border}`,
4213
+ zIndex: m.zIndex.base,
4214
+ display: "flex",
4215
+ flexDirection: "column",
4216
+ overflow: "hidden",
4217
+ transition: y ? "none" : m.transitions.normal,
4218
+ userSelect: y ? "none" : "auto"
4219
+ },
4220
+ children: [
4221
+ /* @__PURE__ */ c(
4222
+ "div",
4223
+ {
4224
+ onMouseDown: T,
4225
+ style: {
4226
+ display: "flex",
4227
+ alignItems: "center",
4228
+ justifyContent: "space-between",
4229
+ padding: m.spacing.md,
4230
+ borderBottom: `1px solid ${m.colors.border}`,
4231
+ backgroundColor: m.colors.surface,
4232
+ cursor: y ? "grabbing" : "grab",
4233
+ userSelect: "none"
4234
+ },
4235
+ children: [
4236
+ /* @__PURE__ */ c("div", { style: {
4237
+ display: "flex",
4238
+ alignItems: "center",
4239
+ gap: m.spacing.sm,
4240
+ flex: 1
4241
+ }, children: [
4242
+ /* @__PURE__ */ s("div", { style: {
4243
+ display: "flex",
4244
+ alignItems: "center",
4245
+ gap: m.spacing.xs,
4246
+ color: m.colors.textTertiary,
4247
+ fontSize: m.typography.fontSize.xs
4248
+ }, children: /* @__PURE__ */ s("span", { children: "⋮⋮" }) }),
4249
+ /* @__PURE__ */ s("div", { style: {
4250
+ width: "8px",
4251
+ height: "8px",
4252
+ borderRadius: "50%",
4253
+ backgroundColor: m.colors.success,
4254
+ boxShadow: `0 0 8px ${m.colors.success}`
4255
+ } }),
4256
+ /* @__PURE__ */ s("h2", { style: {
4257
+ margin: 0,
4258
+ fontSize: m.typography.fontSize.lg,
4259
+ fontWeight: 600,
4260
+ color: m.colors.text
4261
+ }, children: "Performance Monitor" })
4262
+ ] }),
4263
+ /* @__PURE__ */ c("div", { style: {
4264
+ display: "flex",
4265
+ gap: m.spacing.xs,
4266
+ alignItems: "center"
4267
+ }, children: [
4268
+ i && /* @__PURE__ */ s("div", { style: {
4269
+ fontSize: m.typography.fontSize.xs,
4270
+ color: m.colors.warning,
4271
+ fontFamily: m.typography.fontFamilyMono,
4272
+ padding: `0 ${m.spacing.xs}`
4273
+ }, children: "PAUSED" }),
4274
+ /* @__PURE__ */ s(
4275
+ "button",
4276
+ {
4277
+ onClick: () => {
4278
+ k.toggle();
4279
+ },
4280
+ style: {
4281
+ background: "transparent",
4282
+ border: "none",
4283
+ color: i ? m.colors.warning : m.colors.textSecondary,
4284
+ cursor: "pointer",
4285
+ padding: m.spacing.xs,
4286
+ borderRadius: m.borderRadius.sm,
4287
+ transition: m.transitions.fast,
4288
+ display: "flex",
4289
+ alignItems: "center",
4290
+ justifyContent: "center"
4291
+ },
4292
+ onMouseEnter: (b) => {
4293
+ b.currentTarget.style.backgroundColor = m.colors.surfaceElevated, b.currentTarget.style.color = i ? m.colors.warning : m.colors.text;
4294
+ },
4295
+ onMouseLeave: (b) => {
4296
+ b.currentTarget.style.backgroundColor = "transparent", b.currentTarget.style.color = i ? m.colors.warning : m.colors.textSecondary;
4297
+ },
4298
+ title: i ? "Resume" : "Pause",
4299
+ children: i ? "▶" : "⏸"
4300
+ }
4301
+ ),
4302
+ /* @__PURE__ */ s(
4303
+ "button",
4304
+ {
4305
+ onClick: async () => {
4306
+ const { profiler: b } = await Promise.resolve().then(() => ve);
4307
+ await b.copyReportToClipboard(), alert("📊 Performance report copied to clipboard!");
4308
+ },
4309
+ style: {
4310
+ background: "transparent",
4311
+ border: "none",
4312
+ color: m.colors.textSecondary,
4313
+ cursor: "pointer",
4314
+ padding: m.spacing.xs,
4315
+ borderRadius: m.borderRadius.sm,
4316
+ transition: m.transitions.fast,
4317
+ display: "flex",
4318
+ alignItems: "center",
4319
+ justifyContent: "center"
4320
+ },
4321
+ onMouseEnter: (b) => {
4322
+ b.currentTarget.style.backgroundColor = m.colors.surfaceElevated, b.currentTarget.style.color = m.colors.success;
4323
+ },
4324
+ onMouseLeave: (b) => {
4325
+ b.currentTarget.style.backgroundColor = "transparent", b.currentTarget.style.color = m.colors.textSecondary;
4326
+ },
4327
+ title: "Copy Performance Report (for AI analysis)",
4328
+ children: "📊"
4329
+ }
4330
+ ),
4331
+ /* @__PURE__ */ s(
4332
+ "button",
4333
+ {
4334
+ onClick: () => {
4335
+ const b = !l;
4336
+ g(b), z({ collapsed: b });
4337
+ },
4338
+ style: {
4339
+ background: "transparent",
4340
+ border: "none",
4341
+ color: m.colors.textSecondary,
4342
+ cursor: "pointer",
4343
+ padding: m.spacing.xs,
4344
+ borderRadius: m.borderRadius.sm,
4345
+ transition: m.transitions.fast,
4346
+ display: "flex",
4347
+ alignItems: "center",
4348
+ justifyContent: "center"
4349
+ },
4350
+ onMouseEnter: (b) => {
4351
+ b.currentTarget.style.backgroundColor = m.colors.surfaceElevated, b.currentTarget.style.color = m.colors.text;
4352
+ },
4353
+ onMouseLeave: (b) => {
4354
+ b.currentTarget.style.backgroundColor = "transparent", b.currentTarget.style.color = m.colors.textSecondary;
4355
+ },
4356
+ title: l ? "Expand" : "Collapse",
4357
+ children: l ? "◀" : "▼"
4358
+ }
4359
+ )
4360
+ ] })
4361
+ ]
4362
+ }
4363
+ ),
4364
+ !l && /* @__PURE__ */ c(N, { children: [
4365
+ /* @__PURE__ */ s("div", { style: {
4366
+ padding: `0 ${m.spacing.md}`,
4367
+ backgroundColor: m.colors.surface
4368
+ }, children: /* @__PURE__ */ s(
4369
+ Pe,
4370
+ {
4371
+ tabs: P,
4372
+ activeTab: a,
4373
+ onTabChange: (b) => {
4374
+ d(b), z({ activeTab: b });
4375
+ }
4376
+ }
4377
+ ) }),
4378
+ /* @__PURE__ */ c("div", { style: {
4379
+ flex: 1,
4380
+ overflow: "auto",
4381
+ backgroundColor: m.colors.background
4382
+ }, children: [
4383
+ a === "frames" && /* @__PURE__ */ s(De, {}),
4384
+ a === "gpu" && /* @__PURE__ */ s(Le, {}),
4385
+ a === "scene" && /* @__PURE__ */ s(He, {}),
4386
+ a === "memory" && /* @__PURE__ */ s(Ee, {}),
4387
+ a === "frame-time" && /* @__PURE__ */ s(We, {}),
4388
+ a === "budget" && /* @__PURE__ */ s(Oe, {}),
4389
+ a === "react" && /* @__PURE__ */ s(Ne, {}),
4390
+ a === "hot-path" && /* @__PURE__ */ s(Ze, {})
4391
+ ] })
4392
+ ] })
4393
+ ]
4394
+ }
4395
+ );
4396
+ };
4397
+ export {
4398
+ st as P,
4399
+ nt as R,
4400
+ ot as a,
4401
+ be as b,
4402
+ ce as i,
4403
+ E as p,
4404
+ xe as r
4405
+ };
4406
+ //# sourceMappingURL=index-o5zvhDta.js.map