@zkmake/three-meter 0.7.0 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -486,6 +486,7 @@ const dockPanel = (element, options = {}) => {
486
486
  //#endregion
487
487
  //#region src/ui/icons.ts
488
488
  const ICON_MARKUP = {
489
+ flame: "<path d=\"M8.5 14.5A2.5 2.5 0 0 0 11 12c0-1.38-.5-2-1-3-1.072-2.143-.224-4.054 2-6 .5 2.5 2 4.9 4 6.5 2 1.6 3 3.5 3 5.5a7 7 0 1 1-14 0c0-1.153.433-2.294 1-3a2.5 2.5 0 0 0 2.5 2.5z\"/>",
489
490
  activity: "<path d=\"M22 12h-2.48a2 2 0 0 0-1.93 1.46l-2.35 8.36a.25.25 0 0 1-.48 0L9.24 2.18a.25.25 0 0 0-.48 0l-2.35 8.36A2 2 0 0 1 4.49 12H2\"/>",
490
491
  box: "<path d=\"M21 8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16Z\"/><path d=\"m3.3 7 8.7 5 8.7-5\"/><path d=\"M12 22V12\"/>",
491
492
  circleDot: "<circle cx=\"12\" cy=\"12\" r=\"10\"/><circle cx=\"12\" cy=\"12\" r=\"1\"/>",
@@ -526,7 +527,7 @@ const createIcon = (name, className) => {
526
527
  };
527
528
  //#endregion
528
529
  //#region package.json
529
- var version = "0.7.0";
530
+ var version = "0.9.0";
530
531
  //#endregion
531
532
  //#region src/ui/clipboard.ts
532
533
  /**
@@ -604,7 +605,7 @@ const METRIC_HELP = {
604
605
  //#region src/ui/report.ts
605
606
  /**
606
607
  * A plain-text snapshot of the monitor for bug reports: versions, backend and
607
- * GPU, the current sample, stutter stats and the page. Fenced as a `text`
608
+ * GPU, the current sample, stutter stats, the scene's top meshes and the page. Fenced as a `text`
608
609
  * code block so GitHub and Slack keep the line breaks.
609
610
  */
610
611
  const BACKEND_LABELS = {
@@ -619,7 +620,13 @@ const backendLabel = (environment) => {
619
620
  return environment.fallback ? `${label} fallback` : label;
620
621
  };
621
622
  const ms = (value) => `${value.toFixed(1)} ms`;
622
- const renderReport = ({ environment, page, sample, stats }) => {
623
+ /** Top meshes by draw calls, three at most: `Top: cubes ×2,000 (1 call, 24K tris) · …`. */
624
+ const topMeshes = (cost) => `Top: ${cost.meshes.slice(0, 3).map((entry) => {
625
+ const copies = entry.instances > 1 ? ` ×${formatCount(entry.instances)}` : "";
626
+ const calls = `${formatCount(entry.calls)} ${entry.calls === 1 ? "call" : "calls"}`;
627
+ return `${entry.label}${copies} (${calls}, ${formatCount(entry.triangles)} tris)`;
628
+ }).join(" · ")}`;
629
+ const renderReport = ({ cost, environment, page, sample, stats }) => {
623
630
  const { render, resources } = sample;
624
631
  const heading = [
625
632
  `three-meter v${version}`,
@@ -650,6 +657,7 @@ const renderReport = ({ environment, page, sample, stats }) => {
650
657
  `shaders ${formatCount(resources.programs)}`
651
658
  ].join(" · ")
652
659
  ];
660
+ if (cost && cost.meshes.length > 0) lines.push(topMeshes(cost));
653
661
  if (page) lines.push(`Viewport ${page.width}×${page.height} @${page.dpr}x`, page.userAgent);
654
662
  return [
655
663
  "```text",
@@ -665,6 +673,7 @@ const readPage = () => typeof window === "undefined" ? null : {
665
673
  };
666
674
  /** The report for `monitor` right now, as Markdown ready to paste into an issue. */
667
675
  const formatReport = (monitor) => renderReport({
676
+ cost: monitor.getSceneCost(),
668
677
  environment: monitor.getEnvironment(),
669
678
  page: readPage(),
670
679
  sample: monitor.getSample(),
@@ -778,6 +787,24 @@ const THEME_OPTIONS = [
778
787
  const RELEASE_URL = `https://github.com/zkmake/three-meter/releases/tag/v${version}`;
779
788
  /** How long the report button says `copied` / `failed` before reading `copy` again. */
780
789
  const COPY_FEEDBACK_MS = 1500;
790
+ /** Walking the scene graph isn't free; the top-costs list refreshes at 2 Hz while open. */
791
+ const COSTS_INTERVAL_MS = 500;
792
+ const COSTS_ROWS = 5;
793
+ const COST_GROUPS = [{
794
+ group: "meshes",
795
+ label: "meshes"
796
+ }, {
797
+ group: "materials",
798
+ label: "materials"
799
+ }];
800
+ const COSTS_HELP = "The scene's biggest draw costs in the main render pass, estimated from the scene graph. Hidden and off-screen objects are left out; shadow and post-processing passes aren't counted. Click a row to log its objects to the console.";
801
+ /** `×2,000` for instances or copies; nothing for a single object. */
802
+ const copiesOf = (entry) => entry.instances > 1 ? `×${formatCount(entry.instances)}` : "";
803
+ const costTitle = (entry) => {
804
+ const objects = entry.objects.length;
805
+ const shape = entry.instances > objects ? `${formatCount(entry.instances)} instances in ${objects === 1 ? "one object" : `${objects} objects`}` : `${formatCount(objects)} ${objects === 1 ? "object" : "separate objects"}`;
806
+ return `${entry.label}: ${shape}, ${formatCount(entry.calls)} draw ${entry.calls === 1 ? "call" : "calls"}, ${formatCount(entry.triangles)} triangles. Click to log to the console.`;
807
+ };
781
808
  const readTiming = (sample, metric) => {
782
809
  switch (metric) {
783
810
  case "fps": return sample.fps;
@@ -930,7 +957,6 @@ var PerformanceView = class {
930
957
  graphCheckboxes = /* @__PURE__ */ new Map();
931
958
  statValueEls = /* @__PURE__ */ new Map();
932
959
  statCheckboxes = /* @__PURE__ */ new Map();
933
- dimCheckbox;
934
960
  infoCheckbox;
935
961
  themeRadios = /* @__PURE__ */ new Map();
936
962
  footerThreeEl;
@@ -947,6 +973,14 @@ var PerformanceView = class {
947
973
  lastPaintAt = 0;
948
974
  resizeObserver;
949
975
  unsubscribe;
976
+ costsOpen = false;
977
+ costGroup = "meshes";
978
+ costSort = "calls";
979
+ lastCostsAt = -Infinity;
980
+ costsBodyEl;
981
+ costsListEl;
982
+ costGroupRadios = /* @__PURE__ */ new Map();
983
+ costSortButtons = /* @__PURE__ */ new Map();
950
984
  constructor(options) {
951
985
  this.monitor = options.monitor;
952
986
  this.settings = options.settings ?? new HudSettings();
@@ -1014,8 +1048,57 @@ var PerformanceView = class {
1014
1048
  for (const config of TIMINGS) this.paintGraph(config, sample, this.graphValueEls.get(config.metric), this.graphCanvases.get(config.metric), "unavailable");
1015
1049
  const stats = this.monitor.getFrameStats();
1016
1050
  for (const config of NUMBERS) this.paintNumber(config, this.statValueEls.get(config.key), sample, stats);
1051
+ if (this.costsOpen && performance.now() - this.lastCostsAt >= COSTS_INTERVAL_MS) this.renderCosts();
1017
1052
  this.renderFooter();
1018
1053
  }
1054
+ renderCosts() {
1055
+ this.lastCostsAt = performance.now();
1056
+ const cost = this.monitor.getSceneCost();
1057
+ if (!cost) {
1058
+ this.costsListEl.replaceChildren(this.costsNote("No scene rendered yet."));
1059
+ return;
1060
+ }
1061
+ const entries = [...this.costGroup === "meshes" ? cost.meshes : cost.materials];
1062
+ if (this.costSort === "triangles") entries.sort((a, b) => b.triangles - a.triangles || b.calls - a.calls);
1063
+ if (entries.length === 0) {
1064
+ this.costsListEl.replaceChildren(this.costsNote("Nothing drawn."));
1065
+ return;
1066
+ }
1067
+ const rows = entries.slice(0, COSTS_ROWS).map((entry) => {
1068
+ const row = document.createElement("button");
1069
+ row.type = "button";
1070
+ row.className = "perf-monitor__cost";
1071
+ row.title = costTitle(entry);
1072
+ const name = document.createElement("span");
1073
+ name.className = "perf-monitor__cost-name";
1074
+ name.textContent = entry.label;
1075
+ const copies = copiesOf(entry);
1076
+ if (copies) {
1077
+ const suffix = document.createElement("span");
1078
+ suffix.className = "perf-monitor__cost-copies";
1079
+ suffix.textContent = ` ${copies}`;
1080
+ name.append(suffix);
1081
+ }
1082
+ const calls = document.createElement("span");
1083
+ calls.className = "perf-monitor__cost-value";
1084
+ calls.textContent = formatCount(entry.calls);
1085
+ const triangles = document.createElement("span");
1086
+ triangles.className = "perf-monitor__cost-value";
1087
+ triangles.textContent = formatCount(entry.triangles);
1088
+ row.append(name, calls, triangles);
1089
+ row.addEventListener("click", () => {
1090
+ console.log(`three-meter: ${entry.label}`, entry.objects);
1091
+ });
1092
+ return row;
1093
+ });
1094
+ this.costsListEl.replaceChildren(...rows);
1095
+ }
1096
+ costsNote(text) {
1097
+ const note = document.createElement("div");
1098
+ note.className = "perf-monitor__costs-note";
1099
+ note.textContent = text;
1100
+ return note;
1101
+ }
1019
1102
  /** The monitor caches the environment once its backend settles; until then this re-reads. */
1020
1103
  renderFooter() {
1021
1104
  const environment = this.monitor.getEnvironment();
@@ -1105,13 +1188,6 @@ var PerformanceView = class {
1105
1188
  segment.append(radio);
1106
1189
  }
1107
1190
  themeRow.append(createIcon("contrast", "perf-monitor__icon"), themeLabel, segment);
1108
- const dimRow = document.createElement("label");
1109
- dimRow.className = "perf-monitor__row";
1110
- this.dimCheckbox = this.buildCheckbox(this.settings.dim, "Dim the performance panel when the pointer leaves", (on) => this.settings.setDim(on));
1111
- const dimLabel = document.createElement("span");
1112
- dimLabel.className = "perf-monitor__label";
1113
- dimLabel.textContent = "dim on leave";
1114
- dimRow.append(createIcon("blend", "perf-monitor__icon"), dimLabel, this.dimCheckbox);
1115
1191
  const explainRow = document.createElement("label");
1116
1192
  explainRow.className = "perf-monitor__row";
1117
1193
  const explainCheckbox = this.buildCheckbox(false, "Explain each metric", (on) => this.element.classList.toggle("perf-monitor--explain", on));
@@ -1119,7 +1195,7 @@ var PerformanceView = class {
1119
1195
  explainLabel.className = "perf-monitor__label";
1120
1196
  explainLabel.textContent = "explain metrics";
1121
1197
  explainRow.append(createIcon("help", "perf-monitor__icon"), explainLabel, explainCheckbox);
1122
- options.append(themeRow, dimRow, explainRow, this.buildReportRow());
1198
+ options.append(themeRow, explainRow, this.buildReportRow());
1123
1199
  const graphs = document.createElement("div");
1124
1200
  graphs.className = "perf-monitor__graphs";
1125
1201
  for (const config of TIMINGS) {
@@ -1207,7 +1283,7 @@ var PerformanceView = class {
1207
1283
  this.footerHardwareEl.append(this.footerBackendEl, this.footerGpuEl);
1208
1284
  footerBody.append(softwareRow, this.footerHardwareEl);
1209
1285
  footer.append(createIcon("info", "perf-monitor__icon"), footerBody, this.infoCheckbox);
1210
- this.element.append(hud, options, graphs, stats, footer);
1286
+ this.element.append(hud, options, graphs, stats, this.buildCosts(), footer);
1211
1287
  }
1212
1288
  rebuildHud() {
1213
1289
  const { selection } = this.settings;
@@ -1228,10 +1304,13 @@ var PerformanceView = class {
1228
1304
  label.className = "perf-monitor__graph-label";
1229
1305
  label.textContent = config.label;
1230
1306
  label.title = METRIC_HELP[config.metric] ?? "";
1307
+ const head = document.createElement("span");
1308
+ head.className = "perf-monitor__graph-head";
1309
+ head.append(createIcon(config.icon, "perf-monitor__icon"), label);
1231
1310
  const value = document.createElement("span");
1232
1311
  value.className = "perf-monitor__graph-value";
1233
1312
  value.textContent = "—";
1234
- overlay.append(label, value);
1313
+ overlay.append(head, value);
1235
1314
  row.append(canvas, overlay);
1236
1315
  this.hudGraphsEl.append(row);
1237
1316
  const ctx = canvas.getContext("2d");
@@ -1252,8 +1331,8 @@ var PerformanceView = class {
1252
1331
  item.className = "perf-monitor__hud-item";
1253
1332
  const label = document.createElement("span");
1254
1333
  label.className = "perf-monitor__hud-label";
1255
- label.textContent = config.label;
1256
1334
  label.title = METRIC_HELP[config.key] ?? "";
1335
+ label.append(createIcon(config.icon, "perf-monitor__icon"), config.label);
1257
1336
  const value = document.createElement("span");
1258
1337
  value.className = "perf-monitor__hud-value";
1259
1338
  value.textContent = "—";
@@ -1267,7 +1346,6 @@ var PerformanceView = class {
1267
1346
  onSelectionChanged() {
1268
1347
  for (const [metric, checkbox] of this.graphCheckboxes) checkbox.checked = this.settings.isGraphEnabled(metric);
1269
1348
  for (const [key, checkbox] of this.statCheckboxes) checkbox.checked = this.settings.isNumberEnabled(key);
1270
- this.dimCheckbox.checked = this.settings.dim;
1271
1349
  this.infoCheckbox.checked = this.settings.info;
1272
1350
  this.applyInfoClass();
1273
1351
  this.theme.setOverride(this.settings.theme);
@@ -1278,6 +1356,71 @@ var PerformanceView = class {
1278
1356
  applyTheme(this.element, this.theme);
1279
1357
  for (const [mode, radio] of this.themeRadios) radio.setAttribute("aria-checked", String(mode === this.theme.effective));
1280
1358
  }
1359
+ /** "top costs": a toggle row, then meshes / materials and a sortable top five. */
1360
+ buildCosts() {
1361
+ const section = document.createElement("div");
1362
+ section.className = "perf-monitor__section perf-monitor__costs";
1363
+ const toggleRow = document.createElement("label");
1364
+ toggleRow.className = "perf-monitor__row";
1365
+ toggleRow.title = COSTS_HELP;
1366
+ const label = document.createElement("span");
1367
+ label.className = "perf-monitor__label";
1368
+ label.textContent = "top costs";
1369
+ const checkbox = this.buildCheckbox(false, "Show the scene's biggest draw costs", (on) => {
1370
+ this.costsOpen = on;
1371
+ this.costsBodyEl.hidden = !on;
1372
+ if (on) this.renderCosts();
1373
+ });
1374
+ toggleRow.append(createIcon("flame", "perf-monitor__icon"), label, checkbox);
1375
+ this.costsBodyEl = document.createElement("div");
1376
+ this.costsBodyEl.className = "perf-monitor__costs-body";
1377
+ this.costsBodyEl.hidden = true;
1378
+ const head = document.createElement("div");
1379
+ head.className = "perf-monitor__cost perf-monitor__cost--head";
1380
+ const segment = document.createElement("div");
1381
+ segment.className = "perf-monitor__segment";
1382
+ segment.setAttribute("role", "radiogroup");
1383
+ segment.setAttribute("aria-label", "Group costs by");
1384
+ for (const option of COST_GROUPS) {
1385
+ const radio = document.createElement("button");
1386
+ radio.type = "button";
1387
+ radio.className = "perf-monitor__segment-option perf-monitor__segment-option--text";
1388
+ radio.setAttribute("role", "radio");
1389
+ radio.setAttribute("aria-checked", String(option.group === this.costGroup));
1390
+ radio.textContent = option.label;
1391
+ radio.addEventListener("click", () => {
1392
+ this.costGroup = option.group;
1393
+ for (const [group, button] of this.costGroupRadios) button.setAttribute("aria-checked", String(group === option.group));
1394
+ this.renderCosts();
1395
+ });
1396
+ this.costGroupRadios.set(option.group, radio);
1397
+ segment.append(radio);
1398
+ }
1399
+ head.append(segment);
1400
+ for (const sort of ["calls", "triangles"]) {
1401
+ const button = document.createElement("button");
1402
+ button.type = "button";
1403
+ button.className = "perf-monitor__cost-sort";
1404
+ button.textContent = sort === "calls" ? "calls" : "tris";
1405
+ button.title = `Sort by ${sort === "calls" ? "draw calls" : "triangles"}`;
1406
+ button.setAttribute("aria-pressed", String(sort === this.costSort));
1407
+ button.addEventListener("click", () => {
1408
+ this.costSort = sort;
1409
+ for (const [key, other] of this.costSortButtons) other.setAttribute("aria-pressed", String(key === sort));
1410
+ this.renderCosts();
1411
+ });
1412
+ this.costSortButtons.set(sort, button);
1413
+ head.append(button);
1414
+ }
1415
+ this.costsListEl = document.createElement("div");
1416
+ this.costsListEl.className = "perf-monitor__costs-list";
1417
+ const hint = document.createElement("span");
1418
+ hint.className = "perf-monitor__hint";
1419
+ hint.textContent = COSTS_HELP;
1420
+ this.costsBodyEl.append(head, this.costsListEl, hint);
1421
+ section.append(toggleRow, this.costsBodyEl);
1422
+ return section;
1423
+ }
1281
1424
  buildReportRow() {
1282
1425
  const row = document.createElement("div");
1283
1426
  row.className = "perf-monitor__row perf-monitor__row--static";
@@ -1574,6 +1717,96 @@ const PERF_HUD_STYLES = `
1574
1717
  outline-offset: 1px;
1575
1718
  }
1576
1719
 
1720
+ /* Top costs: name, calls, triangles. Rows are buttons that log their objects. */
1721
+ .perf-monitor__costs-body {
1722
+ display: flex;
1723
+ flex-direction: column;
1724
+ gap: 1px;
1725
+ padding-top: 2px;
1726
+ }
1727
+
1728
+ .perf-monitor__costs-body[hidden] {
1729
+ display: none;
1730
+ }
1731
+
1732
+ .perf-monitor__cost {
1733
+ /* Rows are buttons, which shrink to their content without a width. */
1734
+ box-sizing: border-box;
1735
+ width: 100%;
1736
+ display: grid;
1737
+ grid-template-columns: minmax(0, 1fr) 5ch 6ch;
1738
+ gap: 6px;
1739
+ align-items: baseline;
1740
+ padding: 2px 6px;
1741
+ border: 0;
1742
+ border-radius: 3px;
1743
+ background: transparent;
1744
+ color: inherit;
1745
+ font: inherit;
1746
+ text-align: left;
1747
+ cursor: pointer;
1748
+ }
1749
+
1750
+ .perf-monitor__cost:not(.perf-monitor__cost--head):hover {
1751
+ background: var(--perf-row);
1752
+ }
1753
+
1754
+ .perf-monitor__cost:focus-visible {
1755
+ outline: 1px solid color-mix(in srgb, var(--perf-accent) 60%, transparent);
1756
+ outline-offset: -1px;
1757
+ }
1758
+
1759
+ .perf-monitor__cost--head {
1760
+ align-items: center;
1761
+ cursor: default;
1762
+ }
1763
+
1764
+ .perf-monitor__cost-name {
1765
+ overflow: hidden;
1766
+ text-overflow: ellipsis;
1767
+ white-space: nowrap;
1768
+ color: var(--perf-fg-dim);
1769
+ }
1770
+
1771
+ .perf-monitor__cost-copies {
1772
+ color: var(--perf-muted);
1773
+ }
1774
+
1775
+ .perf-monitor__cost-value {
1776
+ font-variant-numeric: tabular-nums lining-nums;
1777
+ text-align: right;
1778
+ }
1779
+
1780
+ .perf-monitor__cost-sort {
1781
+ padding: 0;
1782
+ border: 0;
1783
+ background: transparent;
1784
+ color: var(--perf-muted);
1785
+ font: inherit;
1786
+ font-size: 10px;
1787
+ text-align: right;
1788
+ cursor: pointer;
1789
+ }
1790
+
1791
+ .perf-monitor__cost-sort[aria-pressed="true"] {
1792
+ color: var(--perf-fg);
1793
+ text-decoration: underline;
1794
+ text-underline-offset: 2px;
1795
+ }
1796
+
1797
+ .perf-monitor__segment-option--text {
1798
+ width: auto;
1799
+ padding: 0 5px;
1800
+ font: inherit;
1801
+ font-size: 10px;
1802
+ }
1803
+
1804
+ .perf-monitor__costs-note {
1805
+ padding: 2px 6px;
1806
+ color: var(--perf-muted);
1807
+ font-size: 10px;
1808
+ }
1809
+
1577
1810
  .perf-monitor__checkbox {
1578
1811
  flex: none;
1579
1812
  margin: 0;
@@ -1630,10 +1863,19 @@ const PERF_HUD_STYLES = `
1630
1863
  }
1631
1864
 
1632
1865
  .perf-monitor__hud-label {
1866
+ display: inline-flex;
1867
+ align-items: center;
1868
+ gap: 4px;
1633
1869
  color: var(--perf-muted);
1634
1870
  font-size: 10px;
1635
1871
  }
1636
1872
 
1873
+ .perf-monitor__hud-label .perf-monitor__icon,
1874
+ .perf-monitor__hud-graph .perf-monitor__icon {
1875
+ width: 11px;
1876
+ height: 11px;
1877
+ }
1878
+
1637
1879
  .perf-monitor__hud-value {
1638
1880
  font-weight: 600;
1639
1881
  font-variant-numeric: tabular-nums lining-nums;
@@ -1850,6 +2092,11 @@ const PERF_HUD_STYLES = `
1850
2092
  outline: 1px solid color-mix(in srgb, var(--perf-accent) 60%, transparent);
1851
2093
  outline-offset: 1px;
1852
2094
  }
2095
+
2096
+ /* Dim on: the mark takes the accent, so on and off differ even under the hover ring. */
2097
+ .perf-hud__dim[aria-pressed="true"] {
2098
+ color: var(--perf-accent);
2099
+ }
1853
2100
  `;
1854
2101
  /**
1855
2102
  * Append the stylesheet to `target`'s head, once. Call before mounting a view
@@ -1870,6 +2117,7 @@ const disc = (label, className, icon) => {
1870
2117
  button.type = "button";
1871
2118
  button.className = `perf-hud__disc ${className}`.trim();
1872
2119
  button.setAttribute("aria-label", label);
2120
+ button.title = label;
1873
2121
  button.append(createIcon(icon, "perf-hud__icon"));
1874
2122
  return button;
1875
2123
  };
@@ -1890,7 +2138,9 @@ const mountPerfHud = (monitor, options = {}) => {
1890
2138
  tools.className = "perf-hud__tools";
1891
2139
  const grip = disc("Drag performance panel", "perf-hud__drag", "grip");
1892
2140
  const toggle = disc("Toggle full performance metrics", "", "sliders");
1893
- tools.append(grip, toggle);
2141
+ const dim = disc("Dim the panel when the pointer leaves", "perf-hud__dim", "blend");
2142
+ dim.addEventListener("click", () => settings.setDim(!settings.dim));
2143
+ tools.append(grip, toggle, dim);
1894
2144
  const view = new PerformanceView({
1895
2145
  budgets: options.budgets,
1896
2146
  mode: options.mode ?? "compact",
@@ -1906,6 +2156,7 @@ const mountPerfHud = (monitor, options = {}) => {
1906
2156
  };
1907
2157
  const applyDim = () => {
1908
2158
  host.classList.toggle("perf-hud--dim", settings.dim);
2159
+ dim.setAttribute("aria-pressed", String(settings.dim));
1909
2160
  };
1910
2161
  applyMode();
1911
2162
  applyDim();
@@ -1980,4 +2231,4 @@ const mountPerfHud = (monitor, options = {}) => {
1980
2231
  //#endregion
1981
2232
  export { formatReport as a, HudSettings as c, isThemeMode as d, resolveBudgets as f, PerformanceView as i, HudTheme as l, PERF_HUD_STYLES as n, dockPanel as o, injectStyles as r, DEFAULT_STORAGE_KEY as s, mountPerfHud as t, THEME_MODES as u };
1982
2233
 
1983
- //# sourceMappingURL=mount-perf-hud-DqY_tP6s.js.map
2234
+ //# sourceMappingURL=mount-perf-hud-CdhGeWXh.js.map