@youtyan/code-viewer 0.1.19 → 0.1.20

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.
@@ -342,24 +342,35 @@ function refs(cwd) {
342
342
  "git",
343
343
  "for-each-ref",
344
344
  "--sort=-committerdate",
345
- "--format=%(refname:short)",
345
+ "--format=%(refname)%09%(refname:short)%09%(committerdate:iso-strict)",
346
346
  "refs/heads",
347
347
  "refs/remotes"
348
348
  ], cwd);
349
349
  if (branches.code === 0) {
350
- out.branches = branches.stdout.split(`
351
- `).filter((line) => line && line !== "origin/HEAD");
350
+ for (const line of branches.stdout.split(`
351
+ `)) {
352
+ const [fullName, name, when] = line.split("\t");
353
+ if (!fullName || !name || fullName.startsWith("refs/remotes/") && fullName.endsWith("/HEAD"))
354
+ continue;
355
+ out.branches.push({ name, when });
356
+ }
352
357
  }
353
358
  const tags = run([
354
359
  "git",
355
360
  "for-each-ref",
356
361
  "--sort=-creatordate",
357
- "--format=%(refname:short)",
362
+ "--format=%(refname:short)%09%(creatordate:iso-strict)",
358
363
  "refs/tags"
359
364
  ], cwd);
360
- if (tags.code === 0)
361
- out.tags = tags.stdout.split(`
362
- `).filter(Boolean);
365
+ if (tags.code === 0) {
366
+ for (const line of tags.stdout.split(`
367
+ `)) {
368
+ const [name, when] = line.split("\t");
369
+ if (!name)
370
+ continue;
371
+ out.tags.push({ name, when });
372
+ }
373
+ }
363
374
  out.commits = refCommits(cwd, "", DEFAULT_REF_COMMIT_LIMIT);
364
375
  out.current = currentBranch(cwd) || "";
365
376
  return out;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@youtyan/code-viewer",
3
- "version": "0.1.19",
3
+ "version": "0.1.20",
4
4
  "description": "Local browser-based code and git diff viewer",
5
5
  "type": "module",
6
6
  "bin": {
@@ -37,7 +37,7 @@
37
37
  "preview": "bun run web-src/server/dev.ts",
38
38
  "preview:raw": "bun run web-src/server/preview.ts",
39
39
  "test": "bun test",
40
- "lint": "biome lint web-src/server package.json biome.jsonc",
40
+ "lint": "biome lint web-src package.json biome.jsonc",
41
41
  "verify": "bun run check && bun run lint && bun run check:format && bun run build && bun run check:bundle && bun run test && node --check web/app.js && node --check web/mermaid.js && node --check web/shiki.js && node --check dist/code-viewer.js && node dist/code-viewer.js --help && node scripts/node-smoke.mjs",
42
42
  "pack:dry": "npm pack --dry-run",
43
43
  "prepack": "bun run build",
package/web/app.js CHANGED
@@ -274,7 +274,7 @@
274
274
  const basename = lowerPath.slice(baseStart);
275
275
  if (basename.startsWith(q))
276
276
  score += 30;
277
- if (basename === q || basename.startsWith(q + "."))
277
+ if (basename === q || basename.startsWith(`${q}.`))
278
278
  score += 25;
279
279
  if (lowerPath.endsWith(q))
280
280
  score += 15;
@@ -290,7 +290,7 @@
290
290
  return /[*?]/.test(query.trim());
291
291
  }
292
292
  function escapeRegexChar(ch) {
293
- return /[\\^$+?.()|{}]/.test(ch) ? "\\" + ch : ch;
293
+ return /[\\^$+?.()|{}]/.test(ch) ? `\\${ch}` : ch;
294
294
  }
295
295
  function globToRegExp(query) {
296
296
  const pattern = query.trim();
@@ -314,7 +314,7 @@
314
314
  source += "\\[";
315
315
  } else {
316
316
  const body = pattern.slice(i + 1, close).replace(/\\/g, "\\\\");
317
- source += "[" + body + "]";
317
+ source += `[${body}]`;
318
318
  i = close;
319
319
  }
320
320
  } else {
@@ -6092,7 +6092,7 @@
6092
6092
 
6093
6093
  // web-src/routes.ts
6094
6094
  function assertNever(value) {
6095
- throw new Error("unhandled route: " + JSON.stringify(value));
6095
+ throw new Error(`unhandled route: ${JSON.stringify(value)}`);
6096
6096
  }
6097
6097
  function parseLegacyRange(value, fallback) {
6098
6098
  const raw = value || "";
@@ -6120,7 +6120,7 @@
6120
6120
  return Number.isInteger(line) && line > 0 ? line : undefined;
6121
6121
  }
6122
6122
  function formatLineTarget(line) {
6123
- return typeof line === "number" ? String(line) : line.start + "-" + line.end;
6123
+ return typeof line === "number" ? String(line) : `${line.start}-${line.end}`;
6124
6124
  }
6125
6125
  function parseRoute(pathname, search, fallbackRange) {
6126
6126
  const params = new URLSearchParams(search);
@@ -6194,15 +6194,15 @@
6194
6194
  if (route.path)
6195
6195
  params.set("path", route.path);
6196
6196
  const qs = params.toString();
6197
- return "/" + (qs ? "?" + qs : "");
6197
+ return `/${qs ? `?${qs}` : ""}`;
6198
6198
  }
6199
6199
  case "file":
6200
6200
  if (route.view === "blob") {
6201
- return "/file?path=" + encodeURIComponent(route.path) + "&target=" + encodeURIComponent(route.ref || "worktree") + (route.line ? "&line=" + encodeURIComponent(formatLineTarget(route.line)) : "");
6201
+ return "/file?path=" + encodeURIComponent(route.path) + "&target=" + encodeURIComponent(route.ref || "worktree") + (route.line ? `&line=${encodeURIComponent(formatLineTarget(route.line))}` : "");
6202
6202
  }
6203
- return "/file?path=" + encodeURIComponent(route.path) + "&ref=" + encodeURIComponent(route.ref || "worktree") + "&from=" + encodeURIComponent(route.range.from || "") + "&to=" + encodeURIComponent(route.range.to || "worktree") + (route.line ? "&line=" + encodeURIComponent(formatLineTarget(route.line)) : "");
6203
+ return "/file?path=" + encodeURIComponent(route.path) + "&ref=" + encodeURIComponent(route.ref || "worktree") + "&from=" + encodeURIComponent(route.range.from || "") + "&to=" + encodeURIComponent(route.range.to || "worktree") + (route.line ? `&line=${encodeURIComponent(formatLineTarget(route.line))}` : "");
6204
6204
  case "diff":
6205
- return "/todif?from=" + encodeURIComponent(route.range.from || "") + "&to=" + encodeURIComponent(route.range.to || "worktree") + (route.path ? "&path=" + encodeURIComponent(route.path) : "") + (route.line ? "&line=" + encodeURIComponent(formatLineTarget(route.line)) : "");
6205
+ return "/todif?from=" + encodeURIComponent(route.range.from || "") + "&to=" + encodeURIComponent(route.range.to || "worktree") + (route.path ? `&path=${encodeURIComponent(route.path)}` : "") + (route.line ? `&line=${encodeURIComponent(formatLineTarget(route.line))}` : "");
6206
6206
  case "help": {
6207
6207
  const params = new URLSearchParams;
6208
6208
  if (route.lang && route.lang !== "en")
@@ -6210,7 +6210,7 @@
6210
6210
  if (route.section && route.section !== "keybindings")
6211
6211
  params.set("section", route.section);
6212
6212
  const qs = params.toString();
6213
- return "/help" + (qs ? "?" + qs : "");
6213
+ return `/help${qs ? `?${qs}` : ""}`;
6214
6214
  }
6215
6215
  case "unknown":
6216
6216
  return "/todif?from=" + encodeURIComponent(route.range.from || "") + "&to=" + encodeURIComponent(route.range.to || "worktree");
@@ -6331,7 +6331,7 @@
6331
6331
  });
6332
6332
  } catch {}
6333
6333
  }
6334
- return "<pre><code>" + md.utils.escapeHtml(code2) + "</code></pre>";
6334
+ return `<pre><code>${md.utils.escapeHtml(code2)}</code></pre>`;
6335
6335
  }
6336
6336
  });
6337
6337
  md.use(b, {
@@ -6431,7 +6431,10 @@
6431
6431
  const frontmatter = splitYamlFrontmatter(textValue);
6432
6432
  if (!frontmatter)
6433
6433
  return md.render(textValue);
6434
- return '<div class="gdp-markdown-frontmatter" data-gdp-frontmatter="yaml">' + md.render("```yaml\n" + frontmatter.yaml + "\n```\n") + "</div>" + md.render(frontmatter.body);
6434
+ return '<div class="gdp-markdown-frontmatter" data-gdp-frontmatter="yaml">' + md.render(`\`\`\`yaml
6435
+ ${frontmatter.yaml}
6436
+ \`\`\`
6437
+ `) + "</div>" + md.render(frontmatter.body);
6435
6438
  }
6436
6439
  function splitYamlFrontmatter(textValue) {
6437
6440
  if (!textValue.startsWith(`---
@@ -6443,7 +6446,7 @@
6443
6446
  ` : `
6444
6447
  `;
6445
6448
  const start = 3 + newline2.length;
6446
- const closing = textValue.indexOf(newline2 + "---" + newline2, start);
6449
+ const closing = textValue.indexOf(`${newline2}---${newline2}`, start);
6447
6450
  if (closing < 0)
6448
6451
  return null;
6449
6452
  return {
@@ -6492,9 +6495,9 @@
6492
6495
  const list2 = document.createElement("ul");
6493
6496
  entries.forEach((entry) => {
6494
6497
  const item = document.createElement("li");
6495
- item.className = "level-" + entry.level;
6498
+ item.className = `level-${entry.level}`;
6496
6499
  const link2 = document.createElement("a");
6497
- link2.href = "#" + encodeURIComponent(entry.id);
6500
+ link2.href = `#${encodeURIComponent(entry.id)}`;
6498
6501
  link2.dataset.target = entry.id;
6499
6502
  link2.textContent = entry.text;
6500
6503
  item.appendChild(link2);
@@ -6525,7 +6528,7 @@
6525
6528
  return;
6526
6529
  const entries = Array.from(toc.querySelectorAll("a[data-target]")).map((link2) => ({
6527
6530
  link: link2,
6528
- target: root.querySelector("#" + CSS.escape(link2.dataset.target || ""))
6531
+ target: root.querySelector(`#${CSS.escape(link2.dataset.target || "")}`)
6529
6532
  })).filter((entry) => !!entry.target);
6530
6533
  if (!entries.length)
6531
6534
  return;
@@ -6533,12 +6536,12 @@
6533
6536
  const link2 = e2.target?.closest("a[data-target]");
6534
6537
  if (!link2)
6535
6538
  return;
6536
- const section = root.querySelector("#" + CSS.escape(link2.dataset.target || ""));
6539
+ const section = root.querySelector(`#${CSS.escape(link2.dataset.target || "")}`);
6537
6540
  if (!section)
6538
6541
  return;
6539
6542
  e2.preventDefault();
6540
6543
  section.scrollIntoView({ block: "start", behavior: "smooth" });
6541
- history.replaceState(history.state, "", "#" + encodeURIComponent(section.id));
6544
+ history.replaceState(history.state, "", `#${encodeURIComponent(section.id)}`);
6542
6545
  });
6543
6546
  const controller = new AbortController;
6544
6547
  const scrollRoot = document.scrollingElement || document.documentElement;
@@ -6564,7 +6567,9 @@
6564
6567
  if (window.innerHeight + scrollRoot.scrollTop >= scrollRoot.scrollHeight - 4) {
6565
6568
  active = entries[entries.length - 1];
6566
6569
  }
6567
- entries.forEach((entry) => entry.link.classList.toggle("active", entry === active));
6570
+ entries.forEach((entry) => {
6571
+ entry.link.classList.toggle("active", entry === active);
6572
+ });
6568
6573
  keepTocLinkVisible(toc, active.link);
6569
6574
  };
6570
6575
  const schedule = () => {
@@ -6698,7 +6703,7 @@
6698
6703
  let tx = 0;
6699
6704
  let ty = 0;
6700
6705
  const apply = () => {
6701
- svg.style.transform = "translate(" + tx + "px, " + ty + "px) scale(" + scale + ")";
6706
+ svg.style.transform = `translate(${tx}px, ${ty}px) scale(${scale})`;
6702
6707
  };
6703
6708
  const fit = () => {
6704
6709
  const vw = Math.max(1, window.innerWidth - 128);
@@ -6798,7 +6803,7 @@
6798
6803
  try {
6799
6804
  const box = svg.getBBox();
6800
6805
  if (box.width > 0 && box.height > 0) {
6801
- svg.setAttribute("viewBox", box.x + " " + box.y + " " + box.width + " " + box.height);
6806
+ svg.setAttribute("viewBox", `${box.x} ${box.y} ${box.width} ${box.height}`);
6802
6807
  svg.setAttribute("width", String(box.width));
6803
6808
  svg.setAttribute("height", String(box.height));
6804
6809
  return { width: box.width, height: box.height };
@@ -7040,7 +7045,7 @@
7040
7045
  return Array.from(document.querySelectorAll("#content .gdp-source-virtual-scroller, #content .gdp-source-table")).some((item) => item.offsetParent !== null);
7041
7046
  }
7042
7047
  function sourceCursorKey(target) {
7043
- return target.ref + "\x00" + target.path;
7048
+ return `${target.ref}\x00${target.path}`;
7044
7049
  }
7045
7050
  function sourceCursorMatches(target, line) {
7046
7051
  return !!SOURCE_CURSOR && sourceTargetsEqual(SOURCE_CURSOR.target, target) && SOURCE_CURSOR.line === line;
@@ -7095,7 +7100,7 @@
7095
7100
  syncSourceCursorRows(cursor.target);
7096
7101
  return;
7097
7102
  }
7098
- document.querySelector('#content [data-line="' + cursor.line + '"]')?.scrollIntoView({ block: edge });
7103
+ document.querySelector(`#content [data-line="${cursor.line}"]`)?.scrollIntoView({ block: edge });
7099
7104
  }
7100
7105
  function moveSourceCursor(direction, unit, edge) {
7101
7106
  if (!hasVisibleSourceCodeSurface())
@@ -7175,7 +7180,7 @@
7175
7180
  const tabs = document.querySelector("#content .gdp-source-tabs");
7176
7181
  if (!tabs)
7177
7182
  return false;
7178
- const button = tabs.querySelector('button[data-source-tab="' + tab + '"]');
7183
+ const button = tabs.querySelector(`button[data-source-tab="${tab}"]`);
7179
7184
  if (!button || button.hidden || button.disabled)
7180
7185
  return false;
7181
7186
  button.click();
@@ -7205,7 +7210,7 @@
7205
7210
  if (!project)
7206
7211
  return;
7207
7212
  PROJECT_NAME = project;
7208
- document.title = project + " - code viewer";
7213
+ document.title = `${project} - code viewer`;
7209
7214
  }
7210
7215
  function savedScopeOmitDirs() {
7211
7216
  const raw = localStorage.getItem(scopeOmitDirsStorageKey());
@@ -7248,7 +7253,7 @@
7248
7253
  requestAnimationFrame(() => {
7249
7254
  const head = document.querySelector(".sb-head");
7250
7255
  if (head)
7251
- document.documentElement.style.setProperty("--sidebar-head-h", Math.ceil(head.getBoundingClientRect().height) + "px");
7256
+ document.documentElement.style.setProperty("--sidebar-head-h", `${Math.ceil(head.getBoundingClientRect().height)}px`);
7252
7257
  });
7253
7258
  }
7254
7259
  function observeSidebarHeaderHeight() {
@@ -7293,7 +7298,7 @@
7293
7298
  layout: localStorage.getItem("gdp:layout") || "side-by-side",
7294
7299
  theme: localStorage.getItem("gdp:theme") || (matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light"),
7295
7300
  sbView: localStorage.getItem("gdp:sbview") || "tree",
7296
- sbWidth: parseInt(localStorage.getItem("gdp:sbwidth")) || 308,
7301
+ sbWidth: parseInt(localStorage.getItem("gdp:sbwidth") ?? "", 10) || 308,
7297
7302
  sidebarHidden: localStorage.getItem("gdp:sidebar-hidden") === "1",
7298
7303
  collapsedDirs: new Set(JSON.parse(localStorage.getItem("gdp:collapsed-dirs") || "[]")),
7299
7304
  ignoreWs: igRaw === null ? true : igRaw === "1",
@@ -7321,7 +7326,7 @@
7321
7326
  $("#hljs-dark").disabled = STATE.theme !== "dark";
7322
7327
  }
7323
7328
  function getHljs() {
7324
- const hljsRef = window.hljs || window.Diff2HtmlUI && window.Diff2HtmlUI.hljs;
7329
+ const hljsRef = window.hljs || window.Diff2HtmlUI?.hljs;
7325
7330
  if (!hljsRef)
7326
7331
  return null;
7327
7332
  if (!highlightConfigured && typeof hljsRef.configure === "function") {
@@ -7502,7 +7507,7 @@
7502
7507
  function fileBadge(status) {
7503
7508
  const ch = (status || "M")[0].toUpperCase();
7504
7509
  const span = document.createElement("span");
7505
- span.className = "badge " + ch;
7510
+ span.className = `badge ${ch}`;
7506
7511
  span.textContent = ch;
7507
7512
  span.title = { M: "modified", A: "added", D: "deleted", R: "renamed" }[ch] || ch;
7508
7513
  return span;
@@ -7542,7 +7547,7 @@
7542
7547
  }
7543
7548
  function iconSvg(className, paths) {
7544
7549
  const pathList = Array.isArray(paths) ? paths : [paths];
7545
- return '<svg class="octicon ' + className + '" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" aria-hidden="true">' + pathList.map((path) => '<path fill="currentColor" d="' + path + '"></path>').join("") + "</svg>";
7550
+ return '<svg class="octicon ' + className + '" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" aria-hidden="true">' + pathList.map((path) => `<path fill="currentColor" d="${path}"></path>`).join("") + "</svg>";
7546
7551
  }
7547
7552
  function setUnfoldButtonState(button, expanded) {
7548
7553
  if (!button)
@@ -7672,7 +7677,7 @@
7672
7677
  const dirPartCount = f2.type === "tree" ? parts.length : parts.length - 1;
7673
7678
  for (let i2 = 0;i2 < dirPartCount; i2++) {
7674
7679
  const p2 = parts[i2];
7675
- acc = acc ? acc + "/" + p2 : p2;
7680
+ acc = acc ? `${acc}/${p2}` : p2;
7676
7681
  if (!node.dirs[p2]) {
7677
7682
  node.dirs[p2] = {
7678
7683
  name: p2,
@@ -7700,13 +7705,15 @@
7700
7705
  const ks = Object.keys(node.dirs);
7701
7706
  while (ks.length === 1 && node.files.length === 0 && !node.explicit && node !== root) {
7702
7707
  const only = node.dirs[ks[0]];
7703
- node.name = node.name ? node.name + "/" + only.name : only.name;
7708
+ node.name = node.name ? `${node.name}/${only.name}` : only.name;
7704
7709
  node.dirs = only.dirs;
7705
7710
  node.files = only.files;
7706
7711
  node.path = only.path;
7707
7712
  node.minOrder = Math.min(node.minOrder, only.minOrder);
7708
7713
  ks.length = 0;
7709
- Object.keys(node.dirs).forEach((k) => ks.push(k));
7714
+ Object.keys(node.dirs).forEach((k) => {
7715
+ ks.push(k);
7716
+ });
7710
7717
  }
7711
7718
  Object.values(node.dirs).forEach(compress);
7712
7719
  }
@@ -7741,7 +7748,7 @@
7741
7748
  li.classList.add(dir.children_omitted_reason === "heavy" ? "children-omitted-heavy" : "children-omitted-internal");
7742
7749
  li.title = dir.children_omitted_reason === "heavy" ? "Large generated/vendor directory: open the detail pane to browse its contents" : "Internal Git metadata is not browsed";
7743
7750
  }
7744
- li.style.setProperty("--lvl-pad", 12 + depth * 14 + "px");
7751
+ li.style.setProperty("--lvl-pad", `${12 + depth * 14}px`);
7745
7752
  const chev = document.createElement("span");
7746
7753
  if (dir.children_omitted) {
7747
7754
  chev.className = "chev-spacer";
@@ -7820,7 +7827,7 @@
7820
7827
  li.tabIndex = -1;
7821
7828
  li.dataset.path = f2.path;
7822
7829
  li.classList.toggle("viewed", !onFileClick && STATE.viewedFiles.has(f2.path));
7823
- li.style.setProperty("--lvl-pad", 12 + depth * 14 + "px");
7830
+ li.style.setProperty("--lvl-pad", `${12 + depth * 14}px`);
7824
7831
  const spacer = document.createElement("span");
7825
7832
  spacer.className = "chev-spacer";
7826
7833
  li.appendChild(spacer);
@@ -7901,7 +7908,7 @@
7901
7908
  } else {
7902
7909
  renderFlat(files, ul, onFileClick);
7903
7910
  }
7904
- $("#totals").textContent = files.length ? files.length + " file" + (files.length === 1 ? "" : "s") : "";
7911
+ $("#totals").textContent = files.length ? `${files.length} file${files.length === 1 ? "" : "s"}` : "";
7905
7912
  $$(".sb-view-seg button").forEach((b2) => {
7906
7913
  b2.classList.toggle("active", b2.dataset.view === STATE.sbView);
7907
7914
  });
@@ -7939,7 +7946,7 @@
7939
7946
  }
7940
7947
  function createRefSelectorInput(options) {
7941
7948
  const wrap = document.createElement("div");
7942
- wrap.className = "ref-selector" + (options.extraClass ? " " + options.extraClass : "");
7949
+ wrap.className = `ref-selector${options.extraClass ? ` ${options.extraClass}` : ""}`;
7943
7950
  wrap.dataset.refSelector = "";
7944
7951
  if (options.wrapperId)
7945
7952
  wrap.id = options.wrapperId;
@@ -7990,7 +7997,7 @@
7990
7997
  if (meta.branch) {
7991
7998
  const b2 = document.createElement("span");
7992
7999
  b2.className = "ref";
7993
- b2.textContent = "⎇ " + meta.branch;
8000
+ b2.textContent = `⎇ ${meta.branch}`;
7994
8001
  el.appendChild(b2);
7995
8002
  }
7996
8003
  if (meta.totals) {
@@ -8002,13 +8009,13 @@
8002
8009
  const u2 = document.createElement("span");
8003
8010
  u2.className = "updated-at";
8004
8011
  u2.title = "last updated";
8005
- u2.textContent = "updated " + new Date().toLocaleTimeString([], { hour12: false });
8012
+ u2.textContent = `updated ${new Date().toLocaleTimeString([], { hour12: false })}`;
8006
8013
  el.appendChild(u2);
8007
8014
  }
8008
8015
  let SUPPRESS_SPY_UNTIL = 0;
8009
8016
  function prefetchByPath(path) {
8010
8017
  const card = document.querySelector(diffCardSelector(path));
8011
- if (!card || !card.classList.contains("pending"))
8018
+ if (!card?.classList.contains("pending"))
8012
8019
  return;
8013
8020
  const f2 = STATE.files.find((x) => x.path === path);
8014
8021
  if (!f2)
@@ -8083,7 +8090,7 @@
8083
8090
  for (const dir of sidebarAncestorDirs(path)) {
8084
8091
  if (STATE.collapsedDirs.delete(dir))
8085
8092
  changed = true;
8086
- const row = document.querySelector('#filelist .tree-dir[data-dirpath="' + CSS.escape(dir) + '"]');
8093
+ const row = document.querySelector(`#filelist .tree-dir[data-dirpath="${CSS.escape(dir)}"]`);
8087
8094
  row?.classList.remove("collapsed");
8088
8095
  const icon = row?.querySelector(".dir-icon");
8089
8096
  if (icon)
@@ -8144,7 +8151,7 @@
8144
8151
  function updateTreeDirVisibility(dirMatches, filterActive = false) {
8145
8152
  $$("#filelist .tree-dir").forEach((dir) => {
8146
8153
  const childUl = dir.nextElementSibling;
8147
- if (!childUl || !childUl.classList.contains("tree-children"))
8154
+ if (!childUl?.classList.contains("tree-children"))
8148
8155
  return;
8149
8156
  const anyVisible = !!childUl.querySelector(".tree-file:not(.hidden):not(.hidden-by-tests)");
8150
8157
  const explicitVisible = dir.dataset.explicit === "true" && !filterActive;
@@ -8293,8 +8300,12 @@
8293
8300
  });
8294
8301
  }
8295
8302
  function removeStandaloneSource() {
8296
- document.querySelectorAll(".gdp-standalone-source").forEach((el) => el.remove());
8297
- document.querySelectorAll(".gdp-repo-blob-layout").forEach((el) => el.remove());
8303
+ document.querySelectorAll(".gdp-standalone-source").forEach((el) => {
8304
+ el.remove();
8305
+ });
8306
+ document.querySelectorAll(".gdp-repo-blob-layout").forEach((el) => {
8307
+ el.remove();
8308
+ });
8298
8309
  }
8299
8310
  function renderHelpPage() {
8300
8311
  cancelActiveSourceLoad("navigation");
@@ -8441,7 +8452,7 @@
8441
8452
  delete old.dataset.manualRendered;
8442
8453
  delete old.dataset.manualLoad;
8443
8454
  delete old.dataset.manualMode;
8444
- old.style.minHeight = (f2.estimated_height_px || 80) + "px";
8455
+ old.style.minHeight = `${f2.estimated_height_px || 80}px`;
8445
8456
  old._diffData = null;
8446
8457
  old._file = null;
8447
8458
  } else {
@@ -8456,7 +8467,9 @@
8456
8467
  ordered.push(createPlaceholder(f2));
8457
8468
  }
8458
8469
  });
8459
- oldByKey.forEach((c2) => c2.remove());
8470
+ oldByKey.forEach((c2) => {
8471
+ c2.remove();
8472
+ });
8460
8473
  target.replaceChildren(...ordered);
8461
8474
  for (let i2 = LOAD_QUEUE.length - 1;i2 >= 0; i2--) {
8462
8475
  if (!LOAD_QUEUE[i2].card.isConnected)
@@ -8531,7 +8544,9 @@
8531
8544
  return;
8532
8545
  const form = new FormData;
8533
8546
  form.set("dir", path);
8534
- list2.forEach((file) => form.append("files", file, file.name));
8547
+ list2.forEach((file) => {
8548
+ form.append("files", file, file.name);
8549
+ });
8535
8550
  const res = await fetch("/_upload_files", {
8536
8551
  method: "POST",
8537
8552
  headers: { "X-Code-Viewer-Action": "1" },
@@ -8547,7 +8562,7 @@
8547
8562
  dropPanel.className = "gdp-upload-panel";
8548
8563
  const copy = document.createElement("div");
8549
8564
  copy.className = "gdp-upload-copy";
8550
- copy.textContent = "Drop files into " + (path || PROJECT_NAME || "repository");
8565
+ copy.textContent = `Drop files into ${path || PROJECT_NAME || "repository"}`;
8551
8566
  const input = document.createElement("input");
8552
8567
  input.type = "file";
8553
8568
  input.multiple = true;
@@ -8563,7 +8578,7 @@
8563
8578
  };
8564
8579
  input.addEventListener("change", async () => {
8565
8580
  try {
8566
- if (input.files && input.files.length)
8581
+ if (input.files?.length)
8567
8582
  await uploadFiles(path, input.files);
8568
8583
  } catch {
8569
8584
  fail();
@@ -8581,7 +8596,7 @@
8581
8596
  dropPanel.classList.remove("dragging");
8582
8597
  try {
8583
8598
  const files = event.dataTransfer?.files;
8584
- if (files && files.length)
8599
+ if (files?.length)
8585
8600
  await uploadFiles(path, files);
8586
8601
  } catch {
8587
8602
  fail();
@@ -8723,7 +8738,7 @@
8723
8738
  meta.entries.forEach((entry) => {
8724
8739
  const row = document.createElement("button");
8725
8740
  row.type = "button";
8726
- row.className = "gdp-repo-row " + entry.type;
8741
+ row.className = `gdp-repo-row ${entry.type}`;
8727
8742
  const icon = document.createElement("span");
8728
8743
  icon.className = entry.type === "tree" ? "dir-icon" : "d2h-icon-wrapper";
8729
8744
  if (entry.type === "tree")
@@ -8763,7 +8778,7 @@
8763
8778
  listWrapper.appendChild(list2);
8764
8779
  listCard.appendChild(listWrapper);
8765
8780
  shell.appendChild(listCard);
8766
- if (meta.readme && meta.readme.text) {
8781
+ if (meta.readme?.text) {
8767
8782
  const readme = document.createElement("section");
8768
8783
  readme.className = "gdp-file-shell loaded gdp-repo-readme";
8769
8784
  const wrapper = document.createElement("div");
@@ -8824,7 +8839,7 @@
8824
8839
  params.set("recursive", "1");
8825
8840
  appendScopeOmitDirsParam(params);
8826
8841
  REPO_SIDEBAR_LOAD_REF = normalizedRef;
8827
- const load2 = trackLoad(fetch("/_tree?" + params.toString()).then((r2) => {
8842
+ const load2 = trackLoad(fetch(`/_tree?${params.toString()}`).then((r2) => {
8828
8843
  if (!r2.ok)
8829
8844
  throw new Error("failed to load repository tree");
8830
8845
  return r2.json();
@@ -8883,7 +8898,7 @@
8883
8898
  card.dataset.status = f2.status || "M";
8884
8899
  card.classList.toggle("viewed", STATE.viewedFiles.has(f2.path));
8885
8900
  if (f2.estimated_height_px) {
8886
- card.style.minHeight = f2.estimated_height_px + "px";
8901
+ card.style.minHeight = `${f2.estimated_height_px}px`;
8887
8902
  }
8888
8903
  const head = document.createElement("div");
8889
8904
  head.className = "gdp-shell-header";
@@ -8910,7 +8925,9 @@
8910
8925
  enqueueLoad(f2, card, 0);
8911
8926
  });
8912
8927
  }, { rootMargin: "1200px 0px 1600px 0px" });
8913
- document.querySelectorAll(".gdp-file-shell.pending").forEach((c2) => lazyObserver.observe(c2));
8928
+ document.querySelectorAll(".gdp-file-shell.pending").forEach((c2) => {
8929
+ lazyObserver.observe(c2);
8930
+ });
8914
8931
  }
8915
8932
  window.addEventListener("scroll", () => enqueueInitialLoads(), {
8916
8933
  passive: true
@@ -8981,12 +8998,14 @@
8981
8998
  if (indicator)
8982
8999
  indicator.hidden = true;
8983
9000
  const body = card.querySelector(".gdp-shell-body");
9001
+ if (!body)
9002
+ return;
8984
9003
  body.innerHTML = "";
8985
9004
  const wrap = document.createElement("div");
8986
9005
  wrap.className = "gdp-manual-load";
8987
9006
  const note = document.createElement("div");
8988
9007
  note.className = "gdp-manual-note";
8989
- note.textContent = manualLoadReason(file) + " - click to load diff";
9008
+ note.textContent = `${manualLoadReason(file)} - click to load diff`;
8990
9009
  const previewBtn = document.createElement("button");
8991
9010
  previewBtn.className = "gdp-show-full";
8992
9011
  previewBtn.textContent = "Load preview";
@@ -9091,6 +9110,8 @@
9091
9110
  card.classList.remove("loading");
9092
9111
  card.classList.add("error");
9093
9112
  const body = card.querySelector(".gdp-shell-body");
9113
+ if (!body)
9114
+ return;
9094
9115
  body.innerHTML = '<div class="gdp-error">failed to load — <button class="retry">retry</button></div>';
9095
9116
  const btn = body.querySelector(".retry");
9096
9117
  if (btn)
@@ -9107,8 +9128,10 @@
9107
9128
  if (head)
9108
9129
  head.style.display = "none";
9109
9130
  const body = card.querySelector(".gdp-shell-body");
9131
+ if (!body)
9132
+ return;
9110
9133
  body.innerHTML = "";
9111
- if (!data.diff || !data.diff.trim()) {
9134
+ if (!data.diff?.trim()) {
9112
9135
  body.innerHTML = '<div class="gdp-info">No content</div>';
9113
9136
  return;
9114
9137
  }
@@ -9200,7 +9223,9 @@
9200
9223
  const parsed = group.find((g) => g.hunk) || group[0];
9201
9224
  if (!parsed.hunk)
9202
9225
  return;
9203
- group.forEach((g) => g.tr.classList.add("gdp-hunk-row"));
9226
+ group.forEach((g) => {
9227
+ g.tr.classList.add("gdp-hunk-row");
9228
+ });
9204
9229
  infoRows.push({
9205
9230
  tr: parsed.tr,
9206
9231
  info: parsed.info,
@@ -9264,7 +9289,7 @@
9264
9289
  setBusy(true);
9265
9290
  const url = "/file_range?path=" + refPath + "&ref=" + encodeURIComponent(ref) + "&start=" + start + "&end=" + end;
9266
9291
  trackLoad(fetch(url).then((r2) => r2.json())).then((data) => {
9267
- if (!data || !data.lines) {
9292
+ if (!data?.lines) {
9268
9293
  setBusy(false);
9269
9294
  return;
9270
9295
  }
@@ -9282,7 +9307,7 @@
9282
9307
  item.bottomExpandedEnd = end;
9283
9308
  for (const sib of item.siblings || [{ tr: item.tr }]) {
9284
9309
  const ln = sib.tr.querySelector(".d2h-code-linenumber.d2h-info, .d2h-code-side-linenumber.d2h-info");
9285
- const old = ln && ln.querySelector(".gdp-expand-stack");
9310
+ const old = ln?.querySelector(".gdp-expand-stack");
9286
9311
  if (old)
9287
9312
  old.remove();
9288
9313
  }
@@ -9299,18 +9324,18 @@
9299
9324
  if (isFirst) {
9300
9325
  buttons.push({
9301
9326
  direction: "up",
9302
- title: "Show " + Math.min(STEP, remainingSize) + " more lines",
9327
+ title: `Show ${Math.min(STEP, remainingSize)} more lines`,
9303
9328
  onClick: () => fetchAndInsert(Math.max(remainingStart, remainingEnd - STEP + 1), remainingEnd, "after")
9304
9329
  });
9305
9330
  } else {
9306
9331
  buttons.push({
9307
9332
  direction: "up",
9308
- title: "Show " + Math.min(STEP, remainingSize) + " more lines",
9333
+ title: `Show ${Math.min(STEP, remainingSize)} more lines`,
9309
9334
  onClick: () => fetchAndInsert(remainingStart, Math.min(remainingEnd, remainingStart + STEP - 1), "before")
9310
9335
  });
9311
9336
  buttons.push({
9312
9337
  direction: "down",
9313
- title: "Show " + Math.min(STEP, remainingSize) + " more lines",
9338
+ title: `Show ${Math.min(STEP, remainingSize)} more lines`,
9314
9339
  onClick: () => fetchAndInsert(Math.max(remainingStart, remainingEnd - STEP + 1), remainingEnd, "after")
9315
9340
  });
9316
9341
  }
@@ -9354,12 +9379,14 @@
9354
9379
  const syncHeight = () => {
9355
9380
  const stack = stackRow.querySelector(".gdp-expand-stack");
9356
9381
  const targetH = stack ? Math.max(20, stack.getBoundingClientRect().height) : 20;
9357
- rows.forEach((row) => row.style.setProperty("height", targetH + "px", "important"));
9382
+ rows.forEach((row) => {
9383
+ row.style.setProperty("height", `${targetH}px`, "important");
9384
+ });
9358
9385
  };
9359
9386
  requestAnimationFrame(syncHeight);
9360
9387
  setTimeout(syncHeight, 100);
9361
9388
  }
9362
- function attachTrailingExpandControls(item, file, ref, refPath) {
9389
+ function _attachTrailingExpandControls(item, file, ref, refPath) {
9363
9390
  const STEP = 20;
9364
9391
  let nextNewStart = nextNewLine(item.hunk);
9365
9392
  let nextOldStart = nextOldLine(item.hunk);
@@ -9385,29 +9412,37 @@
9385
9412
  if (!rows.length)
9386
9413
  return;
9387
9414
  const setBusy = (busy) => {
9388
- rows.forEach((row) => row.ln.querySelectorAll(".gdp-expand-btn").forEach((btn) => {
9389
- btn.disabled = busy;
9390
- }));
9415
+ rows.forEach((row) => {
9416
+ row.ln.querySelectorAll(".gdp-expand-btn").forEach((btn) => {
9417
+ btn.disabled = busy;
9418
+ });
9419
+ });
9391
9420
  };
9392
9421
  const fetchAndInsert = () => {
9393
9422
  const range = window.GdpExpandLogic.trailingClickRange(nextNewStart, STEP);
9394
9423
  setBusy(true);
9395
9424
  const url = "/file_range?path=" + refPath + "&ref=" + encodeURIComponent(ref) + "&start=" + range.start + "&end=" + range.end;
9396
9425
  trackLoad(fetch(url).then((r2) => r2.json())).then((data) => {
9397
- const lines = data && data.lines || [];
9426
+ const lines = data?.lines || [];
9398
9427
  if (!lines.length) {
9399
- rows.forEach((row) => row.tr.remove());
9428
+ rows.forEach((row) => {
9429
+ row.tr.remove();
9430
+ });
9400
9431
  return;
9401
9432
  }
9402
9433
  const card = item.tr.closest(".d2h-file-wrapper");
9403
- rows.forEach((row) => insertContextRows(row.tr, lines, range.start, nextOldStart, "before", row.sideIndex));
9434
+ rows.forEach((row) => {
9435
+ insertContextRows(row.tr, lines, range.start, nextOldStart, "before", row.sideIndex);
9436
+ });
9404
9437
  const next = window.GdpExpandLogic.applyTrailingResult({ newStart: nextNewStart, oldStart: nextOldStart }, lines.length, STEP);
9405
9438
  nextNewStart = next.newStart;
9406
9439
  nextOldStart = next.oldStart;
9407
9440
  if (card)
9408
9441
  highlightInsertedSpans(card, file);
9409
9442
  if (next.eof) {
9410
- rows.forEach((row) => row.tr.remove());
9443
+ rows.forEach((row) => {
9444
+ row.tr.remove();
9445
+ });
9411
9446
  return;
9412
9447
  }
9413
9448
  setBusy(false);
@@ -9441,7 +9476,7 @@
9441
9476
  let lnHtml;
9442
9477
  if (isSplit) {
9443
9478
  const num = sideIndex === 0 ? oldStart + i2 : newStart + i2;
9444
- lnHtml = '<td class="d2h-code-side-linenumber d2h-cntx">' + num + "</td>";
9479
+ lnHtml = `<td class="d2h-code-side-linenumber d2h-cntx">${num}</td>`;
9445
9480
  } else {
9446
9481
  lnHtml = '<td class="d2h-code-linenumber d2h-cntx"><div class="line-num1">' + (oldStart + i2) + '</div><div class="line-num2">' + (newStart + i2) + "</div></td>";
9447
9482
  }
@@ -9489,7 +9524,7 @@
9489
9524
  title.textContent = "Loading file";
9490
9525
  const message = document.createElement("div");
9491
9526
  message.className = "gdp-source-loading-message";
9492
- message.textContent = target.path + " at " + target.ref;
9527
+ message.textContent = `${target.path} at ${target.ref}`;
9493
9528
  content.append(title, message);
9494
9529
  if (onCancel) {
9495
9530
  const button = document.createElement("button");
@@ -9513,7 +9548,7 @@
9513
9548
  const body = card.querySelector(".gdp-file-detail-body, .d2h-files-diff, .d2h-file-diff, .gdp-media, .gdp-source-viewer");
9514
9549
  const view = document.createElement("div");
9515
9550
  view.className = "gdp-source-viewer error";
9516
- view.textContent = message || "Cannot load " + target.path + " at " + target.ref;
9551
+ view.textContent = message || `Cannot load ${target.path} at ${target.ref}`;
9517
9552
  if (body)
9518
9553
  body.replaceWith(view);
9519
9554
  else
@@ -9530,7 +9565,7 @@
9530
9565
  title.textContent = "Loading cancelled";
9531
9566
  const message = document.createElement("div");
9532
9567
  message.className = "gdp-source-loading-message";
9533
- message.textContent = target.path + " at " + target.ref;
9568
+ message.textContent = `${target.path} at ${target.ref}`;
9534
9569
  const retry = document.createElement("button");
9535
9570
  retry.type = "button";
9536
9571
  retry.className = "gdp-btn gdp-btn-sm";
@@ -9583,7 +9618,7 @@
9583
9618
  const preview = document.createElement("div");
9584
9619
  preview.className = "gdp-html-preview";
9585
9620
  const frame = document.createElement("iframe");
9586
- frame.title = target.path + " preview";
9621
+ frame.title = `${target.path} preview`;
9587
9622
  frame.srcdoc = html;
9588
9623
  preview.appendChild(frame);
9589
9624
  return preview;
@@ -10021,7 +10056,7 @@
10021
10056
  const header = isStandalone ? null : document.createElement("div");
10022
10057
  if (header) {
10023
10058
  header.className = "gdp-source-meta";
10024
- header.textContent = target.path + " @ " + target.ref;
10059
+ header.textContent = `${target.path} @ ${target.ref}`;
10025
10060
  }
10026
10061
  const lang = inferLang(target.path);
10027
10062
  const usesVirtualSource = shouldVirtualizeSource(textValue, lines) && !isVirtualSourceDisabled();
@@ -10364,7 +10399,7 @@
10364
10399
  return;
10365
10400
  matches = nextMatches;
10366
10401
  active = matches.length ? Math.max(0, Math.min(active, matches.length - 1)) : -1;
10367
- count.textContent = matches.length ? active + 1 + " / " + matches.length : "0 / 0";
10402
+ count.textContent = matches.length ? `${active + 1} / ${matches.length}` : "0 / 0";
10368
10403
  if (active >= 0)
10369
10404
  scroller.scrollTop = Math.max(0, (matches[active].line - 1) * VIRTUAL_SOURCE_ROW_HEIGHT - VIRTUAL_SOURCE_ROW_HEIGHT * 3);
10370
10405
  renderFn();
@@ -10386,7 +10421,7 @@
10386
10421
  if (!matches.length)
10387
10422
  return;
10388
10423
  active = (active + direction + matches.length) % matches.length;
10389
- count.textContent = active + 1 + " / " + matches.length;
10424
+ count.textContent = `${active + 1} / ${matches.length}`;
10390
10425
  scroller.scrollTop = Math.max(0, (matches[active].line - 1) * VIRTUAL_SOURCE_ROW_HEIGHT - VIRTUAL_SOURCE_ROW_HEIGHT * 3);
10391
10426
  renderFn();
10392
10427
  };
@@ -10476,10 +10511,10 @@
10476
10511
  scroller.className = "gdp-source-virtual-scroller";
10477
10512
  scroller.tabIndex = 0;
10478
10513
  scroller.setAttribute("role", "region");
10479
- scroller.setAttribute("aria-label", target.path + " source code");
10514
+ scroller.setAttribute("aria-label", `${target.path} source code`);
10480
10515
  const spacer = document.createElement("div");
10481
10516
  spacer.className = "gdp-source-virtual-spacer";
10482
- spacer.style.height = Math.max(1, lines.length * VIRTUAL_SOURCE_ROW_HEIGHT) + "px";
10517
+ spacer.style.height = `${Math.max(1, lines.length * VIRTUAL_SOURCE_ROW_HEIGHT)}px`;
10483
10518
  const windowEl = document.createElement("div");
10484
10519
  windowEl.className = "gdp-source-virtual-window";
10485
10520
  spacer.appendChild(windowEl);
@@ -10500,7 +10535,7 @@
10500
10535
  renderedStart = start;
10501
10536
  renderedEnd = end;
10502
10537
  windowEl.replaceChildren();
10503
- windowEl.style.transform = "translateY(" + start * VIRTUAL_SOURCE_ROW_HEIGHT + "px)";
10538
+ windowEl.style.transform = `translateY(${start * VIRTUAL_SOURCE_ROW_HEIGHT}px)`;
10504
10539
  const fragment = document.createDocumentFragment();
10505
10540
  for (let index = start;index < end; index++) {
10506
10541
  const row = document.createElement("div");
@@ -10517,7 +10552,7 @@
10517
10552
  const line = lines[index] ?? "";
10518
10553
  const searchQuery = search?.query() || "";
10519
10554
  const activeRange = search?.activeRange() || null;
10520
- if (appendVirtualSourceLineCode(code2, line, searchQuery, activeRange, index + 1)) {} else if (hljsRef && hljsRef.highlight && lang && line.length <= VIRTUAL_SOURCE_HIGHLIGHT_MAX_LINE_LENGTH && (!hljsRef.getLanguage || hljsRef.getLanguage(lang))) {
10555
+ if (appendVirtualSourceLineCode(code2, line, searchQuery, activeRange, index + 1)) {} else if (hljsRef?.highlight && lang && line.length <= VIRTUAL_SOURCE_HIGHLIGHT_MAX_LINE_LENGTH && (!hljsRef.getLanguage || hljsRef.getLanguage(lang))) {
10521
10556
  try {
10522
10557
  code2.innerHTML = hljsRef.highlight(line, {
10523
10558
  language: lang,
@@ -10592,7 +10627,7 @@
10592
10627
  scroller.className = "gdp-source-virtual-scroller";
10593
10628
  scroller.tabIndex = 0;
10594
10629
  scroller.setAttribute("role", "region");
10595
- scroller.setAttribute("aria-label", target.path + " source code");
10630
+ scroller.setAttribute("aria-label", `${target.path} source code`);
10596
10631
  const spacer = document.createElement("div");
10597
10632
  spacer.className = "gdp-source-virtual-spacer";
10598
10633
  const windowEl = document.createElement("div");
@@ -10606,15 +10641,17 @@
10606
10641
  const targetLine = lineTargetStart(currentSourceLineTarget(target)) || 1;
10607
10642
  let complete = initialComplete;
10608
10643
  let totalRows = initialComplete ? Math.max(1, initialTotal) : Math.max(initialTotal || 1, initialStart + initialLines.length - 1, targetLine + VIRTUAL_SOURCE_PAGE_SIZE);
10609
- initialLines.forEach((line, index) => lines.set(initialStart + index, line));
10644
+ initialLines.forEach((line, index) => {
10645
+ lines.set(initialStart + index, line);
10646
+ });
10610
10647
  requestedPages.add(Math.max(0, Math.floor((initialStart - 1) / VIRTUAL_SOURCE_PAGE_SIZE)));
10611
10648
  for (let line = initialStart;line < initialStart + initialLines.length; line += VIRTUAL_SOURCE_PAGE_SIZE) {
10612
10649
  requestedPages.add(Math.max(0, Math.floor((line - 1) / VIRTUAL_SOURCE_PAGE_SIZE)));
10613
10650
  }
10614
10651
  const updateTotals = () => {
10615
10652
  SOURCE_CURSOR_TOTALS.set(sourceCursorKey(target), totalRows);
10616
- summary.textContent = (complete ? totalRows.toLocaleString() : lines.size.toLocaleString() + "+") + " lines loaded from " + formatBytes(size) + ". More rows load as you scroll.";
10617
- spacer.style.height = Math.max(1, totalRows * VIRTUAL_SOURCE_ROW_HEIGHT) + "px";
10653
+ summary.textContent = (complete ? totalRows.toLocaleString() : `${lines.size.toLocaleString()}+`) + " lines loaded from " + formatBytes(size) + ". More rows load as you scroll.";
10654
+ spacer.style.height = `${Math.max(1, totalRows * VIRTUAL_SOURCE_ROW_HEIGHT)}px`;
10618
10655
  };
10619
10656
  const loadPage = (line) => {
10620
10657
  if (signal?.aborted || complete && line > totalRows)
@@ -10630,7 +10667,9 @@
10630
10667
  trackLoad(fetch(buildFileRangeUrl(target, start, end), { signal }).then((res) => res.ok ? res.json() : null).then((data) => {
10631
10668
  if (!data || signal?.aborted)
10632
10669
  return;
10633
- data.lines.forEach((lineValue, index) => lines.set(data.start + index, lineValue));
10670
+ data.lines.forEach((lineValue, index) => {
10671
+ lines.set(data.start + index, lineValue);
10672
+ });
10634
10673
  totalRows = data.complete ? Math.max(1, data.total) : Math.max(totalRows, data.total, end + VIRTUAL_SOURCE_PAGE_SIZE);
10635
10674
  complete = data.complete === true;
10636
10675
  updateTotals();
@@ -10662,7 +10701,7 @@
10662
10701
  renderedStart = start;
10663
10702
  renderedEnd = end;
10664
10703
  windowEl.replaceChildren();
10665
- windowEl.style.transform = "translateY(" + start * VIRTUAL_SOURCE_ROW_HEIGHT + "px)";
10704
+ windowEl.style.transform = `translateY(${start * VIRTUAL_SOURCE_ROW_HEIGHT}px)`;
10666
10705
  const fragment = document.createDocumentFragment();
10667
10706
  for (let index = start;index < end; index++) {
10668
10707
  const lineNumber = index + 1;
@@ -10682,7 +10721,7 @@
10682
10721
  const line = lines.get(lineNumber);
10683
10722
  if (line == null) {
10684
10723
  code2.textContent = "";
10685
- } else if (appendVirtualSourceLineCode(code2, line, search?.query() || "", search?.activeRange() || null, lineNumber)) {} else if (hljsRef && hljsRef.highlight && lang && line.length <= VIRTUAL_SOURCE_HIGHLIGHT_MAX_LINE_LENGTH && (!hljsRef.getLanguage || hljsRef.getLanguage(lang))) {
10724
+ } else if (appendVirtualSourceLineCode(code2, line, search?.query() || "", search?.activeRange() || null, lineNumber)) {} else if (hljsRef?.highlight && lang && line.length <= VIRTUAL_SOURCE_HIGHLIGHT_MAX_LINE_LENGTH && (!hljsRef.getLanguage || hljsRef.getLanguage(lang))) {
10686
10725
  try {
10687
10726
  code2.innerHTML = hljsRef.highlight(line, {
10688
10727
  language: lang,
@@ -10782,7 +10821,7 @@
10782
10821
  const header = isStandalone ? null : document.createElement("div");
10783
10822
  if (header) {
10784
10823
  header.className = "gdp-source-meta";
10785
- header.textContent = target.path + " @ " + target.ref;
10824
+ header.textContent = `${target.path} @ ${target.ref}`;
10786
10825
  view.appendChild(header);
10787
10826
  }
10788
10827
  const lineTarget = lineTargetStart(currentSourceLineTarget(target)) || 1;
@@ -10823,7 +10862,7 @@
10823
10862
  if (!isStandalone) {
10824
10863
  const meta = document.createElement("div");
10825
10864
  meta.className = "gdp-source-meta";
10826
- meta.textContent = target.path + " @ " + target.ref;
10865
+ meta.textContent = `${target.path} @ ${target.ref}`;
10827
10866
  view.appendChild(meta);
10828
10867
  }
10829
10868
  const url = buildRawFileUrl(target);
@@ -10853,7 +10892,7 @@
10853
10892
  img.alt = "";
10854
10893
  img.addEventListener("load", () => {
10855
10894
  const resolution = document.createElement("span");
10856
- resolution.textContent = img.naturalWidth + " x " + img.naturalHeight;
10895
+ resolution.textContent = `${img.naturalWidth} x ${img.naturalHeight}`;
10857
10896
  info.appendChild(resolution);
10858
10897
  }, { once: true });
10859
10898
  view.appendChild(img);
@@ -10863,7 +10902,7 @@
10863
10902
  else
10864
10903
  card.appendChild(view);
10865
10904
  }
10866
- function renderSourceBinary(card, target) {
10905
+ function _renderSourceBinary(card, target) {
10867
10906
  const body = card.querySelector(".gdp-file-detail-body, .d2h-files-diff, .d2h-file-diff, .gdp-media, .gdp-source-viewer");
10868
10907
  const isStandalone = card.classList.contains("gdp-standalone-source");
10869
10908
  const view = document.createElement("div");
@@ -10876,7 +10915,7 @@
10876
10915
  if (!isStandalone) {
10877
10916
  const meta = document.createElement("div");
10878
10917
  meta.className = "gdp-source-meta";
10879
- meta.textContent = target.path + " @ " + target.ref;
10918
+ meta.textContent = `${target.path} @ ${target.ref}`;
10880
10919
  view.appendChild(meta);
10881
10920
  }
10882
10921
  view.appendChild(link2);
@@ -10928,7 +10967,9 @@
10928
10967
  const repoTarget = repoFileTargetFromRoute();
10929
10968
  setPageMode();
10930
10969
  removeStandaloneSource();
10931
- document.querySelectorAll(".gdp-repo-blob-layout").forEach((el) => el.remove());
10970
+ document.querySelectorAll(".gdp-repo-blob-layout").forEach((el) => {
10971
+ el.remove();
10972
+ });
10932
10973
  const card = document.createElement("article");
10933
10974
  card.className = "gdp-file-shell loaded gdp-standalone-source gdp-source-mode";
10934
10975
  card.dataset.path = target.path;
@@ -11034,7 +11075,7 @@
11034
11075
  return;
11035
11076
  if (!response.ok) {
11036
11077
  finishSourceLoad(req);
11037
- renderSourceError(card, target, "Cannot load " + target.path + " at " + target.ref);
11078
+ renderSourceError(card, target, `Cannot load ${target.path} at ${target.ref}`);
11038
11079
  return;
11039
11080
  }
11040
11081
  const textValue = await response.text();
@@ -11056,7 +11097,7 @@
11056
11097
  renderSourceCancelled(card, target);
11057
11098
  return;
11058
11099
  }
11059
- renderSourceError(card, target, "Cannot load " + target.path + " at " + target.ref);
11100
+ renderSourceError(card, target, `Cannot load ${target.path} at ${target.ref}`);
11060
11101
  }
11061
11102
  }
11062
11103
  function scrollStandaloneSourceLine(card, line) {
@@ -11069,7 +11110,7 @@
11069
11110
  virtualScroller.__gdpRenderVirtualSource?.();
11070
11111
  return;
11071
11112
  }
11072
- const row = card.querySelector('.gdp-source-table tr[data-line="' + String(line) + '"]');
11113
+ const row = card.querySelector(`.gdp-source-table tr[data-line="${String(line)}"]`);
11073
11114
  if (row)
11074
11115
  row.scrollIntoView({ block: "center" });
11075
11116
  }
@@ -11210,7 +11251,8 @@
11210
11251
  }
11211
11252
  const total = (file.additions || 0) + (file.deletions || 0);
11212
11253
  const SEG = 5;
11213
- let aSeg, dSeg;
11254
+ let aSeg;
11255
+ let dSeg;
11214
11256
  if (total === 0) {
11215
11257
  aSeg = 0;
11216
11258
  dSeg = 0;
@@ -11267,7 +11309,7 @@
11267
11309
  card.style.minHeight = "";
11268
11310
  mountDiff(card, file, data);
11269
11311
  applyDiffRouteFocus(card);
11270
- card.style.containIntrinsicSize = Math.max(card.offsetHeight, file.estimated_height_px || 200) + "px";
11312
+ card.style.containIntrinsicSize = `${Math.max(card.offsetHeight, file.estimated_height_px || 200)}px`;
11271
11313
  applyViewedToCard(card, STATE.viewedFiles.has(file.path), true);
11272
11314
  if (data.truncated && data.mode === "preview") {
11273
11315
  addExpandHunksUI(file, data, card);
@@ -11294,15 +11336,15 @@
11294
11336
  const step = Math.min(10, remaining);
11295
11337
  const moreBtn = document.createElement("button");
11296
11338
  moreBtn.className = "gdp-show-full";
11297
- moreBtn.textContent = "Show next " + step + " hunk" + (step === 1 ? "" : "s");
11339
+ moreBtn.textContent = `Show next ${step} hunk${step === 1 ? "" : "s"}`;
11298
11340
  moreBtn.addEventListener("click", () => loadMore(rendered + step, false));
11299
11341
  const allBtn = document.createElement("button");
11300
11342
  allBtn.className = "gdp-show-full secondary";
11301
- allBtn.textContent = "Show all (" + remaining + " remaining)";
11343
+ allBtn.textContent = `Show all (${remaining} remaining)`;
11302
11344
  allBtn.addEventListener("click", () => loadMore(total, true));
11303
11345
  const note = document.createElement("span");
11304
11346
  note.className = "gdp-hunk-note";
11305
- note.textContent = rendered + " / " + total + " hunks shown";
11347
+ note.textContent = `${rendered} / ${total} hunks shown`;
11306
11348
  wrap.appendChild(note);
11307
11349
  wrap.appendChild(moreBtn);
11308
11350
  wrap.appendChild(allBtn);
@@ -11350,10 +11392,10 @@
11350
11392
  if (!STATE.syntaxHighlight)
11351
11393
  return;
11352
11394
  const hljsRef = getHljs();
11353
- if (!hljsRef || !hljsRef.highlight)
11395
+ if (!hljsRef?.highlight)
11354
11396
  return;
11355
11397
  const lang = inferLang(file.path);
11356
- if (!lang || !hljsRef.getLanguage || !hljsRef.getLanguage(lang))
11398
+ if (!lang || !hljsRef.getLanguage?.(lang))
11357
11399
  return;
11358
11400
  const spans = card.querySelectorAll("tr.gdp-inserted-ctx .d2h-code-line-ctn:not([data-gdp-hl])");
11359
11401
  spans.forEach((s2) => {
@@ -11381,10 +11423,10 @@
11381
11423
  if (!("requestIdleCallback" in window))
11382
11424
  return;
11383
11425
  const hljsRef = getHljs();
11384
- if (!hljsRef || !hljsRef.highlight)
11426
+ if (!hljsRef?.highlight)
11385
11427
  return;
11386
11428
  const lang = inferLang(file.path);
11387
- if (!lang || !hljsRef.getLanguage || !hljsRef.getLanguage(lang))
11429
+ if (!lang || !hljsRef.getLanguage?.(lang))
11388
11430
  return;
11389
11431
  const work = (deadline) => {
11390
11432
  const spans = card.querySelectorAll(".d2h-code-line-ctn:not([data-gdp-hl])");
@@ -11446,17 +11488,17 @@
11446
11488
  return AUDIO_RE.test(p2);
11447
11489
  }
11448
11490
  function fileURL(path, ref) {
11449
- return "/_file?path=" + encodeURIComponent(path) + "&ref=" + ref;
11491
+ return `/_file?path=${encodeURIComponent(path)}&ref=${ref}`;
11450
11492
  }
11451
11493
  function mediaTag(path, ref) {
11452
11494
  const url = fileURL(path, ref);
11453
11495
  if (isVideo(path)) {
11454
- return '<video src="' + url + '" controls preload="metadata"></video>';
11496
+ return `<video src="${url}" controls preload="metadata"></video>`;
11455
11497
  }
11456
11498
  if (isAudio(path)) {
11457
- return '<audio src="' + url + '" controls preload="metadata"></audio>';
11499
+ return `<audio src="${url}" controls preload="metadata"></audio>`;
11458
11500
  }
11459
- return '<img src="' + url + '" alt="" loading="lazy">';
11501
+ return `<img src="${url}" alt="" loading="lazy">`;
11460
11502
  }
11461
11503
  function enhanceMediaCard(file, card) {
11462
11504
  const path = file.path;
@@ -11470,7 +11512,8 @@
11470
11512
  return;
11471
11513
  const container = document.createElement("div");
11472
11514
  container.className = "gdp-media";
11473
- let leftHTML, rightHTML;
11515
+ let leftHTML;
11516
+ let rightHTML;
11474
11517
  if (file.status === "A") {
11475
11518
  leftHTML = '<div class="media-empty">Not in HEAD</div>';
11476
11519
  rightHTML = mediaTag(path, "worktree");
@@ -11494,7 +11537,7 @@
11494
11537
  handler._raf = null;
11495
11538
  if (performance.now() < SUPPRESS_SPY_UNTIL)
11496
11539
  return;
11497
- const topbarH = parseInt(getComputedStyle(document.documentElement).getPropertyValue("--topbar-h")) || 56;
11540
+ const topbarH = parseInt(getComputedStyle(document.documentElement).getPropertyValue("--topbar-h"), 10) || 56;
11498
11541
  const scanY = topbarH + 24;
11499
11542
  const cards = document.querySelectorAll(".gdp-file-shell");
11500
11543
  for (const w of cards) {
@@ -11512,7 +11555,7 @@
11512
11555
  markActive(best);
11513
11556
  const recentlyTouched = performance.now() - (window.__gdpSidebarTouchedAt || 0) < 1500;
11514
11557
  if (!recentlyTouched) {
11515
- const li = document.querySelector('#filelist li[data-path="' + CSS.escape(best) + '"]');
11558
+ const li = document.querySelector(`#filelist li[data-path="${CSS.escape(best)}"]`);
11516
11559
  if (li) {
11517
11560
  const sb = document.querySelector("#sidebar");
11518
11561
  if (!sb)
@@ -11536,7 +11579,7 @@
11536
11579
  window.addEventListener("scroll", handler, { passive: true });
11537
11580
  handler(new Event("scroll"));
11538
11581
  }
11539
- function collapseAll(force) {
11582
+ function _collapseAll(force) {
11540
11583
  STATE.collapsed = typeof force === "boolean" ? force : !STATE.collapsed;
11541
11584
  document.querySelectorAll(".gdp-file-shell.loaded .d2h-file-wrapper").forEach((w) => {
11542
11585
  const body = w.querySelector(".d2h-files-diff, .d2h-file-diff");
@@ -11580,7 +11623,7 @@
11580
11623
  });
11581
11624
  function applySidebarWidth(w) {
11582
11625
  const cw = Math.max(180, Math.min(900, w));
11583
- document.documentElement.style.setProperty("--sidebar-w", cw + "px");
11626
+ document.documentElement.style.setProperty("--sidebar-w", `${cw}px`);
11584
11627
  STATE.sbWidth = cw;
11585
11628
  localStorage.setItem("gdp:sbwidth", String(cw));
11586
11629
  }
@@ -11621,14 +11664,14 @@
11621
11664
  currentW = startW;
11622
11665
  document.body.classList.add("gdp-resizing");
11623
11666
  preview.style.display = "block";
11624
- preview.style.left = startW + "px";
11667
+ preview.style.left = `${startW}px`;
11625
11668
  e2.preventDefault();
11626
11669
  });
11627
11670
  window.addEventListener("mousemove", (e2) => {
11628
11671
  if (!dragging)
11629
11672
  return;
11630
11673
  currentW = clamp(startW + (e2.clientX - startX));
11631
- preview.style.left = currentW + "px";
11674
+ preview.style.left = `${currentW}px`;
11632
11675
  });
11633
11676
  window.addEventListener("mouseup", () => {
11634
11677
  if (!dragging)
@@ -11962,7 +12005,7 @@
11962
12005
  state.items.forEach((item, index) => {
11963
12006
  const row = document.createElement("button");
11964
12007
  row.type = "button";
11965
- row.id = "gdp-palette-item-" + index;
12008
+ row.id = `gdp-palette-item-${index}`;
11966
12009
  row.className = "gdp-palette-row";
11967
12010
  row.setAttribute("role", "option");
11968
12011
  row.setAttribute("aria-selected", index === state.selected ? "true" : "false");
@@ -11974,10 +12017,10 @@
11974
12017
  title.textContent = item.path.split("/").pop() || item.path;
11975
12018
  appendHighlightedPath(detail, item.displayPath, item.ranges);
11976
12019
  if (item.old_path && item.displayPath !== item.old_path) {
11977
- detail.appendChild(document.createTextNode(" " + item.old_path));
12020
+ detail.appendChild(document.createTextNode(` ${item.old_path}`));
11978
12021
  }
11979
12022
  } else {
11980
- title.textContent = item.path + ":" + item.line;
12023
+ title.textContent = `${item.path}:${item.line}`;
11981
12024
  detail.textContent = item.preview;
11982
12025
  }
11983
12026
  row.append(title, detail);
@@ -11995,7 +12038,7 @@
11995
12038
  syncPaletteSelection(state);
11996
12039
  }
11997
12040
  function syncPaletteSelection(state) {
11998
- state.input.setAttribute("aria-activedescendant", state.selected >= 0 ? "gdp-palette-item-" + state.selected : "");
12041
+ state.input.setAttribute("aria-activedescendant", state.selected >= 0 ? `gdp-palette-item-${state.selected}` : "");
11999
12042
  state.list.querySelectorAll(".gdp-palette-row").forEach((row, index) => {
12000
12043
  row.setAttribute("aria-selected", index === state.selected ? "true" : "false");
12001
12044
  if (index === state.selected)
@@ -12010,7 +12053,7 @@
12010
12053
  const params = new URLSearchParams;
12011
12054
  params.set("ref", ref);
12012
12055
  appendScopeOmitDirsParam(params);
12013
- const res = await trackLoad(fetch("/_files?" + params.toString()).then((r2) => {
12056
+ const res = await trackLoad(fetch(`/_files?${params.toString()}`).then((r2) => {
12014
12057
  if (!r2.ok)
12015
12058
  throw new Error("failed to load files");
12016
12059
  return r2.json();
@@ -12058,7 +12101,7 @@
12058
12101
  }) : [];
12059
12102
  state.items = limitPaletteResults(base2);
12060
12103
  state.selected = state.items.length ? 0 : -1;
12061
- state.status.textContent = source === "diff" ? state.diffSnapshot.length + " diff files" : "Type to search repository files";
12104
+ state.status.textContent = source === "diff" ? `${state.diffSnapshot.length} diff files` : "Type to search repository files";
12062
12105
  renderPalette(state);
12063
12106
  return;
12064
12107
  }
@@ -12080,7 +12123,7 @@
12080
12123
  }));
12081
12124
  }
12082
12125
  state.selected = state.items.length ? 0 : -1;
12083
- state.status.textContent = state.items.length ? state.items.length + " results" : "No results";
12126
+ state.status.textContent = state.items.length ? `${state.items.length} results` : "No results";
12084
12127
  renderPalette(state);
12085
12128
  }
12086
12129
  function updateGrepPalette(state, query) {
@@ -12120,7 +12163,7 @@
12120
12163
  }
12121
12164
  const controller = new AbortController;
12122
12165
  state.controller = controller;
12123
- trackLoad(fetch("/_grep?" + params.toString(), {
12166
+ trackLoad(fetch(`/_grep?${params.toString()}`, {
12124
12167
  signal: controller.signal
12125
12168
  }).then((r2) => {
12126
12169
  if (!r2.ok)
@@ -12378,7 +12421,7 @@
12378
12421
  if (!isPlainPageKey && !isCtrlArrowKey)
12379
12422
  return false;
12380
12423
  const scroller = findMainScrollTarget();
12381
- if (!scroller || !scroller.matches("#content .gdp-source-virtual-scroller"))
12424
+ if (!scroller?.matches("#content .gdp-source-virtual-scroller"))
12382
12425
  return false;
12383
12426
  const pageDown = key === "pagedown" || key === "arrowdown";
12384
12427
  const pageUp = key === "pageup" || key === "arrowup";
@@ -12436,7 +12479,7 @@
12436
12479
  if (STATE.route.path)
12437
12480
  params.set("path", STATE.route.path);
12438
12481
  appendScopeOmitDirsParam(params);
12439
- return trackLoad(fetch("/_tree?" + params.toString()).then((r2) => {
12482
+ return trackLoad(fetch(`/_tree?${params.toString()}`).then((r2) => {
12440
12483
  if (!r2.ok)
12441
12484
  throw new Error("failed to load repository tree");
12442
12485
  return r2.json();
@@ -12465,7 +12508,7 @@
12465
12508
  params.set("to", STATE.to);
12466
12509
  if (options.force)
12467
12510
  params.set("nocache", "1");
12468
- const url = "/diff.json" + (params.toString() ? "?" + params.toString() : "");
12511
+ const url = `/diff.json${params.toString() ? `?${params.toString()}` : ""}`;
12469
12512
  return trackLoad(fetch(url).then((r2) => r2.json())).then((data) => {
12470
12513
  renderShell(data);
12471
12514
  setStatus("live");
@@ -12523,6 +12566,8 @@
12523
12566
  const popover = $("#ref-popover");
12524
12567
  const popBody = popover.querySelector(".rp-body");
12525
12568
  const popSearch = popover.querySelector(".rp-search");
12569
+ if (!popBody || !popSearch)
12570
+ return;
12526
12571
  let popTarget = null;
12527
12572
  function fetchRefs() {
12528
12573
  return fetch("/_refs").then((r2) => r2.json()).then((refs) => {
@@ -12540,7 +12585,7 @@
12540
12585
  if (commitSearchAbort)
12541
12586
  commitSearchAbort.abort();
12542
12587
  commitSearchAbort = new AbortController;
12543
- const url = "/_commits?max=100&q=" + encodeURIComponent((query || "").trim());
12588
+ const url = `/_commits?max=100&q=${encodeURIComponent((query || "").trim())}`;
12544
12589
  return fetch(url, { signal: commitSearchAbort.signal }).then((r2) => r2.json()).then((refs) => {
12545
12590
  if (seq !== commitSearchSeq)
12546
12591
  return;
@@ -12585,21 +12630,21 @@
12585
12630
  html.push('<div class="rp-item-commit" data-val="' + escapeAttr(commit.sha) + '"><div class="row1"><span class="sha">' + escapeHtml2(shortSha) + '</span><span class="subject" title="' + escapeAttr(commit.subject || "") + '">' + escapeHtml2(commit.subject || "") + '</span></div><div class="row2"><span class="author">' + escapeHtml2(commit.author || "") + '</span><span class="when">' + escapeHtml2(commit.when || "") + "</span></div></div>");
12586
12631
  }
12587
12632
  } else if (popTab === "branches") {
12588
- const branches = (REFS.branches || []).filter(m);
12633
+ const branches = (REFS.branches || []).filter((b2) => m(b2.name));
12589
12634
  if (!branches.length) {
12590
12635
  html.push('<div class="rp-empty">no branches</div>');
12591
12636
  }
12592
- for (const b2 of branches) {
12593
- const cur = b2 === REFS.current;
12594
- html.push('<div class="rp-item-ref" data-val="' + escapeAttr(b2) + '"><span class="name">' + escapeHtml2(b2) + "</span>" + (cur ? '<span class="badge cur">current</span>' : '<span class="badge">branch</span>') + "</div>");
12637
+ for (const branch of branches) {
12638
+ const cur = branch.name === REFS.current;
12639
+ html.push('<div class="rp-item-ref" data-val="' + escapeAttr(branch.name) + '"><div class="row1"><span class="name">' + escapeHtml2(branch.name) + "</span>" + (cur ? '<span class="badge cur">current</span>' : '<span class="badge">branch</span>') + "</div>" + (branch.when ? '<div class="row2"><span class="when">' + escapeHtml2(branch.when) + "</span></div>" : "") + "</div>");
12595
12640
  }
12596
12641
  } else if (popTab === "tags") {
12597
- const tags = (REFS.tags || []).filter(m);
12642
+ const tags = (REFS.tags || []).filter((t2) => m(t2.name));
12598
12643
  if (!tags.length) {
12599
12644
  html.push('<div class="rp-empty">no tags</div>');
12600
12645
  }
12601
- for (const t2 of tags) {
12602
- html.push('<div class="rp-item-ref" data-val="' + escapeAttr(t2) + '"><span class="name">' + escapeHtml2(t2) + '</span><span class="badge">tag</span></div>');
12646
+ for (const tag of tags) {
12647
+ html.push('<div class="rp-item-ref" data-val="' + escapeAttr(tag.name) + '"><div class="row1"><span class="name">' + escapeHtml2(tag.name) + '</span><span class="badge">tag</span></div>' + (tag.when ? '<div class="row2"><span class="when">' + escapeHtml2(tag.when) + "</span></div>" : "") + "</div>");
12603
12648
  }
12604
12649
  }
12605
12650
  popBody.innerHTML = html.join("");
@@ -12643,8 +12688,8 @@
12643
12688
  popover.hidden = false;
12644
12689
  const r2 = input.getBoundingClientRect();
12645
12690
  const popWidth = Math.min(560, Math.floor(window.innerWidth * 0.9));
12646
- popover.style.left = Math.max(8, Math.min(r2.left, window.innerWidth - popWidth - 8)) + "px";
12647
- popover.style.top = r2.bottom + 4 + "px";
12691
+ popover.style.left = `${Math.max(8, Math.min(r2.left, window.innerWidth - popWidth - 8))}px`;
12692
+ popover.style.top = `${r2.bottom + 4}px`;
12648
12693
  setTimeout(() => popSearch.focus(), 0);
12649
12694
  }
12650
12695
  function closePopover() {
@@ -12704,7 +12749,9 @@
12704
12749
  popover.querySelectorAll(".rp-tab").forEach((t2) => {
12705
12750
  t2.addEventListener("click", () => {
12706
12751
  popTab = t2.dataset.tab || "commits";
12707
- popover.querySelectorAll(".rp-tab").forEach((b2) => b2.classList.toggle("active", b2 === t2));
12752
+ popover.querySelectorAll(".rp-tab").forEach((b2) => {
12753
+ b2.classList.toggle("active", b2 === t2);
12754
+ });
12708
12755
  if (popTab === "commits")
12709
12756
  scheduleCommitSearch(popSearch.value);
12710
12757
  buildPopBody(popSearch.value);
package/web/style.css CHANGED
@@ -686,9 +686,7 @@ body[data-code-font-size="xlarge"] { --code-font-size: 15px; }
686
686
 
687
687
  /* Branch / tag / special items */
688
688
  .rp-item-ref {
689
- display: flex;
690
- align-items: center;
691
- gap: 10px;
689
+ display: block;
692
690
  padding: 7px 14px;
693
691
  cursor: pointer;
694
692
  border-left: 2px solid transparent;
@@ -699,16 +697,29 @@ body[data-code-font-size="xlarge"] { --code-font-size: 15px; }
699
697
  background: var(--bg-mute);
700
698
  border-left-color: var(--accent);
701
699
  }
700
+ .rp-item-ref .row1 {
701
+ display: grid;
702
+ grid-template-columns: minmax(0, 1fr) max-content;
703
+ align-items: center;
704
+ gap: 10px;
705
+ }
702
706
  .rp-item-ref .name {
703
707
  font-family: "Monaspace Neon", ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
704
- flex: 1;
708
+ min-width: 0;
705
709
  overflow: hidden;
706
710
  text-overflow: ellipsis;
707
711
  white-space: nowrap;
708
712
  color: var(--fg);
709
713
  }
710
714
  .rp-item-ref .badge {
715
+ width: auto;
716
+ height: auto;
717
+ display: inline-flex;
718
+ align-items: center;
719
+ justify-content: center;
720
+ min-height: 18px;
711
721
  font-size: 10px;
722
+ line-height: 1;
712
723
  font-weight: 600;
713
724
  text-transform: uppercase;
714
725
  letter-spacing: 0.06em;
@@ -716,12 +727,14 @@ body[data-code-font-size="xlarge"] { --code-font-size: 15px; }
716
727
  background: var(--bg-mute);
717
728
  padding: 2px 6px;
718
729
  border-radius: 4px;
730
+ white-space: nowrap;
731
+ justify-self: end;
719
732
  }
720
733
  .rp-item-ref .badge.cur { background: var(--accent-subtle); color: var(--accent); }
721
- .rp-item-ref .desc {
734
+ .rp-item-ref .row2 {
722
735
  font-size: 11px;
723
736
  color: var(--fg-subtle);
724
- font-style: italic;
737
+ margin-top: 2px;
725
738
  }
726
739
  .rp-empty {
727
740
  padding: 36px 14px;