@oddsquad/vite-plugin-lit 0.3.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +118 -0
- package/README.md +26 -11
- package/bin.mjs +16 -12
- package/dist/client/assets/{browser-agent-rpc-BXhoSh1z-BvWe4sTJ.js → browser-agent-rpc-BXhoSh1z-CRHFLjFo.js} +2 -2
- package/dist/client/assets/{browser-agent-rpc-BXhoSh1z-BvWe4sTJ.js.map → browser-agent-rpc-BXhoSh1z-CRHFLjFo.js.map} +1 -1
- package/dist/client/assets/flow-DK8vmxvN.js +745 -0
- package/dist/client/assets/flow-DK8vmxvN.js.map +1 -0
- package/dist/client/assets/{index-CFrVgNfS.js → index-Gn4Hk_9s.js} +2749 -793
- package/dist/client/assets/index-Gn4Hk_9s.js.map +1 -0
- package/dist/client/index.html +11 -1
- package/lib/devframe/definition.d.ts +7 -0
- package/lib/devframe/definition.d.ts.map +1 -1
- package/lib/devframe/definition.js +56 -11
- package/lib/devframe/definition.js.map +1 -1
- package/lib/devframe/launch-editor.d.ts +20 -0
- package/lib/devframe/launch-editor.d.ts.map +1 -0
- package/lib/devframe/launch-editor.js +40 -0
- package/lib/devframe/launch-editor.js.map +1 -0
- package/lib/devframe/protocol.d.ts +31 -4
- package/lib/devframe/protocol.d.ts.map +1 -1
- package/lib/devframe/protocol.js +22 -3
- package/lib/devframe/protocol.js.map +1 -1
- package/lib/devframe/rpc-source.d.ts +44 -0
- package/lib/devframe/rpc-source.d.ts.map +1 -0
- package/lib/devframe/rpc-source.js +150 -0
- package/lib/devframe/rpc-source.js.map +1 -0
- package/lib/devframe/source.d.ts +12 -0
- package/lib/devframe/source.d.ts.map +1 -1
- package/lib/devframe/source.js +12 -0
- package/lib/devframe/source.js.map +1 -1
- package/lib/devframe/vite.d.ts +2 -0
- package/lib/devframe/vite.d.ts.map +1 -1
- package/lib/devframe/vite.js +3 -8
- package/lib/devframe/vite.js.map +1 -1
- package/lib/options.d.ts +136 -0
- package/lib/options.d.ts.map +1 -0
- package/lib/options.js +175 -0
- package/lib/options.js.map +1 -0
- package/lib/override-baselines.d.ts +17 -0
- package/lib/override-baselines.d.ts.map +1 -0
- package/lib/override-baselines.js +25 -0
- package/lib/override-baselines.js.map +1 -0
- package/lib/plugin.d.ts +6 -148
- package/lib/plugin.d.ts.map +1 -1
- package/lib/plugin.js +22 -477
- package/lib/plugin.js.map +1 -1
- package/lib/plugins/css-literals.d.ts +15 -0
- package/lib/plugins/css-literals.d.ts.map +1 -0
- package/lib/plugins/css-literals.js +154 -0
- package/lib/plugins/css-literals.js.map +1 -0
- package/lib/plugins/css-queries.d.ts +20 -0
- package/lib/plugins/css-queries.d.ts.map +1 -0
- package/lib/plugins/css-queries.js +139 -0
- package/lib/plugins/css-queries.js.map +1 -0
- package/lib/plugins/open-in-editor.d.ts +16 -0
- package/lib/plugins/open-in-editor.d.ts.map +1 -0
- package/lib/plugins/open-in-editor.js +96 -0
- package/lib/plugins/open-in-editor.js.map +1 -0
- package/lib/plugins/shared.d.ts +13 -0
- package/lib/plugins/shared.d.ts.map +1 -0
- package/lib/plugins/shared.js +23 -0
- package/lib/plugins/shared.js.map +1 -0
- package/lib/plugins/timeline-virtual.d.ts +19 -0
- package/lib/plugins/timeline-virtual.d.ts.map +1 -0
- package/lib/plugins/timeline-virtual.js +53 -0
- package/lib/plugins/timeline-virtual.js.map +1 -0
- package/lib/runtime/css.d.ts.map +1 -1
- package/lib/runtime/css.js +9 -2
- package/lib/runtime/css.js.map +1 -1
- package/lib/runtime/indicator.js.map +1 -1
- package/lib/runtime/inspector/install.js +65 -13
- package/lib/runtime/inspector/install.js.map +1 -1
- package/lib/runtime/inspector/serialize.d.ts.map +1 -1
- package/lib/runtime/inspector/serialize.js +20 -0
- package/lib/runtime/inspector/serialize.js.map +1 -1
- package/lib/runtime/overrides.d.ts +4 -10
- package/lib/runtime/overrides.d.ts.map +1 -1
- package/lib/runtime/overrides.js +5 -3
- package/lib/runtime/overrides.js.map +1 -1
- package/lib/runtime/page-channel.d.ts +52 -0
- package/lib/runtime/page-channel.d.ts.map +1 -0
- package/lib/runtime/page-channel.js +67 -0
- package/lib/runtime/page-channel.js.map +1 -0
- package/lib/runtime/patch.d.ts.map +1 -1
- package/lib/runtime/patch.js +2 -1
- package/lib/runtime/patch.js.map +1 -1
- package/lib/runtime/rpc-transport.d.ts +46 -0
- package/lib/runtime/rpc-transport.d.ts.map +1 -0
- package/lib/runtime/rpc-transport.js +82 -0
- package/lib/runtime/rpc-transport.js.map +1 -0
- package/lib/runtime/source-overlay/overlay-element.d.ts.map +1 -1
- package/lib/runtime/source-overlay/overlay-element.js +30 -7
- package/lib/runtime/source-overlay/overlay-element.js.map +1 -1
- package/lib/runtime/timeline/install.js +25 -9
- package/lib/runtime/timeline/install.js.map +1 -1
- package/lib/runtime/timeline/public-api.d.ts +2 -2
- package/lib/runtime/timeline/public-api.d.ts.map +1 -1
- package/lib/runtime/timeline/public-api.js +13 -5
- package/lib/runtime/timeline/public-api.js.map +1 -1
- package/lib/runtime/timeline/render.d.ts +15 -6
- package/lib/runtime/timeline/render.d.ts.map +1 -1
- package/lib/runtime/timeline/render.js +150 -11
- package/lib/runtime/timeline/render.js.map +1 -1
- package/lib/runtime/timeline/transport.d.ts +6 -9
- package/lib/runtime/timeline/transport.d.ts.map +1 -1
- package/lib/runtime/timeline/transport.js.map +1 -1
- package/lib/timeline/filter.d.ts +38 -0
- package/lib/timeline/filter.d.ts.map +1 -0
- package/lib/timeline/filter.js +44 -0
- package/lib/timeline/filter.js.map +1 -0
- package/lib/timeline/tracks.d.ts +113 -0
- package/lib/timeline/tracks.d.ts.map +1 -0
- package/lib/timeline/tracks.js +168 -0
- package/lib/timeline/tracks.js.map +1 -0
- package/package.json +9 -1
- package/types/timeline.d.ts +50 -1
- package/types/timeline.d.ts.map +1 -1
- package/types/timeline.js +4 -0
- package/types/timeline.js.map +1 -1
- package/dist/client/assets/index-CFrVgNfS.js.map +0 -1
- package/lib/timeline-plugin.d.ts +0 -72
- package/lib/timeline-plugin.d.ts.map +0 -1
- package/lib/timeline-plugin.js +0 -359
- package/lib/timeline-plugin.js.map +0 -1
|
@@ -1044,103 +1044,12 @@ var setColorSchemePreference = (pref) => {
|
|
|
1044
1044
|
localStorage.setItem(COLOR_SCHEME_LS_KEY, pref);
|
|
1045
1045
|
} catch {}
|
|
1046
1046
|
applyColorScheme(pref);
|
|
1047
|
-
}
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
1054
|
-
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
1055
|
-
}
|
|
1056
|
-
//#endregion
|
|
1057
|
-
//#region src/panel/timeline-layers.ts
|
|
1058
|
-
/**
|
|
1059
|
-
* @license
|
|
1060
|
-
* Copyright 2026 Google LLC
|
|
1061
|
-
* SPDX-License-Identifier: BSD-3-Clause
|
|
1062
|
-
*/
|
|
1063
|
-
var TimelineLayers = class TimelineLayers extends i$2 {
|
|
1064
|
-
constructor(..._args) {
|
|
1065
|
-
super(..._args);
|
|
1066
|
-
this.layers = [];
|
|
1067
|
-
}
|
|
1068
|
-
static {
|
|
1069
|
-
this.styles = [tokens, i$5`
|
|
1070
|
-
:host {
|
|
1071
|
-
display: flex;
|
|
1072
|
-
gap: var(--lit-devtools-space-2);
|
|
1073
|
-
padding: var(--lit-devtools-space-3) var(--lit-devtools-space-5);
|
|
1074
|
-
border-bottom: 1px solid var(--lit-devtools-border);
|
|
1075
|
-
background: var(--lit-devtools-surface-low);
|
|
1076
|
-
flex-shrink: 0;
|
|
1077
|
-
flex-wrap: wrap;
|
|
1078
|
-
}
|
|
1079
|
-
button {
|
|
1080
|
-
display: flex;
|
|
1081
|
-
align-items: center;
|
|
1082
|
-
gap: var(--lit-devtools-space-2);
|
|
1083
|
-
padding: var(--lit-devtools-space-2) var(--lit-devtools-space-4);
|
|
1084
|
-
border-radius: var(--lit-devtools-radius-pill);
|
|
1085
|
-
background: var(--lit-devtools-surface-elevated);
|
|
1086
|
-
border: 1px solid transparent;
|
|
1087
|
-
color: var(--lit-devtools-text-secondary);
|
|
1088
|
-
font-size: var(--lit-devtools-text-2xs);
|
|
1089
|
-
cursor: pointer;
|
|
1090
|
-
user-select: none;
|
|
1091
|
-
transition: opacity var(--lit-devtools-dur-fast)
|
|
1092
|
-
var(--lit-devtools-ease-standard);
|
|
1093
|
-
}
|
|
1094
|
-
button.on {
|
|
1095
|
-
color: var(--lit-devtools-text);
|
|
1096
|
-
}
|
|
1097
|
-
button:hover {
|
|
1098
|
-
background: var(--lit-devtools-surface-hover);
|
|
1099
|
-
}
|
|
1100
|
-
.dot {
|
|
1101
|
-
width: 8px;
|
|
1102
|
-
height: 8px;
|
|
1103
|
-
border-radius: 50%;
|
|
1104
|
-
flex-shrink: 0;
|
|
1105
|
-
opacity: 0.4;
|
|
1106
|
-
}
|
|
1107
|
-
button.on .dot {
|
|
1108
|
-
opacity: 1;
|
|
1109
|
-
}
|
|
1110
|
-
`];
|
|
1111
|
-
}
|
|
1112
|
-
_toggle(id) {
|
|
1113
|
-
this.dispatchEvent(new CustomEvent("layer-toggle", {
|
|
1114
|
-
detail: { id },
|
|
1115
|
-
bubbles: true,
|
|
1116
|
-
composed: true
|
|
1117
|
-
}));
|
|
1118
|
-
}
|
|
1119
|
-
render() {
|
|
1120
|
-
return b`${this.layers.map((l) => b`
|
|
1121
|
-
<button
|
|
1122
|
-
class=${l.enabled ? "on" : ""}
|
|
1123
|
-
title=${l.enabled ? `Hide ${l.label}` : `Show ${l.label}`}
|
|
1124
|
-
@click=${() => this._toggle(l.id)}
|
|
1125
|
-
>
|
|
1126
|
-
<span
|
|
1127
|
-
class="dot"
|
|
1128
|
-
style=${"background:#" + l.color.toString(16).padStart(6, "0")}
|
|
1129
|
-
></span>
|
|
1130
|
-
${l.label}
|
|
1131
|
-
</button>
|
|
1132
|
-
`)}`;
|
|
1133
|
-
}
|
|
1134
|
-
};
|
|
1135
|
-
__decorate([n$3({ type: Array })], TimelineLayers.prototype, "layers", void 0);
|
|
1136
|
-
TimelineLayers = __decorate([t$2("timeline-layers")], TimelineLayers);
|
|
1137
|
-
//#endregion
|
|
1138
|
-
//#region node_modules/.pnpm/lit-html@3.3.3/node_modules/lit-html/directive-helpers.js
|
|
1139
|
-
/**
|
|
1140
|
-
* @license
|
|
1141
|
-
* Copyright 2020 Google LLC
|
|
1142
|
-
* SPDX-License-Identifier: BSD-3-Clause
|
|
1143
|
-
*/ var { I: t$1 } = j$1, i$1 = (o) => o, r$1 = (o) => void 0 === o.strings, s$1 = () => document.createComment(""), v = (o, n, e) => {
|
|
1047
|
+
}, { I: t$1 } = j$1, i$1 = (o) => o, r$1 = (o) => void 0 === o.strings, s$1 = () => document.createComment(""), v = (o, n, e) => {
|
|
1048
|
+
/**
|
|
1049
|
+
* @license
|
|
1050
|
+
* Copyright 2020 Google LLC
|
|
1051
|
+
* SPDX-License-Identifier: BSD-3-Clause
|
|
1052
|
+
*/
|
|
1144
1053
|
const l = o._$AA.parentNode, d = void 0 === n ? o._$AB : n._$AA;
|
|
1145
1054
|
if (void 0 === e) e = new t$1(l.insertBefore(s$1(), d), l.insertBefore(s$1(), d), o, o.options);
|
|
1146
1055
|
else {
|
|
@@ -1289,67 +1198,6 @@ var n = e$1(class extends f {
|
|
|
1289
1198
|
}
|
|
1290
1199
|
});
|
|
1291
1200
|
//#endregion
|
|
1292
|
-
//#region node_modules/.pnpm/lit-html@3.3.3/node_modules/lit-html/directives/repeat.js
|
|
1293
|
-
/**
|
|
1294
|
-
* @license
|
|
1295
|
-
* Copyright 2017 Google LLC
|
|
1296
|
-
* SPDX-License-Identifier: BSD-3-Clause
|
|
1297
|
-
*/
|
|
1298
|
-
var u = (e, s, t) => {
|
|
1299
|
-
const r = /* @__PURE__ */ new Map();
|
|
1300
|
-
for (let l = s; l <= t; l++) r.set(e[l], l);
|
|
1301
|
-
return r;
|
|
1302
|
-
};
|
|
1303
|
-
var c = e$1(class extends i {
|
|
1304
|
-
constructor(e) {
|
|
1305
|
-
if (super(e), e.type !== t.CHILD) throw Error("repeat() can only be used in text expressions");
|
|
1306
|
-
}
|
|
1307
|
-
dt(e, s, t) {
|
|
1308
|
-
let r;
|
|
1309
|
-
void 0 === t ? t = s : void 0 !== s && (r = s);
|
|
1310
|
-
const l = [], o = [];
|
|
1311
|
-
let i = 0;
|
|
1312
|
-
for (const s of e) l[i] = r ? r(s, i) : i, o[i] = t(s, i), i++;
|
|
1313
|
-
return {
|
|
1314
|
-
values: o,
|
|
1315
|
-
keys: l
|
|
1316
|
-
};
|
|
1317
|
-
}
|
|
1318
|
-
render(e, s, t) {
|
|
1319
|
-
return this.dt(e, s, t).values;
|
|
1320
|
-
}
|
|
1321
|
-
update(s, [t, r, c]) {
|
|
1322
|
-
const d = M(s), { values: p$3, keys: a } = this.dt(t, r, c);
|
|
1323
|
-
if (!Array.isArray(d)) return this.ut = a, p$3;
|
|
1324
|
-
const h = this.ut ??= [], v$2 = [];
|
|
1325
|
-
let m, y, x = 0, j = d.length - 1, k = 0, w = p$3.length - 1;
|
|
1326
|
-
for (; x <= j && k <= w;) if (null === d[x]) x++;
|
|
1327
|
-
else if (null === d[j]) j--;
|
|
1328
|
-
else if (h[x] === a[k]) v$2[k] = u$1(d[x], p$3[k]), x++, k++;
|
|
1329
|
-
else if (h[j] === a[w]) v$2[w] = u$1(d[j], p$3[w]), j--, w--;
|
|
1330
|
-
else if (h[x] === a[w]) v$2[w] = u$1(d[x], p$3[w]), v(s, v$2[w + 1], d[x]), x++, w--;
|
|
1331
|
-
else if (h[j] === a[k]) v$2[k] = u$1(d[j], p$3[k]), v(s, d[x], d[j]), j--, k++;
|
|
1332
|
-
else if (void 0 === m && (m = u(a, k, w), y = u(h, x, j)), m.has(h[x])) if (m.has(h[j])) {
|
|
1333
|
-
const e = y.get(a[k]), t = void 0 !== e ? d[e] : null;
|
|
1334
|
-
if (null === t) {
|
|
1335
|
-
const e = v(s, d[x]);
|
|
1336
|
-
u$1(e, p$3[k]), v$2[k] = e;
|
|
1337
|
-
} else v$2[k] = u$1(t, p$3[k]), v(s, d[x], t), d[e] = null;
|
|
1338
|
-
k++;
|
|
1339
|
-
} else h$2(d[j]), j--;
|
|
1340
|
-
else h$2(d[x]), x++;
|
|
1341
|
-
for (; k <= w;) {
|
|
1342
|
-
const e = v(s, v$2[w + 1]);
|
|
1343
|
-
u$1(e, p$3[k]), v$2[k++] = e;
|
|
1344
|
-
}
|
|
1345
|
-
for (; x <= j;) {
|
|
1346
|
-
const e = d[x++];
|
|
1347
|
-
null !== e && h$2(e);
|
|
1348
|
-
}
|
|
1349
|
-
return this.ut = a, p(s, v$2), E;
|
|
1350
|
-
}
|
|
1351
|
-
});
|
|
1352
|
-
//#endregion
|
|
1353
1201
|
//#region src/lib/timeline/derive.ts
|
|
1354
1202
|
/**
|
|
1355
1203
|
* @license
|
|
@@ -1560,105 +1408,1353 @@ var attributeInput = (cycles, events, windowMs = 200) => {
|
|
|
1560
1408
|
});
|
|
1561
1409
|
};
|
|
1562
1410
|
//#endregion
|
|
1563
|
-
//#region
|
|
1564
|
-
function makeColor(open, close) {
|
|
1565
|
-
const o = `\x1B[${open}m`;
|
|
1566
|
-
const c = `\x1B[${close}m`;
|
|
1567
|
-
return ((arg, ...values) => {
|
|
1568
|
-
if (Array.isArray(arg) && "raw" in arg) {
|
|
1569
|
-
const strings = arg;
|
|
1570
|
-
let out = "";
|
|
1571
|
-
for (let i = 0; i < strings.length; i++) {
|
|
1572
|
-
out += strings[i];
|
|
1573
|
-
if (i < values.length) out += String(values[i]);
|
|
1574
|
-
}
|
|
1575
|
-
return `${o}${out}${c}`;
|
|
1576
|
-
}
|
|
1577
|
-
return `${o}${String(arg)}${c}`;
|
|
1578
|
-
});
|
|
1579
|
-
}
|
|
1580
|
-
var colors = {
|
|
1581
|
-
blue: makeColor(34, 39),
|
|
1582
|
-
cyan: makeColor(36, 39),
|
|
1583
|
-
gray: makeColor(90, 39),
|
|
1584
|
-
green: makeColor(32, 39),
|
|
1585
|
-
red: makeColor(31, 39),
|
|
1586
|
-
yellow: makeColor(33, 39),
|
|
1587
|
-
bold: makeColor(1, 22),
|
|
1588
|
-
dim: makeColor(2, 22),
|
|
1589
|
-
reset: makeColor(0, 0),
|
|
1590
|
-
underline: makeColor(4, 24)
|
|
1591
|
-
};
|
|
1592
|
-
//#endregion
|
|
1593
|
-
//#region node_modules/.pnpm/nostics@1.2.0/node_modules/nostics/dist/index.mjs
|
|
1411
|
+
//#region src/lib/timeline/filter.ts
|
|
1594
1412
|
/**
|
|
1595
|
-
*
|
|
1596
|
-
*
|
|
1597
|
-
*
|
|
1598
|
-
* @param args arguments to pass to the function if `valFn` is a function
|
|
1599
|
-
*
|
|
1600
|
-
* @internal
|
|
1413
|
+
* @license
|
|
1414
|
+
* Copyright 2026 Google LLC
|
|
1415
|
+
* SPDX-License-Identifier: BSD-3-Clause
|
|
1601
1416
|
*/
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
|
|
1608
|
-
|
|
1609
|
-
|
|
1610
|
-
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
/**
|
|
1614
|
-
* URL to extended documentation for this diagnostic code.
|
|
1615
|
-
* Auto-generated from {@link DefineDiagnosticsOptions.docsBase}.
|
|
1616
|
-
*/
|
|
1617
|
-
docs;
|
|
1618
|
-
/**
|
|
1619
|
-
* Optional actionable instructions on how to resolve the problem.
|
|
1620
|
-
*/
|
|
1621
|
-
fix;
|
|
1622
|
-
/**
|
|
1623
|
-
* Locations in user code that contributed to this diagnostic, in
|
|
1624
|
-
* `file:line:column` format. Relevant when the stack trace doesn't reflect
|
|
1625
|
-
* the user's source (e.g. compilers, bundlers), otherwise redundant with the
|
|
1626
|
-
* stack and should be omitted.
|
|
1627
|
-
*/
|
|
1628
|
-
sources;
|
|
1629
|
-
/**
|
|
1630
|
-
* Alias for {@link Error.message}: the reason this diagnostic was raised.
|
|
1631
|
-
*/
|
|
1632
|
-
get why() {
|
|
1633
|
-
return this.message;
|
|
1634
|
-
}
|
|
1635
|
-
/**
|
|
1636
|
-
* @param init structured initializer; `why` is required
|
|
1637
|
-
* @param captureFrom V8 stack-cutoff frame. Defaults to {@link Diagnostic}
|
|
1638
|
-
* so the top of the trace is the `new Diagnostic(...)` call site.
|
|
1639
|
-
* `defineDiagnostics` passes its action method to strip its own frames too.
|
|
1640
|
-
* Ignored on engines without `Error.captureStackTrace`.
|
|
1641
|
-
*/
|
|
1642
|
-
constructor(init, captureFrom = Diagnostic) {
|
|
1643
|
-
super(init.why, { cause: init.cause });
|
|
1644
|
-
this.code = this.name = init.code;
|
|
1645
|
-
this.fix = init.fix;
|
|
1646
|
-
this.docs = init.docs;
|
|
1647
|
-
this.sources = init.sources;
|
|
1648
|
-
captureStackTrace?.(this, captureFrom);
|
|
1649
|
-
}
|
|
1650
|
-
/**
|
|
1651
|
-
* Converts the diagnostic into a serializable structured object.
|
|
1652
|
-
*/
|
|
1653
|
-
toJSON() {
|
|
1417
|
+
/**
|
|
1418
|
+
* Compiles the regex box. An empty box matches everything. A pattern that
|
|
1419
|
+
* does not compile (the user is mid-typing `foo(`) disables the filter rather
|
|
1420
|
+
* than hiding every row, and is reported as `invalid` so the input can say so.
|
|
1421
|
+
*/
|
|
1422
|
+
var compileRegex = (source) => {
|
|
1423
|
+
if (source === "") return {
|
|
1424
|
+
re: null,
|
|
1425
|
+
invalid: false
|
|
1426
|
+
};
|
|
1427
|
+
try {
|
|
1654
1428
|
return {
|
|
1655
|
-
|
|
1656
|
-
|
|
1657
|
-
|
|
1658
|
-
|
|
1659
|
-
|
|
1660
|
-
|
|
1661
|
-
|
|
1429
|
+
re: new RegExp(source, "i"),
|
|
1430
|
+
invalid: false
|
|
1431
|
+
};
|
|
1432
|
+
} catch {
|
|
1433
|
+
return {
|
|
1434
|
+
re: null,
|
|
1435
|
+
invalid: true
|
|
1436
|
+
};
|
|
1437
|
+
}
|
|
1438
|
+
};
|
|
1439
|
+
/** Text the regex filter searches: element tag, name, subtitle and the
|
|
1440
|
+
* changed property keys (the reason is worth searching for by name). */
|
|
1441
|
+
var spanHaystack = (span) => `${span.meta?.tagName ?? ""} ${span.name} ${span.subtitle ?? ""} ${(span.changed ?? []).join(" ")}`;
|
|
1442
|
+
/**
|
|
1443
|
+
* Applies the element and regex filters. `re` comes from {@link compileRegex}
|
|
1444
|
+
* so a caller filtering on every keystroke compiles once, not per span.
|
|
1445
|
+
*/
|
|
1446
|
+
var filterSpans = (spans, elementId, re) => spans.filter((span) => (elementId === null || span.meta?.elementId === elementId) && (re === null || re.test(spanHaystack(span))));
|
|
1447
|
+
/** Distinct elements (by stable id) seen across the recorded events. */
|
|
1448
|
+
var listElements = (events) => {
|
|
1449
|
+
const seen = /* @__PURE__ */ new Map();
|
|
1450
|
+
for (const ev of events) {
|
|
1451
|
+
const id = ev.meta?.elementId;
|
|
1452
|
+
if (id != null && !seen.has(id)) seen.set(id, ev.meta?.tagName ?? "unknown");
|
|
1453
|
+
}
|
|
1454
|
+
return [...seen].map(([id, tag]) => ({
|
|
1455
|
+
id,
|
|
1456
|
+
tag
|
|
1457
|
+
}));
|
|
1458
|
+
};
|
|
1459
|
+
//#endregion
|
|
1460
|
+
//#region \0@oxc-project+runtime@0.149.0/helpers/esm/decorate.js
|
|
1461
|
+
function __decorate(decorators, target, key, desc) {
|
|
1462
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
1463
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
1464
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
1465
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
1466
|
+
}
|
|
1467
|
+
//#endregion
|
|
1468
|
+
//#region src/lib/segmented-tabs.ts
|
|
1469
|
+
/**
|
|
1470
|
+
* @license
|
|
1471
|
+
* Copyright 2026 Google LLC
|
|
1472
|
+
* SPDX-License-Identifier: BSD-3-Clause
|
|
1473
|
+
*/
|
|
1474
|
+
var SegmentedTabs = class SegmentedTabs extends i$2 {
|
|
1475
|
+
static {
|
|
1476
|
+
this.styles = [tokens, i$5`
|
|
1477
|
+
:host {
|
|
1478
|
+
display: flex;
|
|
1479
|
+
gap: var(--lit-devtools-space-1);
|
|
1480
|
+
align-self: stretch;
|
|
1481
|
+
}
|
|
1482
|
+
button {
|
|
1483
|
+
appearance: none;
|
|
1484
|
+
display: flex;
|
|
1485
|
+
align-items: center;
|
|
1486
|
+
gap: var(--lit-devtools-space-2);
|
|
1487
|
+
border: 0;
|
|
1488
|
+
background: none;
|
|
1489
|
+
font: inherit;
|
|
1490
|
+
color: var(--lit-devtools-text-muted);
|
|
1491
|
+
padding: 0 var(--lit-devtools-space-5);
|
|
1492
|
+
cursor: pointer;
|
|
1493
|
+
border-bottom: 2px solid transparent;
|
|
1494
|
+
white-space: nowrap;
|
|
1495
|
+
transition:
|
|
1496
|
+
color var(--lit-devtools-dur-fast) var(--lit-devtools-ease-standard),
|
|
1497
|
+
border-color var(--lit-devtools-dur-fast)
|
|
1498
|
+
var(--lit-devtools-ease-standard),
|
|
1499
|
+
background var(--lit-devtools-dur-fast)
|
|
1500
|
+
var(--lit-devtools-ease-standard);
|
|
1501
|
+
}
|
|
1502
|
+
button:hover {
|
|
1503
|
+
color: var(--lit-devtools-text);
|
|
1504
|
+
background: var(--lit-devtools-surface-hover);
|
|
1505
|
+
}
|
|
1506
|
+
button.active {
|
|
1507
|
+
color: var(--lit-devtools-accent);
|
|
1508
|
+
border-bottom-color: var(--lit-devtools-accent);
|
|
1509
|
+
}
|
|
1510
|
+
button:focus-visible {
|
|
1511
|
+
outline: 2px solid var(--lit-devtools-accent-ring);
|
|
1512
|
+
outline-offset: -2px;
|
|
1513
|
+
}
|
|
1514
|
+
button svg {
|
|
1515
|
+
width: 18px;
|
|
1516
|
+
height: 18px;
|
|
1517
|
+
flex-shrink: 0;
|
|
1518
|
+
}
|
|
1519
|
+
.badge {
|
|
1520
|
+
flex-shrink: 0;
|
|
1521
|
+
min-width: 16px;
|
|
1522
|
+
padding: 0 var(--lit-devtools-space-1);
|
|
1523
|
+
border-radius: var(--lit-devtools-radius-pill);
|
|
1524
|
+
background: var(--lit-devtools-error-soft);
|
|
1525
|
+
color: var(--lit-devtools-error);
|
|
1526
|
+
font-size: var(--lit-devtools-text-xs);
|
|
1527
|
+
line-height: 16px;
|
|
1528
|
+
text-align: center;
|
|
1529
|
+
}
|
|
1530
|
+
:host([size='sm']) button {
|
|
1531
|
+
font-size: var(--lit-devtools-text-xs);
|
|
1532
|
+
padding: 0 var(--lit-devtools-space-4);
|
|
1533
|
+
}
|
|
1534
|
+
:host([size='md']) button,
|
|
1535
|
+
:host(:not([size])) button {
|
|
1536
|
+
font-size: var(--lit-devtools-text-sm);
|
|
1537
|
+
padding: 0 var(--lit-devtools-space-5);
|
|
1538
|
+
}
|
|
1539
|
+
`];
|
|
1540
|
+
}
|
|
1541
|
+
constructor() {
|
|
1542
|
+
super();
|
|
1543
|
+
this.items = [];
|
|
1544
|
+
this.value = "";
|
|
1545
|
+
this.size = "md";
|
|
1546
|
+
}
|
|
1547
|
+
_select(id) {
|
|
1548
|
+
this.value = id;
|
|
1549
|
+
this.dispatchEvent(new CustomEvent("change", {
|
|
1550
|
+
detail: { value: id },
|
|
1551
|
+
bubbles: true,
|
|
1552
|
+
composed: true
|
|
1553
|
+
}));
|
|
1554
|
+
}
|
|
1555
|
+
render() {
|
|
1556
|
+
return b`
|
|
1557
|
+
${this.items.map((item) => b`
|
|
1558
|
+
<button
|
|
1559
|
+
role="tab"
|
|
1560
|
+
aria-selected=${item.id === this.value}
|
|
1561
|
+
class=${item.id === this.value ? "active" : ""}
|
|
1562
|
+
@click=${() => this._select(item.id)}
|
|
1563
|
+
>
|
|
1564
|
+
${item.icon ? b`<svg
|
|
1565
|
+
viewBox="0 0 256 256"
|
|
1566
|
+
fill="currentColor"
|
|
1567
|
+
aria-hidden="true"
|
|
1568
|
+
>
|
|
1569
|
+
<path d=${item.icon} />
|
|
1570
|
+
</svg>` : A}
|
|
1571
|
+
${item.label}
|
|
1572
|
+
${item.badge ? b`<span class="badge">${item.badge}</span>` : A}
|
|
1573
|
+
</button>
|
|
1574
|
+
`)}
|
|
1575
|
+
`;
|
|
1576
|
+
}
|
|
1577
|
+
};
|
|
1578
|
+
__decorate([n$3({ type: Array })], SegmentedTabs.prototype, "items", void 0);
|
|
1579
|
+
__decorate([n$3()], SegmentedTabs.prototype, "value", void 0);
|
|
1580
|
+
__decorate([n$3()], SegmentedTabs.prototype, "size", void 0);
|
|
1581
|
+
SegmentedTabs = __decorate([t$2("segmented-tabs")], SegmentedTabs);
|
|
1582
|
+
//#endregion
|
|
1583
|
+
//#region src/panel/timeline-layers.ts
|
|
1584
|
+
/**
|
|
1585
|
+
* @license
|
|
1586
|
+
* Copyright 2026 Google LLC
|
|
1587
|
+
* SPDX-License-Identifier: BSD-3-Clause
|
|
1588
|
+
*/
|
|
1589
|
+
/** A layer's `0xRRGGBB` colour as a CSS hex string. */
|
|
1590
|
+
var hexColor = (color) => "#" + color.toString(16).padStart(6, "0");
|
|
1591
|
+
/** CSS colour of layer `id`, grey for a layer `layers` does not know. */
|
|
1592
|
+
var layerColor = (layers, id) => {
|
|
1593
|
+
const layer = layers.find((l) => l.id === id);
|
|
1594
|
+
return layer ? hexColor(layer.color) : "#888";
|
|
1595
|
+
};
|
|
1596
|
+
var TimelineLayers = class TimelineLayers extends i$2 {
|
|
1597
|
+
constructor(..._args) {
|
|
1598
|
+
super(..._args);
|
|
1599
|
+
this.layers = [];
|
|
1600
|
+
this.caption = "";
|
|
1601
|
+
}
|
|
1602
|
+
static {
|
|
1603
|
+
this.styles = [tokens, i$5`
|
|
1604
|
+
:host {
|
|
1605
|
+
display: flex;
|
|
1606
|
+
gap: var(--lit-devtools-space-2);
|
|
1607
|
+
padding: var(--lit-devtools-space-3) var(--lit-devtools-space-5);
|
|
1608
|
+
border-bottom: 1px solid var(--lit-devtools-border);
|
|
1609
|
+
background: var(--lit-devtools-surface-low);
|
|
1610
|
+
flex-shrink: 0;
|
|
1611
|
+
flex-wrap: wrap;
|
|
1612
|
+
}
|
|
1613
|
+
button {
|
|
1614
|
+
display: flex;
|
|
1615
|
+
align-items: center;
|
|
1616
|
+
gap: var(--lit-devtools-space-2);
|
|
1617
|
+
padding: var(--lit-devtools-space-2) var(--lit-devtools-space-4);
|
|
1618
|
+
border-radius: var(--lit-devtools-radius-pill);
|
|
1619
|
+
background: var(--lit-devtools-surface-elevated);
|
|
1620
|
+
border: 1px solid transparent;
|
|
1621
|
+
color: var(--lit-devtools-text-secondary);
|
|
1622
|
+
font-size: var(--lit-devtools-text-2xs);
|
|
1623
|
+
cursor: pointer;
|
|
1624
|
+
user-select: none;
|
|
1625
|
+
transition: opacity var(--lit-devtools-dur-fast)
|
|
1626
|
+
var(--lit-devtools-ease-standard);
|
|
1627
|
+
}
|
|
1628
|
+
button.on {
|
|
1629
|
+
color: var(--lit-devtools-text);
|
|
1630
|
+
}
|
|
1631
|
+
button:hover {
|
|
1632
|
+
background: var(--lit-devtools-surface-hover);
|
|
1633
|
+
}
|
|
1634
|
+
.caption {
|
|
1635
|
+
align-self: center;
|
|
1636
|
+
color: var(--lit-devtools-text-muted);
|
|
1637
|
+
font-size: var(--lit-devtools-text-2xs);
|
|
1638
|
+
margin-right: var(--lit-devtools-space-2);
|
|
1639
|
+
}
|
|
1640
|
+
.dot {
|
|
1641
|
+
width: 8px;
|
|
1642
|
+
height: 8px;
|
|
1643
|
+
border-radius: 50%;
|
|
1644
|
+
flex-shrink: 0;
|
|
1645
|
+
opacity: 0.4;
|
|
1646
|
+
}
|
|
1647
|
+
button.on .dot {
|
|
1648
|
+
opacity: 1;
|
|
1649
|
+
}
|
|
1650
|
+
`];
|
|
1651
|
+
}
|
|
1652
|
+
_toggle(id) {
|
|
1653
|
+
this.dispatchEvent(new CustomEvent("layer-toggle", {
|
|
1654
|
+
detail: { id },
|
|
1655
|
+
bubbles: true,
|
|
1656
|
+
composed: true
|
|
1657
|
+
}));
|
|
1658
|
+
}
|
|
1659
|
+
render() {
|
|
1660
|
+
return b`${this.caption ? b`<span class="caption">${this.caption}</span>` : A}${this.layers.map((l) => b`
|
|
1661
|
+
<button
|
|
1662
|
+
class=${l.enabled ? "on" : ""}
|
|
1663
|
+
title=${l.enabled ? `Hide ${l.label}` : `Show ${l.label}`}
|
|
1664
|
+
@click=${() => this._toggle(l.id)}
|
|
1665
|
+
>
|
|
1666
|
+
<span class="dot" style=${"background:" + hexColor(l.color)}></span>
|
|
1667
|
+
${l.label}
|
|
1668
|
+
</button>
|
|
1669
|
+
`)}`;
|
|
1670
|
+
}
|
|
1671
|
+
};
|
|
1672
|
+
__decorate([n$3({ type: Array })], TimelineLayers.prototype, "layers", void 0);
|
|
1673
|
+
__decorate([n$3()], TimelineLayers.prototype, "caption", void 0);
|
|
1674
|
+
TimelineLayers = __decorate([t$2("timeline-layers")], TimelineLayers);
|
|
1675
|
+
//#endregion
|
|
1676
|
+
//#region node_modules/.pnpm/lit-html@3.3.3/node_modules/lit-html/directives/repeat.js
|
|
1677
|
+
/**
|
|
1678
|
+
* @license
|
|
1679
|
+
* Copyright 2017 Google LLC
|
|
1680
|
+
* SPDX-License-Identifier: BSD-3-Clause
|
|
1681
|
+
*/
|
|
1682
|
+
var u = (e, s, t) => {
|
|
1683
|
+
const r = /* @__PURE__ */ new Map();
|
|
1684
|
+
for (let l = s; l <= t; l++) r.set(e[l], l);
|
|
1685
|
+
return r;
|
|
1686
|
+
};
|
|
1687
|
+
var c = e$1(class extends i {
|
|
1688
|
+
constructor(e) {
|
|
1689
|
+
if (super(e), e.type !== t.CHILD) throw Error("repeat() can only be used in text expressions");
|
|
1690
|
+
}
|
|
1691
|
+
dt(e, s, t) {
|
|
1692
|
+
let r;
|
|
1693
|
+
void 0 === t ? t = s : void 0 !== s && (r = s);
|
|
1694
|
+
const l = [], o = [];
|
|
1695
|
+
let i = 0;
|
|
1696
|
+
for (const s of e) l[i] = r ? r(s, i) : i, o[i] = t(s, i), i++;
|
|
1697
|
+
return {
|
|
1698
|
+
values: o,
|
|
1699
|
+
keys: l
|
|
1700
|
+
};
|
|
1701
|
+
}
|
|
1702
|
+
render(e, s, t) {
|
|
1703
|
+
return this.dt(e, s, t).values;
|
|
1704
|
+
}
|
|
1705
|
+
update(s, [t, r, c]) {
|
|
1706
|
+
const d = M(s), { values: p$3, keys: a } = this.dt(t, r, c);
|
|
1707
|
+
if (!Array.isArray(d)) return this.ut = a, p$3;
|
|
1708
|
+
const h = this.ut ??= [], v$2 = [];
|
|
1709
|
+
let m, y, x = 0, j = d.length - 1, k = 0, w = p$3.length - 1;
|
|
1710
|
+
for (; x <= j && k <= w;) if (null === d[x]) x++;
|
|
1711
|
+
else if (null === d[j]) j--;
|
|
1712
|
+
else if (h[x] === a[k]) v$2[k] = u$1(d[x], p$3[k]), x++, k++;
|
|
1713
|
+
else if (h[j] === a[w]) v$2[w] = u$1(d[j], p$3[w]), j--, w--;
|
|
1714
|
+
else if (h[x] === a[w]) v$2[w] = u$1(d[x], p$3[w]), v(s, v$2[w + 1], d[x]), x++, w--;
|
|
1715
|
+
else if (h[j] === a[k]) v$2[k] = u$1(d[j], p$3[k]), v(s, d[x], d[j]), j--, k++;
|
|
1716
|
+
else if (void 0 === m && (m = u(a, k, w), y = u(h, x, j)), m.has(h[x])) if (m.has(h[j])) {
|
|
1717
|
+
const e = y.get(a[k]), t = void 0 !== e ? d[e] : null;
|
|
1718
|
+
if (null === t) {
|
|
1719
|
+
const e = v(s, d[x]);
|
|
1720
|
+
u$1(e, p$3[k]), v$2[k] = e;
|
|
1721
|
+
} else v$2[k] = u$1(t, p$3[k]), v(s, d[x], t), d[e] = null;
|
|
1722
|
+
k++;
|
|
1723
|
+
} else h$2(d[j]), j--;
|
|
1724
|
+
else h$2(d[x]), x++;
|
|
1725
|
+
for (; k <= w;) {
|
|
1726
|
+
const e = v(s, v$2[w + 1]);
|
|
1727
|
+
u$1(e, p$3[k]), v$2[k++] = e;
|
|
1728
|
+
}
|
|
1729
|
+
for (; x <= j;) {
|
|
1730
|
+
const e = d[x++];
|
|
1731
|
+
null !== e && h$2(e);
|
|
1732
|
+
}
|
|
1733
|
+
return this.ut = a, p(s, v$2), E;
|
|
1734
|
+
}
|
|
1735
|
+
});
|
|
1736
|
+
//#endregion
|
|
1737
|
+
//#region node_modules/.pnpm/@lit-labs+virtualizer@2.1.1/node_modules/@lit-labs/virtualizer/events.js
|
|
1738
|
+
/**
|
|
1739
|
+
* @license
|
|
1740
|
+
* Copyright 2021 Google LLC
|
|
1741
|
+
* SPDX-License-Identifier: BSD-3-Clause
|
|
1742
|
+
*/
|
|
1743
|
+
var RangeChangedEvent = class RangeChangedEvent extends Event {
|
|
1744
|
+
constructor(range) {
|
|
1745
|
+
super(RangeChangedEvent.eventName, { bubbles: false });
|
|
1746
|
+
this.first = range.first;
|
|
1747
|
+
this.last = range.last;
|
|
1748
|
+
}
|
|
1749
|
+
};
|
|
1750
|
+
RangeChangedEvent.eventName = "rangeChanged";
|
|
1751
|
+
var VisibilityChangedEvent = class VisibilityChangedEvent extends Event {
|
|
1752
|
+
constructor(range) {
|
|
1753
|
+
super(VisibilityChangedEvent.eventName, { bubbles: false });
|
|
1754
|
+
this.first = range.first;
|
|
1755
|
+
this.last = range.last;
|
|
1756
|
+
}
|
|
1757
|
+
};
|
|
1758
|
+
VisibilityChangedEvent.eventName = "visibilityChanged";
|
|
1759
|
+
var UnpinnedEvent = class UnpinnedEvent extends Event {
|
|
1760
|
+
constructor() {
|
|
1761
|
+
super(UnpinnedEvent.eventName, { bubbles: false });
|
|
1762
|
+
}
|
|
1763
|
+
};
|
|
1764
|
+
UnpinnedEvent.eventName = "unpinned";
|
|
1765
|
+
//#endregion
|
|
1766
|
+
//#region node_modules/.pnpm/@lit-labs+virtualizer@2.1.1/node_modules/@lit-labs/virtualizer/ScrollerController.js
|
|
1767
|
+
/**
|
|
1768
|
+
* @license
|
|
1769
|
+
* Copyright 2021 Google LLC
|
|
1770
|
+
* SPDX-License-Identifier: BSD-3-Clause
|
|
1771
|
+
*/
|
|
1772
|
+
var ScrollerShim = class {
|
|
1773
|
+
constructor(element) {
|
|
1774
|
+
this._element = null;
|
|
1775
|
+
const node = element ?? window;
|
|
1776
|
+
this._node = node;
|
|
1777
|
+
if (element) this._element = element;
|
|
1778
|
+
}
|
|
1779
|
+
get element() {
|
|
1780
|
+
return this._element || document.scrollingElement || document.documentElement;
|
|
1781
|
+
}
|
|
1782
|
+
get scrollTop() {
|
|
1783
|
+
return this.element.scrollTop || window.scrollY;
|
|
1784
|
+
}
|
|
1785
|
+
get scrollLeft() {
|
|
1786
|
+
return this.element.scrollLeft || window.scrollX;
|
|
1787
|
+
}
|
|
1788
|
+
get scrollHeight() {
|
|
1789
|
+
return this.element.scrollHeight;
|
|
1790
|
+
}
|
|
1791
|
+
get scrollWidth() {
|
|
1792
|
+
return this.element.scrollWidth;
|
|
1793
|
+
}
|
|
1794
|
+
get viewportHeight() {
|
|
1795
|
+
return this._element ? this._element.getBoundingClientRect().height : window.innerHeight;
|
|
1796
|
+
}
|
|
1797
|
+
get viewportWidth() {
|
|
1798
|
+
return this._element ? this._element.getBoundingClientRect().width : window.innerWidth;
|
|
1799
|
+
}
|
|
1800
|
+
get maxScrollTop() {
|
|
1801
|
+
return this.scrollHeight - this.viewportHeight;
|
|
1802
|
+
}
|
|
1803
|
+
get maxScrollLeft() {
|
|
1804
|
+
return this.scrollWidth - this.viewportWidth;
|
|
1805
|
+
}
|
|
1806
|
+
};
|
|
1807
|
+
var ScrollerController = class extends ScrollerShim {
|
|
1808
|
+
constructor(client, element) {
|
|
1809
|
+
super(element);
|
|
1810
|
+
this._clients = /* @__PURE__ */ new Set();
|
|
1811
|
+
this._retarget = null;
|
|
1812
|
+
this._end = null;
|
|
1813
|
+
this.__destination = null;
|
|
1814
|
+
this.correctingScrollError = false;
|
|
1815
|
+
this._checkForArrival = this._checkForArrival.bind(this);
|
|
1816
|
+
this._updateManagedScrollTo = this._updateManagedScrollTo.bind(this);
|
|
1817
|
+
this.scrollTo = this.scrollTo.bind(this);
|
|
1818
|
+
this.scrollBy = this.scrollBy.bind(this);
|
|
1819
|
+
const node = this._node;
|
|
1820
|
+
this._originalScrollTo = node.scrollTo;
|
|
1821
|
+
this._originalScrollBy = node.scrollBy;
|
|
1822
|
+
this._originalScroll = node.scroll;
|
|
1823
|
+
this._attach(client);
|
|
1824
|
+
}
|
|
1825
|
+
get _destination() {
|
|
1826
|
+
return this.__destination;
|
|
1827
|
+
}
|
|
1828
|
+
get scrolling() {
|
|
1829
|
+
return this._destination !== null;
|
|
1830
|
+
}
|
|
1831
|
+
scrollTo(p1, p2) {
|
|
1832
|
+
const options = typeof p1 === "number" && typeof p2 === "number" ? {
|
|
1833
|
+
left: p1,
|
|
1834
|
+
top: p2
|
|
1835
|
+
} : p1;
|
|
1836
|
+
this._scrollTo(options);
|
|
1837
|
+
}
|
|
1838
|
+
scrollBy(p1, p2) {
|
|
1839
|
+
const options = typeof p1 === "number" && typeof p2 === "number" ? {
|
|
1840
|
+
left: p1,
|
|
1841
|
+
top: p2
|
|
1842
|
+
} : p1;
|
|
1843
|
+
if (options.top !== void 0) options.top += this.scrollTop;
|
|
1844
|
+
if (options.left !== void 0) options.left += this.scrollLeft;
|
|
1845
|
+
this._scrollTo(options);
|
|
1846
|
+
}
|
|
1847
|
+
_nativeScrollTo(options) {
|
|
1848
|
+
this._originalScrollTo.bind(this._element || window)(options);
|
|
1849
|
+
}
|
|
1850
|
+
_scrollTo(options, retarget = null, end = null) {
|
|
1851
|
+
if (this._end !== null) this._end();
|
|
1852
|
+
if (options.behavior === "smooth") {
|
|
1853
|
+
this._setDestination(options);
|
|
1854
|
+
this._retarget = retarget;
|
|
1855
|
+
this._end = end;
|
|
1856
|
+
} else this._resetScrollState();
|
|
1857
|
+
this._nativeScrollTo(options);
|
|
1858
|
+
}
|
|
1859
|
+
_setDestination(options) {
|
|
1860
|
+
let { top, left } = options;
|
|
1861
|
+
top = top === void 0 ? void 0 : Math.max(0, Math.min(top, this.maxScrollTop));
|
|
1862
|
+
left = left === void 0 ? void 0 : Math.max(0, Math.min(left, this.maxScrollLeft));
|
|
1863
|
+
if (this._destination !== null && left === this._destination.left && top === this._destination.top) return false;
|
|
1864
|
+
this.__destination = {
|
|
1865
|
+
top,
|
|
1866
|
+
left,
|
|
1867
|
+
behavior: "smooth"
|
|
1868
|
+
};
|
|
1869
|
+
return true;
|
|
1870
|
+
}
|
|
1871
|
+
_resetScrollState() {
|
|
1872
|
+
this.__destination = null;
|
|
1873
|
+
this._retarget = null;
|
|
1874
|
+
this._end = null;
|
|
1875
|
+
}
|
|
1876
|
+
_updateManagedScrollTo(coordinates) {
|
|
1877
|
+
if (this._destination) {
|
|
1878
|
+
if (this._setDestination(coordinates)) this._nativeScrollTo(this._destination);
|
|
1879
|
+
}
|
|
1880
|
+
}
|
|
1881
|
+
managedScrollTo(options, retarget, end) {
|
|
1882
|
+
this._scrollTo(options, retarget, end);
|
|
1883
|
+
return this._updateManagedScrollTo;
|
|
1884
|
+
}
|
|
1885
|
+
correctScrollError(coordinates) {
|
|
1886
|
+
this.correctingScrollError = true;
|
|
1887
|
+
requestAnimationFrame(() => requestAnimationFrame(() => this.correctingScrollError = false));
|
|
1888
|
+
this._nativeScrollTo(coordinates);
|
|
1889
|
+
if (this._retarget) this._setDestination(this._retarget());
|
|
1890
|
+
if (this._destination) this._nativeScrollTo(this._destination);
|
|
1891
|
+
}
|
|
1892
|
+
_checkForArrival() {
|
|
1893
|
+
if (this._destination !== null) {
|
|
1894
|
+
const { scrollTop, scrollLeft } = this;
|
|
1895
|
+
let { top, left } = this._destination;
|
|
1896
|
+
top = Math.min(top || 0, this.maxScrollTop);
|
|
1897
|
+
left = Math.min(left || 0, this.maxScrollLeft);
|
|
1898
|
+
const topDiff = Math.abs(top - scrollTop);
|
|
1899
|
+
const leftDiff = Math.abs(left - scrollLeft);
|
|
1900
|
+
if (topDiff < 1 && leftDiff < 1) {
|
|
1901
|
+
if (this._end) this._end();
|
|
1902
|
+
this._resetScrollState();
|
|
1903
|
+
}
|
|
1904
|
+
}
|
|
1905
|
+
}
|
|
1906
|
+
detach(client) {
|
|
1907
|
+
this._clients.delete(client);
|
|
1908
|
+
/**
|
|
1909
|
+
* If there aren't any more clients, then return the node's default
|
|
1910
|
+
* scrolling methods
|
|
1911
|
+
*/
|
|
1912
|
+
if (this._clients.size === 0) {
|
|
1913
|
+
this._node.scrollTo = this._originalScrollTo;
|
|
1914
|
+
this._node.scrollBy = this._originalScrollBy;
|
|
1915
|
+
this._node.scroll = this._originalScroll;
|
|
1916
|
+
this._node.removeEventListener("scroll", this._checkForArrival);
|
|
1917
|
+
}
|
|
1918
|
+
return null;
|
|
1919
|
+
}
|
|
1920
|
+
_attach(client) {
|
|
1921
|
+
this._clients.add(client);
|
|
1922
|
+
/**
|
|
1923
|
+
* The node should only have the methods shimmed when adding the first
|
|
1924
|
+
* client – otherwise it's redundant
|
|
1925
|
+
*/
|
|
1926
|
+
if (this._clients.size === 1) {
|
|
1927
|
+
this._node.scrollTo = this.scrollTo;
|
|
1928
|
+
this._node.scrollBy = this.scrollBy;
|
|
1929
|
+
this._node.scroll = this.scrollTo;
|
|
1930
|
+
this._node.addEventListener("scroll", this._checkForArrival);
|
|
1931
|
+
}
|
|
1932
|
+
}
|
|
1933
|
+
};
|
|
1934
|
+
//#endregion
|
|
1935
|
+
//#region \0vite/preload-helper.js
|
|
1936
|
+
var scriptRel = "modulepreload";
|
|
1937
|
+
var assetsURL = function(dep, importerUrl) {
|
|
1938
|
+
return new URL(dep, importerUrl).href;
|
|
1939
|
+
};
|
|
1940
|
+
var seen = {};
|
|
1941
|
+
var __vitePreload = function preload(baseModule, deps, importerUrl) {
|
|
1942
|
+
let promise = Promise.resolve();
|
|
1943
|
+
if (deps && deps.length > 0) {
|
|
1944
|
+
const links = document.getElementsByTagName("link");
|
|
1945
|
+
const cspNonceMeta = document.querySelector("meta[property=csp-nonce]");
|
|
1946
|
+
const cspNonce = cspNonceMeta?.nonce || cspNonceMeta?.getAttribute("nonce");
|
|
1947
|
+
function allSettled(promises) {
|
|
1948
|
+
return Promise.all(promises.map((p) => Promise.resolve(p).then((value) => ({
|
|
1949
|
+
status: "fulfilled",
|
|
1950
|
+
value
|
|
1951
|
+
}), (reason) => ({
|
|
1952
|
+
status: "rejected",
|
|
1953
|
+
reason
|
|
1954
|
+
}))));
|
|
1955
|
+
}
|
|
1956
|
+
function importMetaResolve(specifier) {
|
|
1957
|
+
if (import.meta.resolve) return import.meta.resolve(specifier);
|
|
1958
|
+
return new URL(
|
|
1959
|
+
specifier,
|
|
1960
|
+
/** #__KEEP__ */
|
|
1961
|
+
import.meta.url
|
|
1962
|
+
).href;
|
|
1963
|
+
}
|
|
1964
|
+
promise = allSettled(deps.map((dep) => {
|
|
1965
|
+
dep = assetsURL(dep, importerUrl);
|
|
1966
|
+
dep = importMetaResolve(dep);
|
|
1967
|
+
if (dep in seen) return;
|
|
1968
|
+
seen[dep] = true;
|
|
1969
|
+
const isCss = dep.endsWith(".css");
|
|
1970
|
+
for (let i = links.length - 1; i >= 0; i--) {
|
|
1971
|
+
const link = links[i];
|
|
1972
|
+
if (link.href === dep && (!isCss || link.rel === "stylesheet")) return;
|
|
1973
|
+
}
|
|
1974
|
+
const link = document.createElement("link");
|
|
1975
|
+
link.rel = isCss ? "stylesheet" : scriptRel;
|
|
1976
|
+
if (!isCss) link.as = "script";
|
|
1977
|
+
link.crossOrigin = "";
|
|
1978
|
+
link.href = dep;
|
|
1979
|
+
if (cspNonce) link.setAttribute("nonce", cspNonce);
|
|
1980
|
+
document.head.appendChild(link);
|
|
1981
|
+
if (isCss) return new Promise((res, rej) => {
|
|
1982
|
+
link.addEventListener("load", res);
|
|
1983
|
+
link.addEventListener("error", () => rej(/* @__PURE__ */ new Error(`Unable to preload CSS for ${dep}`)));
|
|
1984
|
+
});
|
|
1985
|
+
}).filter((p) => p !== void 0));
|
|
1986
|
+
}
|
|
1987
|
+
function handlePreloadError(err) {
|
|
1988
|
+
const e = new Event("vite:preloadError", { cancelable: true });
|
|
1989
|
+
e.payload = err;
|
|
1990
|
+
window.dispatchEvent(e);
|
|
1991
|
+
if (!e.defaultPrevented) throw err;
|
|
1992
|
+
}
|
|
1993
|
+
return promise.then((res) => {
|
|
1994
|
+
for (const item of res || []) {
|
|
1995
|
+
if (item.status !== "rejected") continue;
|
|
1996
|
+
handlePreloadError(item.reason);
|
|
1997
|
+
}
|
|
1998
|
+
return baseModule().catch(handlePreloadError);
|
|
1999
|
+
});
|
|
2000
|
+
};
|
|
2001
|
+
//#endregion
|
|
2002
|
+
//#region node_modules/.pnpm/@lit-labs+virtualizer@2.1.1/node_modules/@lit-labs/virtualizer/Virtualizer.js
|
|
2003
|
+
/**
|
|
2004
|
+
* @license
|
|
2005
|
+
* Copyright 2021 Google LLC
|
|
2006
|
+
* SPDX-License-Identifier: BSD-3-Clause
|
|
2007
|
+
*/
|
|
2008
|
+
var _ResizeObserver = typeof window !== "undefined" ? window.ResizeObserver : void 0;
|
|
2009
|
+
var virtualizerRef = Symbol("virtualizerRef");
|
|
2010
|
+
var SIZER_ATTRIBUTE = "virtualizer-sizer";
|
|
2011
|
+
var DefaultLayoutConstructor;
|
|
2012
|
+
/**
|
|
2013
|
+
* Provides virtual scrolling boilerplate.
|
|
2014
|
+
*
|
|
2015
|
+
* Extensions of this class must set hostElement and layout.
|
|
2016
|
+
*
|
|
2017
|
+
* Extensions of this class must also override VirtualRepeater's DOM
|
|
2018
|
+
* manipulation methods.
|
|
2019
|
+
*/
|
|
2020
|
+
var Virtualizer = class {
|
|
2021
|
+
constructor(config) {
|
|
2022
|
+
this._benchmarkStart = null;
|
|
2023
|
+
this._layout = null;
|
|
2024
|
+
this._clippingAncestors = [];
|
|
2025
|
+
/**
|
|
2026
|
+
* Layout provides these values, we set them on _render().
|
|
2027
|
+
* TODO @straversi: Can we find an XOR type, usable for the key here?
|
|
2028
|
+
*/
|
|
2029
|
+
this._scrollSize = null;
|
|
2030
|
+
/**
|
|
2031
|
+
* Difference between scroll target's current and required scroll offsets.
|
|
2032
|
+
* Provided by layout.
|
|
2033
|
+
*/
|
|
2034
|
+
this._scrollError = null;
|
|
2035
|
+
/**
|
|
2036
|
+
* A list of the positions (top, left) of the children in the current range.
|
|
2037
|
+
*/
|
|
2038
|
+
this._childrenPos = null;
|
|
2039
|
+
this._childMeasurements = null;
|
|
2040
|
+
this._toBeMeasured = /* @__PURE__ */ new Map();
|
|
2041
|
+
this._rangeChanged = true;
|
|
2042
|
+
this._itemsChanged = true;
|
|
2043
|
+
this._visibilityChanged = true;
|
|
2044
|
+
this._scrollerController = null;
|
|
2045
|
+
this._isScroller = false;
|
|
2046
|
+
this._sizer = null;
|
|
2047
|
+
/**
|
|
2048
|
+
* Resize observer attached to hostElement.
|
|
2049
|
+
*/
|
|
2050
|
+
this._hostElementRO = null;
|
|
2051
|
+
/**
|
|
2052
|
+
* Resize observer attached to children.
|
|
2053
|
+
*/
|
|
2054
|
+
this._childrenRO = null;
|
|
2055
|
+
this._mutationObserver = null;
|
|
2056
|
+
this._scrollEventListeners = [];
|
|
2057
|
+
this._scrollEventListenerOptions = { passive: true };
|
|
2058
|
+
this._loadListener = this._childLoaded.bind(this);
|
|
2059
|
+
/**
|
|
2060
|
+
* Index of element to scroll into view, plus scroll
|
|
2061
|
+
* behavior options, as imperatively specified via
|
|
2062
|
+
* `element(index).scrollIntoView()`
|
|
2063
|
+
*/
|
|
2064
|
+
this._scrollIntoViewTarget = null;
|
|
2065
|
+
this._updateScrollIntoViewCoordinates = null;
|
|
2066
|
+
/**
|
|
2067
|
+
* Items to render. Set by items.
|
|
2068
|
+
*/
|
|
2069
|
+
this._items = [];
|
|
2070
|
+
/**
|
|
2071
|
+
* Index of the first child in the range, not necessarily the first visible child.
|
|
2072
|
+
* TODO @straversi: Consider renaming these.
|
|
2073
|
+
*/
|
|
2074
|
+
this._first = -1;
|
|
2075
|
+
/**
|
|
2076
|
+
* Index of the last child in the range.
|
|
2077
|
+
*/
|
|
2078
|
+
this._last = -1;
|
|
2079
|
+
/**
|
|
2080
|
+
* Index of the first item intersecting the viewport.
|
|
2081
|
+
*/
|
|
2082
|
+
this._firstVisible = -1;
|
|
2083
|
+
/**
|
|
2084
|
+
* Index of the last item intersecting the viewport.
|
|
2085
|
+
*/
|
|
2086
|
+
this._lastVisible = -1;
|
|
2087
|
+
this._scheduled = /* @__PURE__ */ new WeakSet();
|
|
2088
|
+
/**
|
|
2089
|
+
* Invoked at the end of each render cycle: children in the range are
|
|
2090
|
+
* measured, and their dimensions passed to this callback. Use it to layout
|
|
2091
|
+
* children as needed.
|
|
2092
|
+
*/
|
|
2093
|
+
this._measureCallback = null;
|
|
2094
|
+
this._measureChildOverride = null;
|
|
2095
|
+
/**
|
|
2096
|
+
* State for `layoutComplete` promise
|
|
2097
|
+
*/
|
|
2098
|
+
this._layoutCompletePromise = null;
|
|
2099
|
+
this._layoutCompleteResolver = null;
|
|
2100
|
+
this._layoutCompleteRejecter = null;
|
|
2101
|
+
this._pendingLayoutComplete = null;
|
|
2102
|
+
/**
|
|
2103
|
+
* Layout initialization is async because we dynamically load
|
|
2104
|
+
* the default layout if none is specified. This state is to track
|
|
2105
|
+
* whether init is complete.
|
|
2106
|
+
*/
|
|
2107
|
+
this._layoutInitialized = null;
|
|
2108
|
+
/**
|
|
2109
|
+
* Track connection state to guard against errors / unnecessary work
|
|
2110
|
+
*/
|
|
2111
|
+
this._connected = false;
|
|
2112
|
+
if (!config) throw new Error("Virtualizer constructor requires a configuration object");
|
|
2113
|
+
if (config.hostElement) this._init(config);
|
|
2114
|
+
else throw new Error("Virtualizer configuration requires the \"hostElement\" property");
|
|
2115
|
+
}
|
|
2116
|
+
set items(items) {
|
|
2117
|
+
if (Array.isArray(items) && items !== this._items) {
|
|
2118
|
+
this._itemsChanged = true;
|
|
2119
|
+
this._items = items;
|
|
2120
|
+
this._schedule(this._updateLayout);
|
|
2121
|
+
}
|
|
2122
|
+
}
|
|
2123
|
+
_init(config) {
|
|
2124
|
+
this._isScroller = !!config.scroller;
|
|
2125
|
+
this._initHostElement(config);
|
|
2126
|
+
const layoutConfig = config.layout || {};
|
|
2127
|
+
this._layoutInitialized = this._initLayout(layoutConfig);
|
|
2128
|
+
}
|
|
2129
|
+
_initObservers() {
|
|
2130
|
+
this._mutationObserver = new MutationObserver(this._finishDOMUpdate.bind(this));
|
|
2131
|
+
this._hostElementRO = new _ResizeObserver(() => this._hostElementSizeChanged());
|
|
2132
|
+
this._childrenRO = new _ResizeObserver(this._childrenSizeChanged.bind(this));
|
|
2133
|
+
}
|
|
2134
|
+
_initHostElement(config) {
|
|
2135
|
+
const hostElement = this._hostElement = config.hostElement;
|
|
2136
|
+
this._applyVirtualizerStyles();
|
|
2137
|
+
hostElement[virtualizerRef] = this;
|
|
2138
|
+
}
|
|
2139
|
+
connected() {
|
|
2140
|
+
this._initObservers();
|
|
2141
|
+
const includeSelf = this._isScroller;
|
|
2142
|
+
this._clippingAncestors = getClippingAncestors(this._hostElement, includeSelf);
|
|
2143
|
+
this._scrollerController = new ScrollerController(this, this._clippingAncestors[0]);
|
|
2144
|
+
this._schedule(this._updateLayout);
|
|
2145
|
+
this._observeAndListen();
|
|
2146
|
+
this._connected = true;
|
|
2147
|
+
}
|
|
2148
|
+
_observeAndListen() {
|
|
2149
|
+
this._mutationObserver.observe(this._hostElement, { childList: true });
|
|
2150
|
+
this._hostElementRO.observe(this._hostElement);
|
|
2151
|
+
this._scrollEventListeners.push(window);
|
|
2152
|
+
window.addEventListener("scroll", this, this._scrollEventListenerOptions);
|
|
2153
|
+
this._clippingAncestors.forEach((ancestor) => {
|
|
2154
|
+
ancestor.addEventListener("scroll", this, this._scrollEventListenerOptions);
|
|
2155
|
+
this._scrollEventListeners.push(ancestor);
|
|
2156
|
+
this._hostElementRO.observe(ancestor);
|
|
2157
|
+
});
|
|
2158
|
+
this._hostElementRO.observe(this._scrollerController.element);
|
|
2159
|
+
this._children.forEach((child) => this._childrenRO.observe(child));
|
|
2160
|
+
this._scrollEventListeners.forEach((target) => target.addEventListener("scroll", this, this._scrollEventListenerOptions));
|
|
2161
|
+
}
|
|
2162
|
+
disconnected() {
|
|
2163
|
+
this._scrollEventListeners.forEach((target) => target.removeEventListener("scroll", this, this._scrollEventListenerOptions));
|
|
2164
|
+
this._scrollEventListeners = [];
|
|
2165
|
+
this._clippingAncestors = [];
|
|
2166
|
+
this._scrollerController?.detach(this);
|
|
2167
|
+
this._scrollerController = null;
|
|
2168
|
+
this._mutationObserver?.disconnect();
|
|
2169
|
+
this._mutationObserver = null;
|
|
2170
|
+
this._hostElementRO?.disconnect();
|
|
2171
|
+
this._hostElementRO = null;
|
|
2172
|
+
this._childrenRO?.disconnect();
|
|
2173
|
+
this._childrenRO = null;
|
|
2174
|
+
this._rejectLayoutCompletePromise("disconnected");
|
|
2175
|
+
this._connected = false;
|
|
2176
|
+
}
|
|
2177
|
+
_applyVirtualizerStyles() {
|
|
2178
|
+
const style = this._hostElement.style;
|
|
2179
|
+
style.display = style.display || "block";
|
|
2180
|
+
style.position = style.position || "relative";
|
|
2181
|
+
style.contain = style.contain || "size layout";
|
|
2182
|
+
if (this._isScroller) {
|
|
2183
|
+
style.overflow = style.overflow || "auto";
|
|
2184
|
+
style.minHeight = style.minHeight || "150px";
|
|
2185
|
+
}
|
|
2186
|
+
}
|
|
2187
|
+
_getSizer() {
|
|
2188
|
+
const hostElement = this._hostElement;
|
|
2189
|
+
if (!this._sizer) {
|
|
2190
|
+
let sizer = hostElement.querySelector(`[${SIZER_ATTRIBUTE}]`);
|
|
2191
|
+
if (!sizer) {
|
|
2192
|
+
sizer = document.createElement("div");
|
|
2193
|
+
sizer.setAttribute(SIZER_ATTRIBUTE, "");
|
|
2194
|
+
hostElement.appendChild(sizer);
|
|
2195
|
+
}
|
|
2196
|
+
Object.assign(sizer.style, {
|
|
2197
|
+
position: "absolute",
|
|
2198
|
+
margin: "-2px 0 0 0",
|
|
2199
|
+
padding: 0,
|
|
2200
|
+
visibility: "hidden",
|
|
2201
|
+
fontSize: "2px"
|
|
2202
|
+
});
|
|
2203
|
+
sizer.textContent = " ";
|
|
2204
|
+
sizer.setAttribute(SIZER_ATTRIBUTE, "");
|
|
2205
|
+
this._sizer = sizer;
|
|
2206
|
+
}
|
|
2207
|
+
return this._sizer;
|
|
2208
|
+
}
|
|
2209
|
+
async updateLayoutConfig(layoutConfig) {
|
|
2210
|
+
await this._layoutInitialized;
|
|
2211
|
+
const Ctor = layoutConfig.type || DefaultLayoutConstructor;
|
|
2212
|
+
if (typeof Ctor === "function" && this._layout instanceof Ctor) {
|
|
2213
|
+
const config = { ...layoutConfig };
|
|
2214
|
+
delete config.type;
|
|
2215
|
+
this._layout.config = config;
|
|
2216
|
+
return true;
|
|
2217
|
+
}
|
|
2218
|
+
return false;
|
|
2219
|
+
}
|
|
2220
|
+
async _initLayout(layoutConfig) {
|
|
2221
|
+
let config;
|
|
2222
|
+
let Ctor;
|
|
2223
|
+
if (typeof layoutConfig.type === "function") {
|
|
2224
|
+
Ctor = layoutConfig.type;
|
|
2225
|
+
const copy = { ...layoutConfig };
|
|
2226
|
+
delete copy.type;
|
|
2227
|
+
config = copy;
|
|
2228
|
+
} else config = layoutConfig;
|
|
2229
|
+
if (Ctor === void 0) DefaultLayoutConstructor = Ctor = (await __vitePreload(async () => {
|
|
2230
|
+
const { FlowLayout } = await import("./flow-DK8vmxvN.js");
|
|
2231
|
+
return { FlowLayout };
|
|
2232
|
+
}, [], import.meta.url)).FlowLayout;
|
|
2233
|
+
this._layout = new Ctor((message) => this._handleLayoutMessage(message), config);
|
|
2234
|
+
if (this._layout.measureChildren && typeof this._layout.updateItemSizes === "function") {
|
|
2235
|
+
if (typeof this._layout.measureChildren === "function") this._measureChildOverride = this._layout.measureChildren;
|
|
2236
|
+
this._measureCallback = this._layout.updateItemSizes.bind(this._layout);
|
|
2237
|
+
}
|
|
2238
|
+
if (this._layout.listenForChildLoadEvents) this._hostElement.addEventListener("load", this._loadListener, true);
|
|
2239
|
+
this._schedule(this._updateLayout);
|
|
2240
|
+
}
|
|
2241
|
+
startBenchmarking() {
|
|
2242
|
+
if (this._benchmarkStart === null) this._benchmarkStart = window.performance.now();
|
|
2243
|
+
}
|
|
2244
|
+
stopBenchmarking() {
|
|
2245
|
+
if (this._benchmarkStart !== null) {
|
|
2246
|
+
const now = window.performance.now();
|
|
2247
|
+
const timeElapsed = now - this._benchmarkStart;
|
|
2248
|
+
const virtualizationTime = performance.getEntriesByName("uv-virtualizing", "measure").filter((e) => e.startTime >= this._benchmarkStart && e.startTime < now).reduce((t, m) => t + m.duration, 0);
|
|
2249
|
+
this._benchmarkStart = null;
|
|
2250
|
+
return {
|
|
2251
|
+
timeElapsed,
|
|
2252
|
+
virtualizationTime
|
|
2253
|
+
};
|
|
2254
|
+
}
|
|
2255
|
+
return null;
|
|
2256
|
+
}
|
|
2257
|
+
_measureChildren() {
|
|
2258
|
+
const mm = {};
|
|
2259
|
+
const children = this._children;
|
|
2260
|
+
const fn = this._measureChildOverride || this._measureChild;
|
|
2261
|
+
for (let i = 0; i < children.length; i++) {
|
|
2262
|
+
const child = children[i];
|
|
2263
|
+
const idx = this._first + i;
|
|
2264
|
+
if (this._itemsChanged || this._toBeMeasured.has(child)) mm[idx] = fn.call(this, child, this._items[idx]);
|
|
2265
|
+
}
|
|
2266
|
+
this._childMeasurements = mm;
|
|
2267
|
+
this._schedule(this._updateLayout);
|
|
2268
|
+
this._toBeMeasured.clear();
|
|
2269
|
+
}
|
|
2270
|
+
/**
|
|
2271
|
+
* Returns the width, height, and margins of the given child.
|
|
2272
|
+
*/
|
|
2273
|
+
_measureChild(element) {
|
|
2274
|
+
const { width, height } = element.getBoundingClientRect();
|
|
2275
|
+
return Object.assign({
|
|
2276
|
+
width,
|
|
2277
|
+
height
|
|
2278
|
+
}, getMargins(element));
|
|
2279
|
+
}
|
|
2280
|
+
async _schedule(method) {
|
|
2281
|
+
if (!this._scheduled.has(method)) {
|
|
2282
|
+
this._scheduled.add(method);
|
|
2283
|
+
await Promise.resolve();
|
|
2284
|
+
this._scheduled.delete(method);
|
|
2285
|
+
method.call(this);
|
|
2286
|
+
}
|
|
2287
|
+
}
|
|
2288
|
+
async _updateDOM(state) {
|
|
2289
|
+
this._scrollSize = state.scrollSize;
|
|
2290
|
+
this._adjustRange(state.range);
|
|
2291
|
+
this._childrenPos = state.childPositions;
|
|
2292
|
+
this._scrollError = state.scrollError || null;
|
|
2293
|
+
const { _rangeChanged, _itemsChanged } = this;
|
|
2294
|
+
if (this._visibilityChanged) {
|
|
2295
|
+
this._notifyVisibility();
|
|
2296
|
+
this._visibilityChanged = false;
|
|
2297
|
+
}
|
|
2298
|
+
if (_rangeChanged || _itemsChanged) {
|
|
2299
|
+
this._notifyRange();
|
|
2300
|
+
this._rangeChanged = false;
|
|
2301
|
+
}
|
|
2302
|
+
this._finishDOMUpdate();
|
|
2303
|
+
}
|
|
2304
|
+
_finishDOMUpdate() {
|
|
2305
|
+
if (this._connected) {
|
|
2306
|
+
this._children.forEach((child) => this._childrenRO.observe(child));
|
|
2307
|
+
this._checkScrollIntoViewTarget(this._childrenPos);
|
|
2308
|
+
this._positionChildren(this._childrenPos);
|
|
2309
|
+
this._sizeHostElement(this._scrollSize);
|
|
2310
|
+
this._correctScrollError();
|
|
2311
|
+
if (this._benchmarkStart && "mark" in window.performance) window.performance.mark("uv-end");
|
|
2312
|
+
}
|
|
2313
|
+
}
|
|
2314
|
+
_updateLayout() {
|
|
2315
|
+
if (this._layout && this._connected) {
|
|
2316
|
+
this._layout.items = this._items;
|
|
2317
|
+
this._updateView();
|
|
2318
|
+
if (this._childMeasurements !== null) {
|
|
2319
|
+
if (this._measureCallback) this._measureCallback(this._childMeasurements);
|
|
2320
|
+
this._childMeasurements = null;
|
|
2321
|
+
}
|
|
2322
|
+
this._layout.reflowIfNeeded();
|
|
2323
|
+
if (this._benchmarkStart && "mark" in window.performance) window.performance.mark("uv-end");
|
|
2324
|
+
}
|
|
2325
|
+
}
|
|
2326
|
+
_handleScrollEvent() {
|
|
2327
|
+
if (this._benchmarkStart && "mark" in window.performance) {
|
|
2328
|
+
try {
|
|
2329
|
+
window.performance.measure("uv-virtualizing", "uv-start", "uv-end");
|
|
2330
|
+
} catch (e) {
|
|
2331
|
+
console.warn("Error measuring performance data: ", e);
|
|
2332
|
+
}
|
|
2333
|
+
window.performance.mark("uv-start");
|
|
2334
|
+
}
|
|
2335
|
+
if (this._scrollerController.correctingScrollError === false) this._layout?.unpin();
|
|
2336
|
+
this._schedule(this._updateLayout);
|
|
2337
|
+
}
|
|
2338
|
+
handleEvent(event) {
|
|
2339
|
+
switch (event.type) {
|
|
2340
|
+
case "scroll":
|
|
2341
|
+
if (event.currentTarget === window || this._clippingAncestors.includes(event.currentTarget)) this._handleScrollEvent();
|
|
2342
|
+
break;
|
|
2343
|
+
default: console.warn("event not handled", event);
|
|
2344
|
+
}
|
|
2345
|
+
}
|
|
2346
|
+
_handleLayoutMessage(message) {
|
|
2347
|
+
if (message.type === "stateChanged") this._updateDOM(message);
|
|
2348
|
+
else if (message.type === "visibilityChanged") {
|
|
2349
|
+
this._firstVisible = message.firstVisible;
|
|
2350
|
+
this._lastVisible = message.lastVisible;
|
|
2351
|
+
this._notifyVisibility();
|
|
2352
|
+
} else if (message.type === "unpinned") this._hostElement.dispatchEvent(new UnpinnedEvent());
|
|
2353
|
+
}
|
|
2354
|
+
get _children() {
|
|
2355
|
+
const arr = [];
|
|
2356
|
+
let next = this._hostElement.firstElementChild;
|
|
2357
|
+
while (next) {
|
|
2358
|
+
if (!next.hasAttribute(SIZER_ATTRIBUTE)) arr.push(next);
|
|
2359
|
+
next = next.nextElementSibling;
|
|
2360
|
+
}
|
|
2361
|
+
return arr;
|
|
2362
|
+
}
|
|
2363
|
+
_updateView() {
|
|
2364
|
+
const hostElement = this._hostElement;
|
|
2365
|
+
const scrollingElement = this._scrollerController?.element;
|
|
2366
|
+
const layout = this._layout;
|
|
2367
|
+
if (hostElement && scrollingElement && layout) {
|
|
2368
|
+
let top, left, bottom, right;
|
|
2369
|
+
const hostElementBounds = hostElement.getBoundingClientRect();
|
|
2370
|
+
top = 0;
|
|
2371
|
+
left = 0;
|
|
2372
|
+
bottom = window.innerHeight;
|
|
2373
|
+
right = window.innerWidth;
|
|
2374
|
+
const ancestorBounds = this._clippingAncestors.map((ancestor) => ancestor.getBoundingClientRect());
|
|
2375
|
+
ancestorBounds.unshift(hostElementBounds);
|
|
2376
|
+
for (const bounds of ancestorBounds) {
|
|
2377
|
+
top = Math.max(top, bounds.top);
|
|
2378
|
+
left = Math.max(left, bounds.left);
|
|
2379
|
+
bottom = Math.min(bottom, bounds.bottom);
|
|
2380
|
+
right = Math.min(right, bounds.right);
|
|
2381
|
+
}
|
|
2382
|
+
const scrollingElementBounds = scrollingElement.getBoundingClientRect();
|
|
2383
|
+
const offsetWithinScroller = {
|
|
2384
|
+
left: hostElementBounds.left - scrollingElementBounds.left,
|
|
2385
|
+
top: hostElementBounds.top - scrollingElementBounds.top
|
|
2386
|
+
};
|
|
2387
|
+
const totalScrollSize = {
|
|
2388
|
+
width: scrollingElement.scrollWidth,
|
|
2389
|
+
height: scrollingElement.scrollHeight
|
|
2390
|
+
};
|
|
2391
|
+
const scrollTop = top - hostElementBounds.top + hostElement.scrollTop;
|
|
2392
|
+
const scrollLeft = left - hostElementBounds.left + hostElement.scrollLeft;
|
|
2393
|
+
const height = Math.max(0, bottom - top);
|
|
2394
|
+
layout.viewportSize = {
|
|
2395
|
+
width: Math.max(0, right - left),
|
|
2396
|
+
height
|
|
2397
|
+
};
|
|
2398
|
+
layout.viewportScroll = {
|
|
2399
|
+
top: scrollTop,
|
|
2400
|
+
left: scrollLeft
|
|
2401
|
+
};
|
|
2402
|
+
layout.totalScrollSize = totalScrollSize;
|
|
2403
|
+
layout.offsetWithinScroller = offsetWithinScroller;
|
|
2404
|
+
}
|
|
2405
|
+
}
|
|
2406
|
+
/**
|
|
2407
|
+
* Styles the host element so that its size reflects the
|
|
2408
|
+
* total size of all items.
|
|
2409
|
+
*/
|
|
2410
|
+
_sizeHostElement(size) {
|
|
2411
|
+
const max = 82e5;
|
|
2412
|
+
const h = size && size.width !== null ? Math.min(max, size.width) : 0;
|
|
2413
|
+
const v = size && size.height !== null ? Math.min(max, size.height) : 0;
|
|
2414
|
+
if (this._isScroller) this._getSizer().style.transform = `translate(${h}px, ${v}px)`;
|
|
2415
|
+
else {
|
|
2416
|
+
const style = this._hostElement.style;
|
|
2417
|
+
style.minWidth = h ? `${h}px` : "100%";
|
|
2418
|
+
style.minHeight = v ? `${v}px` : "100%";
|
|
2419
|
+
}
|
|
2420
|
+
}
|
|
2421
|
+
/**
|
|
2422
|
+
* Sets the top and left transform style of the children from the values in
|
|
2423
|
+
* pos.
|
|
2424
|
+
*/
|
|
2425
|
+
_positionChildren(pos) {
|
|
2426
|
+
if (pos) pos.forEach(({ top, left, width, height, xOffset, yOffset }, index) => {
|
|
2427
|
+
const child = this._children[index - this._first];
|
|
2428
|
+
if (child) {
|
|
2429
|
+
child.style.position = "absolute";
|
|
2430
|
+
child.style.boxSizing = "border-box";
|
|
2431
|
+
child.style.transform = `translate(${left}px, ${top}px)`;
|
|
2432
|
+
if (width !== void 0) child.style.width = width + "px";
|
|
2433
|
+
if (height !== void 0) child.style.height = height + "px";
|
|
2434
|
+
child.style.left = xOffset === void 0 ? null : xOffset + "px";
|
|
2435
|
+
child.style.top = yOffset === void 0 ? null : yOffset + "px";
|
|
2436
|
+
}
|
|
2437
|
+
});
|
|
2438
|
+
}
|
|
2439
|
+
async _adjustRange(range) {
|
|
2440
|
+
const { _first, _last, _firstVisible, _lastVisible } = this;
|
|
2441
|
+
this._first = range.first;
|
|
2442
|
+
this._last = range.last;
|
|
2443
|
+
this._firstVisible = range.firstVisible;
|
|
2444
|
+
this._lastVisible = range.lastVisible;
|
|
2445
|
+
this._rangeChanged = this._rangeChanged || this._first !== _first || this._last !== _last;
|
|
2446
|
+
this._visibilityChanged = this._visibilityChanged || this._firstVisible !== _firstVisible || this._lastVisible !== _lastVisible;
|
|
2447
|
+
}
|
|
2448
|
+
_correctScrollError() {
|
|
2449
|
+
if (this._scrollError) {
|
|
2450
|
+
const { scrollTop, scrollLeft } = this._scrollerController;
|
|
2451
|
+
const { top, left } = this._scrollError;
|
|
2452
|
+
this._scrollError = null;
|
|
2453
|
+
this._scrollerController.correctScrollError({
|
|
2454
|
+
top: scrollTop - top,
|
|
2455
|
+
left: scrollLeft - left
|
|
2456
|
+
});
|
|
2457
|
+
}
|
|
2458
|
+
}
|
|
2459
|
+
element(index) {
|
|
2460
|
+
if (index === Infinity) index = this._items.length - 1;
|
|
2461
|
+
return this._items?.[index] === void 0 ? void 0 : { scrollIntoView: (options = {}) => this._scrollElementIntoView({
|
|
2462
|
+
...options,
|
|
2463
|
+
index
|
|
2464
|
+
}) };
|
|
2465
|
+
}
|
|
2466
|
+
_scrollElementIntoView(options) {
|
|
2467
|
+
if (options.index >= this._first && options.index <= this._last) this._children[options.index - this._first].scrollIntoView(options);
|
|
2468
|
+
else {
|
|
2469
|
+
options.index = Math.min(options.index, this._items.length - 1);
|
|
2470
|
+
if (options.behavior === "smooth") {
|
|
2471
|
+
const coordinates = this._layout.getScrollIntoViewCoordinates(options);
|
|
2472
|
+
const { behavior } = options;
|
|
2473
|
+
this._updateScrollIntoViewCoordinates = this._scrollerController.managedScrollTo(Object.assign(coordinates, { behavior }), () => this._layout.getScrollIntoViewCoordinates(options), () => this._scrollIntoViewTarget = null);
|
|
2474
|
+
this._scrollIntoViewTarget = options;
|
|
2475
|
+
} else this._layout.pin = options;
|
|
2476
|
+
}
|
|
2477
|
+
}
|
|
2478
|
+
/**
|
|
2479
|
+
* If we are smoothly scrolling to an element and the target element
|
|
2480
|
+
* is in the DOM, we update our target coordinates as needed
|
|
2481
|
+
*/
|
|
2482
|
+
_checkScrollIntoViewTarget(pos) {
|
|
2483
|
+
const { index } = this._scrollIntoViewTarget || {};
|
|
2484
|
+
if (index && pos?.has(index)) this._updateScrollIntoViewCoordinates(this._layout.getScrollIntoViewCoordinates(this._scrollIntoViewTarget));
|
|
2485
|
+
}
|
|
2486
|
+
/**
|
|
2487
|
+
* Emits a rangechange event with the current first, last, firstVisible, and
|
|
2488
|
+
* lastVisible.
|
|
2489
|
+
*/
|
|
2490
|
+
_notifyRange() {
|
|
2491
|
+
this._hostElement.dispatchEvent(new RangeChangedEvent({
|
|
2492
|
+
first: this._first,
|
|
2493
|
+
last: this._last
|
|
2494
|
+
}));
|
|
2495
|
+
}
|
|
2496
|
+
_notifyVisibility() {
|
|
2497
|
+
this._hostElement.dispatchEvent(new VisibilityChangedEvent({
|
|
2498
|
+
first: this._firstVisible,
|
|
2499
|
+
last: this._lastVisible
|
|
2500
|
+
}));
|
|
2501
|
+
}
|
|
2502
|
+
get layoutComplete() {
|
|
2503
|
+
if (!this._layoutCompletePromise) this._layoutCompletePromise = new Promise((resolve, reject) => {
|
|
2504
|
+
this._layoutCompleteResolver = resolve;
|
|
2505
|
+
this._layoutCompleteRejecter = reject;
|
|
2506
|
+
});
|
|
2507
|
+
return this._layoutCompletePromise;
|
|
2508
|
+
}
|
|
2509
|
+
_rejectLayoutCompletePromise(reason) {
|
|
2510
|
+
if (this._layoutCompleteRejecter !== null) this._layoutCompleteRejecter(reason);
|
|
2511
|
+
this._resetLayoutCompleteState();
|
|
2512
|
+
}
|
|
2513
|
+
_scheduleLayoutComplete() {
|
|
2514
|
+
if (this._layoutCompletePromise && this._pendingLayoutComplete === null) this._pendingLayoutComplete = requestAnimationFrame(() => requestAnimationFrame(() => this._resolveLayoutCompletePromise()));
|
|
2515
|
+
}
|
|
2516
|
+
_resolveLayoutCompletePromise() {
|
|
2517
|
+
if (this._layoutCompleteResolver !== null) this._layoutCompleteResolver();
|
|
2518
|
+
this._resetLayoutCompleteState();
|
|
2519
|
+
}
|
|
2520
|
+
_resetLayoutCompleteState() {
|
|
2521
|
+
this._layoutCompletePromise = null;
|
|
2522
|
+
this._layoutCompleteResolver = null;
|
|
2523
|
+
this._layoutCompleteRejecter = null;
|
|
2524
|
+
this._pendingLayoutComplete = null;
|
|
2525
|
+
}
|
|
2526
|
+
/**
|
|
2527
|
+
* Render and update the view at the next opportunity with the given
|
|
2528
|
+
* hostElement size.
|
|
2529
|
+
*/
|
|
2530
|
+
_hostElementSizeChanged() {
|
|
2531
|
+
this._schedule(this._updateLayout);
|
|
2532
|
+
}
|
|
2533
|
+
_childLoaded() {}
|
|
2534
|
+
_childrenSizeChanged(changes) {
|
|
2535
|
+
if (this._layout?.measureChildren) {
|
|
2536
|
+
for (const change of changes) this._toBeMeasured.set(change.target, change.contentRect);
|
|
2537
|
+
this._measureChildren();
|
|
2538
|
+
}
|
|
2539
|
+
this._scheduleLayoutComplete();
|
|
2540
|
+
this._itemsChanged = false;
|
|
2541
|
+
this._rangeChanged = false;
|
|
2542
|
+
}
|
|
2543
|
+
};
|
|
2544
|
+
function getMargins(el) {
|
|
2545
|
+
const style = window.getComputedStyle(el);
|
|
2546
|
+
return {
|
|
2547
|
+
marginTop: getMarginValue(style.marginTop),
|
|
2548
|
+
marginRight: getMarginValue(style.marginRight),
|
|
2549
|
+
marginBottom: getMarginValue(style.marginBottom),
|
|
2550
|
+
marginLeft: getMarginValue(style.marginLeft)
|
|
2551
|
+
};
|
|
2552
|
+
}
|
|
2553
|
+
function getMarginValue(value) {
|
|
2554
|
+
const float = value ? parseFloat(value) : NaN;
|
|
2555
|
+
return Number.isNaN(float) ? 0 : float;
|
|
2556
|
+
}
|
|
2557
|
+
function getParentElement(el) {
|
|
2558
|
+
if (el.assignedSlot !== null) return el.assignedSlot;
|
|
2559
|
+
if (el.parentElement !== null) return el.parentElement;
|
|
2560
|
+
const parentNode = el.parentNode;
|
|
2561
|
+
if (parentNode && parentNode.nodeType === Node.DOCUMENT_FRAGMENT_NODE) return parentNode.host || null;
|
|
2562
|
+
return null;
|
|
2563
|
+
}
|
|
2564
|
+
function getElementAncestors(el, includeSelf = false) {
|
|
2565
|
+
const ancestors = [];
|
|
2566
|
+
let parent = includeSelf ? el : getParentElement(el);
|
|
2567
|
+
while (parent !== null) {
|
|
2568
|
+
ancestors.push(parent);
|
|
2569
|
+
parent = getParentElement(parent);
|
|
2570
|
+
}
|
|
2571
|
+
return ancestors;
|
|
2572
|
+
}
|
|
2573
|
+
function getClippingAncestors(el, includeSelf = false) {
|
|
2574
|
+
let foundFixed = false;
|
|
2575
|
+
return getElementAncestors(el, includeSelf).filter((a) => {
|
|
2576
|
+
if (foundFixed) return false;
|
|
2577
|
+
const style = getComputedStyle(a);
|
|
2578
|
+
foundFixed = style.position === "fixed";
|
|
2579
|
+
return style.overflow !== "visible";
|
|
2580
|
+
});
|
|
2581
|
+
}
|
|
2582
|
+
//#endregion
|
|
2583
|
+
//#region node_modules/.pnpm/@lit-labs+virtualizer@2.1.1/node_modules/@lit-labs/virtualizer/virtualize.js
|
|
2584
|
+
/**
|
|
2585
|
+
* @license
|
|
2586
|
+
* Copyright 2021 Google LLC
|
|
2587
|
+
* SPDX-License-Identifier: BSD-3-Clause
|
|
2588
|
+
*/
|
|
2589
|
+
var defaultKeyFunction = (item) => item;
|
|
2590
|
+
var defaultRenderItem = (item, idx) => b`${idx}: ${JSON.stringify(item, null, 2)}`;
|
|
2591
|
+
var VirtualizeDirective = class extends f {
|
|
2592
|
+
constructor(part) {
|
|
2593
|
+
super(part);
|
|
2594
|
+
this._virtualizer = null;
|
|
2595
|
+
this._first = 0;
|
|
2596
|
+
this._last = -1;
|
|
2597
|
+
this._renderItem = (item, idx) => defaultRenderItem(item, idx + this._first);
|
|
2598
|
+
this._keyFunction = (item, idx) => defaultKeyFunction(item, idx + this._first);
|
|
2599
|
+
this._items = [];
|
|
2600
|
+
if (part.type !== t.CHILD) throw new Error("The virtualize directive can only be used in child expressions");
|
|
2601
|
+
}
|
|
2602
|
+
render(config) {
|
|
2603
|
+
if (config) this._setFunctions(config);
|
|
2604
|
+
const itemsToRender = [];
|
|
2605
|
+
if (this._first >= 0 && this._last >= this._first) for (let i = this._first; i <= this._last; i++) itemsToRender.push(this._items[i]);
|
|
2606
|
+
return c(itemsToRender, this._keyFunction, this._renderItem);
|
|
2607
|
+
}
|
|
2608
|
+
update(part, [config]) {
|
|
2609
|
+
this._setFunctions(config);
|
|
2610
|
+
const itemsChanged = this._items !== config.items;
|
|
2611
|
+
this._items = config.items || [];
|
|
2612
|
+
if (this._virtualizer) this._updateVirtualizerConfig(part, config);
|
|
2613
|
+
else this._initialize(part, config);
|
|
2614
|
+
return itemsChanged ? E : this.render();
|
|
2615
|
+
}
|
|
2616
|
+
async _updateVirtualizerConfig(part, config) {
|
|
2617
|
+
if (!await this._virtualizer.updateLayoutConfig(config.layout || {})) {
|
|
2618
|
+
const hostElement = part.parentNode;
|
|
2619
|
+
this._makeVirtualizer(hostElement, config);
|
|
2620
|
+
}
|
|
2621
|
+
this._virtualizer.items = this._items;
|
|
2622
|
+
}
|
|
2623
|
+
_setFunctions(config) {
|
|
2624
|
+
const { renderItem, keyFunction } = config;
|
|
2625
|
+
if (renderItem) this._renderItem = (item, idx) => renderItem(item, idx + this._first);
|
|
2626
|
+
if (keyFunction) this._keyFunction = (item, idx) => keyFunction(item, idx + this._first);
|
|
2627
|
+
}
|
|
2628
|
+
_makeVirtualizer(hostElement, config) {
|
|
2629
|
+
if (this._virtualizer) this._virtualizer.disconnected();
|
|
2630
|
+
const { layout, scroller, items } = config;
|
|
2631
|
+
this._virtualizer = new Virtualizer({
|
|
2632
|
+
hostElement,
|
|
2633
|
+
layout,
|
|
2634
|
+
scroller
|
|
2635
|
+
});
|
|
2636
|
+
this._virtualizer.items = items;
|
|
2637
|
+
this._virtualizer.connected();
|
|
2638
|
+
}
|
|
2639
|
+
_initialize(part, config) {
|
|
2640
|
+
const hostElement = part.parentNode;
|
|
2641
|
+
if (hostElement && hostElement.nodeType === 1) {
|
|
2642
|
+
hostElement.addEventListener("rangeChanged", (e) => {
|
|
2643
|
+
this._first = e.first;
|
|
2644
|
+
this._last = e.last;
|
|
2645
|
+
this.setValue(this.render());
|
|
2646
|
+
});
|
|
2647
|
+
this._makeVirtualizer(hostElement, config);
|
|
2648
|
+
}
|
|
2649
|
+
}
|
|
2650
|
+
disconnected() {
|
|
2651
|
+
this._virtualizer?.disconnected();
|
|
2652
|
+
}
|
|
2653
|
+
reconnected() {
|
|
2654
|
+
this._virtualizer?.connected();
|
|
2655
|
+
}
|
|
2656
|
+
};
|
|
2657
|
+
var virtualize = e$1(VirtualizeDirective);
|
|
2658
|
+
//#endregion
|
|
2659
|
+
//#region node_modules/.pnpm/devframe@1.0.0_@devframes+agentic@1.0.0_cac@7.0.0_srvx@1.0.5/node_modules/devframe/dist/utils/colors.mjs
|
|
2660
|
+
function makeColor(open, close) {
|
|
2661
|
+
const o = `\x1B[${open}m`;
|
|
2662
|
+
const c = `\x1B[${close}m`;
|
|
2663
|
+
return ((arg, ...values) => {
|
|
2664
|
+
if (Array.isArray(arg) && "raw" in arg) {
|
|
2665
|
+
const strings = arg;
|
|
2666
|
+
let out = "";
|
|
2667
|
+
for (let i = 0; i < strings.length; i++) {
|
|
2668
|
+
out += strings[i];
|
|
2669
|
+
if (i < values.length) out += String(values[i]);
|
|
2670
|
+
}
|
|
2671
|
+
return `${o}${out}${c}`;
|
|
2672
|
+
}
|
|
2673
|
+
return `${o}${String(arg)}${c}`;
|
|
2674
|
+
});
|
|
2675
|
+
}
|
|
2676
|
+
var colors = {
|
|
2677
|
+
blue: makeColor(34, 39),
|
|
2678
|
+
cyan: makeColor(36, 39),
|
|
2679
|
+
gray: makeColor(90, 39),
|
|
2680
|
+
green: makeColor(32, 39),
|
|
2681
|
+
red: makeColor(31, 39),
|
|
2682
|
+
yellow: makeColor(33, 39),
|
|
2683
|
+
bold: makeColor(1, 22),
|
|
2684
|
+
dim: makeColor(2, 22),
|
|
2685
|
+
reset: makeColor(0, 0),
|
|
2686
|
+
underline: makeColor(4, 24)
|
|
2687
|
+
};
|
|
2688
|
+
//#endregion
|
|
2689
|
+
//#region node_modules/.pnpm/nostics@1.2.0/node_modules/nostics/dist/index.mjs
|
|
2690
|
+
/**
|
|
2691
|
+
* Transforms a value or a function that returns a value to a value.
|
|
2692
|
+
*
|
|
2693
|
+
* @param valFn either a value or a function that returns a value
|
|
2694
|
+
* @param args arguments to pass to the function if `valFn` is a function
|
|
2695
|
+
*
|
|
2696
|
+
* @internal
|
|
2697
|
+
*/
|
|
2698
|
+
function toValueWithArgs(valFn, ...args) {
|
|
2699
|
+
return typeof valFn === "function" ? valFn(...args) : valFn;
|
|
2700
|
+
}
|
|
2701
|
+
var captureStackTrace = Error.captureStackTrace;
|
|
2702
|
+
var Diagnostic = class Diagnostic extends Error {
|
|
2703
|
+
name;
|
|
2704
|
+
/**
|
|
2705
|
+
* The diagnostic code, e.g. `MATH_E001`.
|
|
2706
|
+
* Also appears as the `name` property.
|
|
2707
|
+
*/
|
|
2708
|
+
code;
|
|
2709
|
+
/**
|
|
2710
|
+
* URL to extended documentation for this diagnostic code.
|
|
2711
|
+
* Auto-generated from {@link DefineDiagnosticsOptions.docsBase}.
|
|
2712
|
+
*/
|
|
2713
|
+
docs;
|
|
2714
|
+
/**
|
|
2715
|
+
* Optional actionable instructions on how to resolve the problem.
|
|
2716
|
+
*/
|
|
2717
|
+
fix;
|
|
2718
|
+
/**
|
|
2719
|
+
* Locations in user code that contributed to this diagnostic, in
|
|
2720
|
+
* `file:line:column` format. Relevant when the stack trace doesn't reflect
|
|
2721
|
+
* the user's source (e.g. compilers, bundlers), otherwise redundant with the
|
|
2722
|
+
* stack and should be omitted.
|
|
2723
|
+
*/
|
|
2724
|
+
sources;
|
|
2725
|
+
/**
|
|
2726
|
+
* Alias for {@link Error.message}: the reason this diagnostic was raised.
|
|
2727
|
+
*/
|
|
2728
|
+
get why() {
|
|
2729
|
+
return this.message;
|
|
2730
|
+
}
|
|
2731
|
+
/**
|
|
2732
|
+
* @param init structured initializer; `why` is required
|
|
2733
|
+
* @param captureFrom V8 stack-cutoff frame. Defaults to {@link Diagnostic}
|
|
2734
|
+
* so the top of the trace is the `new Diagnostic(...)` call site.
|
|
2735
|
+
* `defineDiagnostics` passes its action method to strip its own frames too.
|
|
2736
|
+
* Ignored on engines without `Error.captureStackTrace`.
|
|
2737
|
+
*/
|
|
2738
|
+
constructor(init, captureFrom = Diagnostic) {
|
|
2739
|
+
super(init.why, { cause: init.cause });
|
|
2740
|
+
this.code = this.name = init.code;
|
|
2741
|
+
this.fix = init.fix;
|
|
2742
|
+
this.docs = init.docs;
|
|
2743
|
+
this.sources = init.sources;
|
|
2744
|
+
captureStackTrace?.(this, captureFrom);
|
|
2745
|
+
}
|
|
2746
|
+
/**
|
|
2747
|
+
* Converts the diagnostic into a serializable structured object.
|
|
2748
|
+
*/
|
|
2749
|
+
toJSON() {
|
|
2750
|
+
return {
|
|
2751
|
+
name: this.name,
|
|
2752
|
+
why: this.why,
|
|
2753
|
+
fix: this.fix,
|
|
2754
|
+
docs: this.docs,
|
|
2755
|
+
sources: this.sources,
|
|
2756
|
+
cause: this.cause,
|
|
2757
|
+
stack: this.stack
|
|
1662
2758
|
};
|
|
1663
2759
|
}
|
|
1664
2760
|
};
|
|
@@ -4013,73 +5109,6 @@ function toAgentToolName(id) {
|
|
|
4013
5109
|
return id.replace(/[^\w-]+/g, "_").slice(0, MAX_TOOL_NAME_LENGTH);
|
|
4014
5110
|
}
|
|
4015
5111
|
//#endregion
|
|
4016
|
-
//#region \0vite/preload-helper.js
|
|
4017
|
-
var scriptRel = "modulepreload";
|
|
4018
|
-
var assetsURL = function(dep, importerUrl) {
|
|
4019
|
-
return new URL(dep, importerUrl).href;
|
|
4020
|
-
};
|
|
4021
|
-
var seen = {};
|
|
4022
|
-
var __vitePreload = function preload(baseModule, deps, importerUrl) {
|
|
4023
|
-
let promise = Promise.resolve();
|
|
4024
|
-
if (deps && deps.length > 0) {
|
|
4025
|
-
const links = document.getElementsByTagName("link");
|
|
4026
|
-
const cspNonceMeta = document.querySelector("meta[property=csp-nonce]");
|
|
4027
|
-
const cspNonce = cspNonceMeta?.nonce || cspNonceMeta?.getAttribute("nonce");
|
|
4028
|
-
function allSettled(promises) {
|
|
4029
|
-
return Promise.all(promises.map((p) => Promise.resolve(p).then((value) => ({
|
|
4030
|
-
status: "fulfilled",
|
|
4031
|
-
value
|
|
4032
|
-
}), (reason) => ({
|
|
4033
|
-
status: "rejected",
|
|
4034
|
-
reason
|
|
4035
|
-
}))));
|
|
4036
|
-
}
|
|
4037
|
-
function importMetaResolve(specifier) {
|
|
4038
|
-
if (import.meta.resolve) return import.meta.resolve(specifier);
|
|
4039
|
-
return new URL(
|
|
4040
|
-
specifier,
|
|
4041
|
-
/** #__KEEP__ */
|
|
4042
|
-
import.meta.url
|
|
4043
|
-
).href;
|
|
4044
|
-
}
|
|
4045
|
-
promise = allSettled(deps.map((dep) => {
|
|
4046
|
-
dep = assetsURL(dep, importerUrl);
|
|
4047
|
-
dep = importMetaResolve(dep);
|
|
4048
|
-
if (dep in seen) return;
|
|
4049
|
-
seen[dep] = true;
|
|
4050
|
-
const isCss = dep.endsWith(".css");
|
|
4051
|
-
for (let i = links.length - 1; i >= 0; i--) {
|
|
4052
|
-
const link = links[i];
|
|
4053
|
-
if (link.href === dep && (!isCss || link.rel === "stylesheet")) return;
|
|
4054
|
-
}
|
|
4055
|
-
const link = document.createElement("link");
|
|
4056
|
-
link.rel = isCss ? "stylesheet" : scriptRel;
|
|
4057
|
-
if (!isCss) link.as = "script";
|
|
4058
|
-
link.crossOrigin = "";
|
|
4059
|
-
link.href = dep;
|
|
4060
|
-
if (cspNonce) link.setAttribute("nonce", cspNonce);
|
|
4061
|
-
document.head.appendChild(link);
|
|
4062
|
-
if (isCss) return new Promise((res, rej) => {
|
|
4063
|
-
link.addEventListener("load", res);
|
|
4064
|
-
link.addEventListener("error", () => rej(/* @__PURE__ */ new Error(`Unable to preload CSS for ${dep}`)));
|
|
4065
|
-
});
|
|
4066
|
-
}).filter((p) => p !== void 0));
|
|
4067
|
-
}
|
|
4068
|
-
function handlePreloadError(err) {
|
|
4069
|
-
const e = new Event("vite:preloadError", { cancelable: true });
|
|
4070
|
-
e.payload = err;
|
|
4071
|
-
window.dispatchEvent(e);
|
|
4072
|
-
if (!e.defaultPrevented) throw err;
|
|
4073
|
-
}
|
|
4074
|
-
return promise.then((res) => {
|
|
4075
|
-
for (const item of res || []) {
|
|
4076
|
-
if (item.status !== "rejected") continue;
|
|
4077
|
-
handlePreloadError(item.reason);
|
|
4078
|
-
}
|
|
4079
|
-
return baseModule().catch(handlePreloadError);
|
|
4080
|
-
});
|
|
4081
|
-
};
|
|
4082
|
-
//#endregion
|
|
4083
5112
|
//#region node_modules/.pnpm/devframe@1.0.0_@devframes+agentic@1.0.0_cac@7.0.0_srvx@1.0.5/node_modules/devframe/dist/client/index.mjs
|
|
4084
5113
|
/** Devframe runtime routes and static output conventions. */
|
|
4085
5114
|
var DEVFRAME_CONNECTION_META_FILENAME = "__connection.json";
|
|
@@ -5980,7 +7009,7 @@ async function getDevframeRpcClient(options = {}) {
|
|
|
5980
7009
|
bootstrapAuthSettled = true;
|
|
5981
7010
|
});
|
|
5982
7011
|
if (connectionMeta.mcp) __vitePreload(async () => {
|
|
5983
|
-
const { setupBrowserAgentRpcBridge } = await import("./browser-agent-rpc-BXhoSh1z-
|
|
7012
|
+
const { setupBrowserAgentRpcBridge } = await import("./browser-agent-rpc-BXhoSh1z-CRHFLjFo.js");
|
|
5984
7013
|
return { setupBrowserAgentRpcBridge };
|
|
5985
7014
|
}, [], import.meta.url).then(({ setupBrowserAgentRpcBridge }) => {
|
|
5986
7015
|
if (!closed) disposeBrowserAgentBridge = setupBrowserAgentRpcBridge(rpc);
|
|
@@ -6026,6 +7055,8 @@ var SOURCE_OVERLAY_EDITORS = [
|
|
|
6026
7055
|
];
|
|
6027
7056
|
/** localStorage key holding the {@link SettingsOverride}. */
|
|
6028
7057
|
var SETTINGS_OVERRIDE_LS_KEY = "lit-devtools-overrides";
|
|
7058
|
+
/** localStorage key holding the {@link OverrideBaselines}. */
|
|
7059
|
+
var OVERRIDE_BASELINES_LS_KEY = "lit-devtools-override-baselines";
|
|
6029
7060
|
//#endregion
|
|
6030
7061
|
//#region src/lib/devframe/protocol.ts
|
|
6031
7062
|
/**
|
|
@@ -6042,6 +7073,7 @@ var SESSION_STATE_KEY = "session";
|
|
|
6042
7073
|
var LAYER_FLAGS = {
|
|
6043
7074
|
"lit-lifecycle": "litLifecycleEnabled",
|
|
6044
7075
|
"lit-render": "litRenderEnabled",
|
|
7076
|
+
"lit-render-verbose": "litRenderVerboseEnabled",
|
|
6045
7077
|
mouse: "mouseEventEnabled",
|
|
6046
7078
|
keyboard: "keyboardEventEnabled"
|
|
6047
7079
|
};
|
|
@@ -6160,12 +7192,139 @@ var openInEditor = async (file, line) => {
|
|
|
6160
7192
|
} catch (err) {
|
|
6161
7193
|
console.warn("[lit-devtools] open-source failed, falling back to the endpoint", err);
|
|
6162
7194
|
}
|
|
6163
|
-
try {
|
|
6164
|
-
await openViaEndpoint(file, line);
|
|
6165
|
-
} catch (err) {
|
|
6166
|
-
console.warn("[lit-devtools] open-in-editor failed", err);
|
|
7195
|
+
try {
|
|
7196
|
+
await openViaEndpoint(file, line);
|
|
7197
|
+
} catch (err) {
|
|
7198
|
+
console.warn("[lit-devtools] open-in-editor failed", err);
|
|
7199
|
+
}
|
|
7200
|
+
};
|
|
7201
|
+
//#endregion
|
|
7202
|
+
//#region src/panel/timeline-span-detail.ts
|
|
7203
|
+
/**
|
|
7204
|
+
* @license
|
|
7205
|
+
* Copyright 2026 Google LLC
|
|
7206
|
+
* SPDX-License-Identifier: BSD-3-Clause
|
|
7207
|
+
*/
|
|
7208
|
+
var TimelineSpanDetail = class TimelineSpanDetail extends i$2 {
|
|
7209
|
+
constructor(..._args) {
|
|
7210
|
+
super(..._args);
|
|
7211
|
+
this.filterable = false;
|
|
7212
|
+
}
|
|
7213
|
+
static {
|
|
7214
|
+
this.styles = [tokens, i$5`
|
|
7215
|
+
:host {
|
|
7216
|
+
display: block;
|
|
7217
|
+
border-top: 1px solid var(--lit-devtools-border);
|
|
7218
|
+
background: var(--lit-devtools-surface-low);
|
|
7219
|
+
padding: var(--lit-devtools-space-5) var(--lit-devtools-space-5);
|
|
7220
|
+
font-size: var(--lit-devtools-text-2xs);
|
|
7221
|
+
font-family: var(--lit-devtools-font-mono);
|
|
7222
|
+
color: var(--lit-devtools-text-secondary);
|
|
7223
|
+
flex-shrink: 0;
|
|
7224
|
+
max-height: 130px;
|
|
7225
|
+
overflow-y: auto;
|
|
7226
|
+
}
|
|
7227
|
+
table {
|
|
7228
|
+
border-collapse: collapse;
|
|
7229
|
+
width: 100%;
|
|
7230
|
+
}
|
|
7231
|
+
td {
|
|
7232
|
+
padding: var(--lit-devtools-space-1) var(--lit-devtools-space-4)
|
|
7233
|
+
var(--lit-devtools-space-1) 0;
|
|
7234
|
+
vertical-align: top;
|
|
7235
|
+
}
|
|
7236
|
+
.key {
|
|
7237
|
+
color: var(--lit-devtools-text-muted);
|
|
7238
|
+
white-space: nowrap;
|
|
7239
|
+
}
|
|
7240
|
+
.val {
|
|
7241
|
+
color: var(--lit-devtools-text);
|
|
7242
|
+
word-break: break-all;
|
|
7243
|
+
}
|
|
7244
|
+
a {
|
|
7245
|
+
color: var(--lit-devtools-accent);
|
|
7246
|
+
text-decoration: none;
|
|
7247
|
+
cursor: pointer;
|
|
7248
|
+
}
|
|
7249
|
+
a:hover {
|
|
7250
|
+
text-decoration: underline;
|
|
7251
|
+
}
|
|
7252
|
+
.filter-link {
|
|
7253
|
+
margin-left: var(--lit-devtools-space-4);
|
|
7254
|
+
font-size: var(--lit-devtools-text-2xs);
|
|
7255
|
+
}
|
|
7256
|
+
`];
|
|
7257
|
+
}
|
|
7258
|
+
_emit(type, id) {
|
|
7259
|
+
this.dispatchEvent(new CustomEvent(type, {
|
|
7260
|
+
detail: { id },
|
|
7261
|
+
bubbles: true,
|
|
7262
|
+
composed: true
|
|
7263
|
+
}));
|
|
7264
|
+
}
|
|
7265
|
+
render() {
|
|
7266
|
+
const row = this.span;
|
|
7267
|
+
if (!row) return A;
|
|
7268
|
+
const { meta } = row;
|
|
7269
|
+
const src = meta?.source;
|
|
7270
|
+
const data = row.events[0]?.data;
|
|
7271
|
+
const id = meta?.elementId;
|
|
7272
|
+
return b`
|
|
7273
|
+
<table>
|
|
7274
|
+
<tr>
|
|
7275
|
+
<td class="key">layer</td>
|
|
7276
|
+
<td class="val">${row.layerId}</td>
|
|
7277
|
+
</tr>
|
|
7278
|
+
<tr>
|
|
7279
|
+
<td class="key">time</td>
|
|
7280
|
+
<td class="val">${row.start.toFixed(3)} ms</td>
|
|
7281
|
+
</tr>
|
|
7282
|
+
${row.duration !== void 0 ? b`<tr>
|
|
7283
|
+
<td class="key">duration</td>
|
|
7284
|
+
<td class="val">${row.duration.toFixed(3)} ms</td>
|
|
7285
|
+
</tr>` : A}
|
|
7286
|
+
${row.changed?.length ? b`<tr>
|
|
7287
|
+
<td class="key">changed</td>
|
|
7288
|
+
<td class="val">${row.changed.join(", ")}</td>
|
|
7289
|
+
</tr>` : A}
|
|
7290
|
+
${meta?.tagName ? b`<tr>
|
|
7291
|
+
<td class="key">element</td>
|
|
7292
|
+
<td class="val">
|
|
7293
|
+
<${meta.tagName}> #${id}
|
|
7294
|
+
${id != null && this.filterable ? b`<a
|
|
7295
|
+
class="filter-link"
|
|
7296
|
+
@click=${() => this._emit("element-filter", id)}
|
|
7297
|
+
>filter</a
|
|
7298
|
+
>` : A}${id != null ? b`<a
|
|
7299
|
+
class="filter-link"
|
|
7300
|
+
title="Open this element in the Components tab"
|
|
7301
|
+
@click=${() => this._emit("inspect-element", id)}
|
|
7302
|
+
>inspect</a
|
|
7303
|
+
>` : A}
|
|
7304
|
+
</td>
|
|
7305
|
+
</tr>` : A}
|
|
7306
|
+
${src ? b`<tr>
|
|
7307
|
+
<td class="key">source</td>
|
|
7308
|
+
<td class="val">
|
|
7309
|
+
<a
|
|
7310
|
+
class="src-link"
|
|
7311
|
+
title="Open this file in your editor"
|
|
7312
|
+
@click=${() => openInEditor(src.file, src.line)}
|
|
7313
|
+
>${src.file}:${src.line}</a
|
|
7314
|
+
>
|
|
7315
|
+
</td>
|
|
7316
|
+
</tr>` : A}
|
|
7317
|
+
${data != null ? b`<tr>
|
|
7318
|
+
<td class="key">data</td>
|
|
7319
|
+
<td class="val">${JSON.stringify(data)}</td>
|
|
7320
|
+
</tr>` : A}
|
|
7321
|
+
</table>
|
|
7322
|
+
`;
|
|
6167
7323
|
}
|
|
6168
7324
|
};
|
|
7325
|
+
__decorate([n$3({ attribute: false })], TimelineSpanDetail.prototype, "span", void 0);
|
|
7326
|
+
__decorate([n$3({ type: Boolean })], TimelineSpanDetail.prototype, "filterable", void 0);
|
|
7327
|
+
TimelineSpanDetail = __decorate([t$2("timeline-span-detail")], TimelineSpanDetail);
|
|
6169
7328
|
//#endregion
|
|
6170
7329
|
//#region src/panel/timeline-event-list.ts
|
|
6171
7330
|
/**
|
|
@@ -6173,6 +7332,9 @@ var openInEditor = async (file, line) => {
|
|
|
6173
7332
|
* Copyright 2026 Google LLC
|
|
6174
7333
|
* SPDX-License-Identifier: BSD-3-Clause
|
|
6175
7334
|
*/
|
|
7335
|
+
var RAW_KEY_PREFIX = "raw:";
|
|
7336
|
+
/** Whether `key` names a Raw-mode row rather than a collapsed span. */
|
|
7337
|
+
var isRawKey = (key) => key.startsWith(RAW_KEY_PREFIX);
|
|
6176
7338
|
/**
|
|
6177
7339
|
* Adapts one raw event to the row shape for the Raw toggle. Deliberately
|
|
6178
7340
|
* drops `groupId`: pairing is what the collapsed mode is for, and without it
|
|
@@ -6180,7 +7342,7 @@ var openInEditor = async (file, line) => {
|
|
|
6180
7342
|
*/
|
|
6181
7343
|
var rawRow = (event, index) => ({
|
|
6182
7344
|
layerId: event.layerId,
|
|
6183
|
-
key:
|
|
7345
|
+
key: `${RAW_KEY_PREFIX}${index}`,
|
|
6184
7346
|
name: event.title ?? event.layerId,
|
|
6185
7347
|
start: event.time,
|
|
6186
7348
|
subtitle: event.subtitle,
|
|
@@ -6198,14 +7360,15 @@ var TimelineEventList = class TimelineEventList extends i$2 {
|
|
|
6198
7360
|
constructor(..._args) {
|
|
6199
7361
|
super(..._args);
|
|
6200
7362
|
this.events = [];
|
|
7363
|
+
this.spans = [];
|
|
6201
7364
|
this.layers = [];
|
|
6202
|
-
this.
|
|
6203
|
-
this.
|
|
6204
|
-
this.
|
|
7365
|
+
this.selectedKey = null;
|
|
7366
|
+
this.elementFilter = null;
|
|
7367
|
+
this.regex = "";
|
|
6205
7368
|
this._raw = false;
|
|
6206
7369
|
this._scrollRef = e();
|
|
6207
|
-
this._elementsCache = [];
|
|
6208
7370
|
this._rowsCache = [];
|
|
7371
|
+
this._visibleCache = [];
|
|
6209
7372
|
}
|
|
6210
7373
|
static {
|
|
6211
7374
|
this.styles = [tokens, i$5`
|
|
@@ -6225,31 +7388,6 @@ var TimelineEventList = class TimelineEventList extends i$2 {
|
|
|
6225
7388
|
color: var(--lit-devtools-text-muted);
|
|
6226
7389
|
flex-shrink: 0;
|
|
6227
7390
|
}
|
|
6228
|
-
.filterbar select {
|
|
6229
|
-
background: var(--lit-devtools-surface-elevated);
|
|
6230
|
-
color: var(--lit-devtools-text);
|
|
6231
|
-
border: 1px solid var(--lit-devtools-border-strong);
|
|
6232
|
-
border-radius: var(--lit-devtools-radius-sm);
|
|
6233
|
-
padding: var(--lit-devtools-space-1) var(--lit-devtools-space-3);
|
|
6234
|
-
font-size: var(--lit-devtools-text-2xs);
|
|
6235
|
-
font-family: var(--lit-devtools-font-mono);
|
|
6236
|
-
}
|
|
6237
|
-
.filterbar input.regex {
|
|
6238
|
-
background: var(--lit-devtools-surface-elevated);
|
|
6239
|
-
color: var(--lit-devtools-text);
|
|
6240
|
-
border: 1px solid var(--lit-devtools-border-strong);
|
|
6241
|
-
border-radius: var(--lit-devtools-radius-sm);
|
|
6242
|
-
padding: var(--lit-devtools-space-1) var(--lit-devtools-space-3);
|
|
6243
|
-
font-size: var(--lit-devtools-text-2xs);
|
|
6244
|
-
font-family: var(--lit-devtools-font-mono);
|
|
6245
|
-
min-width: 140px;
|
|
6246
|
-
}
|
|
6247
|
-
.filterbar input.regex::placeholder {
|
|
6248
|
-
color: var(--lit-devtools-text-muted);
|
|
6249
|
-
}
|
|
6250
|
-
.filterbar input.regex.invalid {
|
|
6251
|
-
border-color: var(--lit-devtools-error);
|
|
6252
|
-
}
|
|
6253
7391
|
.filterbar button {
|
|
6254
7392
|
background: var(--lit-devtools-surface-elevated);
|
|
6255
7393
|
color: var(--lit-devtools-text-muted);
|
|
@@ -6288,6 +7426,9 @@ var TimelineEventList = class TimelineEventList extends i$2 {
|
|
|
6288
7426
|
color: var(--lit-devtools-text-muted);
|
|
6289
7427
|
}
|
|
6290
7428
|
.row {
|
|
7429
|
+
/* The virtualizer positions rows absolutely; stretch them back. */
|
|
7430
|
+
box-sizing: border-box;
|
|
7431
|
+
width: 100%;
|
|
6291
7432
|
display: flex;
|
|
6292
7433
|
align-items: baseline;
|
|
6293
7434
|
gap: var(--lit-devtools-space-4);
|
|
@@ -6303,314 +7444,728 @@ var TimelineEventList = class TimelineEventList extends i$2 {
|
|
|
6303
7444
|
.row.selected {
|
|
6304
7445
|
background: var(--lit-devtools-surface-active);
|
|
6305
7446
|
}
|
|
6306
|
-
.time {
|
|
6307
|
-
color: var(--lit-devtools-text-muted);
|
|
6308
|
-
flex-shrink: 0;
|
|
6309
|
-
width: 56px;
|
|
6310
|
-
text-align: right;
|
|
7447
|
+
.time {
|
|
7448
|
+
color: var(--lit-devtools-text-muted);
|
|
7449
|
+
flex-shrink: 0;
|
|
7450
|
+
width: 56px;
|
|
7451
|
+
text-align: right;
|
|
7452
|
+
}
|
|
7453
|
+
.dot {
|
|
7454
|
+
width: 8px;
|
|
7455
|
+
height: 8px;
|
|
7456
|
+
border-radius: 50%;
|
|
7457
|
+
flex-shrink: 0;
|
|
7458
|
+
margin-top: 2px;
|
|
7459
|
+
}
|
|
7460
|
+
.title {
|
|
7461
|
+
flex: 1;
|
|
7462
|
+
color: var(--lit-devtools-text);
|
|
7463
|
+
overflow: hidden;
|
|
7464
|
+
text-overflow: ellipsis;
|
|
7465
|
+
white-space: nowrap;
|
|
7466
|
+
}
|
|
7467
|
+
.subtitle {
|
|
7468
|
+
color: var(--lit-devtools-text-muted);
|
|
7469
|
+
flex-shrink: 0;
|
|
7470
|
+
max-width: 200px;
|
|
7471
|
+
overflow: hidden;
|
|
7472
|
+
text-overflow: ellipsis;
|
|
7473
|
+
white-space: nowrap;
|
|
7474
|
+
}
|
|
7475
|
+
.changed {
|
|
7476
|
+
color: var(--lit-devtools-accent);
|
|
7477
|
+
flex-shrink: 0;
|
|
7478
|
+
max-width: 220px;
|
|
7479
|
+
overflow: hidden;
|
|
7480
|
+
text-overflow: ellipsis;
|
|
7481
|
+
white-space: nowrap;
|
|
7482
|
+
}
|
|
7483
|
+
.dur {
|
|
7484
|
+
color: var(--lit-devtools-text-secondary);
|
|
7485
|
+
flex-shrink: 0;
|
|
7486
|
+
width: 62px;
|
|
7487
|
+
text-align: right;
|
|
7488
|
+
}
|
|
7489
|
+
.dur.open {
|
|
7490
|
+
color: var(--lit-devtools-text-muted);
|
|
7491
|
+
}
|
|
7492
|
+
`];
|
|
7493
|
+
}
|
|
7494
|
+
willUpdate(changed) {
|
|
7495
|
+
if (changed.has("events") || changed.has("spans") || changed.has("_raw")) this._rowsCache = this._raw ? this.events.map(rawRow) : this.spans;
|
|
7496
|
+
if (changed.has("events") || changed.has("spans") || changed.has("_raw") || changed.has("layers") || changed.has("elementFilter") || changed.has("regex")) this._visibleCache = filterSpans(this._rowsCache.filter((row) => this._layerOn(row)), this.elementFilter, compileRegex(this.regex).re);
|
|
7497
|
+
}
|
|
7498
|
+
updated(changed) {
|
|
7499
|
+
if (changed.has("events")) {
|
|
7500
|
+
const el = this._scrollRef.value;
|
|
7501
|
+
if (el) el.scrollTop = el.scrollHeight;
|
|
7502
|
+
}
|
|
7503
|
+
}
|
|
7504
|
+
_select(key) {
|
|
7505
|
+
this.dispatchEvent(new CustomEvent("span-select", {
|
|
7506
|
+
detail: { key },
|
|
7507
|
+
bubbles: true,
|
|
7508
|
+
composed: true
|
|
7509
|
+
}));
|
|
7510
|
+
}
|
|
7511
|
+
/**
|
|
7512
|
+
* Scrolls the selected row into view, or to the newest row when nothing is
|
|
7513
|
+
* selected. `timeline-view` calls this when switching back from Tracks: the
|
|
7514
|
+
* list was hidden while the selection moved, so its own auto-scroll could
|
|
7515
|
+
* not follow.
|
|
7516
|
+
*/
|
|
7517
|
+
reveal() {
|
|
7518
|
+
const el = this._scrollRef.value;
|
|
7519
|
+
if (!el) return;
|
|
7520
|
+
const index = this.selectedKey === null ? -1 : this._visibleCache.findIndex((row) => row.key === this.selectedKey);
|
|
7521
|
+
if (index === -1) {
|
|
7522
|
+
el.scrollTop = el.scrollHeight;
|
|
7523
|
+
return;
|
|
7524
|
+
}
|
|
7525
|
+
const attempt = (left) => {
|
|
7526
|
+
try {
|
|
7527
|
+
el[virtualizerRef]?.element(index)?.scrollIntoView({ block: "center" });
|
|
7528
|
+
} catch {
|
|
7529
|
+
if (left > 0) requestAnimationFrame(() => attempt(left - 1));
|
|
7530
|
+
}
|
|
7531
|
+
};
|
|
7532
|
+
attempt(30);
|
|
7533
|
+
}
|
|
7534
|
+
_layerOn(row) {
|
|
7535
|
+
const l = this.layers.find((l) => l.id === row.layerId);
|
|
7536
|
+
return !l || l.enabled;
|
|
7537
|
+
}
|
|
7538
|
+
render() {
|
|
7539
|
+
const visible = this._visibleCache;
|
|
7540
|
+
const selected = this.selectedKey === null ? void 0 : this._rowsCache.find((row) => row.key === this.selectedKey);
|
|
7541
|
+
return b`
|
|
7542
|
+
${this.events.length > 0 ? b`
|
|
7543
|
+
<div class="filterbar">
|
|
7544
|
+
<button
|
|
7545
|
+
class=${this._raw ? "on" : ""}
|
|
7546
|
+
title="Show one row per recorded event instead of collapsing start/end pairs"
|
|
7547
|
+
@click=${() => {
|
|
7548
|
+
this._raw = !this._raw;
|
|
7549
|
+
this._select(null);
|
|
7550
|
+
}}
|
|
7551
|
+
>
|
|
7552
|
+
Raw
|
|
7553
|
+
</button>
|
|
7554
|
+
<span class="count"
|
|
7555
|
+
>${visible.length} / ${this._rowsCache.length}</span
|
|
7556
|
+
>
|
|
7557
|
+
</div>
|
|
7558
|
+
` : A}
|
|
7559
|
+
${visible.length === 0 ? b`
|
|
7560
|
+
<div class="scroll">
|
|
7561
|
+
<div class="empty">
|
|
7562
|
+
<span>No events recorded.</span>
|
|
7563
|
+
<span class="hint"
|
|
7564
|
+
>Press Record then interact with the page.</span
|
|
7565
|
+
>
|
|
7566
|
+
</div>
|
|
7567
|
+
</div>
|
|
7568
|
+
` : b`
|
|
7569
|
+
<div class="scroll" ${n(this._scrollRef)}>
|
|
7570
|
+
${virtualize({
|
|
7571
|
+
scroller: true,
|
|
7572
|
+
items: visible,
|
|
7573
|
+
keyFunction: (row, i) => row?.key ?? i,
|
|
7574
|
+
renderItem: (row) => row ? this._renderRow(row) : b``
|
|
7575
|
+
})}
|
|
7576
|
+
</div>
|
|
7577
|
+
`}
|
|
7578
|
+
${selected ? b`<timeline-span-detail
|
|
7579
|
+
filterable
|
|
7580
|
+
.span=${selected}
|
|
7581
|
+
></timeline-span-detail>` : A}
|
|
7582
|
+
`;
|
|
7583
|
+
}
|
|
7584
|
+
/** One row of the virtualized list (`virtualize`'s `renderItem`). */
|
|
7585
|
+
_renderRow(row) {
|
|
7586
|
+
return b`
|
|
7587
|
+
<div
|
|
7588
|
+
class="row ${this.selectedKey === row.key ? "selected" : ""}"
|
|
7589
|
+
@click=${() => this._select(row.key)}
|
|
7590
|
+
>
|
|
7591
|
+
<span class="time">${row.start.toFixed(1)}ms</span>
|
|
7592
|
+
<span
|
|
7593
|
+
class="dot"
|
|
7594
|
+
style=${"background:" + layerColor(this.layers, row.layerId)}
|
|
7595
|
+
></span>
|
|
7596
|
+
<span class="title">${row.name}</span>
|
|
7597
|
+
${row.changed?.length ? b`<span class="changed">${row.changed.join(", ")}</span>` : A}
|
|
7598
|
+
<span class="subtitle">${row.subtitle ?? A}</span>
|
|
7599
|
+
<span class="dur ${row.duration === void 0 ? "open" : ""}"
|
|
7600
|
+
>${renderDuration(row)}</span
|
|
7601
|
+
>
|
|
7602
|
+
</div>
|
|
7603
|
+
`;
|
|
7604
|
+
}
|
|
7605
|
+
};
|
|
7606
|
+
__decorate([n$3({ type: Array })], TimelineEventList.prototype, "events", void 0);
|
|
7607
|
+
__decorate([n$3({ type: Array })], TimelineEventList.prototype, "spans", void 0);
|
|
7608
|
+
__decorate([n$3({ type: Array })], TimelineEventList.prototype, "layers", void 0);
|
|
7609
|
+
__decorate([n$3({ attribute: false })], TimelineEventList.prototype, "selectedKey", void 0);
|
|
7610
|
+
__decorate([n$3({ attribute: false })], TimelineEventList.prototype, "elementFilter", void 0);
|
|
7611
|
+
__decorate([n$3({ attribute: false })], TimelineEventList.prototype, "regex", void 0);
|
|
7612
|
+
__decorate([r$2()], TimelineEventList.prototype, "_raw", void 0);
|
|
7613
|
+
TimelineEventList = __decorate([t$2("timeline-event-list")], TimelineEventList);
|
|
7614
|
+
//#endregion
|
|
7615
|
+
//#region src/lib/timeline/tracks.ts
|
|
7616
|
+
/**
|
|
7617
|
+
* @license
|
|
7618
|
+
* Copyright 2026 Google LLC
|
|
7619
|
+
* SPDX-License-Identifier: BSD-3-Clause
|
|
7620
|
+
*/
|
|
7621
|
+
/**
|
|
7622
|
+
* Where a span stops occupying its row. A point event occupies only its own
|
|
7623
|
+
* instant; a span whose end has not arrived (still running, or its end fell
|
|
7624
|
+
* out of the buffer) occupies the rest of the recording, because that is
|
|
7625
|
+
* where it is drawn — up to the live edge.
|
|
7626
|
+
*/
|
|
7627
|
+
var occupiedEnd = (span) => {
|
|
7628
|
+
if (span.end !== void 0) return span.end;
|
|
7629
|
+
return span.groupId === void 0 ? span.start : Infinity;
|
|
7630
|
+
};
|
|
7631
|
+
/**
|
|
7632
|
+
* Groups spans into one track per layer, in `layers` order, then any layer
|
|
7633
|
+
* the spans mention that `layers` does not (a custom layer announced after the
|
|
7634
|
+
* last `get-meta`), in first-seen order. A layer with no spans still gets an
|
|
7635
|
+
* empty track, so a lane does not appear and vanish as events arrive.
|
|
7636
|
+
*
|
|
7637
|
+
* Within a track, spans are packed greedily: each goes into the first row
|
|
7638
|
+
* whose last span has ended by the time it starts. Lit's lifecycle phases
|
|
7639
|
+
* nest, so one update tick lands as `performUpdate` on row 0 and
|
|
7640
|
+
* `willUpdate` / `update` / `updated` side by side on row 1 — the flame shape
|
|
7641
|
+
* falls out of the packing without modelling it.
|
|
7642
|
+
*/
|
|
7643
|
+
var buildTracks = (spans, layers) => {
|
|
7644
|
+
const byLayer = /* @__PURE__ */ new Map();
|
|
7645
|
+
for (const layer of layers) byLayer.set(layer.id, []);
|
|
7646
|
+
for (const span of spans) {
|
|
7647
|
+
let list = byLayer.get(span.layerId);
|
|
7648
|
+
if (list === void 0) {
|
|
7649
|
+
list = [];
|
|
7650
|
+
byLayer.set(span.layerId, list);
|
|
7651
|
+
}
|
|
7652
|
+
list.push(span);
|
|
7653
|
+
}
|
|
7654
|
+
return [...byLayer].map(([layerId, list]) => ({
|
|
7655
|
+
layerId,
|
|
7656
|
+
rows: packRows(list)
|
|
7657
|
+
}));
|
|
7658
|
+
};
|
|
7659
|
+
var packRows = (spans) => {
|
|
7660
|
+
const sorted = spans.every((s, i) => i === 0 || spans[i - 1].start <= s.start) ? spans : [...spans].sort((a, b) => a.start - b.start);
|
|
7661
|
+
const rows = [];
|
|
7662
|
+
const rowEnds = [];
|
|
7663
|
+
for (const span of sorted) {
|
|
7664
|
+
let row = rowEnds.findIndex((end) => end <= span.start);
|
|
7665
|
+
if (row === -1) {
|
|
7666
|
+
row = rows.length;
|
|
7667
|
+
rows.push([]);
|
|
7668
|
+
rowEnds.push(-Infinity);
|
|
7669
|
+
}
|
|
7670
|
+
rows[row].push(span);
|
|
7671
|
+
rowEnds[row] = occupiedEnd(span);
|
|
7672
|
+
}
|
|
7673
|
+
return rows;
|
|
7674
|
+
};
|
|
7675
|
+
/**
|
|
7676
|
+
* The recording's time bounds over `spans`: the earliest start, and the
|
|
7677
|
+
* latest instant anything is known to have happened (an end, or the start of
|
|
7678
|
+
* a span with none). The origin is the earliest start rather than zero
|
|
7679
|
+
* because the panel's buffer is capped and rolls its oldest events off; a
|
|
7680
|
+
* long recording would otherwise open on an empty stretch.
|
|
7681
|
+
*/
|
|
7682
|
+
var timeBounds = (spans) => {
|
|
7683
|
+
if (spans.length === 0) return {
|
|
7684
|
+
origin: 0,
|
|
7685
|
+
extent: 0
|
|
7686
|
+
};
|
|
7687
|
+
let origin = Infinity;
|
|
7688
|
+
let last = -Infinity;
|
|
7689
|
+
for (const span of spans) {
|
|
7690
|
+
origin = Math.min(origin, span.start);
|
|
7691
|
+
last = Math.max(last, span.end ?? span.start);
|
|
7692
|
+
}
|
|
7693
|
+
return {
|
|
7694
|
+
origin,
|
|
7695
|
+
extent: last - origin
|
|
7696
|
+
};
|
|
7697
|
+
};
|
|
7698
|
+
/** Deepest zoom, in multiples of "fit": about a microsecond per pixel on a
|
|
7699
|
+
* second-long recording, past which there is nothing left to separate. */
|
|
7700
|
+
var MAX_ZOOM = 1e5;
|
|
7701
|
+
/** A recording with a single instant in it still needs a nonzero axis. */
|
|
7702
|
+
var MIN_EXTENT_MS = 1;
|
|
7703
|
+
/**
|
|
7704
|
+
* Builds the scale for a plot `width` pixels wide showing a recording that
|
|
7705
|
+
* begins at `originMs` and runs for `extentMs`.
|
|
7706
|
+
*
|
|
7707
|
+
* `zoom` is a multiple of "fit" (1 shows the whole recording); `pan` is how
|
|
7708
|
+
* many milliseconds past the origin the left edge sits. Both are clamped, so
|
|
7709
|
+
* callers can apply a raw wheel or drag delta and read back where it landed.
|
|
7710
|
+
*/
|
|
7711
|
+
var timeScale = (originMs, extentMs, width, zoom = 1, pan = 0) => {
|
|
7712
|
+
const extent = Math.max(extentMs, MIN_EXTENT_MS);
|
|
7713
|
+
const z = clampZoom(zoom);
|
|
7714
|
+
const visibleMs = extent / z;
|
|
7715
|
+
const p = clampPan(pan, extent, z);
|
|
7716
|
+
const pxPerMs = Math.max(width, 1) / visibleMs;
|
|
7717
|
+
const start = originMs + p;
|
|
7718
|
+
return {
|
|
7719
|
+
pxPerMs,
|
|
7720
|
+
start,
|
|
7721
|
+
end: start + visibleMs,
|
|
7722
|
+
toX: (ms) => (ms - start) * pxPerMs,
|
|
7723
|
+
toMs: (x) => start + x / pxPerMs
|
|
7724
|
+
};
|
|
7725
|
+
};
|
|
7726
|
+
var clampZoom = (zoom) => Math.min(Math.max(Number.isNaN(zoom) ? 1 : zoom, 1), MAX_ZOOM);
|
|
7727
|
+
/** Keeps the visible window inside the recording. */
|
|
7728
|
+
var clampPan = (pan, extentMs, zoom) => {
|
|
7729
|
+
const extent = Math.max(extentMs, MIN_EXTENT_MS);
|
|
7730
|
+
const max = extent - extent / clampZoom(zoom);
|
|
7731
|
+
return Math.min(Math.max(Number.isNaN(pan) ? 0 : pan, 0), max);
|
|
7732
|
+
};
|
|
7733
|
+
/** The pan that puts the live edge (the end of the recording) at the right
|
|
7734
|
+
* of the plot, for following a recording in progress. */
|
|
7735
|
+
var livePan = (extentMs, zoom) => clampPan(Infinity, extentMs, zoom);
|
|
7736
|
+
/**
|
|
7737
|
+
* Zooms by `factor` while keeping the millisecond under pixel `x` where it
|
|
7738
|
+
* is, which is what a wheel over a timeline is expected to do.
|
|
7739
|
+
*/
|
|
7740
|
+
var zoomAt = (originMs, extentMs, width, zoom, pan, x, factor) => {
|
|
7741
|
+
const anchor = timeScale(originMs, extentMs, width, zoom, pan).toMs(x);
|
|
7742
|
+
const nextZoom = clampZoom(clampZoom(zoom) * factor);
|
|
7743
|
+
const after = timeScale(originMs, extentMs, width, nextZoom, 0);
|
|
7744
|
+
return {
|
|
7745
|
+
zoom: nextZoom,
|
|
7746
|
+
pan: clampPan(anchor - originMs - x / after.pxPerMs, extentMs, nextZoom)
|
|
7747
|
+
};
|
|
7748
|
+
};
|
|
7749
|
+
/**
|
|
7750
|
+
* Index range `[from, to)` of the spans in `row` that intersect the window
|
|
7751
|
+
* `[start, end]`, found by binary search so a zoomed-in lane renders a
|
|
7752
|
+
* handful of marks rather than walking thousands.
|
|
7753
|
+
*
|
|
7754
|
+
* Only the span just before the first one starting inside the window can
|
|
7755
|
+
* reach into it, because a row's spans never overlap.
|
|
7756
|
+
*/
|
|
7757
|
+
var visibleRange = (row, start, end) => {
|
|
7758
|
+
const firstAtOrAfter = (t, inclusive) => {
|
|
7759
|
+
let lo = 0;
|
|
7760
|
+
let hi = row.length;
|
|
7761
|
+
while (lo < hi) {
|
|
7762
|
+
const mid = lo + hi >> 1;
|
|
7763
|
+
const s = row[mid].start;
|
|
7764
|
+
if (inclusive ? s < t : s <= t) lo = mid + 1;
|
|
7765
|
+
else hi = mid;
|
|
7766
|
+
}
|
|
7767
|
+
return lo;
|
|
7768
|
+
};
|
|
7769
|
+
let from = firstAtOrAfter(start, true);
|
|
7770
|
+
if (from > 0 && occupiedEnd(row[from - 1]) >= start) from--;
|
|
7771
|
+
const to = firstAtOrAfter(end, false);
|
|
7772
|
+
return [from, Math.max(from, to)];
|
|
7773
|
+
};
|
|
7774
|
+
/**
|
|
7775
|
+
* A round tick interval (1, 2 or 5 times a power of ten, in milliseconds) at
|
|
7776
|
+
* least `minMs` long, for axis labels that land on readable numbers.
|
|
7777
|
+
*/
|
|
7778
|
+
var niceStep = (minMs) => {
|
|
7779
|
+
if (!(minMs > 0) || !Number.isFinite(minMs)) return 1;
|
|
7780
|
+
const pow = 10 ** Math.floor(Math.log10(minMs));
|
|
7781
|
+
for (const m of [
|
|
7782
|
+
1,
|
|
7783
|
+
2,
|
|
7784
|
+
5,
|
|
7785
|
+
10
|
|
7786
|
+
]) if (m * pow >= minMs) return m * pow;
|
|
7787
|
+
return 10 * pow;
|
|
7788
|
+
};
|
|
7789
|
+
//#endregion
|
|
7790
|
+
//#region src/panel/timeline-tracks.ts
|
|
7791
|
+
/**
|
|
7792
|
+
* @license
|
|
7793
|
+
* Copyright 2026 Google LLC
|
|
7794
|
+
* SPDX-License-Identifier: BSD-3-Clause
|
|
7795
|
+
*/
|
|
7796
|
+
/** Height of one packed row inside a lane. */
|
|
7797
|
+
var ROW_PX = 14;
|
|
7798
|
+
/** Marks narrower than this draw as a fixed-width tick, so sub-millisecond
|
|
7799
|
+
* Lit phases stay visible at any zoom. */
|
|
7800
|
+
var MIN_MARK_PX = 2;
|
|
7801
|
+
/** Rough spacing between axis labels. */
|
|
7802
|
+
var TICK_PX = 90;
|
|
7803
|
+
/** A pointer that moves less than this between down and up was a click. */
|
|
7804
|
+
var DRAG_SLOP_PX = 3;
|
|
7805
|
+
var formatAxis = (ms, step) => step >= 1e3 ? `${(ms / 1e3).toFixed(step >= 1e4 ? 0 : 1)}s` : `${ms.toFixed(step >= 1 ? 0 : step >= .1 ? 1 : 2)}ms`;
|
|
7806
|
+
var describe = (span) => {
|
|
7807
|
+
const parts = [span.name];
|
|
7808
|
+
if (span.subtitle) parts.push(span.subtitle);
|
|
7809
|
+
parts.push(`@ ${span.start.toFixed(2)}ms`);
|
|
7810
|
+
if (span.duration !== void 0) parts.push(`${span.duration.toFixed(3)}ms`);
|
|
7811
|
+
else if (span.groupId !== void 0) parts.push("still open");
|
|
7812
|
+
return parts.join(" · ");
|
|
7813
|
+
};
|
|
7814
|
+
var TimelineTracks = class TimelineTracks extends i$2 {
|
|
7815
|
+
constructor(..._args) {
|
|
7816
|
+
super(..._args);
|
|
7817
|
+
this.spans = [];
|
|
7818
|
+
this.layers = [];
|
|
7819
|
+
this.selectedKey = null;
|
|
7820
|
+
this.visibleTracks = [];
|
|
7821
|
+
this.recording = false;
|
|
7822
|
+
this._zoom = 1;
|
|
7823
|
+
this._pan = 0;
|
|
7824
|
+
this._follow = true;
|
|
7825
|
+
this._width = 0;
|
|
7826
|
+
this._ticksRef = e();
|
|
7827
|
+
this._resize = null;
|
|
7828
|
+
this._observed = null;
|
|
7829
|
+
this._tracks = [];
|
|
7830
|
+
this._visibleSpans = [];
|
|
7831
|
+
this._bounds = {
|
|
7832
|
+
origin: 0,
|
|
7833
|
+
extent: 0
|
|
7834
|
+
};
|
|
7835
|
+
this._drag = null;
|
|
7836
|
+
this._suppressClick = false;
|
|
7837
|
+
}
|
|
7838
|
+
static {
|
|
7839
|
+
this.styles = [tokens, i$5`
|
|
7840
|
+
:host {
|
|
7841
|
+
display: flex;
|
|
7842
|
+
flex-direction: column;
|
|
7843
|
+
flex: 1;
|
|
7844
|
+
overflow: hidden;
|
|
7845
|
+
font-size: var(--lit-devtools-text-2xs);
|
|
7846
|
+
font-family: var(--lit-devtools-font-mono);
|
|
7847
|
+
--gutter: 120px;
|
|
7848
|
+
}
|
|
7849
|
+
.axis,
|
|
7850
|
+
.lane {
|
|
7851
|
+
display: flex;
|
|
6311
7852
|
}
|
|
6312
|
-
.
|
|
6313
|
-
width: 8px;
|
|
6314
|
-
height: 8px;
|
|
6315
|
-
border-radius: 50%;
|
|
7853
|
+
.axis {
|
|
6316
7854
|
flex-shrink: 0;
|
|
6317
|
-
|
|
7855
|
+
height: 20px;
|
|
7856
|
+
border-bottom: 1px solid var(--lit-devtools-border);
|
|
7857
|
+
color: var(--lit-devtools-text-muted);
|
|
6318
7858
|
}
|
|
6319
|
-
.
|
|
6320
|
-
flex:
|
|
6321
|
-
|
|
7859
|
+
.gutter {
|
|
7860
|
+
flex: 0 0 var(--gutter);
|
|
7861
|
+
box-sizing: border-box;
|
|
7862
|
+
padding: 0 var(--lit-devtools-space-4);
|
|
7863
|
+
display: flex;
|
|
7864
|
+
align-items: center;
|
|
7865
|
+
gap: var(--lit-devtools-space-2);
|
|
6322
7866
|
overflow: hidden;
|
|
6323
|
-
text-overflow: ellipsis;
|
|
6324
7867
|
white-space: nowrap;
|
|
7868
|
+
border-right: 1px solid var(--lit-devtools-border);
|
|
6325
7869
|
}
|
|
6326
|
-
.
|
|
6327
|
-
|
|
6328
|
-
flex
|
|
6329
|
-
max-width: 200px;
|
|
7870
|
+
.ticks {
|
|
7871
|
+
position: relative;
|
|
7872
|
+
flex: 1;
|
|
6330
7873
|
overflow: hidden;
|
|
6331
|
-
text-overflow: ellipsis;
|
|
6332
|
-
white-space: nowrap;
|
|
6333
7874
|
}
|
|
6334
|
-
.
|
|
6335
|
-
|
|
6336
|
-
|
|
6337
|
-
|
|
6338
|
-
|
|
6339
|
-
text-overflow: ellipsis;
|
|
7875
|
+
.tick-label {
|
|
7876
|
+
position: absolute;
|
|
7877
|
+
top: 3px;
|
|
7878
|
+
padding-left: var(--lit-devtools-space-2);
|
|
7879
|
+
border-left: 1px solid var(--lit-devtools-border-strong);
|
|
6340
7880
|
white-space: nowrap;
|
|
6341
7881
|
}
|
|
6342
|
-
.
|
|
6343
|
-
|
|
6344
|
-
|
|
6345
|
-
|
|
6346
|
-
|
|
7882
|
+
.lanes {
|
|
7883
|
+
flex: 1;
|
|
7884
|
+
overflow-y: auto;
|
|
7885
|
+
cursor: grab;
|
|
7886
|
+
user-select: none;
|
|
7887
|
+
touch-action: none;
|
|
6347
7888
|
}
|
|
6348
|
-
.
|
|
6349
|
-
|
|
7889
|
+
.lanes.dragging {
|
|
7890
|
+
cursor: grabbing;
|
|
6350
7891
|
}
|
|
6351
|
-
.
|
|
6352
|
-
border-
|
|
6353
|
-
|
|
6354
|
-
|
|
6355
|
-
font-size: var(--lit-devtools-text-2xs);
|
|
6356
|
-
font-family: var(--lit-devtools-font-mono);
|
|
7892
|
+
.lane {
|
|
7893
|
+
border-bottom: 1px solid var(--lit-devtools-border);
|
|
7894
|
+
}
|
|
7895
|
+
.lane .gutter {
|
|
6357
7896
|
color: var(--lit-devtools-text-secondary);
|
|
7897
|
+
cursor: default;
|
|
7898
|
+
}
|
|
7899
|
+
.dot {
|
|
7900
|
+
width: 8px;
|
|
7901
|
+
height: 8px;
|
|
7902
|
+
border-radius: 50%;
|
|
6358
7903
|
flex-shrink: 0;
|
|
6359
|
-
max-height: 130px;
|
|
6360
|
-
overflow-y: auto;
|
|
6361
7904
|
}
|
|
6362
|
-
|
|
6363
|
-
|
|
6364
|
-
width:
|
|
7905
|
+
.plot {
|
|
7906
|
+
flex: 1;
|
|
7907
|
+
min-width: 0;
|
|
7908
|
+
max-height: calc(8 * ${ROW_PX}px);
|
|
7909
|
+
overflow-x: hidden;
|
|
7910
|
+
overflow-y: auto;
|
|
6365
7911
|
}
|
|
6366
|
-
|
|
6367
|
-
|
|
6368
|
-
var(--lit-devtools-space-1) 0;
|
|
6369
|
-
vertical-align: top;
|
|
7912
|
+
.rows {
|
|
7913
|
+
position: relative;
|
|
6370
7914
|
}
|
|
6371
|
-
.
|
|
6372
|
-
|
|
7915
|
+
.mark {
|
|
7916
|
+
position: absolute;
|
|
7917
|
+
box-sizing: border-box;
|
|
7918
|
+
height: ${11}px;
|
|
7919
|
+
margin-top: 1px;
|
|
7920
|
+
border-radius: 2px;
|
|
7921
|
+
opacity: 0.85;
|
|
7922
|
+
overflow: hidden;
|
|
6373
7923
|
white-space: nowrap;
|
|
7924
|
+
color: var(--lit-devtools-surface-low);
|
|
7925
|
+
font-size: 9px;
|
|
7926
|
+
line-height: ${11}px;
|
|
7927
|
+
padding: 0 2px;
|
|
7928
|
+
cursor: pointer;
|
|
6374
7929
|
}
|
|
6375
|
-
.
|
|
6376
|
-
|
|
6377
|
-
word-break: break-all;
|
|
7930
|
+
.mark.tick {
|
|
7931
|
+
padding: 0;
|
|
6378
7932
|
}
|
|
6379
|
-
|
|
6380
|
-
|
|
6381
|
-
text-decoration: none;
|
|
7933
|
+
.mark.open {
|
|
7934
|
+
opacity: 0.45;
|
|
6382
7935
|
}
|
|
6383
|
-
|
|
6384
|
-
|
|
7936
|
+
.mark:hover {
|
|
7937
|
+
opacity: 1;
|
|
6385
7938
|
}
|
|
6386
|
-
.
|
|
6387
|
-
|
|
7939
|
+
.mark.selected {
|
|
7940
|
+
opacity: 1;
|
|
7941
|
+
outline: 2px solid var(--lit-devtools-text);
|
|
7942
|
+
outline-offset: 0;
|
|
7943
|
+
z-index: 1;
|
|
6388
7944
|
}
|
|
6389
|
-
.
|
|
6390
|
-
|
|
6391
|
-
|
|
6392
|
-
|
|
7945
|
+
.mark:focus-visible {
|
|
7946
|
+
outline: 2px solid var(--lit-devtools-accent-ring);
|
|
7947
|
+
z-index: 1;
|
|
7948
|
+
}
|
|
7949
|
+
.empty {
|
|
7950
|
+
display: flex;
|
|
7951
|
+
flex-direction: column;
|
|
7952
|
+
align-items: center;
|
|
7953
|
+
justify-content: center;
|
|
7954
|
+
flex: 1;
|
|
7955
|
+
gap: var(--lit-devtools-space-4);
|
|
7956
|
+
color: var(--lit-devtools-text-muted);
|
|
7957
|
+
font-family: var(--lit-devtools-font-sans);
|
|
7958
|
+
font-size: var(--lit-devtools-text-xs);
|
|
6393
7959
|
}
|
|
6394
7960
|
`];
|
|
6395
7961
|
}
|
|
6396
|
-
|
|
6397
|
-
|
|
6398
|
-
|
|
6399
|
-
|
|
6400
|
-
|
|
6401
|
-
|
|
6402
|
-
|
|
6403
|
-
|
|
6404
|
-
|
|
6405
|
-
|
|
6406
|
-
|
|
6407
|
-
if (
|
|
6408
|
-
|
|
6409
|
-
|
|
6410
|
-
}
|
|
6411
|
-
|
|
6412
|
-
_colorOf(layerId) {
|
|
6413
|
-
const l = this.layers.find((l) => l.id === layerId);
|
|
6414
|
-
if (!l) return "#888";
|
|
6415
|
-
return "#" + l.color.toString(16).padStart(6, "0");
|
|
6416
|
-
}
|
|
6417
|
-
_isVisible(row) {
|
|
6418
|
-
const l = this.layers.find((l) => l.id === row.layerId);
|
|
6419
|
-
if (l && !l.enabled) return false;
|
|
6420
|
-
if (this._elementFilter !== null && row.meta?.elementId !== this._elementFilter) return false;
|
|
6421
|
-
return true;
|
|
7962
|
+
disconnectedCallback() {
|
|
7963
|
+
super.disconnectedCallback();
|
|
7964
|
+
this._resize?.disconnect();
|
|
7965
|
+
this._resize = null;
|
|
7966
|
+
this._observed = null;
|
|
7967
|
+
}
|
|
7968
|
+
updated() {
|
|
7969
|
+
const el = this._ticksRef.value ?? null;
|
|
7970
|
+
if (el === this._observed) return;
|
|
7971
|
+
this._resize?.disconnect();
|
|
7972
|
+
this._observed = el;
|
|
7973
|
+
if (!el) return;
|
|
7974
|
+
this._resize ??= new ResizeObserver(() => {
|
|
7975
|
+
this._width = this._observed?.clientWidth ?? 0;
|
|
7976
|
+
});
|
|
7977
|
+
this._resize.observe(el);
|
|
6422
7978
|
}
|
|
6423
|
-
|
|
6424
|
-
|
|
6425
|
-
|
|
6426
|
-
|
|
6427
|
-
|
|
6428
|
-
|
|
7979
|
+
willUpdate(changed) {
|
|
7980
|
+
if (changed.has("spans") || changed.has("layers") || changed.has("visibleTracks")) {
|
|
7981
|
+
const shown = new Set(this.visibleTracks);
|
|
7982
|
+
this._visibleSpans = this.spans.filter((s) => shown.has(s.layerId));
|
|
7983
|
+
this._tracks = buildTracks(this._visibleSpans, this.layers).filter((t) => shown.has(t.layerId));
|
|
7984
|
+
this._bounds = timeBounds(this._visibleSpans);
|
|
7985
|
+
}
|
|
7986
|
+
}
|
|
7987
|
+
_scale() {
|
|
7988
|
+
const { origin, extent } = this._bounds;
|
|
7989
|
+
const pan = this._follow && this.recording ? livePan(extent, this._zoom) : this._pan;
|
|
7990
|
+
return timeScale(origin, extent, this._width, this._zoom, pan);
|
|
7991
|
+
}
|
|
7992
|
+
/** Commit a zoom/pan, and keep following only if it still ends at the live
|
|
7993
|
+
* edge. */
|
|
7994
|
+
_setView(zoom, pan) {
|
|
7995
|
+
const { extent } = this._bounds;
|
|
7996
|
+
this._zoom = clampZoom(zoom);
|
|
7997
|
+
this._pan = clampPan(pan, extent, this._zoom);
|
|
7998
|
+
this._follow = this._pan >= livePan(extent, this._zoom) - 1e-9;
|
|
7999
|
+
}
|
|
8000
|
+
_currentPan() {
|
|
8001
|
+
return this._scale().start - this._bounds.origin;
|
|
8002
|
+
}
|
|
8003
|
+
_onWheel(e) {
|
|
8004
|
+
if (this._width === 0 || this._visibleSpans.length === 0) return;
|
|
8005
|
+
const plot = this._ticksRef.value;
|
|
8006
|
+
if (!plot) return;
|
|
8007
|
+
const x = e.clientX - plot.getBoundingClientRect().left;
|
|
8008
|
+
if (x < 0) return;
|
|
8009
|
+
e.preventDefault();
|
|
8010
|
+
const { origin, extent } = this._bounds;
|
|
8011
|
+
const pan = this._currentPan();
|
|
8012
|
+
if (Math.abs(e.deltaX) > Math.abs(e.deltaY) || e.shiftKey) {
|
|
8013
|
+
const delta = e.shiftKey ? e.deltaY : e.deltaX;
|
|
8014
|
+
const scale = this._scale();
|
|
8015
|
+
this._setView(this._zoom, pan + delta / scale.pxPerMs);
|
|
8016
|
+
return;
|
|
6429
8017
|
}
|
|
6430
|
-
|
|
6431
|
-
|
|
6432
|
-
|
|
6433
|
-
}));
|
|
8018
|
+
const factor = Math.exp(-e.deltaY * .002);
|
|
8019
|
+
const next = zoomAt(origin, extent, this._width, this._zoom, pan, x, factor);
|
|
8020
|
+
this._setView(next.zoom, next.pan);
|
|
6434
8021
|
}
|
|
6435
|
-
|
|
6436
|
-
|
|
6437
|
-
this.
|
|
8022
|
+
_onPointerDown(e) {
|
|
8023
|
+
if (e.button !== 0) return;
|
|
8024
|
+
this._drag = {
|
|
8025
|
+
x: e.clientX,
|
|
8026
|
+
pan: this._currentPan(),
|
|
8027
|
+
moved: false
|
|
8028
|
+
};
|
|
6438
8029
|
}
|
|
6439
|
-
|
|
6440
|
-
|
|
6441
|
-
|
|
6442
|
-
|
|
8030
|
+
_onPointerMove(e) {
|
|
8031
|
+
const drag = this._drag;
|
|
8032
|
+
if (!drag) return;
|
|
8033
|
+
const dx = e.clientX - drag.x;
|
|
8034
|
+
if (!drag.moved && Math.abs(dx) < DRAG_SLOP_PX) return;
|
|
8035
|
+
if (!drag.moved) {
|
|
8036
|
+
drag.moved = true;
|
|
8037
|
+
e.currentTarget.setPointerCapture(e.pointerId);
|
|
8038
|
+
this.requestUpdate();
|
|
8039
|
+
}
|
|
8040
|
+
this._setView(this._zoom, drag.pan - dx / this._scale().pxPerMs);
|
|
8041
|
+
}
|
|
8042
|
+
_onPointerUp() {
|
|
8043
|
+
if (this._drag?.moved) {
|
|
8044
|
+
this._suppressClick = true;
|
|
8045
|
+
setTimeout(() => this._suppressClick = false);
|
|
8046
|
+
this.requestUpdate();
|
|
8047
|
+
}
|
|
8048
|
+
this._drag = null;
|
|
8049
|
+
}
|
|
8050
|
+
_refit() {
|
|
8051
|
+
this._zoom = 1;
|
|
8052
|
+
this._pan = 0;
|
|
8053
|
+
this._follow = true;
|
|
8054
|
+
}
|
|
8055
|
+
_select(key) {
|
|
8056
|
+
if (this._suppressClick) return;
|
|
8057
|
+
this.dispatchEvent(new CustomEvent("span-select", {
|
|
8058
|
+
detail: { key },
|
|
6443
8059
|
bubbles: true,
|
|
6444
8060
|
composed: true
|
|
6445
8061
|
}));
|
|
6446
8062
|
}
|
|
6447
|
-
_onRegexInput(e) {
|
|
6448
|
-
this._regex = e.target.value;
|
|
6449
|
-
}
|
|
6450
|
-
/** Text searched by the regex filter — element tag, name, subtitle and the
|
|
6451
|
-
* changed property keys (the reason is worth searching for by name). */
|
|
6452
|
-
_haystack(row) {
|
|
6453
|
-
return `${row.meta?.tagName ?? ""} ${row.name} ${row.subtitle ?? ""} ${(row.changed ?? []).join(" ")}`;
|
|
6454
|
-
}
|
|
6455
8063
|
render() {
|
|
6456
|
-
const
|
|
6457
|
-
|
|
6458
|
-
|
|
6459
|
-
|
|
6460
|
-
|
|
6461
|
-
|
|
6462
|
-
|
|
6463
|
-
|
|
6464
|
-
|
|
6465
|
-
const
|
|
8064
|
+
const selected = this.selectedSpan;
|
|
8065
|
+
const detail = selected ? b`<timeline-span-detail
|
|
8066
|
+
filterable
|
|
8067
|
+
.span=${selected}
|
|
8068
|
+
></timeline-span-detail>` : A;
|
|
8069
|
+
if (this._tracks.length === 0) return b`<div class="empty">
|
|
8070
|
+
${this.visibleTracks.length === 0 ? "No tracks shown. Pick some above." : "No events recorded."}
|
|
8071
|
+
</div>
|
|
8072
|
+
${detail}`;
|
|
8073
|
+
const scale = this._scale();
|
|
6466
8074
|
return b`
|
|
6467
|
-
|
|
6468
|
-
|
|
6469
|
-
|
|
6470
|
-
|
|
6471
|
-
|
|
6472
|
-
|
|
6473
|
-
|
|
6474
|
-
|
|
6475
|
-
|
|
6476
|
-
|
|
6477
|
-
|
|
6478
|
-
|
|
6479
|
-
|
|
6480
|
-
|
|
6481
|
-
|
|
6482
|
-
|
|
6483
|
-
|
|
6484
|
-
</option>
|
|
6485
|
-
`)}
|
|
6486
|
-
</select>
|
|
6487
|
-
` : A}
|
|
6488
|
-
<input
|
|
6489
|
-
class="regex ${regexInvalid ? "invalid" : ""}"
|
|
6490
|
-
type="text"
|
|
6491
|
-
spellcheck="false"
|
|
6492
|
-
placeholder="filter regex…"
|
|
6493
|
-
title="Case-insensitive regex matched against element tag, title and subtitle"
|
|
6494
|
-
.value=${this._regex}
|
|
6495
|
-
@input=${this._onRegexInput}
|
|
6496
|
-
/>
|
|
6497
|
-
<button
|
|
6498
|
-
class=${this._raw ? "on" : ""}
|
|
6499
|
-
title="Show one row per recorded event instead of collapsing start/end pairs"
|
|
6500
|
-
@click=${() => {
|
|
6501
|
-
this._raw = !this._raw;
|
|
6502
|
-
}}
|
|
6503
|
-
>
|
|
6504
|
-
Raw
|
|
6505
|
-
</button>
|
|
6506
|
-
<span class="count"
|
|
6507
|
-
>${visible.length} / ${this._rowsCache.length}</span
|
|
6508
|
-
>
|
|
6509
|
-
</div>
|
|
6510
|
-
` : A}
|
|
6511
|
-
<div class="scroll" ${n(this._scrollRef)}>
|
|
6512
|
-
${visible.length === 0 ? b`
|
|
6513
|
-
<div class="empty">
|
|
6514
|
-
<span>No events recorded.</span>
|
|
6515
|
-
<span class="hint"
|
|
6516
|
-
>Press Record then interact with the page.</span
|
|
6517
|
-
>
|
|
6518
|
-
</div>
|
|
6519
|
-
` : c(visible, (row) => row.key, (row) => b`
|
|
6520
|
-
<div
|
|
6521
|
-
class="row ${this._selectedKey === row.key ? "selected" : ""}"
|
|
6522
|
-
@click=${() => {
|
|
6523
|
-
this._selectedKey = row.key;
|
|
6524
|
-
}}
|
|
6525
|
-
>
|
|
6526
|
-
<span class="time">${row.start.toFixed(1)}ms</span>
|
|
6527
|
-
<span
|
|
6528
|
-
class="dot"
|
|
6529
|
-
style=${"background:" + this._colorOf(row.layerId)}
|
|
6530
|
-
></span>
|
|
6531
|
-
<span class="title">${row.name}</span>
|
|
6532
|
-
${row.changed?.length ? b`<span class="changed"
|
|
6533
|
-
>${row.changed.join(", ")}</span
|
|
6534
|
-
>` : A}
|
|
6535
|
-
<span class="subtitle">${row.subtitle ?? A}</span>
|
|
6536
|
-
<span
|
|
6537
|
-
class="dur ${row.duration === void 0 ? "open" : ""}"
|
|
6538
|
-
>${renderDuration(row)}</span
|
|
6539
|
-
>
|
|
6540
|
-
</div>
|
|
6541
|
-
`)}
|
|
8075
|
+
<div class="axis">
|
|
8076
|
+
<div class="gutter"></div>
|
|
8077
|
+
<div class="ticks" ${n(this._ticksRef)}>
|
|
8078
|
+
${this._width > 0 ? this._renderTicks(scale) : A}
|
|
8079
|
+
</div>
|
|
8080
|
+
</div>
|
|
8081
|
+
<div
|
|
8082
|
+
class="lanes ${this._drag?.moved ? "dragging" : ""}"
|
|
8083
|
+
title="Wheel to zoom, drag to pan, double-click to fit"
|
|
8084
|
+
@wheel=${this._onWheel}
|
|
8085
|
+
@pointerdown=${this._onPointerDown}
|
|
8086
|
+
@pointermove=${this._onPointerMove}
|
|
8087
|
+
@pointerup=${this._onPointerUp}
|
|
8088
|
+
@pointercancel=${this._onPointerUp}
|
|
8089
|
+
@dblclick=${this._refit}
|
|
8090
|
+
>
|
|
8091
|
+
${this._tracks.map((track) => this._renderLane(track, scale))}
|
|
6542
8092
|
</div>
|
|
6543
|
-
${
|
|
8093
|
+
${detail}
|
|
6544
8094
|
`;
|
|
6545
8095
|
}
|
|
6546
|
-
|
|
6547
|
-
const
|
|
6548
|
-
const
|
|
6549
|
-
|
|
8096
|
+
_renderTicks(scale) {
|
|
8097
|
+
const step = niceStep(TICK_PX / scale.pxPerMs);
|
|
8098
|
+
const labels = [];
|
|
8099
|
+
for (let t = Math.ceil(scale.start / step) * step; t <= scale.end && labels.length < 200; t += step) labels.push(b`<span class="tick-label" style="left:${scale.toX(t)}px"
|
|
8100
|
+
>${formatAxis(t, step)}</span
|
|
8101
|
+
>`);
|
|
8102
|
+
return labels;
|
|
8103
|
+
}
|
|
8104
|
+
_renderLane(track, scale) {
|
|
8105
|
+
const layer = this.layers.find((l) => l.id === track.layerId);
|
|
8106
|
+
const color = layerColor(this.layers, track.layerId);
|
|
8107
|
+
const rows = Math.max(track.rows.length, 1);
|
|
6550
8108
|
return b`
|
|
6551
|
-
<div class="
|
|
6552
|
-
<
|
|
6553
|
-
<
|
|
6554
|
-
|
|
6555
|
-
|
|
6556
|
-
|
|
6557
|
-
<
|
|
6558
|
-
|
|
6559
|
-
|
|
6560
|
-
|
|
6561
|
-
${row.duration !== void 0 ? b`<tr>
|
|
6562
|
-
<td class="key">duration</td>
|
|
6563
|
-
<td class="val">${row.duration.toFixed(3)} ms</td>
|
|
6564
|
-
</tr>` : A}
|
|
6565
|
-
${row.changed?.length ? b`<tr>
|
|
6566
|
-
<td class="key">changed</td>
|
|
6567
|
-
<td class="val">${row.changed.join(", ")}</td>
|
|
6568
|
-
</tr>` : A}
|
|
6569
|
-
${meta?.tagName ? b`<tr>
|
|
6570
|
-
<td class="key">element</td>
|
|
6571
|
-
<td class="val">
|
|
6572
|
-
<${meta.tagName}> #${meta.elementId}
|
|
6573
|
-
${meta.elementId != null ? b`<a
|
|
6574
|
-
class="filter-link"
|
|
6575
|
-
@click=${() => {
|
|
6576
|
-
this._elementFilter = meta.elementId;
|
|
6577
|
-
}}
|
|
6578
|
-
>filter</a
|
|
6579
|
-
><a
|
|
6580
|
-
class="filter-link"
|
|
6581
|
-
title="Open this element in the Components tab"
|
|
6582
|
-
@click=${() => this._inspect(meta.elementId)}
|
|
6583
|
-
>inspect</a
|
|
6584
|
-
>` : A}
|
|
6585
|
-
</td>
|
|
6586
|
-
</tr>` : A}
|
|
6587
|
-
${src ? b`<tr>
|
|
6588
|
-
<td class="key">source</td>
|
|
6589
|
-
<td class="val">
|
|
6590
|
-
<a
|
|
6591
|
-
class="src-link"
|
|
6592
|
-
title="Open this file in your editor"
|
|
6593
|
-
@click=${() => openInEditor(src.file, src.line)}
|
|
6594
|
-
>${src.file}:${src.line}</a
|
|
6595
|
-
>
|
|
6596
|
-
</td>
|
|
6597
|
-
</tr>` : A}
|
|
6598
|
-
${data != null ? b`<tr>
|
|
6599
|
-
<td class="key">data</td>
|
|
6600
|
-
<td class="val">${JSON.stringify(data)}</td>
|
|
6601
|
-
</tr>` : A}
|
|
6602
|
-
</table>
|
|
8109
|
+
<div class="lane">
|
|
8110
|
+
<div class="gutter" title=${layer?.label ?? track.layerId}>
|
|
8111
|
+
<span class="dot" style="background:${color}"></span>
|
|
8112
|
+
${layer?.label ?? track.layerId}
|
|
8113
|
+
</div>
|
|
8114
|
+
<div class="plot">
|
|
8115
|
+
<div class="rows" style="height:${rows * ROW_PX}px">
|
|
8116
|
+
${this._width > 0 ? track.rows.map((row, i) => this._renderRow(row, i, scale, color)) : A}
|
|
8117
|
+
</div>
|
|
8118
|
+
</div>
|
|
6603
8119
|
</div>
|
|
6604
8120
|
`;
|
|
6605
8121
|
}
|
|
8122
|
+
_renderRow(row, rowIndex, scale, color) {
|
|
8123
|
+
const [from, to] = visibleRange(row, scale.start, scale.end);
|
|
8124
|
+
const liveEdge = this._bounds.origin + this._bounds.extent;
|
|
8125
|
+
const marks = [];
|
|
8126
|
+
let lastTickPx = -Infinity;
|
|
8127
|
+
for (let i = from; i < to; i++) {
|
|
8128
|
+
const span = row[i];
|
|
8129
|
+
const open = span.end === void 0 && span.groupId !== void 0;
|
|
8130
|
+
const x0 = scale.toX(span.start);
|
|
8131
|
+
const x1 = scale.toX(span.end ?? (open ? liveEdge : span.start));
|
|
8132
|
+
const isTick = x1 - x0 < MIN_MARK_PX;
|
|
8133
|
+
const selected = span.key === this.selectedKey;
|
|
8134
|
+
if (isTick && !selected && Math.round(x0) === lastTickPx) continue;
|
|
8135
|
+
if (isTick) lastTickPx = Math.round(x0);
|
|
8136
|
+
const left = Math.max(x0, -1);
|
|
8137
|
+
const width = isTick ? MIN_MARK_PX : Math.min(x1, this._width + 1) - left;
|
|
8138
|
+
marks.push(b`<div
|
|
8139
|
+
class="mark ${isTick ? "tick" : ""} ${open ? "open" : ""} ${selected ? "selected" : ""}"
|
|
8140
|
+
role="button"
|
|
8141
|
+
tabindex="0"
|
|
8142
|
+
title=${describe(span)}
|
|
8143
|
+
style="left:${left}px;width:${width}px;top:${rowIndex * ROW_PX}px;background:${color}"
|
|
8144
|
+
@click=${() => this._select(span.key)}
|
|
8145
|
+
@keydown=${(e) => {
|
|
8146
|
+
if (e.key === "Enter" || e.key === " ") {
|
|
8147
|
+
e.preventDefault();
|
|
8148
|
+
this._select(span.key);
|
|
8149
|
+
}
|
|
8150
|
+
}}
|
|
8151
|
+
>
|
|
8152
|
+
${isTick || width < 40 ? A : span.name}
|
|
8153
|
+
</div>`);
|
|
8154
|
+
}
|
|
8155
|
+
return marks;
|
|
8156
|
+
}
|
|
6606
8157
|
};
|
|
6607
|
-
__decorate([n$3({ type: Array })],
|
|
6608
|
-
__decorate([n$3({ type: Array })],
|
|
6609
|
-
__decorate([
|
|
6610
|
-
__decorate([
|
|
6611
|
-
__decorate([
|
|
6612
|
-
__decorate([
|
|
6613
|
-
|
|
8158
|
+
__decorate([n$3({ type: Array })], TimelineTracks.prototype, "spans", void 0);
|
|
8159
|
+
__decorate([n$3({ type: Array })], TimelineTracks.prototype, "layers", void 0);
|
|
8160
|
+
__decorate([n$3({ attribute: false })], TimelineTracks.prototype, "selectedKey", void 0);
|
|
8161
|
+
__decorate([n$3({ attribute: false })], TimelineTracks.prototype, "selectedSpan", void 0);
|
|
8162
|
+
__decorate([n$3({ type: Array })], TimelineTracks.prototype, "visibleTracks", void 0);
|
|
8163
|
+
__decorate([n$3({ type: Boolean })], TimelineTracks.prototype, "recording", void 0);
|
|
8164
|
+
__decorate([r$2()], TimelineTracks.prototype, "_zoom", void 0);
|
|
8165
|
+
__decorate([r$2()], TimelineTracks.prototype, "_pan", void 0);
|
|
8166
|
+
__decorate([r$2()], TimelineTracks.prototype, "_follow", void 0);
|
|
8167
|
+
__decorate([r$2()], TimelineTracks.prototype, "_width", void 0);
|
|
8168
|
+
TimelineTracks = __decorate([t$2("timeline-tracks")], TimelineTracks);
|
|
6614
8169
|
//#endregion
|
|
6615
8170
|
//#region src/panel/timeline-store.ts
|
|
6616
8171
|
/**
|
|
@@ -6640,6 +8195,47 @@ TimelineEventList = __decorate([t$2("timeline-event-list")], TimelineEventList);
|
|
|
6640
8195
|
* recent events; older ones scroll off.
|
|
6641
8196
|
*/
|
|
6642
8197
|
var MAX_EVENTS = 5e3;
|
|
8198
|
+
/**
|
|
8199
|
+
* sessionStorage key for the id of the newest event Clear (or a fresh
|
|
8200
|
+
* recording) threw away. A reloaded panel is refilled from the node's
|
|
8201
|
+
* `timeline-history`, which Clear does not touch (agents still read the same
|
|
8202
|
+
* buffer through `recent-events`), so without this a reload would resurrect
|
|
8203
|
+
* everything the developer cleared. sessionStorage, not a module variable:
|
|
8204
|
+
* the point is to survive the reload. Ids are `${epoch}-${seq}` with a seq
|
|
8205
|
+
* that never resets across Clear (see `devframe/definition.ts`).
|
|
8206
|
+
*/
|
|
8207
|
+
var CLEARED_THROUGH_KEY = "lit-devtools:timeline-cleared-through";
|
|
8208
|
+
var parseEventId = (id) => {
|
|
8209
|
+
if (id === void 0) return void 0;
|
|
8210
|
+
const cut = id.lastIndexOf("-");
|
|
8211
|
+
const seq = Number(id.slice(cut + 1));
|
|
8212
|
+
return cut > 0 && Number.isInteger(seq) ? {
|
|
8213
|
+
epoch: id.slice(0, cut),
|
|
8214
|
+
seq
|
|
8215
|
+
} : void 0;
|
|
8216
|
+
};
|
|
8217
|
+
var readClearedThrough = () => {
|
|
8218
|
+
try {
|
|
8219
|
+
return parseEventId(sessionStorage.getItem(CLEARED_THROUGH_KEY) ?? void 0);
|
|
8220
|
+
} catch {
|
|
8221
|
+
return;
|
|
8222
|
+
}
|
|
8223
|
+
};
|
|
8224
|
+
var rememberClearedThrough = (id) => {
|
|
8225
|
+
try {
|
|
8226
|
+
sessionStorage.setItem(CLEARED_THROUGH_KEY, id);
|
|
8227
|
+
} catch {}
|
|
8228
|
+
};
|
|
8229
|
+
/** Drops events at or before the cleared-through mark. A mark from another
|
|
8230
|
+
* epoch belongs to an earlier dev server and says nothing about these ids. */
|
|
8231
|
+
var withoutCleared = (batch) => {
|
|
8232
|
+
const mark = readClearedThrough();
|
|
8233
|
+
if (mark === void 0) return batch;
|
|
8234
|
+
return batch.filter((event) => {
|
|
8235
|
+
const id = parseEventId(event.id);
|
|
8236
|
+
return id === void 0 || id.epoch !== mark.epoch || id.seq > mark.seq;
|
|
8237
|
+
});
|
|
8238
|
+
};
|
|
6643
8239
|
var events = [];
|
|
6644
8240
|
var error = null;
|
|
6645
8241
|
var started = false;
|
|
@@ -6654,6 +8250,8 @@ var getTimelineEvents = () => events;
|
|
|
6654
8250
|
var getTimelineError = () => error;
|
|
6655
8251
|
var clearTimelineEvents = () => {
|
|
6656
8252
|
if (events.length === 0) return;
|
|
8253
|
+
const newest = events[events.length - 1].id;
|
|
8254
|
+
if (newest !== void 0) rememberClearedThrough(newest);
|
|
6657
8255
|
events = [];
|
|
6658
8256
|
notify$1();
|
|
6659
8257
|
};
|
|
@@ -6679,8 +8277,16 @@ var start = async () => {
|
|
|
6679
8277
|
return;
|
|
6680
8278
|
}
|
|
6681
8279
|
const reader = rpc.rpc.streaming.subscribe(meta.stream.channel, meta.stream.id, { highWaterMark: 4096 });
|
|
8280
|
+
const seeded = withoutCleared(await rpc.rpc.call("timeline-history").catch(() => [])).slice(-5e3);
|
|
8281
|
+
const seededIds = new Set(seeded.map((event) => event.id));
|
|
8282
|
+
if (seeded.length > 0) {
|
|
8283
|
+
events = seeded;
|
|
8284
|
+
notify$1();
|
|
8285
|
+
}
|
|
6682
8286
|
for await (const batch of reader) {
|
|
6683
|
-
const
|
|
8287
|
+
const fresh = withoutCleared(batch).filter((event) => event.id === void 0 || !seededIds.has(event.id));
|
|
8288
|
+
if (fresh.length === 0) continue;
|
|
8289
|
+
const next = [...events, ...fresh];
|
|
6684
8290
|
events = next.length > MAX_EVENTS ? next.slice(-5e3) : next;
|
|
6685
8291
|
notify$1();
|
|
6686
8292
|
}
|
|
@@ -6696,15 +8302,63 @@ var start = async () => {
|
|
|
6696
8302
|
* Copyright 2026 Google LLC
|
|
6697
8303
|
* SPDX-License-Identifier: BSD-3-Clause
|
|
6698
8304
|
*/
|
|
8305
|
+
/** localStorage key remembering List vs Tracks. */
|
|
8306
|
+
var MODE_LS_KEY = "lit-devtools-timeline-mode";
|
|
8307
|
+
/** localStorage key remembering which tracks the user hid. Stored as the
|
|
8308
|
+
* hidden set, not the shown one, so a layer seen for the first time (a
|
|
8309
|
+
* custom layer, a new built-in) gets a track by default. */
|
|
8310
|
+
var HIDDEN_TRACKS_LS_KEY = "lit-devtools-timeline-hidden-tracks";
|
|
8311
|
+
var MODE_TABS = [{
|
|
8312
|
+
id: "list",
|
|
8313
|
+
label: "List"
|
|
8314
|
+
}, {
|
|
8315
|
+
id: "tracks",
|
|
8316
|
+
label: "Tracks"
|
|
8317
|
+
}];
|
|
8318
|
+
var readMode = () => {
|
|
8319
|
+
try {
|
|
8320
|
+
return localStorage.getItem(MODE_LS_KEY) === "tracks" ? "tracks" : "list";
|
|
8321
|
+
} catch {
|
|
8322
|
+
return "list";
|
|
8323
|
+
}
|
|
8324
|
+
};
|
|
8325
|
+
var readHiddenTracks = () => {
|
|
8326
|
+
try {
|
|
8327
|
+
const parsed = JSON.parse(localStorage.getItem(HIDDEN_TRACKS_LS_KEY) ?? "[]");
|
|
8328
|
+
return new Set(Array.isArray(parsed) ? parsed.filter((id) => typeof id === "string") : []);
|
|
8329
|
+
} catch {
|
|
8330
|
+
return /* @__PURE__ */ new Set();
|
|
8331
|
+
}
|
|
8332
|
+
};
|
|
8333
|
+
var store = (key, value) => {
|
|
8334
|
+
try {
|
|
8335
|
+
localStorage.setItem(key, value);
|
|
8336
|
+
} catch {}
|
|
8337
|
+
};
|
|
6699
8338
|
var TimelineView = class TimelineView extends i$2 {
|
|
6700
8339
|
constructor(..._args) {
|
|
6701
8340
|
super(..._args);
|
|
6702
8341
|
this._recording = false;
|
|
8342
|
+
this._sessionSeen = false;
|
|
6703
8343
|
this._exporting = false;
|
|
6704
8344
|
this._exportNote = null;
|
|
6705
8345
|
this._events = [];
|
|
6706
8346
|
this._layers = [];
|
|
6707
8347
|
this._error = null;
|
|
8348
|
+
this._mode = readMode();
|
|
8349
|
+
this._hiddenTracks = readHiddenTracks();
|
|
8350
|
+
this._selectedKey = null;
|
|
8351
|
+
this._elementFilter = null;
|
|
8352
|
+
this._regex = "";
|
|
8353
|
+
this._spans = [];
|
|
8354
|
+
this._spansOf = null;
|
|
8355
|
+
this._elements = [];
|
|
8356
|
+
this._filteredSpans = [];
|
|
8357
|
+
this._pendingEventId = null;
|
|
8358
|
+
this._revealSelection = false;
|
|
8359
|
+
this._pendingSettled = false;
|
|
8360
|
+
this._listRef = e();
|
|
8361
|
+
this._visibleTracks = [];
|
|
6708
8362
|
this._baseLayers = [];
|
|
6709
8363
|
this._rpc = null;
|
|
6710
8364
|
this._sessionOff = null;
|
|
@@ -6749,20 +8403,57 @@ var TimelineView = class TimelineView extends i$2 {
|
|
|
6749
8403
|
}
|
|
6750
8404
|
.export-note {
|
|
6751
8405
|
color: var(--lit-devtools-text-muted);
|
|
6752
|
-
font-size: var(--lit-devtools-text-2xs);
|
|
6753
|
-
overflow: hidden;
|
|
6754
|
-
text-overflow: ellipsis;
|
|
6755
|
-
white-space: nowrap;
|
|
8406
|
+
font-size: var(--lit-devtools-text-2xs);
|
|
8407
|
+
overflow: hidden;
|
|
8408
|
+
text-overflow: ellipsis;
|
|
8409
|
+
white-space: nowrap;
|
|
8410
|
+
}
|
|
8411
|
+
.record.active {
|
|
8412
|
+
border-color: var(--lit-devtools-error);
|
|
8413
|
+
background: var(--lit-devtools-error-soft);
|
|
8414
|
+
color: var(--lit-devtools-error);
|
|
8415
|
+
}
|
|
8416
|
+
.toolbar segmented-tabs {
|
|
8417
|
+
align-self: stretch;
|
|
8418
|
+
margin: calc(-1 * var(--lit-devtools-space-3)) 0;
|
|
8419
|
+
}
|
|
8420
|
+
.filterbar {
|
|
8421
|
+
display: flex;
|
|
8422
|
+
align-items: center;
|
|
8423
|
+
gap: var(--lit-devtools-space-3);
|
|
8424
|
+
padding: var(--lit-devtools-space-2) var(--lit-devtools-space-5);
|
|
8425
|
+
border-bottom: 1px solid var(--lit-devtools-border);
|
|
8426
|
+
font-size: var(--lit-devtools-text-2xs);
|
|
8427
|
+
color: var(--lit-devtools-text-muted);
|
|
8428
|
+
flex-shrink: 0;
|
|
8429
|
+
}
|
|
8430
|
+
.filterbar select,
|
|
8431
|
+
.filterbar input.regex {
|
|
8432
|
+
background: var(--lit-devtools-surface-elevated);
|
|
8433
|
+
color: var(--lit-devtools-text);
|
|
8434
|
+
border: 1px solid var(--lit-devtools-border-strong);
|
|
8435
|
+
border-radius: var(--lit-devtools-radius-sm);
|
|
8436
|
+
padding: var(--lit-devtools-space-1) var(--lit-devtools-space-3);
|
|
8437
|
+
font-size: var(--lit-devtools-text-2xs);
|
|
8438
|
+
font-family: var(--lit-devtools-font-mono);
|
|
8439
|
+
}
|
|
8440
|
+
.filterbar input.regex {
|
|
8441
|
+
min-width: 140px;
|
|
8442
|
+
}
|
|
8443
|
+
.filterbar input.regex::placeholder {
|
|
8444
|
+
color: var(--lit-devtools-text-muted);
|
|
6756
8445
|
}
|
|
6757
|
-
.
|
|
8446
|
+
.filterbar input.regex.invalid {
|
|
6758
8447
|
border-color: var(--lit-devtools-error);
|
|
6759
|
-
background: var(--lit-devtools-error-soft);
|
|
6760
|
-
color: var(--lit-devtools-error);
|
|
6761
8448
|
}
|
|
6762
|
-
timeline-event-list
|
|
8449
|
+
timeline-event-list,
|
|
8450
|
+
timeline-tracks {
|
|
6763
8451
|
flex: 1;
|
|
6764
8452
|
overflow: hidden;
|
|
6765
8453
|
}
|
|
8454
|
+
[hidden] {
|
|
8455
|
+
display: none !important;
|
|
8456
|
+
}
|
|
6766
8457
|
.error {
|
|
6767
8458
|
padding: var(--lit-devtools-space-5);
|
|
6768
8459
|
color: var(--lit-devtools-text-secondary);
|
|
@@ -6785,6 +8476,60 @@ var TimelineView = class TimelineView extends i$2 {
|
|
|
6785
8476
|
this._storeOff?.();
|
|
6786
8477
|
this._storeOff = null;
|
|
6787
8478
|
}
|
|
8479
|
+
willUpdate(changed) {
|
|
8480
|
+
if (changed.has("_layers") || changed.has("_hiddenTracks")) this._visibleTracks = this._layers.filter((l) => l.enabled && !this._hiddenTracks.has(l.id)).map((l) => l.id);
|
|
8481
|
+
if (this._events !== this._spansOf) {
|
|
8482
|
+
this._spansOf = this._events;
|
|
8483
|
+
this._spans = toSpans(this._events);
|
|
8484
|
+
this._elements = listElements(this._events);
|
|
8485
|
+
if (this._elementFilter !== null && !this._elements.some((el) => el.id === this._elementFilter)) this._elementFilter = null;
|
|
8486
|
+
const key = this._selectedKey;
|
|
8487
|
+
if (key !== null && !isRawKey(key) && !this._spans.some((s) => s.key === key)) this._selectedKey = null;
|
|
8488
|
+
this._applyPendingEvent();
|
|
8489
|
+
}
|
|
8490
|
+
if (changed.has("_events") || changed.has("_elementFilter") || changed.has("_regex")) this._filteredSpans = filterSpans(this._spans, this._elementFilter, compileRegex(this._regex).re);
|
|
8491
|
+
}
|
|
8492
|
+
/**
|
|
8493
|
+
* Select the span a deep link named. Its start event is the natural target
|
|
8494
|
+
* (`span.events[0]`), but any of the span's events matches, so a link to
|
|
8495
|
+
* either half of a pair lands on the same row.
|
|
8496
|
+
*
|
|
8497
|
+
* An id the buffer does not hold — evicted, or from another session — ends
|
|
8498
|
+
* with no selection and no error, once there are events to have looked in.
|
|
8499
|
+
*/
|
|
8500
|
+
selectEvent(id) {
|
|
8501
|
+
this._pendingEventId = id;
|
|
8502
|
+
this._applyPendingEvent();
|
|
8503
|
+
this.requestUpdate();
|
|
8504
|
+
}
|
|
8505
|
+
_applyPendingEvent() {
|
|
8506
|
+
const id = this._pendingEventId;
|
|
8507
|
+
if (id === null || this._spans.length === 0) return;
|
|
8508
|
+
const span = this._spans.find((s) => s.events.some((e) => e.id === id));
|
|
8509
|
+
this._pendingEventId = null;
|
|
8510
|
+
this._pendingSettled = true;
|
|
8511
|
+
this._selectedKey = span?.key ?? null;
|
|
8512
|
+
if (span !== void 0) this._revealSelection = true;
|
|
8513
|
+
}
|
|
8514
|
+
/** Id of the selected span's start event, for the shell's URL sync. While a
|
|
8515
|
+
* linked id is still waiting on the store it is reported as-is, so the
|
|
8516
|
+
* address bar does not drop it before the events land. */
|
|
8517
|
+
get selectedEventId() {
|
|
8518
|
+
if (this._pendingEventId !== null) return this._pendingEventId;
|
|
8519
|
+
const key = this._selectedKey;
|
|
8520
|
+
if (key === null) return null;
|
|
8521
|
+
return this._spans.find((s) => s.key === key)?.events[0]?.id ?? null;
|
|
8522
|
+
}
|
|
8523
|
+
updated(changed) {
|
|
8524
|
+
if (this._revealSelection) {
|
|
8525
|
+
this._revealSelection = false;
|
|
8526
|
+
this.updateComplete.then(() => this._listRef.value?.updateComplete).then(() => this._listRef.value?.reveal());
|
|
8527
|
+
}
|
|
8528
|
+
if (changed.has("_selectedKey") || this._pendingSettled) {
|
|
8529
|
+
this._pendingSettled = false;
|
|
8530
|
+
this.dispatchEvent(new CustomEvent("selection-change"));
|
|
8531
|
+
}
|
|
8532
|
+
}
|
|
6788
8533
|
_readStore() {
|
|
6789
8534
|
if (!this._active) return;
|
|
6790
8535
|
this._events = getTimelineEvents();
|
|
@@ -6816,7 +8561,8 @@ var TimelineView = class TimelineView extends i$2 {
|
|
|
6816
8561
|
* to the recording flag and merged layer list. */
|
|
6817
8562
|
_applySession(state) {
|
|
6818
8563
|
const { recordingState } = state.layers;
|
|
6819
|
-
if (recordingState && !this._recording) clearTimelineEvents();
|
|
8564
|
+
if (this._sessionSeen && recordingState && !this._recording) clearTimelineEvents();
|
|
8565
|
+
this._sessionSeen = true;
|
|
6820
8566
|
this._recording = recordingState;
|
|
6821
8567
|
this._layers = this._mergeLayers(state.layers, state.customLayers);
|
|
6822
8568
|
}
|
|
@@ -6871,10 +8617,46 @@ var TimelineView = class TimelineView extends i$2 {
|
|
|
6871
8617
|
console.warn("[lit-devtools] toggle-layer failed", err);
|
|
6872
8618
|
});
|
|
6873
8619
|
}
|
|
8620
|
+
_onModeChange(e) {
|
|
8621
|
+
e.stopPropagation();
|
|
8622
|
+
this._mode = e.detail.value === "tracks" ? "tracks" : "list";
|
|
8623
|
+
store(MODE_LS_KEY, this._mode);
|
|
8624
|
+
if (this._mode === "list") this.updateComplete.then(() => this._listRef.value?.reveal());
|
|
8625
|
+
}
|
|
8626
|
+
_onTrackToggle(e) {
|
|
8627
|
+
e.stopPropagation();
|
|
8628
|
+
const hidden = new Set(this._hiddenTracks);
|
|
8629
|
+
if (!hidden.delete(e.detail.id)) hidden.add(e.detail.id);
|
|
8630
|
+
this._hiddenTracks = hidden;
|
|
8631
|
+
store(HIDDEN_TRACKS_LS_KEY, JSON.stringify([...hidden]));
|
|
8632
|
+
}
|
|
8633
|
+
_onElementSelect(e) {
|
|
8634
|
+
const v = e.target.value;
|
|
8635
|
+
this._elementFilter = v === "" ? null : Number(v);
|
|
8636
|
+
}
|
|
8637
|
+
_onRegexInput(e) {
|
|
8638
|
+
this._regex = e.target.value;
|
|
8639
|
+
}
|
|
8640
|
+
/** The detail pane's **filter** link. */
|
|
8641
|
+
_onElementFilter(e) {
|
|
8642
|
+
this._elementFilter = e.detail.id;
|
|
8643
|
+
}
|
|
8644
|
+
_onSpanSelect(e) {
|
|
8645
|
+
this._pendingEventId = null;
|
|
8646
|
+
this._selectedKey = e.detail.key;
|
|
8647
|
+
}
|
|
6874
8648
|
render() {
|
|
6875
8649
|
if (this._error !== null) return b`<div class="error">${this._error}</div>`;
|
|
8650
|
+
const tracks = this._mode === "tracks";
|
|
8651
|
+
const captured = this._layers.filter((l) => l.enabled);
|
|
6876
8652
|
return b`
|
|
6877
8653
|
<div class="toolbar">
|
|
8654
|
+
<segmented-tabs
|
|
8655
|
+
size="sm"
|
|
8656
|
+
.items=${MODE_TABS}
|
|
8657
|
+
.value=${this._mode}
|
|
8658
|
+
@change=${this._onModeChange}
|
|
8659
|
+
></segmented-tabs>
|
|
6878
8660
|
${this._exportNote === null ? A : b`<span class="export-note">${this._exportNote}</span>`}
|
|
6879
8661
|
<span class="spacer"></span>
|
|
6880
8662
|
<button
|
|
@@ -6896,10 +8678,67 @@ var TimelineView = class TimelineView extends i$2 {
|
|
|
6896
8678
|
.layers=${this._layers}
|
|
6897
8679
|
@layer-toggle=${this._onLayerToggle}
|
|
6898
8680
|
></timeline-layers>
|
|
8681
|
+
${tracks ? b`<timeline-layers
|
|
8682
|
+
caption="Tracks"
|
|
8683
|
+
.layers=${captured.map((l) => ({
|
|
8684
|
+
...l,
|
|
8685
|
+
enabled: !this._hiddenTracks.has(l.id)
|
|
8686
|
+
}))}
|
|
8687
|
+
@layer-toggle=${this._onTrackToggle}
|
|
8688
|
+
></timeline-layers>` : A}
|
|
8689
|
+
${this._events.length > 0 ? b`<div class="filterbar">
|
|
8690
|
+
${this._elements.length > 0 ? b`
|
|
8691
|
+
<span>Element:</span>
|
|
8692
|
+
<select @change=${this._onElementSelect}>
|
|
8693
|
+
<option
|
|
8694
|
+
value=""
|
|
8695
|
+
?selected=${this._elementFilter === null}
|
|
8696
|
+
>
|
|
8697
|
+
All elements
|
|
8698
|
+
</option>
|
|
8699
|
+
${this._elements.map((el) => b`
|
|
8700
|
+
<option
|
|
8701
|
+
value=${el.id}
|
|
8702
|
+
?selected=${this._elementFilter === el.id}
|
|
8703
|
+
>
|
|
8704
|
+
<${el.tag}> #${el.id}
|
|
8705
|
+
</option>
|
|
8706
|
+
`)}
|
|
8707
|
+
</select>
|
|
8708
|
+
` : A}
|
|
8709
|
+
<input
|
|
8710
|
+
class="regex ${compileRegex(this._regex).invalid ? "invalid" : ""}"
|
|
8711
|
+
type="text"
|
|
8712
|
+
spellcheck="false"
|
|
8713
|
+
placeholder="filter regex…"
|
|
8714
|
+
title="Case-insensitive regex matched against element tag, title and subtitle"
|
|
8715
|
+
.value=${this._regex}
|
|
8716
|
+
@input=${this._onRegexInput}
|
|
8717
|
+
/>
|
|
8718
|
+
</div>` : A}
|
|
6899
8719
|
<timeline-event-list
|
|
8720
|
+
${n(this._listRef)}
|
|
8721
|
+
?hidden=${tracks}
|
|
6900
8722
|
.events=${this._events}
|
|
8723
|
+
.spans=${this._spans}
|
|
6901
8724
|
.layers=${this._layers}
|
|
8725
|
+
.selectedKey=${this._selectedKey}
|
|
8726
|
+
.elementFilter=${this._elementFilter}
|
|
8727
|
+
.regex=${this._regex}
|
|
8728
|
+
@span-select=${this._onSpanSelect}
|
|
8729
|
+
@element-filter=${this._onElementFilter}
|
|
6902
8730
|
></timeline-event-list>
|
|
8731
|
+
<timeline-tracks
|
|
8732
|
+
?hidden=${!tracks}
|
|
8733
|
+
.spans=${this._filteredSpans}
|
|
8734
|
+
.layers=${this._layers}
|
|
8735
|
+
.visibleTracks=${this._visibleTracks}
|
|
8736
|
+
.selectedKey=${this._selectedKey}
|
|
8737
|
+
.selectedSpan=${this._selectedKey === null ? void 0 : this._spans.find((s) => s.key === this._selectedKey)}
|
|
8738
|
+
?recording=${this._recording}
|
|
8739
|
+
@span-select=${this._onSpanSelect}
|
|
8740
|
+
@element-filter=${this._onElementFilter}
|
|
8741
|
+
></timeline-tracks>
|
|
6903
8742
|
`;
|
|
6904
8743
|
}
|
|
6905
8744
|
};
|
|
@@ -6909,6 +8748,11 @@ __decorate([r$2()], TimelineView.prototype, "_exportNote", void 0);
|
|
|
6909
8748
|
__decorate([r$2()], TimelineView.prototype, "_events", void 0);
|
|
6910
8749
|
__decorate([r$2()], TimelineView.prototype, "_layers", void 0);
|
|
6911
8750
|
__decorate([r$2()], TimelineView.prototype, "_error", void 0);
|
|
8751
|
+
__decorate([r$2()], TimelineView.prototype, "_mode", void 0);
|
|
8752
|
+
__decorate([r$2()], TimelineView.prototype, "_hiddenTracks", void 0);
|
|
8753
|
+
__decorate([r$2()], TimelineView.prototype, "_selectedKey", void 0);
|
|
8754
|
+
__decorate([r$2()], TimelineView.prototype, "_elementFilter", void 0);
|
|
8755
|
+
__decorate([r$2()], TimelineView.prototype, "_regex", void 0);
|
|
6912
8756
|
TimelineView = __decorate([t$2("timeline-view")], TimelineView);
|
|
6913
8757
|
//#endregion
|
|
6914
8758
|
//#region src/types/hmr-incompatibility.ts
|
|
@@ -7723,6 +9567,29 @@ var writeLocal = (override) => {
|
|
|
7723
9567
|
else localStorage.setItem(SETTINGS_OVERRIDE_LS_KEY, JSON.stringify(override));
|
|
7724
9568
|
} catch {}
|
|
7725
9569
|
};
|
|
9570
|
+
/**
|
|
9571
|
+
* The config values the current overrides were made against; `{}` when unset
|
|
9572
|
+
* or unparsable. Deliberately separate from the override itself, so the
|
|
9573
|
+
* runtime's apply and the live push never carry it.
|
|
9574
|
+
*/
|
|
9575
|
+
var readBaselines = () => {
|
|
9576
|
+
try {
|
|
9577
|
+
const raw = localStorage.getItem(OVERRIDE_BASELINES_LS_KEY);
|
|
9578
|
+
if (raw !== null) return JSON.parse(raw);
|
|
9579
|
+
} catch {}
|
|
9580
|
+
return {};
|
|
9581
|
+
};
|
|
9582
|
+
var writeLocalBaselines = (baselines) => {
|
|
9583
|
+
try {
|
|
9584
|
+
if (baselines === null || Object.keys(baselines).length === 0) localStorage.removeItem(OVERRIDE_BASELINES_LS_KEY);
|
|
9585
|
+
else localStorage.setItem(OVERRIDE_BASELINES_LS_KEY, JSON.stringify(baselines));
|
|
9586
|
+
} catch {}
|
|
9587
|
+
};
|
|
9588
|
+
/** Write the durable baselines (or delete them when empty), best-effort. */
|
|
9589
|
+
var persistBaselines = (baselines) => {
|
|
9590
|
+
const empty = baselines === void 0 || Object.keys(baselines).length === 0;
|
|
9591
|
+
litRpc().then((rpc) => empty ? rpc.settings.global.delete("overrideBaselines") : rpc.settings.global.set("overrideBaselines", baselines)).catch(() => {});
|
|
9592
|
+
};
|
|
7726
9593
|
/** Send an override to the app runtime over RPC, best-effort. */
|
|
7727
9594
|
var pushLive = (override) => {
|
|
7728
9595
|
litRpc().then((rpc) => rpc.rpc.call("set-settings-override", override)).catch(() => {});
|
|
@@ -7742,10 +9609,18 @@ var onOverrideChange = (cb) => {
|
|
|
7742
9609
|
listeners.delete(cb);
|
|
7743
9610
|
};
|
|
7744
9611
|
};
|
|
7745
|
-
/**
|
|
7746
|
-
|
|
9612
|
+
/**
|
|
9613
|
+
* A change made in this panel: all three copies, then listeners. `baselines`,
|
|
9614
|
+
* when given, replaces the recorded baselines (local and durable; never sent
|
|
9615
|
+
* to the page).
|
|
9616
|
+
*/
|
|
9617
|
+
var commitOverride = (next, baselines) => {
|
|
7747
9618
|
writeLocal(next);
|
|
7748
9619
|
persist(next);
|
|
9620
|
+
if (baselines !== void 0) {
|
|
9621
|
+
writeLocalBaselines(baselines);
|
|
9622
|
+
persistBaselines(baselines);
|
|
9623
|
+
}
|
|
7749
9624
|
pushLive(next);
|
|
7750
9625
|
notify(next);
|
|
7751
9626
|
};
|
|
@@ -7760,8 +9635,9 @@ var patchOverride = (patch) => {
|
|
|
7760
9635
|
* A value that arrived *from* the durable store: mirror it locally and to the
|
|
7761
9636
|
* page, but don't write it back — that would be a pointless round trip.
|
|
7762
9637
|
*/
|
|
7763
|
-
var adoptOverride = (next) => {
|
|
9638
|
+
var adoptOverride = (next, baselines) => {
|
|
7764
9639
|
writeLocal(next);
|
|
9640
|
+
if (baselines !== void 0) writeLocalBaselines(baselines);
|
|
7765
9641
|
pushLive(next);
|
|
7766
9642
|
notify(next);
|
|
7767
9643
|
};
|
|
@@ -7773,9 +9649,46 @@ var adoptOverride = (next) => {
|
|
|
7773
9649
|
var resetOverride = (envValues) => {
|
|
7774
9650
|
writeLocal(null);
|
|
7775
9651
|
persist(void 0);
|
|
9652
|
+
writeLocalBaselines(null);
|
|
9653
|
+
persistBaselines(void 0);
|
|
7776
9654
|
if (envValues !== void 0) pushLive(envValues);
|
|
7777
9655
|
notify({});
|
|
7778
9656
|
};
|
|
9657
|
+
/**
|
|
9658
|
+
* Drop one key from the override, leaving the rest in place. `baseline` is
|
|
9659
|
+
* that key's resolved config value; it goes to the live runtime alongside the
|
|
9660
|
+
* remaining override (a missing field would leave the current live value in
|
|
9661
|
+
* place) but isn't stored, so the key reads as un-overridden again.
|
|
9662
|
+
*/
|
|
9663
|
+
var dropOverrideKey = (key, baseline) => {
|
|
9664
|
+
const next = { ...readOverride() };
|
|
9665
|
+
delete next[key];
|
|
9666
|
+
const empty = Object.keys(next).length === 0;
|
|
9667
|
+
writeLocal(empty ? null : next);
|
|
9668
|
+
persist(empty ? void 0 : next);
|
|
9669
|
+
const baselines = readBaselines();
|
|
9670
|
+
delete baselines[key];
|
|
9671
|
+
writeLocalBaselines(baselines);
|
|
9672
|
+
persistBaselines(baselines);
|
|
9673
|
+
pushLive({
|
|
9674
|
+
...next,
|
|
9675
|
+
[key]: baseline
|
|
9676
|
+
});
|
|
9677
|
+
notify(next);
|
|
9678
|
+
};
|
|
9679
|
+
/**
|
|
9680
|
+
* Re-stamp one key's baseline to the config value it has now ("Keep"), so the
|
|
9681
|
+
* changed-config hint goes away while the override stays.
|
|
9682
|
+
*/
|
|
9683
|
+
var keepBaseline = (key, current) => {
|
|
9684
|
+
const next = {
|
|
9685
|
+
...readBaselines(),
|
|
9686
|
+
[key]: current
|
|
9687
|
+
};
|
|
9688
|
+
writeLocalBaselines(next);
|
|
9689
|
+
persistBaselines(next);
|
|
9690
|
+
notify(readOverride());
|
|
9691
|
+
};
|
|
7779
9692
|
//#endregion
|
|
7780
9693
|
//#region src/panel/components-view.ts
|
|
7781
9694
|
/**
|
|
@@ -8833,6 +10746,8 @@ var DEEP_LINK_TABS = [
|
|
|
8833
10746
|
"settings"
|
|
8834
10747
|
];
|
|
8835
10748
|
var isTab = (value) => typeof value === "string" && DEEP_LINK_TABS.includes(value);
|
|
10749
|
+
/** True when a link asks for anything at all. */
|
|
10750
|
+
var hasLink = (link) => link.tab !== void 0 || link.componentId !== void 0 || link.eventId !== void 0;
|
|
8836
10751
|
/** Parse a `DeepLink` out of hash params, ignoring anything unrecognised. */
|
|
8837
10752
|
var fromParams = (params) => {
|
|
8838
10753
|
const link = {};
|
|
@@ -8840,6 +10755,8 @@ var fromParams = (params) => {
|
|
|
8840
10755
|
if (isTab(tab)) link.tab = tab;
|
|
8841
10756
|
const id = Number(params.get("component"));
|
|
8842
10757
|
if (params.get("component") !== null && Number.isInteger(id)) link.componentId = id;
|
|
10758
|
+
const eventId = params.get("event");
|
|
10759
|
+
if (eventId !== null && eventId !== "") link.eventId = eventId;
|
|
8843
10760
|
return link;
|
|
8844
10761
|
};
|
|
8845
10762
|
/** Read the link encoded in the current URL hash, if any. */
|
|
@@ -8859,6 +10776,8 @@ var writeHashLink = (link) => {
|
|
|
8859
10776
|
else params.set("tab", link.tab);
|
|
8860
10777
|
if (link.componentId === void 0) params.delete("component");
|
|
8861
10778
|
else params.set("component", String(link.componentId));
|
|
10779
|
+
if (link.eventId === void 0) params.delete("event");
|
|
10780
|
+
else params.set("event", link.eventId);
|
|
8862
10781
|
const next = params.toString();
|
|
8863
10782
|
if (next === location.hash.replace(/^#/, "")) return;
|
|
8864
10783
|
history.replaceState(history.state, "", next === "" ? location.pathname : `#${next}`);
|
|
@@ -8873,7 +10792,7 @@ var writeHashLink = (link) => {
|
|
|
8873
10792
|
*/
|
|
8874
10793
|
var onDeepLink = (apply) => {
|
|
8875
10794
|
const hashLink = readHashLink();
|
|
8876
|
-
if (hashLink
|
|
10795
|
+
if (hasLink(hashLink)) apply(hashLink);
|
|
8877
10796
|
window.addEventListener("hashchange", () => apply(readHashLink()));
|
|
8878
10797
|
(async () => {
|
|
8879
10798
|
try {
|
|
@@ -8888,7 +10807,9 @@ var onDeepLink = (apply) => {
|
|
|
8888
10807
|
if (isTab(tab)) link.tab = tab;
|
|
8889
10808
|
const id = params["componentId"];
|
|
8890
10809
|
if (typeof id === "number" && Number.isInteger(id)) link.componentId = id;
|
|
8891
|
-
|
|
10810
|
+
const eventId = params["eventId"];
|
|
10811
|
+
if (typeof eventId === "string" && eventId !== "") link.eventId = eventId;
|
|
10812
|
+
if (hasLink(link)) apply(link);
|
|
8892
10813
|
};
|
|
8893
10814
|
handle(state.value());
|
|
8894
10815
|
state.on("updated", handle);
|
|
@@ -8896,6 +10817,27 @@ var onDeepLink = (apply) => {
|
|
|
8896
10817
|
})();
|
|
8897
10818
|
};
|
|
8898
10819
|
//#endregion
|
|
10820
|
+
//#region src/lib/override-baselines.ts
|
|
10821
|
+
/**
|
|
10822
|
+
* @license
|
|
10823
|
+
* Copyright 2026 Google LLC
|
|
10824
|
+
* SPDX-License-Identifier: BSD-3-Clause
|
|
10825
|
+
*/
|
|
10826
|
+
/**
|
|
10827
|
+
* Whether the config value an override was made against has since changed.
|
|
10828
|
+
*
|
|
10829
|
+
* `recorded` is `undefined` for a legacy override that predates baseline
|
|
10830
|
+
* tracking, which never counts as a change (no false positives). Values are
|
|
10831
|
+
* compared structurally. The source-overlay editor reports `'custom'` for an
|
|
10832
|
+
* `EditorConfig` object, which can't be compared meaningfully, so any side
|
|
10833
|
+
* being `'custom'` skips the check.
|
|
10834
|
+
*/
|
|
10835
|
+
var baselineChanged = (key, recorded, current) => {
|
|
10836
|
+
if (recorded === void 0 || current === void 0) return false;
|
|
10837
|
+
if (key === "sourceOverlayEditor" && (recorded === "custom" || current === "custom")) return false;
|
|
10838
|
+
return JSON.stringify(recorded) !== JSON.stringify(current);
|
|
10839
|
+
};
|
|
10840
|
+
//#endregion
|
|
8899
10841
|
//#region src/panel/devtools-settings.ts
|
|
8900
10842
|
/**
|
|
8901
10843
|
* @license
|
|
@@ -8907,6 +10849,7 @@ var DevtoolsSettings = class DevtoolsSettings extends i$2 {
|
|
|
8907
10849
|
super(..._args);
|
|
8908
10850
|
this._settings = null;
|
|
8909
10851
|
this._override = {};
|
|
10852
|
+
this._recorded = {};
|
|
8910
10853
|
this._loaded = false;
|
|
8911
10854
|
this._colorScheme = "auto";
|
|
8912
10855
|
this._unsubscribeOverride = null;
|
|
@@ -9006,6 +10949,52 @@ var DevtoolsSettings = class DevtoolsSettings extends i$2 {
|
|
|
9006
10949
|
margin-left: var(--lit-devtools-space-3);
|
|
9007
10950
|
vertical-align: middle;
|
|
9008
10951
|
}
|
|
10952
|
+
.src {
|
|
10953
|
+
margin-left: var(--lit-devtools-space-3);
|
|
10954
|
+
vertical-align: middle;
|
|
10955
|
+
}
|
|
10956
|
+
.row-reset {
|
|
10957
|
+
appearance: none;
|
|
10958
|
+
border: 1px solid var(--lit-devtools-border-strong);
|
|
10959
|
+
background: var(--lit-devtools-surface-elevated);
|
|
10960
|
+
color: var(--lit-devtools-text-muted);
|
|
10961
|
+
border-radius: var(--lit-devtools-radius-sm);
|
|
10962
|
+
font: inherit;
|
|
10963
|
+
font-size: var(--lit-devtools-text-2xs);
|
|
10964
|
+
line-height: 1;
|
|
10965
|
+
padding: 1px var(--lit-devtools-space-2);
|
|
10966
|
+
margin-left: var(--lit-devtools-space-3);
|
|
10967
|
+
vertical-align: middle;
|
|
10968
|
+
cursor: pointer;
|
|
10969
|
+
}
|
|
10970
|
+
.row-reset:hover {
|
|
10971
|
+
background: var(--lit-devtools-surface-hover);
|
|
10972
|
+
color: var(--lit-devtools-text);
|
|
10973
|
+
}
|
|
10974
|
+
.nudge {
|
|
10975
|
+
display: flex;
|
|
10976
|
+
align-items: center;
|
|
10977
|
+
flex-wrap: wrap;
|
|
10978
|
+
gap: var(--lit-devtools-space-3);
|
|
10979
|
+
margin-top: var(--lit-devtools-space-2);
|
|
10980
|
+
color: var(--lit-devtools-warning);
|
|
10981
|
+
font-family: inherit;
|
|
10982
|
+
font-size: var(--lit-devtools-text-2xs);
|
|
10983
|
+
}
|
|
10984
|
+
.nudge button {
|
|
10985
|
+
appearance: none;
|
|
10986
|
+
border: 1px solid var(--lit-devtools-border-strong);
|
|
10987
|
+
background: var(--lit-devtools-surface-elevated);
|
|
10988
|
+
color: var(--lit-devtools-text);
|
|
10989
|
+
border-radius: var(--lit-devtools-radius-sm);
|
|
10990
|
+
font: inherit;
|
|
10991
|
+
line-height: 1;
|
|
10992
|
+
padding: 1px var(--lit-devtools-space-3);
|
|
10993
|
+
cursor: pointer;
|
|
10994
|
+
}
|
|
10995
|
+
.nudge button:hover {
|
|
10996
|
+
background: var(--lit-devtools-surface-hover);
|
|
10997
|
+
}
|
|
9009
10998
|
label.toggle {
|
|
9010
10999
|
display: inline-flex;
|
|
9011
11000
|
align-items: center;
|
|
@@ -9046,8 +11035,10 @@ var DevtoolsSettings = class DevtoolsSettings extends i$2 {
|
|
|
9046
11035
|
connectedCallback() {
|
|
9047
11036
|
super.connectedCallback();
|
|
9048
11037
|
this._override = readOverride();
|
|
11038
|
+
this._recorded = readBaselines();
|
|
9049
11039
|
this._unsubscribeOverride = onOverrideChange((o) => {
|
|
9050
11040
|
this._override = o;
|
|
11041
|
+
this._recorded = readBaselines();
|
|
9051
11042
|
});
|
|
9052
11043
|
this._colorScheme = readColorSchemePreference();
|
|
9053
11044
|
this._fetch();
|
|
@@ -9087,16 +11078,16 @@ var DevtoolsSettings = class DevtoolsSettings extends i$2 {
|
|
|
9087
11078
|
}
|
|
9088
11079
|
/**
|
|
9089
11080
|
* Apply a settings snapshot. Both branches no-op when the value already
|
|
9090
|
-
* matches, which is what stops `_adopt` -> `
|
|
11081
|
+
* matches, which is what stops `_adopt` -> `commitOverride` -> store write ->
|
|
9091
11082
|
* `onChange` -> `_adopt` from looping.
|
|
9092
11083
|
*/
|
|
9093
11084
|
_adopt(all) {
|
|
9094
|
-
const { appearance, override } = all;
|
|
11085
|
+
const { appearance, override, overrideBaselines } = all;
|
|
9095
11086
|
if (appearance !== void 0 && appearance !== this._colorScheme) {
|
|
9096
11087
|
this._colorScheme = appearance;
|
|
9097
11088
|
setColorSchemePreference(appearance);
|
|
9098
11089
|
}
|
|
9099
|
-
if (override !== void 0 && JSON.stringify(override) !== JSON.stringify(this._override)) adoptOverride(override);
|
|
11090
|
+
if (override !== void 0 && (JSON.stringify(override) !== JSON.stringify(this._override) || JSON.stringify(overrideBaselines ?? {}) !== JSON.stringify(readBaselines()))) adoptOverride(override, overrideBaselines ?? {});
|
|
9100
11091
|
}
|
|
9101
11092
|
/** Write one preference through to the durable store, best-effort. */
|
|
9102
11093
|
_persist(key, value) {
|
|
@@ -9117,43 +11108,91 @@ var DevtoolsSettings = class DevtoolsSettings extends i$2 {
|
|
|
9117
11108
|
this._loaded = true;
|
|
9118
11109
|
}
|
|
9119
11110
|
}
|
|
9120
|
-
/** Persist the merged override and push it to the app runtime. */
|
|
9121
|
-
_push(override) {
|
|
9122
|
-
commitOverride(override);
|
|
9123
|
-
}
|
|
9124
11111
|
_set(key, value) {
|
|
9125
|
-
this.
|
|
11112
|
+
const s = this._settings;
|
|
11113
|
+
const baselines = readBaselines();
|
|
11114
|
+
if (s !== null && key in this._baselines(s)) baselines[key] = this._baselines(s)[key];
|
|
11115
|
+
commitOverride({
|
|
9126
11116
|
...this._override,
|
|
9127
11117
|
[key]: value
|
|
9128
|
-
});
|
|
11118
|
+
}, baselines);
|
|
9129
11119
|
}
|
|
9130
|
-
/**
|
|
9131
|
-
|
|
9132
|
-
|
|
9133
|
-
resetOverride(s === null ? void 0 : {
|
|
11120
|
+
/** The resolved config value of every overridable setting. */
|
|
11121
|
+
_baselines(s) {
|
|
11122
|
+
return {
|
|
9134
11123
|
hmrReconnect: s.hmr.reconnect,
|
|
9135
11124
|
hmrOnIncompatible: s.hmr.onIncompatible,
|
|
9136
11125
|
hmrIndicatorVisible: s.hmr.indicatorEnabled,
|
|
9137
11126
|
hmrIndicatorCount: s.hmr.indicatorCount,
|
|
9138
|
-
sourceOverlayEditor: s.sourceOverlay.editor
|
|
11127
|
+
sourceOverlayEditor: s.sourceOverlay.editor
|
|
11128
|
+
};
|
|
11129
|
+
}
|
|
11130
|
+
/** Clear overrides and revert the runtime to the resolved env values. */
|
|
11131
|
+
_reset() {
|
|
11132
|
+
const s = this._settings;
|
|
11133
|
+
resetOverride(s === null ? void 0 : {
|
|
11134
|
+
...this._baselines(s),
|
|
9139
11135
|
flashUpdates: false,
|
|
9140
11136
|
flashUpdatesRamp: false
|
|
9141
11137
|
});
|
|
9142
11138
|
}
|
|
11139
|
+
/** Drop one overridden setting, reverting it (live) to its baseline. */
|
|
11140
|
+
_resetKey(key) {
|
|
11141
|
+
const s = this._settings;
|
|
11142
|
+
if (s === null) return;
|
|
11143
|
+
dropOverrideKey(key, this._baselines(s)[key]);
|
|
11144
|
+
}
|
|
9143
11145
|
_pill(on) {
|
|
9144
11146
|
return b`<span class="pill ${on ? "on" : ""}"
|
|
9145
11147
|
>${on ? "enabled" : "disabled"}</span
|
|
9146
11148
|
>`;
|
|
9147
11149
|
}
|
|
9148
|
-
|
|
9149
|
-
|
|
11150
|
+
/**
|
|
11151
|
+
* Origin badge behind a value, from the server-side provenance:
|
|
11152
|
+
* "(env)", "(option)" or "(default)". Nothing when the server sent none.
|
|
11153
|
+
*/
|
|
11154
|
+
_source(key) {
|
|
11155
|
+
const src = this._settings?.sources?.[key];
|
|
11156
|
+
return src ? b`<span class="env src">(${src})</span>` : A;
|
|
11157
|
+
}
|
|
11158
|
+
/**
|
|
11159
|
+
* Badge for an overridable row. Without an override it's the plain origin
|
|
11160
|
+
* badge; with one it's "(overridden)", the baseline it replaced
|
|
11161
|
+
* ("env: Zed") and a reset for just this row. `baseline` is the config
|
|
11162
|
+
* value as the row displays it, `fmt` renders a recorded raw value the same
|
|
11163
|
+
* way. When the config value moved since the override was made, a second
|
|
11164
|
+
* line says so and offers Reset or Keep.
|
|
11165
|
+
*/
|
|
11166
|
+
_ovrSource(key, baseline, fmt = String) {
|
|
11167
|
+
if (this._override[key] === void 0) return this._source(key);
|
|
11168
|
+
const src = this._settings?.sources?.[key] ?? "config";
|
|
11169
|
+
const s = this._settings;
|
|
11170
|
+
const current = s === null ? void 0 : this._baselines(s)[key];
|
|
11171
|
+
return b`<span class="ovr">(overridden)</span>
|
|
11172
|
+
<span class="env">${src}: ${baseline}</span>
|
|
11173
|
+
<button
|
|
11174
|
+
class="row-reset"
|
|
11175
|
+
title="Reset to the ${src} value"
|
|
11176
|
+
aria-label="Reset to the ${src} value"
|
|
11177
|
+
@click=${() => this._resetKey(key)}
|
|
11178
|
+
>
|
|
11179
|
+
×
|
|
11180
|
+
</button>
|
|
11181
|
+
${baselineChanged(key, this._recorded[key], current) ? b`<div class="nudge" data-nudge=${key}>
|
|
11182
|
+
<span
|
|
11183
|
+
>Config changed since you overrode this: was
|
|
11184
|
+
${fmt(this._recorded[key])}, now ${baseline}</span
|
|
11185
|
+
>
|
|
11186
|
+
<button @click=${() => this._resetKey(key)}>Reset</button>
|
|
11187
|
+
<button @click=${() => keepBaseline(key, current)}>Keep</button>
|
|
11188
|
+
</div>` : A}`;
|
|
9150
11189
|
}
|
|
9151
|
-
_readonlyRow(key, value, env) {
|
|
11190
|
+
_readonlyRow(key, value, env, source) {
|
|
9152
11191
|
return b`
|
|
9153
11192
|
<tr>
|
|
9154
11193
|
<td class="key">${key}</td>
|
|
9155
11194
|
<td class="val">
|
|
9156
|
-
${String(value)}
|
|
11195
|
+
${String(value)} ${source ? this._source(source) : A}
|
|
9157
11196
|
${env ? b`<span class="env">${env}</span>` : A}
|
|
9158
11197
|
</td>
|
|
9159
11198
|
</tr>
|
|
@@ -9209,7 +11248,7 @@ var DevtoolsSettings = class DevtoolsSettings extends i$2 {
|
|
|
9209
11248
|
/>
|
|
9210
11249
|
${reconnect ? "on" : "off"}
|
|
9211
11250
|
</label>
|
|
9212
|
-
${this.
|
|
11251
|
+
${this._ovrSource("hmrReconnect", s.hmr.reconnect ? "on" : "off", (v) => v ? "on" : "off")}
|
|
9213
11252
|
</td>
|
|
9214
11253
|
</tr>
|
|
9215
11254
|
<tr>
|
|
@@ -9225,7 +11264,7 @@ var DevtoolsSettings = class DevtoolsSettings extends i$2 {
|
|
|
9225
11264
|
warn
|
|
9226
11265
|
</option>
|
|
9227
11266
|
</select>
|
|
9228
|
-
${this.
|
|
11267
|
+
${this._ovrSource("hmrOnIncompatible", s.hmr.onIncompatible)}
|
|
9229
11268
|
</td>
|
|
9230
11269
|
</tr>
|
|
9231
11270
|
<tr class=${s.hmr.indicatorEnabled ? "" : "row-disabled"}>
|
|
@@ -9240,7 +11279,7 @@ var DevtoolsSettings = class DevtoolsSettings extends i$2 {
|
|
|
9240
11279
|
/>
|
|
9241
11280
|
${s.hmr.indicatorEnabled ? indicatorVisible ? "shown" : "hidden" : "off (config)"}
|
|
9242
11281
|
</label>
|
|
9243
|
-
${this.
|
|
11282
|
+
${this._ovrSource("hmrIndicatorVisible", s.hmr.indicatorEnabled ? "shown" : "off (config)", (v) => v ? "shown" : "off (config)")}
|
|
9244
11283
|
</td>
|
|
9245
11284
|
</tr>
|
|
9246
11285
|
<tr class=${s.hmr.indicatorEnabled ? "" : "row-disabled"}>
|
|
@@ -9255,10 +11294,41 @@ var DevtoolsSettings = class DevtoolsSettings extends i$2 {
|
|
|
9255
11294
|
/>
|
|
9256
11295
|
${indicatorCount ? "shown" : "hidden"}
|
|
9257
11296
|
</label>
|
|
9258
|
-
${this.
|
|
11297
|
+
${this._ovrSource("hmrIndicatorCount", s.hmr.indicatorCount ? "shown" : "hidden", (v) => v ? "shown" : "hidden")}
|
|
9259
11298
|
</td>
|
|
9260
11299
|
</tr>
|
|
9261
11300
|
</table>
|
|
11301
|
+
`;
|
|
11302
|
+
}
|
|
11303
|
+
/**
|
|
11304
|
+
* The editor select. A custom `EditorConfig` object (reported as
|
|
11305
|
+
* `'custom'`) isn't one of the built-in choices, so the select is disabled
|
|
11306
|
+
* and just shows "Custom".
|
|
11307
|
+
*/
|
|
11308
|
+
_renderEditorRow(s) {
|
|
11309
|
+
const baseline = s.sourceOverlay.editor;
|
|
11310
|
+
const custom = baseline === "custom";
|
|
11311
|
+
const current = this._override.sourceOverlayEditor ?? baseline;
|
|
11312
|
+
const editorLabel = (value) => SOURCE_OVERLAY_EDITORS.find((ed) => ed.value === value)?.label ?? (value === "custom" ? "Custom" : value);
|
|
11313
|
+
const label = editorLabel(baseline);
|
|
11314
|
+
return b`
|
|
11315
|
+
<tr>
|
|
11316
|
+
<td class="key">editor</td>
|
|
11317
|
+
<td class="val">
|
|
11318
|
+
<select
|
|
11319
|
+
?disabled=${custom}
|
|
11320
|
+
@change=${(e) => this._set("sourceOverlayEditor", e.target.value)}
|
|
11321
|
+
>
|
|
11322
|
+
${custom ? b`<option value="custom" selected>Custom</option>` : SOURCE_OVERLAY_EDITORS.map((ed) => b`<option
|
|
11323
|
+
value=${ed.value}
|
|
11324
|
+
?selected=${ed.value === current}
|
|
11325
|
+
>
|
|
11326
|
+
${ed.label}
|
|
11327
|
+
</option>`)}
|
|
11328
|
+
</select>
|
|
11329
|
+
${this._ovrSource("sourceOverlayEditor", label, (v) => editorLabel(String(v)))}
|
|
11330
|
+
</td>
|
|
11331
|
+
</tr>
|
|
9262
11332
|
`;
|
|
9263
11333
|
}
|
|
9264
11334
|
/**
|
|
@@ -9329,24 +11399,9 @@ var DevtoolsSettings = class DevtoolsSettings extends i$2 {
|
|
|
9329
11399
|
<section>
|
|
9330
11400
|
<h3>Source Overlay ${this._pill(s.sourceOverlay.enabled)}</h3>
|
|
9331
11401
|
${s.sourceOverlay.enabled ? b`<table>
|
|
9332
|
-
${this._readonlyRow("hotkey", `Ctrl+Shift+${s.sourceOverlay.key.toUpperCase()}`, "LIT_PLUGIN_SOURCE_OVERLAY_KEY")}
|
|
9333
|
-
|
|
9334
|
-
|
|
9335
|
-
<td class="val">
|
|
9336
|
-
<select
|
|
9337
|
-
@change=${(e) => this._set("sourceOverlayEditor", e.target.value)}
|
|
9338
|
-
>
|
|
9339
|
-
${SOURCE_OVERLAY_EDITORS.map((ed) => b`<option
|
|
9340
|
-
value=${ed.value}
|
|
9341
|
-
?selected=${ed.value === (this._override.sourceOverlayEditor ?? s.sourceOverlay.editor)}
|
|
9342
|
-
>
|
|
9343
|
-
${ed.label}
|
|
9344
|
-
</option>`)}
|
|
9345
|
-
</select>
|
|
9346
|
-
${this._ovr(this._override.sourceOverlayEditor !== void 0)}
|
|
9347
|
-
</td>
|
|
9348
|
-
</tr>
|
|
9349
|
-
${this._readonlyRow("throttle (ms)", s.sourceOverlay.throttleMs, "LIT_PLUGIN_SOURCE_OVERLAY_THROTTLE_MS")}
|
|
11402
|
+
${this._readonlyRow("hotkey", `Ctrl+Shift+${s.sourceOverlay.key.toUpperCase()}`, "LIT_PLUGIN_SOURCE_OVERLAY_KEY", "sourceOverlayKey")}
|
|
11403
|
+
${this._renderEditorRow(s)}
|
|
11404
|
+
${this._readonlyRow("throttle (ms)", s.sourceOverlay.throttleMs, "LIT_PLUGIN_SOURCE_OVERLAY_THROTTLE_MS", "sourceOverlayThrottleMs")}
|
|
9350
11405
|
</table>` : b`<p class="empty">
|
|
9351
11406
|
Enable with <code>sourceOverlay: true</code> or
|
|
9352
11407
|
<code>LIT_PLUGIN_SOURCE_OVERLAY=true</code>.
|
|
@@ -9373,125 +11428,11 @@ var DevtoolsSettings = class DevtoolsSettings extends i$2 {
|
|
|
9373
11428
|
};
|
|
9374
11429
|
__decorate([r$2()], DevtoolsSettings.prototype, "_settings", void 0);
|
|
9375
11430
|
__decorate([r$2()], DevtoolsSettings.prototype, "_override", void 0);
|
|
11431
|
+
__decorate([r$2()], DevtoolsSettings.prototype, "_recorded", void 0);
|
|
9376
11432
|
__decorate([r$2()], DevtoolsSettings.prototype, "_loaded", void 0);
|
|
9377
11433
|
__decorate([r$2()], DevtoolsSettings.prototype, "_colorScheme", void 0);
|
|
9378
11434
|
DevtoolsSettings = __decorate([t$2("devtools-settings")], DevtoolsSettings);
|
|
9379
11435
|
//#endregion
|
|
9380
|
-
//#region src/lib/segmented-tabs.ts
|
|
9381
|
-
/**
|
|
9382
|
-
* @license
|
|
9383
|
-
* Copyright 2026 Google LLC
|
|
9384
|
-
* SPDX-License-Identifier: BSD-3-Clause
|
|
9385
|
-
*/
|
|
9386
|
-
var SegmentedTabs = class SegmentedTabs extends i$2 {
|
|
9387
|
-
static {
|
|
9388
|
-
this.styles = [tokens, i$5`
|
|
9389
|
-
:host {
|
|
9390
|
-
display: flex;
|
|
9391
|
-
gap: var(--lit-devtools-space-1);
|
|
9392
|
-
align-self: stretch;
|
|
9393
|
-
}
|
|
9394
|
-
button {
|
|
9395
|
-
appearance: none;
|
|
9396
|
-
display: flex;
|
|
9397
|
-
align-items: center;
|
|
9398
|
-
gap: var(--lit-devtools-space-2);
|
|
9399
|
-
border: 0;
|
|
9400
|
-
background: none;
|
|
9401
|
-
font: inherit;
|
|
9402
|
-
color: var(--lit-devtools-text-muted);
|
|
9403
|
-
padding: 0 var(--lit-devtools-space-5);
|
|
9404
|
-
cursor: pointer;
|
|
9405
|
-
border-bottom: 2px solid transparent;
|
|
9406
|
-
white-space: nowrap;
|
|
9407
|
-
transition:
|
|
9408
|
-
color var(--lit-devtools-dur-fast) var(--lit-devtools-ease-standard),
|
|
9409
|
-
border-color var(--lit-devtools-dur-fast)
|
|
9410
|
-
var(--lit-devtools-ease-standard),
|
|
9411
|
-
background var(--lit-devtools-dur-fast)
|
|
9412
|
-
var(--lit-devtools-ease-standard);
|
|
9413
|
-
}
|
|
9414
|
-
button:hover {
|
|
9415
|
-
color: var(--lit-devtools-text);
|
|
9416
|
-
background: var(--lit-devtools-surface-hover);
|
|
9417
|
-
}
|
|
9418
|
-
button.active {
|
|
9419
|
-
color: var(--lit-devtools-accent);
|
|
9420
|
-
border-bottom-color: var(--lit-devtools-accent);
|
|
9421
|
-
}
|
|
9422
|
-
button:focus-visible {
|
|
9423
|
-
outline: 2px solid var(--lit-devtools-accent-ring);
|
|
9424
|
-
outline-offset: -2px;
|
|
9425
|
-
}
|
|
9426
|
-
button svg {
|
|
9427
|
-
width: 18px;
|
|
9428
|
-
height: 18px;
|
|
9429
|
-
flex-shrink: 0;
|
|
9430
|
-
}
|
|
9431
|
-
.badge {
|
|
9432
|
-
flex-shrink: 0;
|
|
9433
|
-
min-width: 16px;
|
|
9434
|
-
padding: 0 var(--lit-devtools-space-1);
|
|
9435
|
-
border-radius: var(--lit-devtools-radius-pill);
|
|
9436
|
-
background: var(--lit-devtools-error-soft);
|
|
9437
|
-
color: var(--lit-devtools-error);
|
|
9438
|
-
font-size: var(--lit-devtools-text-xs);
|
|
9439
|
-
line-height: 16px;
|
|
9440
|
-
text-align: center;
|
|
9441
|
-
}
|
|
9442
|
-
:host([size='sm']) button {
|
|
9443
|
-
font-size: var(--lit-devtools-text-xs);
|
|
9444
|
-
padding: 0 var(--lit-devtools-space-4);
|
|
9445
|
-
}
|
|
9446
|
-
:host([size='md']) button,
|
|
9447
|
-
:host(:not([size])) button {
|
|
9448
|
-
font-size: var(--lit-devtools-text-sm);
|
|
9449
|
-
padding: 0 var(--lit-devtools-space-5);
|
|
9450
|
-
}
|
|
9451
|
-
`];
|
|
9452
|
-
}
|
|
9453
|
-
constructor() {
|
|
9454
|
-
super();
|
|
9455
|
-
this.items = [];
|
|
9456
|
-
this.value = "";
|
|
9457
|
-
this.size = "md";
|
|
9458
|
-
}
|
|
9459
|
-
_select(id) {
|
|
9460
|
-
this.value = id;
|
|
9461
|
-
this.dispatchEvent(new CustomEvent("change", {
|
|
9462
|
-
detail: { value: id },
|
|
9463
|
-
bubbles: true,
|
|
9464
|
-
composed: true
|
|
9465
|
-
}));
|
|
9466
|
-
}
|
|
9467
|
-
render() {
|
|
9468
|
-
return b`
|
|
9469
|
-
${this.items.map((item) => b`
|
|
9470
|
-
<button
|
|
9471
|
-
role="tab"
|
|
9472
|
-
aria-selected=${item.id === this.value}
|
|
9473
|
-
class=${item.id === this.value ? "active" : ""}
|
|
9474
|
-
@click=${() => this._select(item.id)}
|
|
9475
|
-
>
|
|
9476
|
-
${item.icon ? b`<svg
|
|
9477
|
-
viewBox="0 0 256 256"
|
|
9478
|
-
fill="currentColor"
|
|
9479
|
-
aria-hidden="true"
|
|
9480
|
-
>
|
|
9481
|
-
<path d=${item.icon} />
|
|
9482
|
-
</svg>` : A}
|
|
9483
|
-
${item.label}
|
|
9484
|
-
${item.badge ? b`<span class="badge">${item.badge}</span>` : A}
|
|
9485
|
-
</button>
|
|
9486
|
-
`)}
|
|
9487
|
-
`;
|
|
9488
|
-
}
|
|
9489
|
-
};
|
|
9490
|
-
__decorate([n$3({ type: Array })], SegmentedTabs.prototype, "items", void 0);
|
|
9491
|
-
__decorate([n$3()], SegmentedTabs.prototype, "value", void 0);
|
|
9492
|
-
__decorate([n$3()], SegmentedTabs.prototype, "size", void 0);
|
|
9493
|
-
SegmentedTabs = __decorate([t$2("segmented-tabs")], SegmentedTabs);
|
|
9494
|
-
//#endregion
|
|
9495
11436
|
//#region src/lib/icons.ts
|
|
9496
11437
|
/**
|
|
9497
11438
|
* @license
|
|
@@ -9636,6 +11577,15 @@ var LitDevtoolsPanel = class LitDevtoolsPanel extends i$2 {
|
|
|
9636
11577
|
firstUpdated() {
|
|
9637
11578
|
onDeepLink((link) => {
|
|
9638
11579
|
if (link.tab !== void 0) this._tab = link.tab;
|
|
11580
|
+
if (link.componentId === void 0 && link.eventId !== void 0) {
|
|
11581
|
+
this._tab = "timeline";
|
|
11582
|
+
const eventId = link.eventId;
|
|
11583
|
+
this.updateComplete.then(() => {
|
|
11584
|
+
this._timelineView?.selectEvent(eventId);
|
|
11585
|
+
this._syncHash();
|
|
11586
|
+
});
|
|
11587
|
+
return;
|
|
11588
|
+
}
|
|
9639
11589
|
if (link.componentId === void 0) {
|
|
9640
11590
|
this._syncHash();
|
|
9641
11591
|
return;
|
|
@@ -9658,9 +11608,11 @@ var LitDevtoolsPanel = class LitDevtoolsPanel extends i$2 {
|
|
|
9658
11608
|
_syncHash() {
|
|
9659
11609
|
if (window.top !== window.self) return;
|
|
9660
11610
|
const selectedId = this._tab === "updates" ? this._updatesView?.selectedId : this._componentsView?.selectedId;
|
|
11611
|
+
const eventId = this._tab === "timeline" ? this._timelineView?.selectedEventId : null;
|
|
9661
11612
|
writeHashLink({
|
|
9662
11613
|
tab: this._tab,
|
|
9663
|
-
...selectedId === null || selectedId === void 0 ? {} : { componentId: selectedId }
|
|
11614
|
+
...selectedId === null || selectedId === void 0 ? {} : { componentId: selectedId },
|
|
11615
|
+
...eventId === null || eventId === void 0 ? {} : { eventId }
|
|
9664
11616
|
});
|
|
9665
11617
|
}
|
|
9666
11618
|
/**
|
|
@@ -9702,7 +11654,10 @@ var LitDevtoolsPanel = class LitDevtoolsPanel extends i$2 {
|
|
|
9702
11654
|
></segmented-tabs>
|
|
9703
11655
|
</header>
|
|
9704
11656
|
<div class="view" @inspect-element=${this._onInspectElement}>
|
|
9705
|
-
<timeline-view
|
|
11657
|
+
<timeline-view
|
|
11658
|
+
?hidden=${this._tab !== "timeline"}
|
|
11659
|
+
@selection-change=${this._syncHash}
|
|
11660
|
+
></timeline-view>
|
|
9706
11661
|
<!-- Kept mounted (like the timeline) so an overlay inspect-pick can
|
|
9707
11662
|
arrive and switch us here even while another tab is in front. -->
|
|
9708
11663
|
<components-view
|
|
@@ -9726,6 +11681,7 @@ __decorate([r$2()], LitDevtoolsPanel.prototype, "_tab", void 0);
|
|
|
9726
11681
|
__decorate([r$2()], LitDevtoolsPanel.prototype, "_hmrCount", void 0);
|
|
9727
11682
|
__decorate([e$3("components-view")], LitDevtoolsPanel.prototype, "_componentsView", void 0);
|
|
9728
11683
|
__decorate([e$3("updates-view")], LitDevtoolsPanel.prototype, "_updatesView", void 0);
|
|
11684
|
+
__decorate([e$3("timeline-view")], LitDevtoolsPanel.prototype, "_timelineView", void 0);
|
|
9729
11685
|
LitDevtoolsPanel = __decorate([t$2("lit-devtools-panel")], LitDevtoolsPanel);
|
|
9730
11686
|
//#endregion
|
|
9731
11687
|
//#region src/panel/main.ts
|
|
@@ -9737,4 +11693,4 @@ LitDevtoolsPanel = __decorate([t$2("lit-devtools-panel")], LitDevtoolsPanel);
|
|
|
9737
11693
|
//#endregion
|
|
9738
11694
|
export { onBrowserAgentToolsChanged as n, nanoid as r, listBrowserAgentTools as t };
|
|
9739
11695
|
|
|
9740
|
-
//# sourceMappingURL=index-
|
|
11696
|
+
//# sourceMappingURL=index-Gn4Hk_9s.js.map
|