@davmash/bygone 0.8.5 → 0.8.6

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 CHANGED
@@ -2,11 +2,18 @@
2
2
 
3
3
  ## Unreleased
4
4
 
5
+ ## 0.8.6
6
+
7
+ - Added optional authored-tour `windowTitle` labels and context-aware desktop and VS Code window titles
8
+ - Fixed tour presenter windows so authored `windowTitle` values appear in the native title instead of staying on the default `Bygone Tour` label
9
+
5
10
  ## 0.8.5
6
11
 
7
12
  - Fixed Homebrew cask `bygone` CLI launch on Apple Silicon by routing through a bundle-aware launcher script inside the app
8
13
  - Documented the macOS **“app is damaged”** workaround for unsigned desktop downloads (README, releasing docs, PR Tour Guide skill)
9
14
 
15
+ **macOS install:** Desktop builds are unsigned. If Gatekeeper reports the app is damaged, run `xattr -cr /Applications/Bygone.app` then open the app.
16
+
10
17
  ## 0.8.4
11
18
 
12
19
  - Clarified PR Tour Guide skill install commands for project scope and agent-specific global installs
package/cli/present.js CHANGED
@@ -3,6 +3,7 @@ const { createServer } = require('http');
3
3
  const path = require('path');
4
4
  const { spawn } = require('child_process');
5
5
  const { buildChangeTourManifest, parseChangeTourStory } = require('../out/changeTour.js');
6
+ const { buildTourWindowTitle } = require('../out/windowTitle.js');
6
7
  const { tokenMatches } = require('./commandSpec.js');
7
8
  const { loadTourSource } = require('./tourFile.js');
8
9
 
@@ -39,6 +40,10 @@ async function startPresentation(args, cwd, packageRoot, options = {}) {
39
40
  process.stdout.write(`Wrote change-tour manifest to ${resolvedOutput}\n`);
40
41
  }
41
42
 
43
+ const tourWindowTitle = buildTourWindowTitle(manifest, 'Bygone');
44
+ const presenterIndexPath = path.join(packageRoot, 'web', 'index.html');
45
+ let presenterIndexTemplate;
46
+
42
47
  const server = createServer((request, response) => {
43
48
  const requestUrl = new URL(request.url || '/', 'http://127.0.0.1');
44
49
  if (requestUrl.pathname === '/tour.json') {
@@ -49,6 +54,21 @@ async function startPresentation(args, cwd, packageRoot, options = {}) {
49
54
  response.end(serializedManifest);
50
55
  return;
51
56
  }
57
+ if (requestUrl.pathname === '/' || requestUrl.pathname === '/index.html') {
58
+ if (!presenterIndexTemplate) {
59
+ presenterIndexTemplate = readFileSync(presenterIndexPath, 'utf8');
60
+ }
61
+ const html = presenterIndexTemplate.replace(
62
+ /<title>Bygone Tour<\/title>/,
63
+ `<title>${escapeHtml(tourWindowTitle)}</title>`
64
+ );
65
+ response.writeHead(200, {
66
+ 'Content-Type': 'text/html; charset=utf-8',
67
+ 'Cache-Control': 'no-store'
68
+ });
69
+ response.end(html);
70
+ return;
71
+ }
52
72
  const targetPath = resolveAssetPath(packageRoot, requestUrl.pathname);
53
73
  if (!targetPath) {
54
74
  respond(response, 404, 'Not found');
@@ -120,7 +140,7 @@ function parsePresentArgs(args) {
120
140
 
121
141
  function resolveAssetPath(packageRoot, requestPath) {
122
142
  if (requestPath === '/' || requestPath === '/index.html') {
123
- return path.join(packageRoot, 'web', 'index.html');
143
+ return null;
124
144
  }
125
145
  if (!requestPath.startsWith('/web/') && !requestPath.startsWith('/media/')) {
126
146
  return null;
@@ -160,7 +180,16 @@ function respond(response, statusCode, message) {
160
180
  response.end(message);
161
181
  }
162
182
 
183
+ function escapeHtml(text) {
184
+ return text
185
+ .replaceAll('&', '&amp;')
186
+ .replaceAll('<', '&lt;')
187
+ .replaceAll('>', '&gt;')
188
+ .replaceAll('"', '&quot;');
189
+ }
190
+
163
191
  module.exports = {
164
192
  parsePresentArgs,
165
- startPresentation
193
+ startPresentation,
194
+ escapeHtml
166
195
  };
@@ -35,11 +35,16 @@ contents, and diffs into the portable JSON manifest served by the presenter.
35
35
  Compilation fails if an anchor has no match or has multiple matches without an
36
36
  explicit `occurrence`.
37
37
 
38
+ The optional `windowTitle` sets the native window title for the tour presenter.
39
+ Use a short label such as a pull request number when several tours may be open at
40
+ once. When omitted, the presenter falls back to `title`, then a generic tour label.
41
+
38
42
  ## Structure
39
43
 
40
44
  ```yaml
41
45
  version: 1
42
46
  title: A reviewer-facing title
47
+ windowTitle: PR-1234
43
48
  sourceUrl: https://example.test/pull/123
44
49
  range:
45
50
  base: 0123456789abcdef
package/out/changeTour.js CHANGED
@@ -239,6 +239,9 @@ function parseChangeTourManifest(value) {
239
239
  }
240
240
  requireString(value.title, "title");
241
241
  requireString(value.generatedAt, "generatedAt");
242
+ if (value.windowTitle !== void 0) {
243
+ requireString(value.windowTitle, "windowTitle");
244
+ }
242
245
  if (value.sourceUrl !== void 0) {
243
246
  requireString(value.sourceUrl, "sourceUrl");
244
247
  }
@@ -533,8 +536,9 @@ function parseChangeTourSource(value) {
533
536
  if (!isRecord2(value) || value.version !== CHANGE_TOUR_SOURCE_VERSION) {
534
537
  throw new Error("Unsupported or missing change-tour source version.");
535
538
  }
536
- requireOnlyKeys(value, ["version", "title", "sourceUrl", "range", "anchors", "connections", "chapters", "coverage"], "source");
539
+ requireOnlyKeys(value, ["version", "title", "windowTitle", "sourceUrl", "range", "anchors", "connections", "chapters", "coverage"], "source");
537
540
  optionalString(value.title, "title");
541
+ optionalString(value.windowTitle, "windowTitle");
538
542
  optionalString(value.sourceUrl, "sourceUrl");
539
543
  if (value.range !== void 0) {
540
544
  if (!isRecord2(value.range)) throw new Error("range must be an object.");
@@ -1385,7 +1389,7 @@ var CHAPTERS = {
1385
1389
  packaging: { id: "packaging", title: "Packaging and dependencies", priority: 4 }
1386
1390
  };
1387
1391
  function buildChangeTourManifest(startPath, options = {}) {
1388
- var _a, _b, _c, _d;
1392
+ var _a, _b, _c, _d, _e;
1389
1393
  const range = resolveBranchReviewRange(startPath, options.headRef, options.baseRef);
1390
1394
  const maxFileBytes = options.maxFileBytes ?? DEFAULT_MAX_TOUR_FILE_BYTES;
1391
1395
  const maxLineBytes = options.maxLineBytes ?? DEFAULT_MAX_TOUR_LINE_BYTES;
@@ -1457,7 +1461,8 @@ function buildChangeTourManifest(startPath, options = {}) {
1457
1461
  const manifest = {
1458
1462
  version: CHANGE_TOUR_MANIFEST_VERSION,
1459
1463
  title: ((_a = options.source) == null ? void 0 : _a.title) || ((_b = options.story) == null ? void 0 : _b.title) || options.title || `${range.headRef} against ${range.baseRef}`,
1460
- sourceUrl: ((_c = options.source) == null ? void 0 : _c.sourceUrl) || ((_d = options.story) == null ? void 0 : _d.sourceUrl) || options.sourceUrl,
1464
+ windowTitle: (_c = options.source) == null ? void 0 : _c.windowTitle,
1465
+ sourceUrl: ((_d = options.source) == null ? void 0 : _d.sourceUrl) || ((_e = options.story) == null ? void 0 : _e.sourceUrl) || options.sourceUrl,
1461
1466
  generatedAt: options.generatedAt || (/* @__PURE__ */ new Date()).toISOString(),
1462
1467
  range: {
1463
1468
  baseRef: range.baseRef,
@@ -3811,6 +3811,9 @@ var require_changeTour = __commonJS({
3811
3811
  }
3812
3812
  requireString(value.title, "title");
3813
3813
  requireString(value.generatedAt, "generatedAt");
3814
+ if (value.windowTitle !== void 0) {
3815
+ requireString(value.windowTitle, "windowTitle");
3816
+ }
3814
3817
  if (value.sourceUrl !== void 0) {
3815
3818
  requireString(value.sourceUrl, "sourceUrl");
3816
3819
  }
@@ -4103,8 +4106,9 @@ var require_changeTour = __commonJS({
4103
4106
  if (!isRecord22(value) || value.version !== CHANGE_TOUR_SOURCE_VERSION) {
4104
4107
  throw new Error("Unsupported or missing change-tour source version.");
4105
4108
  }
4106
- requireOnlyKeys(value, ["version", "title", "sourceUrl", "range", "anchors", "connections", "chapters", "coverage"], "source");
4109
+ requireOnlyKeys(value, ["version", "title", "windowTitle", "sourceUrl", "range", "anchors", "connections", "chapters", "coverage"], "source");
4107
4110
  optionalString(value.title, "title");
4111
+ optionalString(value.windowTitle, "windowTitle");
4108
4112
  optionalString(value.sourceUrl, "sourceUrl");
4109
4113
  if (value.range !== void 0) {
4110
4114
  if (!isRecord22(value.range)) throw new Error("range must be an object.");
@@ -4947,7 +4951,7 @@ var require_changeTour = __commonJS({
4947
4951
  packaging: { id: "packaging", title: "Packaging and dependencies", priority: 4 }
4948
4952
  };
4949
4953
  function buildChangeTourManifest(startPath, options = {}) {
4950
- var _a, _b, _c, _d;
4954
+ var _a, _b, _c, _d, _e;
4951
4955
  const range = resolveBranchReviewRange3(startPath, options.headRef, options.baseRef);
4952
4956
  const maxFileBytes = options.maxFileBytes ?? DEFAULT_MAX_TOUR_FILE_BYTES;
4953
4957
  const maxLineBytes = options.maxLineBytes ?? DEFAULT_MAX_TOUR_LINE_BYTES;
@@ -5019,7 +5023,8 @@ var require_changeTour = __commonJS({
5019
5023
  const manifest = {
5020
5024
  version: CHANGE_TOUR_MANIFEST_VERSION,
5021
5025
  title: ((_a = options.source) == null ? void 0 : _a.title) || ((_b = options.story) == null ? void 0 : _b.title) || options.title || `${range.headRef} against ${range.baseRef}`,
5022
- sourceUrl: ((_c = options.source) == null ? void 0 : _c.sourceUrl) || ((_d = options.story) == null ? void 0 : _d.sourceUrl) || options.sourceUrl,
5026
+ windowTitle: (_c = options.source) == null ? void 0 : _c.windowTitle,
5027
+ sourceUrl: ((_d = options.source) == null ? void 0 : _d.sourceUrl) || ((_e = options.story) == null ? void 0 : _e.sourceUrl) || options.sourceUrl,
5023
5028
  generatedAt: options.generatedAt || (/* @__PURE__ */ new Date()).toISOString(),
5024
5029
  range: {
5025
5030
  baseRef: range.baseRef,
@@ -5466,6 +5471,140 @@ var require_changeTour = __commonJS({
5466
5471
  }
5467
5472
  });
5468
5473
 
5474
+ // out/windowTitle.js
5475
+ var require_windowTitle = __commonJS({
5476
+ "out/windowTitle.js"(exports2, module2) {
5477
+ "use strict";
5478
+ var __defProp2 = Object.defineProperty;
5479
+ var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor;
5480
+ var __getOwnPropNames2 = Object.getOwnPropertyNames;
5481
+ var __hasOwnProp2 = Object.prototype.hasOwnProperty;
5482
+ var __export2 = (target, all) => {
5483
+ for (var name in all)
5484
+ __defProp2(target, name, { get: all[name], enumerable: true });
5485
+ };
5486
+ var __copyProps2 = (to, from, except, desc) => {
5487
+ if (from && typeof from === "object" || typeof from === "function") {
5488
+ for (let key of __getOwnPropNames2(from))
5489
+ if (!__hasOwnProp2.call(to, key) && key !== except)
5490
+ __defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable });
5491
+ }
5492
+ return to;
5493
+ };
5494
+ var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod);
5495
+ var windowTitle_exports2 = {};
5496
+ __export2(windowTitle_exports2, {
5497
+ MAX_WINDOW_TITLE_LENGTH: () => MAX_WINDOW_TITLE_LENGTH2,
5498
+ buildHistoryTitle: () => buildHistoryTitle3,
5499
+ buildHistoryTitleFromViewState: () => buildHistoryTitleFromViewState2,
5500
+ buildMultiPanelTitle: () => buildMultiPanelTitle2,
5501
+ buildStandaloneSessionTitle: () => buildStandaloneSessionTitle3,
5502
+ buildTourWindowTitle: () => buildTourWindowTitle3,
5503
+ buildTwoWayComparisonTitle: () => buildTwoWayComparisonTitle2,
5504
+ formatComparisonPair: () => formatComparisonPair2,
5505
+ truncateTitle: () => truncateTitle2
5506
+ });
5507
+ module2.exports = __toCommonJS2(windowTitle_exports2);
5508
+ var MAX_WINDOW_TITLE_LENGTH2 = 120;
5509
+ function truncateTitle2(text, max = MAX_WINDOW_TITLE_LENGTH2) {
5510
+ if (text.length <= max) {
5511
+ return text;
5512
+ }
5513
+ return `${text.slice(0, max - 1)}\u2026`;
5514
+ }
5515
+ function formatComparisonPair2(left, right) {
5516
+ return `${left} \u2194 ${right}`;
5517
+ }
5518
+ function buildMultiPanelTitle2(input) {
5519
+ const { panels, activePanelId, activePairIndex, panelIds } = input;
5520
+ if (panels.length === 0) {
5521
+ return "Multi-Panel Compare";
5522
+ }
5523
+ if (panels.length === 1) {
5524
+ return truncateTitle2(panels[0].label);
5525
+ }
5526
+ if (panels.length === 2) {
5527
+ return truncateTitle2(formatComparisonPair2(panels[0].label, panels[1].label));
5528
+ }
5529
+ const ids = panelIds ?? panels.map((_panel, index) => String(index));
5530
+ const activeIndex = activePanelId ? ids.findIndex((id) => id === activePanelId) : -1;
5531
+ if (activePairIndex !== null && activePairIndex !== void 0 && activePairIndex >= 0 && activePairIndex < panels.length - 1) {
5532
+ return truncateTitle2(formatComparisonPair2(
5533
+ panels[activePairIndex].label,
5534
+ panels[activePairIndex + 1].label
5535
+ ));
5536
+ }
5537
+ if (activeIndex >= 0) {
5538
+ const derivedPairIndex = activeIndex < panels.length - 1 ? activeIndex : Math.max(0, activeIndex - 1);
5539
+ return truncateTitle2(formatComparisonPair2(
5540
+ panels[derivedPairIndex].label,
5541
+ panels[derivedPairIndex + 1].label
5542
+ ));
5543
+ }
5544
+ return truncateTitle2(formatComparisonPair2(panels[0].label, panels[panels.length - 1].label));
5545
+ }
5546
+ function buildHistoryTitle3(fileName, options) {
5547
+ const parts = [`${fileName} History`];
5548
+ if (options == null ? void 0 : options.shortCommit) {
5549
+ parts.push(options.shortCommit);
5550
+ }
5551
+ if (options == null ? void 0 : options.positionLabel) {
5552
+ parts.push(`(${options.positionLabel})`);
5553
+ }
5554
+ return truncateTitle2(parts.join(" \u2014 "));
5555
+ }
5556
+ function buildHistoryTitleFromViewState2(fileName, history) {
5557
+ const shortCommit = history.rightCommitLabel.split(/\s+/)[0] || void 0;
5558
+ return buildHistoryTitle3(fileName, {
5559
+ shortCommit,
5560
+ positionLabel: history.positionLabel
5561
+ });
5562
+ }
5563
+ function buildTwoWayComparisonTitle2(left, right) {
5564
+ return truncateTitle2(formatComparisonPair2(left, right));
5565
+ }
5566
+ function buildTourWindowTitle3(manifest, appName = "Bygone") {
5567
+ var _a, _b;
5568
+ const label = ((_a = manifest == null ? void 0 : manifest.windowTitle) == null ? void 0 : _a.trim()) || ((_b = manifest == null ? void 0 : manifest.title) == null ? void 0 : _b.trim());
5569
+ return label ? truncateTitle2(label) : `${appName} Tour`;
5570
+ }
5571
+ function buildStandaloneSessionTitle3(session2) {
5572
+ var _a, _b, _c, _d;
5573
+ if (session2.mode === "multi-diff" && session2.multi) {
5574
+ return buildMultiPanelTitle2({
5575
+ panels: session2.multi.files,
5576
+ activePanelId: session2.multi.activePanelId,
5577
+ activePairIndex: session2.multi.activePairIndex,
5578
+ panelIds: session2.multi.files.map((file) => file.id)
5579
+ });
5580
+ }
5581
+ if (session2.mode === "history" && ((_a = session2.history) == null ? void 0 : _a.filePath)) {
5582
+ const entry = (_b = session2.history.entries) == null ? void 0 : _b[session2.history.index ?? 0];
5583
+ return buildHistoryTitle3(
5584
+ session2.history.filePath.split("/").pop() || "File",
5585
+ { shortCommit: entry == null ? void 0 : entry.shortCommit }
5586
+ );
5587
+ }
5588
+ if (session2.mode === "directory-history" && session2.dirHistory) {
5589
+ const name = session2.dirHistory.displayName || session2.dirHistory.viewRelativePath || "Directory";
5590
+ return truncateTitle2(`${name} Directory History`);
5591
+ }
5592
+ if (session2.mode === "directory" && session2.directory) {
5593
+ if ((_c = session2.directory.review) == null ? void 0 : _c.headRef) {
5594
+ return truncateTitle2(`${session2.directory.review.headRef} Branch Change`);
5595
+ }
5596
+ if ((_d = session2.directory.labels) == null ? void 0 : _d.length) {
5597
+ return truncateTitle2(session2.directory.labels.join(" \u2194 "));
5598
+ }
5599
+ }
5600
+ if (session2.left && session2.right) {
5601
+ return buildTwoWayComparisonTitle2(session2.left.label, session2.right.label);
5602
+ }
5603
+ return "Compare";
5604
+ }
5605
+ }
5606
+ });
5607
+
5469
5608
  // node_modules/js-yaml/lib/common.js
5470
5609
  var require_common = __commonJS({
5471
5610
  "node_modules/js-yaml/lib/common.js"(exports2, module2) {
@@ -8594,6 +8733,7 @@ var require_present = __commonJS({
8594
8733
  var path9 = require("path");
8595
8734
  var { spawn: spawn2 } = require("child_process");
8596
8735
  var { buildChangeTourManifest, parseChangeTourStory } = require_changeTour();
8736
+ var { buildTourWindowTitle: buildTourWindowTitle3 } = require_windowTitle();
8597
8737
  var { tokenMatches: tokenMatches2 } = require_commandSpec();
8598
8738
  var { loadTourSource } = require_tourFile();
8599
8739
  var MIME_TYPES = /* @__PURE__ */ new Map([
@@ -8627,6 +8767,9 @@ var require_present = __commonJS({
8627
8767
  process.stdout.write(`Wrote change-tour manifest to ${resolvedOutput}
8628
8768
  `);
8629
8769
  }
8770
+ const tourWindowTitle = buildTourWindowTitle3(manifest, "Bygone");
8771
+ const presenterIndexPath = path9.join(packageRoot2, "web", "index.html");
8772
+ let presenterIndexTemplate;
8630
8773
  const server = createServer((request, response) => {
8631
8774
  const requestUrl = new URL(request.url || "/", "http://127.0.0.1");
8632
8775
  if (requestUrl.pathname === "/tour.json") {
@@ -8637,6 +8780,21 @@ var require_present = __commonJS({
8637
8780
  response.end(serializedManifest);
8638
8781
  return;
8639
8782
  }
8783
+ if (requestUrl.pathname === "/" || requestUrl.pathname === "/index.html") {
8784
+ if (!presenterIndexTemplate) {
8785
+ presenterIndexTemplate = readFileSync5(presenterIndexPath, "utf8");
8786
+ }
8787
+ const html = presenterIndexTemplate.replace(
8788
+ /<title>Bygone Tour<\/title>/,
8789
+ `<title>${escapeHtml(tourWindowTitle)}</title>`
8790
+ );
8791
+ response.writeHead(200, {
8792
+ "Content-Type": "text/html; charset=utf-8",
8793
+ "Cache-Control": "no-store"
8794
+ });
8795
+ response.end(html);
8796
+ return;
8797
+ }
8640
8798
  const targetPath = resolveAssetPath(packageRoot2, requestUrl.pathname);
8641
8799
  if (!targetPath) {
8642
8800
  respond(response, 404, "Not found");
@@ -8707,7 +8865,7 @@ var require_present = __commonJS({
8707
8865
  }
8708
8866
  function resolveAssetPath(packageRoot2, requestPath) {
8709
8867
  if (requestPath === "/" || requestPath === "/index.html") {
8710
- return path9.join(packageRoot2, "web", "index.html");
8868
+ return null;
8711
8869
  }
8712
8870
  if (!requestPath.startsWith("/web/") && !requestPath.startsWith("/media/")) {
8713
8871
  return null;
@@ -8739,9 +8897,13 @@ var require_present = __commonJS({
8739
8897
  }
8740
8898
  response.end(message);
8741
8899
  }
8900
+ function escapeHtml(text) {
8901
+ return text.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;");
8902
+ }
8742
8903
  module2.exports = {
8743
8904
  parsePresentArgs,
8744
- startPresentation: startPresentation2
8905
+ startPresentation: startPresentation2,
8906
+ escapeHtml
8745
8907
  };
8746
8908
  }
8747
8909
  });
@@ -8789,6 +8951,121 @@ var require_launchArgs = __commonJS({
8789
8951
  }
8790
8952
  });
8791
8953
 
8954
+ // src/windowTitle.ts
8955
+ var windowTitle_exports = {};
8956
+ __export(windowTitle_exports, {
8957
+ MAX_WINDOW_TITLE_LENGTH: () => MAX_WINDOW_TITLE_LENGTH,
8958
+ buildHistoryTitle: () => buildHistoryTitle,
8959
+ buildHistoryTitleFromViewState: () => buildHistoryTitleFromViewState,
8960
+ buildMultiPanelTitle: () => buildMultiPanelTitle,
8961
+ buildStandaloneSessionTitle: () => buildStandaloneSessionTitle,
8962
+ buildTourWindowTitle: () => buildTourWindowTitle,
8963
+ buildTwoWayComparisonTitle: () => buildTwoWayComparisonTitle,
8964
+ formatComparisonPair: () => formatComparisonPair,
8965
+ truncateTitle: () => truncateTitle
8966
+ });
8967
+ function truncateTitle(text, max = MAX_WINDOW_TITLE_LENGTH) {
8968
+ if (text.length <= max) {
8969
+ return text;
8970
+ }
8971
+ return `${text.slice(0, max - 1)}\u2026`;
8972
+ }
8973
+ function formatComparisonPair(left, right) {
8974
+ return `${left} \u2194 ${right}`;
8975
+ }
8976
+ function buildMultiPanelTitle(input) {
8977
+ const { panels, activePanelId, activePairIndex, panelIds } = input;
8978
+ if (panels.length === 0) {
8979
+ return "Multi-Panel Compare";
8980
+ }
8981
+ if (panels.length === 1) {
8982
+ return truncateTitle(panels[0].label);
8983
+ }
8984
+ if (panels.length === 2) {
8985
+ return truncateTitle(formatComparisonPair(panels[0].label, panels[1].label));
8986
+ }
8987
+ const ids = panelIds ?? panels.map((_panel, index) => String(index));
8988
+ const activeIndex = activePanelId ? ids.findIndex((id) => id === activePanelId) : -1;
8989
+ if (activePairIndex !== null && activePairIndex !== void 0 && activePairIndex >= 0 && activePairIndex < panels.length - 1) {
8990
+ return truncateTitle(formatComparisonPair(
8991
+ panels[activePairIndex].label,
8992
+ panels[activePairIndex + 1].label
8993
+ ));
8994
+ }
8995
+ if (activeIndex >= 0) {
8996
+ const derivedPairIndex = activeIndex < panels.length - 1 ? activeIndex : Math.max(0, activeIndex - 1);
8997
+ return truncateTitle(formatComparisonPair(
8998
+ panels[derivedPairIndex].label,
8999
+ panels[derivedPairIndex + 1].label
9000
+ ));
9001
+ }
9002
+ return truncateTitle(formatComparisonPair(panels[0].label, panels[panels.length - 1].label));
9003
+ }
9004
+ function buildHistoryTitle(fileName, options) {
9005
+ const parts = [`${fileName} History`];
9006
+ if (options?.shortCommit) {
9007
+ parts.push(options.shortCommit);
9008
+ }
9009
+ if (options?.positionLabel) {
9010
+ parts.push(`(${options.positionLabel})`);
9011
+ }
9012
+ return truncateTitle(parts.join(" \u2014 "));
9013
+ }
9014
+ function buildHistoryTitleFromViewState(fileName, history) {
9015
+ const shortCommit = history.rightCommitLabel.split(/\s+/)[0] || void 0;
9016
+ return buildHistoryTitle(fileName, {
9017
+ shortCommit,
9018
+ positionLabel: history.positionLabel
9019
+ });
9020
+ }
9021
+ function buildTwoWayComparisonTitle(left, right) {
9022
+ return truncateTitle(formatComparisonPair(left, right));
9023
+ }
9024
+ function buildTourWindowTitle(manifest, appName = "Bygone") {
9025
+ const label = manifest?.windowTitle?.trim() || manifest?.title?.trim();
9026
+ return label ? truncateTitle(label) : `${appName} Tour`;
9027
+ }
9028
+ function buildStandaloneSessionTitle(session2) {
9029
+ if (session2.mode === "multi-diff" && session2.multi) {
9030
+ return buildMultiPanelTitle({
9031
+ panels: session2.multi.files,
9032
+ activePanelId: session2.multi.activePanelId,
9033
+ activePairIndex: session2.multi.activePairIndex,
9034
+ panelIds: session2.multi.files.map((file) => file.id)
9035
+ });
9036
+ }
9037
+ if (session2.mode === "history" && session2.history?.filePath) {
9038
+ const entry = session2.history.entries?.[session2.history.index ?? 0];
9039
+ return buildHistoryTitle(
9040
+ session2.history.filePath.split("/").pop() || "File",
9041
+ { shortCommit: entry?.shortCommit }
9042
+ );
9043
+ }
9044
+ if (session2.mode === "directory-history" && session2.dirHistory) {
9045
+ const name = session2.dirHistory.displayName || session2.dirHistory.viewRelativePath || "Directory";
9046
+ return truncateTitle(`${name} Directory History`);
9047
+ }
9048
+ if (session2.mode === "directory" && session2.directory) {
9049
+ if (session2.directory.review?.headRef) {
9050
+ return truncateTitle(`${session2.directory.review.headRef} Branch Change`);
9051
+ }
9052
+ if (session2.directory.labels?.length) {
9053
+ return truncateTitle(session2.directory.labels.join(" \u2194 "));
9054
+ }
9055
+ }
9056
+ if (session2.left && session2.right) {
9057
+ return buildTwoWayComparisonTitle(session2.left.label, session2.right.label);
9058
+ }
9059
+ return "Compare";
9060
+ }
9061
+ var MAX_WINDOW_TITLE_LENGTH;
9062
+ var init_windowTitle = __esm({
9063
+ "src/windowTitle.ts"() {
9064
+ "use strict";
9065
+ MAX_WINDOW_TITLE_LENGTH = 120;
9066
+ }
9067
+ });
9068
+
8792
9069
  // package.json
8793
9070
  var require_package = __commonJS({
8794
9071
  "package.json"(exports2, module2) {
@@ -8798,7 +9075,7 @@ var require_package = __commonJS({
8798
9075
  displayName: "Bygone",
8799
9076
  desktopName: "com.davidmashburn.bygone.desktop",
8800
9077
  description: "See how change happened. Visual diff and file history for VS Code.",
8801
- version: "0.8.5",
9078
+ version: "0.8.6",
8802
9079
  author: "David Mashburn",
8803
9080
  license: "MIT",
8804
9081
  private: false,
@@ -22047,6 +22324,11 @@ var { tokenMatches, tokensFor } = require_commandSpec();
22047
22324
  var { startPresentation } = require_present();
22048
22325
  var { resolveWorkingDirectory } = require_workingDirectory();
22049
22326
  var { getCliArgsFromArgv, getForwardedLaunchArgs } = require_launchArgs();
22327
+ var {
22328
+ buildHistoryTitle: buildHistoryTitle2,
22329
+ buildStandaloneSessionTitle: buildStandaloneSessionTitle2,
22330
+ buildTourWindowTitle: buildTourWindowTitle2
22331
+ } = (init_windowTitle(), __toCommonJS(windowTitle_exports));
22050
22332
  var APP_NAME = "Bygone";
22051
22333
  var APP_VERSION = require_package().version;
22052
22334
  var HELP_URL = "https://github.com/davidmashburn/bygone";
@@ -22281,7 +22563,7 @@ async function openTourPresentation(args, cwd) {
22281
22563
  });
22282
22564
  activeTourServers.add(presentation.server);
22283
22565
  try {
22284
- await showTourWindow(presentation.url, presentation.server);
22566
+ await showTourWindow(presentation.url, presentation.server, presentation.manifest);
22285
22567
  } catch (error) {
22286
22568
  closeTourServer(presentation.server);
22287
22569
  throw error;
@@ -22291,7 +22573,7 @@ async function openAuthoredTourDocument(sourcePath) {
22291
22573
  const document2 = discoverAuthoredTourDocument2(sourcePath);
22292
22574
  await openTourPresentation(["--tour", document2.documentPath], document2.repoRoot);
22293
22575
  }
22294
- async function showTourWindow(url, server) {
22576
+ async function showTourWindow(url, server, manifest) {
22295
22577
  const parsedUrl = new URL(url);
22296
22578
  if (parsedUrl.protocol !== "http:" || parsedUrl.hostname !== "127.0.0.1") {
22297
22579
  throw new Error("Tour presenter URL must use the local Bygone server.");
@@ -22303,7 +22585,7 @@ async function showTourWindow(url, server) {
22303
22585
  minWidth: 960,
22304
22586
  minHeight: 640,
22305
22587
  show: false,
22306
- title: `${APP_NAME} Tour`,
22588
+ title: buildTourWindowTitle2(manifest, APP_NAME),
22307
22589
  webPreferences: {
22308
22590
  sandbox: true,
22309
22591
  contextIsolation: true,
@@ -22341,12 +22623,24 @@ async function showTourWindow(url, server) {
22341
22623
  latestTourWindow = getLatestTourWindow();
22342
22624
  }
22343
22625
  });
22626
+ const tourWindowTitle = buildTourWindowTitle2(manifest, APP_NAME);
22627
+ const applyTourWindowTitle = () => {
22628
+ if (!tourWindow.isDestroyed()) {
22629
+ tourWindow.setTitle(tourWindowTitle);
22630
+ }
22631
+ };
22632
+ tourWindow.webContents.on("page-title-updated", (event) => {
22633
+ event.preventDefault();
22634
+ queueMicrotask(applyTourWindowTitle);
22635
+ });
22636
+ tourWindow.webContents.on("did-finish-load", applyTourWindowTitle);
22344
22637
  try {
22345
22638
  await tourWindow.loadURL(url);
22346
22639
  } catch (error) {
22347
22640
  tourWindow.destroy();
22348
22641
  throw error;
22349
22642
  }
22643
+ applyTourWindowTitle();
22350
22644
  tourWindow.show();
22351
22645
  tourWindow.focus();
22352
22646
  return tourWindow;
@@ -23435,11 +23729,15 @@ async function handleRendererMessage(message) {
23435
23729
  return;
23436
23730
  }
23437
23731
  if (message.type === "multiSetActivePanel" && typeof message.panelId === "string") {
23438
- setActiveMultiPanel(message.panelId);
23732
+ if (setActiveMultiPanel(message.panelId)) {
23733
+ refreshSessionWindowTitle();
23734
+ }
23439
23735
  return;
23440
23736
  }
23441
23737
  if (message.type === "multiSetActivePair" && Number.isInteger(message.pairIndex)) {
23442
- setActiveMultiPair(message.pairIndex);
23738
+ if (setActiveMultiPair(message.pairIndex)) {
23739
+ refreshSessionWindowTitle();
23740
+ }
23443
23741
  return;
23444
23742
  }
23445
23743
  if (message.type === "multiAddPanel" && typeof message.anchorPanelId === "string" && (message.side === "left" || message.side === "right")) {
@@ -23463,7 +23761,7 @@ async function handleRendererMessage(message) {
23463
23761
  if (panel) {
23464
23762
  panel.content = message.content;
23465
23763
  panel.dirty = panel.content !== panel.savedContent;
23466
- updateWindowTitle(session.multi.files.map((file) => file.label).join(" \u2194 ") || "Multi-Panel Compare");
23764
+ refreshSessionWindowTitle();
23467
23765
  }
23468
23766
  return;
23469
23767
  }
@@ -24117,7 +24415,7 @@ async function sendCurrentDirectoryDiff() {
24117
24415
  canMutate: !review && session.source?.kind === "directories",
24118
24416
  review: buildReviewViewState(review)
24119
24417
  });
24120
- updateWindowTitle(review ? `${review.headRef} Branch Change` : session.directory.labels.join(" \u2194 "));
24418
+ refreshSessionWindowTitle();
24121
24419
  if (launchArguments.kind === "smoke-directory" && mainWindow && !mainWindow.isDestroyed()) {
24122
24420
  setTimeout(() => {
24123
24421
  void mainWindow.webContents.executeJavaScript(`document.querySelector('.dir-entry[data-is-dir="false"]')?.click()`);
@@ -24182,7 +24480,7 @@ async function sendCurrentDirectoryHistoryEntry() {
24182
24480
  fileNavigation: buildDirectoryHistoryFileNavigationState(session.dirHistory, entry),
24183
24481
  canReturnToDirectory: true
24184
24482
  });
24185
- updateWindowTitle(`${relativePath} Directory History`);
24483
+ refreshSessionWindowTitle();
24186
24484
  scheduleCaptureIfNeeded();
24187
24485
  return;
24188
24486
  }
@@ -24206,7 +24504,7 @@ async function sendCurrentDirectoryHistoryEntry() {
24206
24504
  history,
24207
24505
  canMutate: true
24208
24506
  });
24209
- updateWindowTitle(`${session.dirHistory.displayName} Directory History`);
24507
+ refreshSessionWindowTitle();
24210
24508
  scheduleCaptureIfNeeded();
24211
24509
  }
24212
24510
  function buildDirectoryHistoryViewState(dirHistory, entry) {
@@ -25377,7 +25675,7 @@ async function sendCurrentMultiDiff() {
25377
25675
  fileNavigation: buildStandaloneFileNavigationState(),
25378
25676
  mutationEnabled: !isDirectoryDrilldown
25379
25677
  });
25380
- updateWindowTitle(panels.map((panel) => panel.label).join(" \u2194 ") || "Multi-Panel Compare");
25678
+ refreshSessionWindowTitle();
25381
25679
  if (mainWindow && !mainWindow.isDestroyed()) {
25382
25680
  setTimeout(() => {
25383
25681
  void mainWindow.webContents.executeJavaScript(`(() => ({
@@ -25495,7 +25793,7 @@ async function sendCurrentDiff() {
25495
25793
  directoryNavigation: buildDirectoryDrilldownNavigationState(),
25496
25794
  canReturnToDirectory: Boolean(session.returnDirectory)
25497
25795
  });
25498
- updateWindowTitle(`${session.left.label} \u2194 ${session.right.label}`);
25796
+ refreshSessionWindowTitle();
25499
25797
  scheduleCaptureIfNeeded();
25500
25798
  return;
25501
25799
  }
@@ -25523,7 +25821,7 @@ async function sendCurrentDiff() {
25523
25821
  comparisonSummary: session.returnDirectory?.comparisonSummary
25524
25822
  };
25525
25823
  postOrQueue(message);
25526
- updateWindowTitle(`${session.left.label} \u2194 ${session.right.label}`);
25824
+ refreshSessionWindowTitle();
25527
25825
  if (mainWindow && !mainWindow.isDestroyed()) {
25528
25826
  setTimeout(() => {
25529
25827
  void mainWindow.webContents.executeJavaScript(`(() => ({
@@ -25611,7 +25909,7 @@ async function sendCurrentHistoryEntry() {
25611
25909
  rail
25612
25910
  }
25613
25911
  });
25614
- updateWindowTitle(`${fileName} History`);
25912
+ refreshSessionWindowTitle();
25615
25913
  if (mainWindow && !mainWindow.isDestroyed()) {
25616
25914
  setTimeout(() => {
25617
25915
  void mainWindow.webContents.executeJavaScript(`(() => ({
@@ -25931,7 +26229,7 @@ async function saveDirtyMultiPanels() {
25931
26229
  }
25932
26230
  updateWatchers();
25933
26231
  await sendCurrentMultiDiff();
25934
- updateWindowTitle(session.multi.files.map((file) => file.label).join(" \u2194 ") || "Multi-Panel Compare");
26232
+ refreshSessionWindowTitle();
25935
26233
  return true;
25936
26234
  }
25937
26235
  async function saveMultiPanel(panel, { dialogTitle, refreshView }) {
@@ -25957,7 +26255,7 @@ async function saveMultiPanel(panel, { dialogTitle, refreshView }) {
25957
26255
  if (refreshView) {
25958
26256
  updateWatchers();
25959
26257
  await sendCurrentMultiDiff();
25960
- updateWindowTitle(session.multi.files.map((file) => file.label).join(" \u2194 ") || "Multi-Panel Compare");
26258
+ refreshSessionWindowTitle();
25961
26259
  }
25962
26260
  return true;
25963
26261
  }
@@ -26071,6 +26369,20 @@ function updateWindowTitle(title) {
26071
26369
  const dirtySuffix = hasUnsavedChanges() ? " \u2022 Unsaved" : "";
26072
26370
  mainWindow.setTitle(`${APP_NAME} \u2014 ${title}${dirtySuffix}`);
26073
26371
  }
26372
+ function refreshSessionWindowTitle() {
26373
+ if (session.mode === "history" && session.history) {
26374
+ const visibleIndices = getVisibleFileHistoryIndices(session.history);
26375
+ const visiblePosition = visibleIndices.indexOf(session.history.index);
26376
+ const entry = session.history.entries[session.history.index];
26377
+ const fileName = path8.basename(session.history.filePath);
26378
+ updateWindowTitle(buildHistoryTitle2(fileName, {
26379
+ shortCommit: entry?.shortCommit,
26380
+ positionLabel: visiblePosition >= 0 ? `${visiblePosition + 1} / ${visibleIndices.length}` : void 0
26381
+ }));
26382
+ return;
26383
+ }
26384
+ updateWindowTitle(buildStandaloneSessionTitle2(session));
26385
+ }
26074
26386
  async function confirmSessionReplacement(action) {
26075
26387
  if (!hasUnsavedChanges()) {
26076
26388
  return true;
@@ -481,6 +481,9 @@ function parseChangeTourManifest(value) {
481
481
  }
482
482
  requireString(value.title, "title");
483
483
  requireString(value.generatedAt, "generatedAt");
484
+ if (value.windowTitle !== void 0) {
485
+ requireString(value.windowTitle, "windowTitle");
486
+ }
484
487
  if (value.sourceUrl !== void 0) {
485
488
  requireString(value.sourceUrl, "sourceUrl");
486
489
  }
@@ -744,8 +747,9 @@ function parseChangeTourSource(value) {
744
747
  if (!isRecord2(value) || value.version !== CHANGE_TOUR_SOURCE_VERSION) {
745
748
  throw new Error("Unsupported or missing change-tour source version.");
746
749
  }
747
- requireOnlyKeys(value, ["version", "title", "sourceUrl", "range", "anchors", "connections", "chapters", "coverage"], "source");
750
+ requireOnlyKeys(value, ["version", "title", "windowTitle", "sourceUrl", "range", "anchors", "connections", "chapters", "coverage"], "source");
748
751
  optionalString(value.title, "title");
752
+ optionalString(value.windowTitle, "windowTitle");
749
753
  optionalString(value.sourceUrl, "sourceUrl");
750
754
  if (value.range !== void 0) {
751
755
  if (!isRecord2(value.range)) throw new Error("range must be an object.");
@@ -1162,7 +1166,7 @@ var CHAPTERS = {
1162
1166
  packaging: { id: "packaging", title: "Packaging and dependencies", priority: 4 }
1163
1167
  };
1164
1168
  function buildChangeTourManifest(startPath, options = {}) {
1165
- var _a, _b, _c, _d;
1169
+ var _a, _b, _c, _d, _e;
1166
1170
  const range = resolveBranchReviewRange(startPath, options.headRef, options.baseRef);
1167
1171
  const maxFileBytes = options.maxFileBytes ?? DEFAULT_MAX_TOUR_FILE_BYTES;
1168
1172
  const maxLineBytes = options.maxLineBytes ?? DEFAULT_MAX_TOUR_LINE_BYTES;
@@ -1234,7 +1238,8 @@ function buildChangeTourManifest(startPath, options = {}) {
1234
1238
  const manifest = {
1235
1239
  version: CHANGE_TOUR_MANIFEST_VERSION,
1236
1240
  title: ((_a = options.source) == null ? void 0 : _a.title) || ((_b = options.story) == null ? void 0 : _b.title) || options.title || `${range.headRef} against ${range.baseRef}`,
1237
- sourceUrl: ((_c = options.source) == null ? void 0 : _c.sourceUrl) || ((_d = options.story) == null ? void 0 : _d.sourceUrl) || options.sourceUrl,
1241
+ windowTitle: (_c = options.source) == null ? void 0 : _c.windowTitle,
1242
+ sourceUrl: ((_d = options.source) == null ? void 0 : _d.sourceUrl) || ((_e = options.story) == null ? void 0 : _e.sourceUrl) || options.sourceUrl,
1238
1243
  generatedAt: options.generatedAt || (/* @__PURE__ */ new Date()).toISOString(),
1239
1244
  range: {
1240
1245
  baseRef: range.baseRef,
@@ -0,0 +1,143 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/windowTitle.ts
21
+ var windowTitle_exports = {};
22
+ __export(windowTitle_exports, {
23
+ MAX_WINDOW_TITLE_LENGTH: () => MAX_WINDOW_TITLE_LENGTH,
24
+ buildHistoryTitle: () => buildHistoryTitle,
25
+ buildHistoryTitleFromViewState: () => buildHistoryTitleFromViewState,
26
+ buildMultiPanelTitle: () => buildMultiPanelTitle,
27
+ buildStandaloneSessionTitle: () => buildStandaloneSessionTitle,
28
+ buildTourWindowTitle: () => buildTourWindowTitle,
29
+ buildTwoWayComparisonTitle: () => buildTwoWayComparisonTitle,
30
+ formatComparisonPair: () => formatComparisonPair,
31
+ truncateTitle: () => truncateTitle
32
+ });
33
+ module.exports = __toCommonJS(windowTitle_exports);
34
+ var MAX_WINDOW_TITLE_LENGTH = 120;
35
+ function truncateTitle(text, max = MAX_WINDOW_TITLE_LENGTH) {
36
+ if (text.length <= max) {
37
+ return text;
38
+ }
39
+ return `${text.slice(0, max - 1)}\u2026`;
40
+ }
41
+ function formatComparisonPair(left, right) {
42
+ return `${left} \u2194 ${right}`;
43
+ }
44
+ function buildMultiPanelTitle(input) {
45
+ const { panels, activePanelId, activePairIndex, panelIds } = input;
46
+ if (panels.length === 0) {
47
+ return "Multi-Panel Compare";
48
+ }
49
+ if (panels.length === 1) {
50
+ return truncateTitle(panels[0].label);
51
+ }
52
+ if (panels.length === 2) {
53
+ return truncateTitle(formatComparisonPair(panels[0].label, panels[1].label));
54
+ }
55
+ const ids = panelIds ?? panels.map((_panel, index) => String(index));
56
+ const activeIndex = activePanelId ? ids.findIndex((id) => id === activePanelId) : -1;
57
+ if (activePairIndex !== null && activePairIndex !== void 0 && activePairIndex >= 0 && activePairIndex < panels.length - 1) {
58
+ return truncateTitle(formatComparisonPair(
59
+ panels[activePairIndex].label,
60
+ panels[activePairIndex + 1].label
61
+ ));
62
+ }
63
+ if (activeIndex >= 0) {
64
+ const derivedPairIndex = activeIndex < panels.length - 1 ? activeIndex : Math.max(0, activeIndex - 1);
65
+ return truncateTitle(formatComparisonPair(
66
+ panels[derivedPairIndex].label,
67
+ panels[derivedPairIndex + 1].label
68
+ ));
69
+ }
70
+ return truncateTitle(formatComparisonPair(panels[0].label, panels[panels.length - 1].label));
71
+ }
72
+ function buildHistoryTitle(fileName, options) {
73
+ const parts = [`${fileName} History`];
74
+ if (options == null ? void 0 : options.shortCommit) {
75
+ parts.push(options.shortCommit);
76
+ }
77
+ if (options == null ? void 0 : options.positionLabel) {
78
+ parts.push(`(${options.positionLabel})`);
79
+ }
80
+ return truncateTitle(parts.join(" \u2014 "));
81
+ }
82
+ function buildHistoryTitleFromViewState(fileName, history) {
83
+ const shortCommit = history.rightCommitLabel.split(/\s+/)[0] || void 0;
84
+ return buildHistoryTitle(fileName, {
85
+ shortCommit,
86
+ positionLabel: history.positionLabel
87
+ });
88
+ }
89
+ function buildTwoWayComparisonTitle(left, right) {
90
+ return truncateTitle(formatComparisonPair(left, right));
91
+ }
92
+ function buildTourWindowTitle(manifest, appName = "Bygone") {
93
+ var _a, _b;
94
+ const label = ((_a = manifest == null ? void 0 : manifest.windowTitle) == null ? void 0 : _a.trim()) || ((_b = manifest == null ? void 0 : manifest.title) == null ? void 0 : _b.trim());
95
+ return label ? truncateTitle(label) : `${appName} Tour`;
96
+ }
97
+ function buildStandaloneSessionTitle(session) {
98
+ var _a, _b, _c, _d;
99
+ if (session.mode === "multi-diff" && session.multi) {
100
+ return buildMultiPanelTitle({
101
+ panels: session.multi.files,
102
+ activePanelId: session.multi.activePanelId,
103
+ activePairIndex: session.multi.activePairIndex,
104
+ panelIds: session.multi.files.map((file) => file.id)
105
+ });
106
+ }
107
+ if (session.mode === "history" && ((_a = session.history) == null ? void 0 : _a.filePath)) {
108
+ const entry = (_b = session.history.entries) == null ? void 0 : _b[session.history.index ?? 0];
109
+ return buildHistoryTitle(
110
+ session.history.filePath.split("/").pop() || "File",
111
+ { shortCommit: entry == null ? void 0 : entry.shortCommit }
112
+ );
113
+ }
114
+ if (session.mode === "directory-history" && session.dirHistory) {
115
+ const name = session.dirHistory.displayName || session.dirHistory.viewRelativePath || "Directory";
116
+ return truncateTitle(`${name} Directory History`);
117
+ }
118
+ if (session.mode === "directory" && session.directory) {
119
+ if ((_c = session.directory.review) == null ? void 0 : _c.headRef) {
120
+ return truncateTitle(`${session.directory.review.headRef} Branch Change`);
121
+ }
122
+ if ((_d = session.directory.labels) == null ? void 0 : _d.length) {
123
+ return truncateTitle(session.directory.labels.join(" \u2194 "));
124
+ }
125
+ }
126
+ if (session.left && session.right) {
127
+ return buildTwoWayComparisonTitle(session.left.label, session.right.label);
128
+ }
129
+ return "Compare";
130
+ }
131
+ // Annotate the CommonJS export names for ESM import in node:
132
+ 0 && (module.exports = {
133
+ MAX_WINDOW_TITLE_LENGTH,
134
+ buildHistoryTitle,
135
+ buildHistoryTitleFromViewState,
136
+ buildMultiPanelTitle,
137
+ buildStandaloneSessionTitle,
138
+ buildTourWindowTitle,
139
+ buildTwoWayComparisonTitle,
140
+ formatComparisonPair,
141
+ truncateTitle
142
+ });
143
+ //# sourceMappingURL=windowTitle.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@davmash/bygone",
3
- "version": "0.8.5",
3
+ "version": "0.8.6",
4
4
  "description": "See how change happened. Visual diff and file history.",
5
5
  "author": "David Mashburn",
6
6
  "license": "MIT",
@@ -9,6 +9,10 @@
9
9
  "properties": {
10
10
  "version": { "const": 1 },
11
11
  "title": { "$ref": "#/$defs/nonEmptyString" },
12
+ "windowTitle": {
13
+ "$ref": "#/$defs/nonEmptyString",
14
+ "description": "Optional native window title for the tour presenter. Use a short label such as a pull request number when multiple tours may be open."
15
+ },
12
16
  "sourceUrl": { "type": "string", "minLength": 1 },
13
17
  "range": {
14
18
  "type": "object",
@@ -171,6 +171,10 @@ context, and keep the file within the corresponding repository so Bygone can
171
171
  resolve those objects. Use a compiled `.tour.json` only when a portable
172
172
  snapshot is required.
173
173
 
174
+ Set optional `windowTitle` when the tour should appear in the native window
175
+ title — for example a pull request number (`PR-1234`) so multiple open tours
176
+ stay distinguishable. When omitted, the presenter falls back to `title`.
177
+
174
178
  For every step:
175
179
 
176
180
  - make one concise explanatory claim;
package/web/web-host.js CHANGED
@@ -1,7 +1,7 @@
1
- "use strict";(()=>{function V(){}V.prototype={diff:function(t,n){var r,s=arguments.length>2&&arguments[2]!==void 0?arguments[2]:{},a=s.callback;typeof s=="function"&&(a=s,s={}),this.options=s;var l=this;function i(N){return a?(setTimeout(function(){a(void 0,N)},0),!0):N}t=this.castInput(t),n=this.castInput(n),t=this.removeEmpty(this.tokenize(t)),n=this.removeEmpty(this.tokenize(n));var u=n.length,d=t.length,g=1,h=u+d;s.maxEditLength&&(h=Math.min(h,s.maxEditLength));var T=(r=s.timeout)!==null&&r!==void 0?r:1/0,L=Date.now()+T,C=[{oldPos:-1,lastComponent:void 0}],I=this.extractCommon(C[0],n,t,0);if(C[0].oldPos+1>=d&&I+1>=u)return i([{value:this.join(n),count:n.length}]);var w=-1/0,b=1/0;function x(){for(var N=Math.max(w,-g);N<=Math.min(b,g);N+=2){var _=void 0,M=C[N-1],O=C[N+1];M&&(C[N-1]=void 0);var B=!1;if(O){var ie=O.oldPos-N;B=O&&0<=ie&&ie<u}var fe=M&&M.oldPos+1<d;if(!B&&!fe){C[N]=void 0;continue}if(!fe||B&&M.oldPos+1<O.oldPos?_=l.addToPath(O,!0,void 0,0):_=l.addToPath(M,void 0,!0,1),I=l.extractCommon(_,n,t,N),_.oldPos+1>=d&&I+1>=u)return i(Vt(l,_.lastComponent,n,t,l.useLongestToken));C[N]=_,_.oldPos+1>=d&&(b=Math.min(b,N-1)),I+1>=u&&(w=Math.max(w,N+1))}g++}if(a)(function N(){setTimeout(function(){if(g>h||Date.now()>L)return a();x()||N()},0)})();else for(;g<=h&&Date.now()<=L;){var k=x();if(k)return k}},addToPath:function(t,n,r,s){var a=t.lastComponent;return a&&a.added===n&&a.removed===r?{oldPos:t.oldPos+s,lastComponent:{count:a.count+1,added:n,removed:r,previousComponent:a.previousComponent}}:{oldPos:t.oldPos+s,lastComponent:{count:1,added:n,removed:r,previousComponent:a}}},extractCommon:function(t,n,r,s){for(var a=n.length,l=r.length,i=t.oldPos,u=i-s,d=0;u+1<a&&i+1<l&&this.equals(n[u+1],r[i+1]);)u++,i++,d++;return d&&(t.lastComponent={count:d,previousComponent:t.lastComponent}),t.oldPos=i,u},equals:function(t,n){return this.options.comparator?this.options.comparator(t,n):t===n||this.options.ignoreCase&&t.toLowerCase()===n.toLowerCase()},removeEmpty:function(t){for(var n=[],r=0;r<t.length;r++)t[r]&&n.push(t[r]);return n},castInput:function(t){return t},tokenize:function(t){return t.split("")},join:function(t){return t.join("")}};function Vt(e,t,n,r,s){for(var a=[],l;t;)a.push(t),l=t.previousComponent,delete t.previousComponent,t=l;a.reverse();for(var i=0,u=a.length,d=0,g=0;i<u;i++){var h=a[i];if(h.removed){if(h.value=e.join(r.slice(g,g+h.count)),g+=h.count,i&&a[i-1].added){var L=a[i-1];a[i-1]=a[i],a[i]=L}}else{if(!h.added&&s){var T=n.slice(d,d+h.count);T=T.map(function(I,w){var b=r[g+w];return b.length>I.length?b:I}),h.value=e.join(T)}else h.value=e.join(n.slice(d,d+h.count));d+=h.count,h.added||(g+=h.count)}}var C=a[u-1];return u>1&&typeof C.value=="string"&&(C.added||C.removed)&&e.equals("",C.value)&&(a[u-2].value+=C.value,a.pop()),a}var Xt=new V;function Ze(e,t,n){return Xt.diff(e,t,n)}var Ye=/^[A-Za-z\xC0-\u02C6\u02C8-\u02D7\u02DE-\u02FF\u1E00-\u1EFF]+$/,Je=/\S/,Fe=new V;Fe.equals=function(e,t){return this.options.ignoreCase&&(e=e.toLowerCase(),t=t.toLowerCase()),e===t||this.options.ignoreWhitespace&&!Je.test(e)&&!Je.test(t)};Fe.tokenize=function(e){for(var t=e.split(/([^\S\r\n]+|[()[\]{}'"\r\n]|\b)/),n=0;n<t.length-1;n++)!t[n+1]&&t[n+2]&&Ye.test(t[n])&&Ye.test(t[n+2])&&(t[n]+=t[n+2],t.splice(n+1,2),n--);return t};function Qe(e,t,n){return Fe.diff(e,t,n)}var et=new V;et.tokenize=function(e){this.options.stripTrailingCr&&(e=e.replace(/\r\n/g,`
2
- `));var t=[],n=e.split(/(\n|\r\n)/);n[n.length-1]||n.pop();for(var r=0;r<n.length;r++){var s=n[r];r%2&&!this.options.newlineIsToken?t[t.length-1]+=s:(this.options.ignoreWhitespace&&(s=s.trim()),t.push(s))}return t};var Yt=new V;Yt.tokenize=function(e){return e.split(/(\S.+?[.!?])(?=\s+|$)/)};var Jt=new V;Jt.tokenize=function(e){return e.split(/([{}:;,]|\s+)/)};function ye(e){"@babel/helpers - typeof";return typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?ye=function(t){return typeof t}:ye=function(t){return t&&typeof Symbol=="function"&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},ye(e)}var Zt=Object.prototype.toString,le=new V;le.useLongestToken=!0;le.tokenize=et.tokenize;le.castInput=function(e){var t=this.options,n=t.undefinedReplacement,r=t.stringifyReplacer,s=r===void 0?function(a,l){return typeof l>"u"?n:l}:r;return typeof e=="string"?e:JSON.stringify(Re(e,null,null,s),s," ")};le.equals=function(e,t){return V.prototype.equals.call(le,e.replace(/,([\r\n])/g,"$1"),t.replace(/,([\r\n])/g,"$1"))};function Re(e,t,n,r,s){t=t||[],n=n||[],r&&(e=r(s,e));var a;for(a=0;a<t.length;a+=1)if(t[a]===e)return n[a];var l;if(Zt.call(e)==="[object Array]"){for(t.push(e),l=new Array(e.length),n.push(l),a=0;a<e.length;a+=1)l[a]=Re(e[a],t,n,r,s);return t.pop(),n.pop(),l}if(e&&e.toJSON&&(e=e.toJSON()),ye(e)==="object"&&e!==null){t.push(e),l={},n.push(l);var i=[],u;for(u in e)e.hasOwnProperty(u)&&i.push(u);for(i.sort(),a=0;a<i.length;a+=1)u=i[a],l[u]=Re(e[u],t,n,r,u);t.pop(),n.pop()}else l=e;return l}var Ie=new V;Ie.tokenize=function(e){return e.slice()};Ie.join=Ie.removeEmpty=function(e){return e};function tt(e,t,n){return Ie.diff(e,t,n)}var en=500,tn=100,nt=wt("BYGONE_MAX_INLINE_HIGHLIGHT_LINE_LENGTH",en),nn=wt("BYGONE_DIFF_TIMEOUT_MS",tn);function Q(e,t,n={}){let r=rt(e),s=rt(t),a=tt(r,s,{timeout:n.timeoutMs??nn});if(!a)return rn(r,s);let l=[],i=[],u=[],d=[],g=1,h=1;for(let L=0;L<a.length;L++){let C=a[L],I=C.removed?C.value:[],w=C.added?C.value:[];if(!C.added&&!C.removed){for(let b of C.value)i.push(Y("context",b,g)),u.push(Y("context",b,h)),l.push(re(X("context",b,g++),X("context",b,h++)));continue}if(C.removed&&L+1<a.length&&a[L+1].added){let b=a[L+1],x=i.length,k=u.length,N=pt(I,b.value);for(let{left:_,right:M}of N){let O,B;_!==void 0&&(O=Y("removed",_,g),i.push(O)),M!==void 0&&(B=Y("added",M,h),u.push(B)),O&&B&&En(O,B),l.push(re(_===void 0?ne():X("removed",_,g++),M===void 0?ne():X("added",M,h++)))}d.push(Se("replace",x,i.length,k,u.length)),L++;continue}if(C.removed){let b=i.length,x=u.length;for(let k of I)i.push(Y("removed",k,g)),l.push(re(X("removed",k,g++),ne()));d.push(Se("delete",b,i.length,x,u.length));continue}if(C.added){let b=i.length,x=u.length;for(let k of w)u.push(Y("added",k,h)),l.push(re(ne(),X("added",k,h++)));d.push(Se("insert",b,i.length,x,u.length))}}let T=l.some(L=>L.left.kind!=="context"||L.right.kind!=="context");return{rows:l,leftLines:i,rightLines:u,blocks:d,hasChanges:T}}function rn(e,t){let n=e.map((l,i)=>Y("removed",l,i+1)),r=t.map((l,i)=>Y("added",l,i+1)),s=[...e.map((l,i)=>re(X("removed",l,i+1),ne())),...t.map((l,i)=>re(ne(),X("added",l,i+1)))],a="replace";return e.length===0?a="insert":t.length===0&&(a="delete"),{rows:s,leftLines:n,rightLines:r,blocks:s.length===0?[]:[Se(a,0,e.length,0,t.length)],hasChanges:s.length>0}}function rt(e){if(e.length===0)return[];let t=e.replace(/\r\n/g,`
1
+ "use strict";(()=>{function V(){}V.prototype={diff:function(t,n){var r,s=arguments.length>2&&arguments[2]!==void 0?arguments[2]:{},a=s.callback;typeof s=="function"&&(a=s,s={}),this.options=s;var c=this;function i(N){return a?(setTimeout(function(){a(void 0,N)},0),!0):N}t=this.castInput(t),n=this.castInput(n),t=this.removeEmpty(this.tokenize(t)),n=this.removeEmpty(this.tokenize(n));var u=n.length,d=t.length,g=1,h=u+d;s.maxEditLength&&(h=Math.min(h,s.maxEditLength));var E=(r=s.timeout)!==null&&r!==void 0?r:1/0,L=Date.now()+E,C=[{oldPos:-1,lastComponent:void 0}],I=this.extractCommon(C[0],n,t,0);if(C[0].oldPos+1>=d&&I+1>=u)return i([{value:this.join(n),count:n.length}]);var w=-1/0,b=1/0;function x(){for(var N=Math.max(w,-g);N<=Math.min(b,g);N+=2){var _=void 0,F=C[N-1],O=C[N+1];F&&(C[N-1]=void 0);var B=!1;if(O){var ie=O.oldPos-N;B=O&&0<=ie&&ie<u}var fe=F&&F.oldPos+1<d;if(!B&&!fe){C[N]=void 0;continue}if(!fe||B&&F.oldPos+1<O.oldPos?_=c.addToPath(O,!0,void 0,0):_=c.addToPath(F,void 0,!0,1),I=c.extractCommon(_,n,t,N),_.oldPos+1>=d&&I+1>=u)return i(Xt(c,_.lastComponent,n,t,c.useLongestToken));C[N]=_,_.oldPos+1>=d&&(b=Math.min(b,N-1)),I+1>=u&&(w=Math.max(w,N+1))}g++}if(a)(function N(){setTimeout(function(){if(g>h||Date.now()>L)return a();x()||N()},0)})();else for(;g<=h&&Date.now()<=L;){var k=x();if(k)return k}},addToPath:function(t,n,r,s){var a=t.lastComponent;return a&&a.added===n&&a.removed===r?{oldPos:t.oldPos+s,lastComponent:{count:a.count+1,added:n,removed:r,previousComponent:a.previousComponent}}:{oldPos:t.oldPos+s,lastComponent:{count:1,added:n,removed:r,previousComponent:a}}},extractCommon:function(t,n,r,s){for(var a=n.length,c=r.length,i=t.oldPos,u=i-s,d=0;u+1<a&&i+1<c&&this.equals(n[u+1],r[i+1]);)u++,i++,d++;return d&&(t.lastComponent={count:d,previousComponent:t.lastComponent}),t.oldPos=i,u},equals:function(t,n){return this.options.comparator?this.options.comparator(t,n):t===n||this.options.ignoreCase&&t.toLowerCase()===n.toLowerCase()},removeEmpty:function(t){for(var n=[],r=0;r<t.length;r++)t[r]&&n.push(t[r]);return n},castInput:function(t){return t},tokenize:function(t){return t.split("")},join:function(t){return t.join("")}};function Xt(e,t,n,r,s){for(var a=[],c;t;)a.push(t),c=t.previousComponent,delete t.previousComponent,t=c;a.reverse();for(var i=0,u=a.length,d=0,g=0;i<u;i++){var h=a[i];if(h.removed){if(h.value=e.join(r.slice(g,g+h.count)),g+=h.count,i&&a[i-1].added){var L=a[i-1];a[i-1]=a[i],a[i]=L}}else{if(!h.added&&s){var E=n.slice(d,d+h.count);E=E.map(function(I,w){var b=r[g+w];return b.length>I.length?b:I}),h.value=e.join(E)}else h.value=e.join(n.slice(d,d+h.count));d+=h.count,h.added||(g+=h.count)}}var C=a[u-1];return u>1&&typeof C.value=="string"&&(C.added||C.removed)&&e.equals("",C.value)&&(a[u-2].value+=C.value,a.pop()),a}var Yt=new V;function Ze(e,t,n){return Yt.diff(e,t,n)}var Ye=/^[A-Za-z\xC0-\u02C6\u02C8-\u02D7\u02DE-\u02FF\u1E00-\u1EFF]+$/,Je=/\S/,Me=new V;Me.equals=function(e,t){return this.options.ignoreCase&&(e=e.toLowerCase(),t=t.toLowerCase()),e===t||this.options.ignoreWhitespace&&!Je.test(e)&&!Je.test(t)};Me.tokenize=function(e){for(var t=e.split(/([^\S\r\n]+|[()[\]{}'"\r\n]|\b)/),n=0;n<t.length-1;n++)!t[n+1]&&t[n+2]&&Ye.test(t[n])&&Ye.test(t[n+2])&&(t[n]+=t[n+2],t.splice(n+1,2),n--);return t};function Qe(e,t,n){return Me.diff(e,t,n)}var et=new V;et.tokenize=function(e){this.options.stripTrailingCr&&(e=e.replace(/\r\n/g,`
2
+ `));var t=[],n=e.split(/(\n|\r\n)/);n[n.length-1]||n.pop();for(var r=0;r<n.length;r++){var s=n[r];r%2&&!this.options.newlineIsToken?t[t.length-1]+=s:(this.options.ignoreWhitespace&&(s=s.trim()),t.push(s))}return t};var Jt=new V;Jt.tokenize=function(e){return e.split(/(\S.+?[.!?])(?=\s+|$)/)};var Zt=new V;Zt.tokenize=function(e){return e.split(/([{}:;,]|\s+)/)};function ye(e){"@babel/helpers - typeof";return typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?ye=function(t){return typeof t}:ye=function(t){return t&&typeof Symbol=="function"&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},ye(e)}var Qt=Object.prototype.toString,ce=new V;ce.useLongestToken=!0;ce.tokenize=et.tokenize;ce.castInput=function(e){var t=this.options,n=t.undefinedReplacement,r=t.stringifyReplacer,s=r===void 0?function(a,c){return typeof c>"u"?n:c}:r;return typeof e=="string"?e:JSON.stringify(Re(e,null,null,s),s," ")};ce.equals=function(e,t){return V.prototype.equals.call(ce,e.replace(/,([\r\n])/g,"$1"),t.replace(/,([\r\n])/g,"$1"))};function Re(e,t,n,r,s){t=t||[],n=n||[],r&&(e=r(s,e));var a;for(a=0;a<t.length;a+=1)if(t[a]===e)return n[a];var c;if(Qt.call(e)==="[object Array]"){for(t.push(e),c=new Array(e.length),n.push(c),a=0;a<e.length;a+=1)c[a]=Re(e[a],t,n,r,s);return t.pop(),n.pop(),c}if(e&&e.toJSON&&(e=e.toJSON()),ye(e)==="object"&&e!==null){t.push(e),c={},n.push(c);var i=[],u;for(u in e)e.hasOwnProperty(u)&&i.push(u);for(i.sort(),a=0;a<i.length;a+=1)u=i[a],c[u]=Re(e[u],t,n,r,u);t.pop(),n.pop()}else c=e;return c}var Ie=new V;Ie.tokenize=function(e){return e.slice()};Ie.join=Ie.removeEmpty=function(e){return e};function tt(e,t,n){return Ie.diff(e,t,n)}var tn=500,nn=100,nt=wt("BYGONE_MAX_INLINE_HIGHLIGHT_LINE_LENGTH",tn),rn=wt("BYGONE_DIFF_TIMEOUT_MS",nn);function Q(e,t,n={}){let r=rt(e),s=rt(t),a=tt(r,s,{timeout:n.timeoutMs??rn});if(!a)return on(r,s);let c=[],i=[],u=[],d=[],g=1,h=1;for(let L=0;L<a.length;L++){let C=a[L],I=C.removed?C.value:[],w=C.added?C.value:[];if(!C.added&&!C.removed){for(let b of C.value)i.push(Y("context",b,g)),u.push(Y("context",b,h)),c.push(re(X("context",b,g++),X("context",b,h++)));continue}if(C.removed&&L+1<a.length&&a[L+1].added){let b=a[L+1],x=i.length,k=u.length,N=pt(I,b.value);for(let{left:_,right:F}of N){let O,B;_!==void 0&&(O=Y("removed",_,g),i.push(O)),F!==void 0&&(B=Y("added",F,h),u.push(B)),O&&B&&Sn(O,B),c.push(re(_===void 0?ne():X("removed",_,g++),F===void 0?ne():X("added",F,h++)))}d.push(Se("replace",x,i.length,k,u.length)),L++;continue}if(C.removed){let b=i.length,x=u.length;for(let k of I)i.push(Y("removed",k,g)),c.push(re(X("removed",k,g++),ne()));d.push(Se("delete",b,i.length,x,u.length));continue}if(C.added){let b=i.length,x=u.length;for(let k of w)u.push(Y("added",k,h)),c.push(re(ne(),X("added",k,h++)));d.push(Se("insert",b,i.length,x,u.length))}}let E=c.some(L=>L.left.kind!=="context"||L.right.kind!=="context");return{rows:c,leftLines:i,rightLines:u,blocks:d,hasChanges:E}}function on(e,t){let n=e.map((c,i)=>Y("removed",c,i+1)),r=t.map((c,i)=>Y("added",c,i+1)),s=[...e.map((c,i)=>re(X("removed",c,i+1),ne())),...t.map((c,i)=>re(ne(),X("added",c,i+1)))],a="replace";return e.length===0?a="insert":t.length===0&&(a="delete"),{rows:s,leftLines:n,rightLines:r,blocks:s.length===0?[]:[Se(a,0,e.length,0,t.length)],hasChanges:s.length>0}}function rt(e){if(e.length===0)return[];let t=e.replace(/\r\n/g,`
3
3
  `).split(`
4
- `);return t[t.length-1]===""&&t.pop(),t}var ht=1e4,it=2e3,on=.52,sn=.35,gt=.38,an=.33,mt=.86,Te=.08,xe=.05,ve=-.12,ot=5e3,cn=2e3,st=4,ln=8,Me=4;function pt(e,t){if(e.length===0)return t.map(u=>({right:u}));if(t.length===0)return e.map(u=>({left:u}));if(e.length===1&&t.length===1){let u=Oe(e[0],t[0]);return(u.eligible||u.score>=sn)&&_e(e[0],t[0])&&ue(J(e[0]))&&ue(J(t[0]))?[{left:e[0],right:t[0]}]:[{left:e[0]},{right:t[0]}]}if(e.length*t.length>ht)return gn(e,t);let n=un(e,t),r=Array.from({length:e.length+1},()=>new Array(t.length+1).fill(Number.NEGATIVE_INFINITY)),s=Array.from({length:e.length+1},()=>new Array(t.length+1).fill(null));r[0][0]=0;for(let u=1;u<=e.length;u++)r[u][0]=r[u-1][0]+ve,s[u][0]="left";for(let u=1;u<=t.length;u++)r[0][u]=r[0][u-1]+ve,s[0][u]="right";for(let u=1;u<=e.length;u++)for(let d=1;d<=t.length;d++){let g=n[u-1][d-1],T=[{move:"left",score:r[u-1][d]+ve},{move:"right",score:r[u][d-1]+ve},{move:"match",score:g===null?Number.NEGATIVE_INFINITY:r[u-1][d-1]+g}].reduce((L,C)=>C.score>L.score?C:L);r[u][d]=T.score,s[u][d]=T.move}let a=[],l=e.length,i=t.length;for(;l>0||i>0;){let u=s[l][i];u==="match"?a.push({left:e[--l],right:t[--i]}):u==="left"?a.push({left:e[--l]}):a.push({right:t[--i]})}return a.reverse()}function Oe(e,t){let n=J(e),r=J(t),s=ue(n),a=ue(r);if(!s||!a||n.length>it||r.length>it)return{score:0,eligible:!1,characterSimilarity:0,tokenSimilarity:0,lengthSimilarity:0};if(n===r)return{score:1,eligible:!0,characterSimilarity:1,tokenSimilarity:1,lengthSimilarity:1};let l=Pe(n),i=Pe(r),u=vn(n,r),d=In(l,i),g=Math.min(n.length,r.length)/Math.max(n.length,r.length),h=xn(l,i),T=u*.52+d*.32+g*.1+h*.06,L=u>=.52||d>=.45||u>=.48&&d>=.28;return{score:T,eligible:L&&T>=on,characterSimilarity:u,tokenSimilarity:d,lengthSimilarity:g}}function un(e,t){let n=e.map(I=>t.map(w=>Oe(I,w))),r=bt(e,t),s=n.map(I=>De(I)),a=t.map((I,w)=>De(n.map(b=>b[w]))),l=n.map((I,w)=>I.map((b,x)=>{if(r.has(`${w}:${x}`))return Math.max(b.score,1);if(!b.eligible)return null;let k=s[w],N=a[x],_=b.score===k.best&&b.score===N.best,M=b.score>=mt?Te/2:Te,O=k.best-k.second>=M,B=N.best-N.second>=M;return _&&O&&B?b.score:null}));if(Math.max(e.length,t.length)>ln||Math.abs(e.length-t.length)>Me)return l;let i=(I,w,b)=>I.score>=gt&&_e(e[w],t[b])&&Math.abs(w-b)<=Me,u=n.map((I,w)=>Ee(I,(b,x)=>i(b,w,x))),d=t.map((I,w)=>Ee(n.map(b=>b[w]),(b,x)=>i(b,x,w))),g=(I,w,b)=>I.score>=an&&_e(e[w],t[b])&&Math.abs(w-b)<=Me,h=n.map((I,w)=>Ee(I,(b,x)=>g(b,w,x))),T=t.map((I,w)=>Ee(n.map(b=>b[w]),(b,x)=>g(b,x,w))),L=(I,w)=>{let b=n[I][w];if(!i(b,I,w))return!1;let x=u[I],k=d[w];return b.score===x.best&&b.score===k.best&&x.best-x.second>=xe&&k.best-k.second>=xe},C=(I,w)=>{let b=n[I][w];if(!g(b,I,w))return!1;let x=h[I],k=T[w];return b.score===x.best&&b.score===k.best&&x.best-x.second>=xe&&k.best-k.second>=xe};return l.map((I,w)=>I.map((b,x)=>{if(b!==null)return b;let k=L(w,x)&&(dn(l,w,x)||fn(n,w,x,L)),N=hn(n,w,x,(_,M)=>g(n[_][M],_,M),C);return!k&&!N?null:n[w][x].score}))}function dn(e,t,n){return t>0&&n>0&&e[t-1][n-1]!==null||t+1<e.length&&n+1<e[t+1].length&&e[t+1][n+1]!==null}function fn(e,t,n,r){return t>0&&n>0&&r(t-1,n-1)||t+1<e.length&&n+1<e[t+1].length&&r(t+1,n+1)}function hn(e,t,n,r,s){let a=t,l=n;for(;a>0&&l>0&&r(a-1,l-1);)a--,l--;let i=t,u=n,d=e[t][n].score,g=1;for(;i+1<e.length&&u+1<e[i+1].length&&r(i+1,u+1);)i++,u++,d+=e[i][u].score,g++;for(let h=t-1,T=n-1;h>=a&&T>=l;h--,T--)d+=e[h][T].score,g++;return g>=3&&d/g>=gt&&s(a,l)&&s(i,u)}function Ee(e,t){let n=Number.NEGATIVE_INFINITY,r=Number.NEGATIVE_INFINITY;return e.forEach((s,a)=>{t(s,a)&&(s.score>n?(r=n,n=s.score):s.score>r&&(r=s.score))}),{best:n,second:r}}function De(e){let t=Number.NEGATIVE_INFINITY,n=Number.NEGATIVE_INFINITY;for(let r of e)r.eligible&&(r.score>t?(n=t,t=r.score):r.score>n&&(n=r.score));return{best:t,second:n}}function gn(e,t){let n=mn(e,t),r=[],s=0,a=0;for(let l of n)dt(r,e.slice(s,l.leftIndex),t.slice(a,l.rightIndex)),r.push({left:e[l.leftIndex],right:t[l.rightIndex]}),s=l.leftIndex+1,a=l.rightIndex+1;return dt(r,e.slice(s),t.slice(a)),r}function mn(e,t){let n=pn(e,t);if(n===null)return[];let r=bt(e,t),s=n.map(({leftIndex:d,rightIndex:g,exact:h})=>({leftIndex:d,rightIndex:g,exact:h,structural:r.has(`${d}:${g}`),match:Oe(e[d],t[g])})).filter(d=>d.exact||d.structural||d.match.eligible),a=lt(s,"leftIndex"),l=lt(s,"rightIndex"),i=s.filter(d=>{if(d.exact||d.structural)return!0;let g=a.get(d.leftIndex),h=l.get(d.rightIndex);if(!g||!h||d.match.score!==g.best||d.match.score!==h.best)return!1;let T=d.match.score>=mt?Te/2:Te;return g.best-g.second>=T&&h.best-h.second>=T}),u=wn(i,t.length);return u.length<=cn?u:[]}function pn(e,t){let n=at(e,J),r=at(t,J),s=new Map;for(let[i,u]of n){let d=r.get(i);if(!ue(i)||u.length!==1||d?.length!==1)continue;let g=u[0],h=d[0];if(s.set(`${g}:${h}`,{leftIndex:g,rightIndex:h,exact:!0}),s.size>ot)return null}let a=ct(e),l=ct(t);for(let[i,u]of a){let d=l.get(i);if(!(!d||u.length>st||d.length>st))for(let g of u)for(let h of d){let T=`${g}:${h}`;if(!s.has(T)&&(s.set(T,{leftIndex:g,rightIndex:h,exact:!1}),s.size>ot))return null}}return[...s.values()]}function at(e,t){let n=new Map;return e.forEach((r,s)=>{let a=t(r),l=n.get(a)??[];l.push(s),n.set(a,l)}),n}function ct(e){let t=new Map;return e.forEach((n,r)=>{let s=new Set(Pe(J(n)).filter(bn));for(let a of s){let l=t.get(a)??[];l.push(r),t.set(a,l)}}),t}function bn(e){return e.length>=2&&/[\p{L}\p{N}_$]/u.test(e)}function lt(e,t){let n=new Map;for(let r of e){let s=n.get(r[t])??[];s.push(r.match),n.set(r[t],s)}return new Map([...n].map(([r,s])=>[r,De(s)]))}function wn(e,t){let n=[...e].sort((d,g)=>d.leftIndex-g.leftIndex||d.rightIndex-g.rightIndex),r=new Array(t+2).fill(0),s=new Array(t+2).fill(-1),a=new Array(n.length).fill(0),l=new Array(n.length).fill(-1);for(let d=0;d<n.length;){let g=d+1;for(;g<n.length&&n[g].leftIndex===n[d].leftIndex;)g++;for(let h=d;h<g;h++){let T=ut(r,s,n[h].rightIndex),L=n[h].exact||n[h].structural?.5:0;a[h]=T.score+n[h].match.score+L,l[h]=T.candidateIndex}for(let h=d;h<g;h++)yn(r,s,n[h].rightIndex+1,a[h],h);d=g}let i=ut(r,s,t+1),u=[];for(let d=i.candidateIndex;d>=0;d=l[d])u.push({leftIndex:n[d].leftIndex,rightIndex:n[d].rightIndex});return u.reverse()}function ut(e,t,n){let r=0,s=-1;for(let a=n;a>0;a-=a&-a)e[a]>r&&(r=e[a],s=t[a]);return{score:r,candidateIndex:s}}function yn(e,t,n,r,s){for(let a=n;a<e.length;a+=a&-a)r>e[a]&&(e[a]=r,t[a]=s)}function dt(e,t,n){if(t.length*n.length<=ht){e.push(...pt(t,n));return}e.push(...t.map(r=>({left:r}))),e.push(...n.map(r=>({right:r})))}function J(e){return e.trim().replace(/\s+/g," ")}function bt(e,t){let n=ft(e),r=ft(t),s=new Set;for(let[a,l]of n){let i=r.get(a);l.length===1&&i?.length===1&&s.add(`${l[0]}:${i[0]}`)}return s}function ft(e){let t=new Map;return e.forEach((n,r)=>{let s=He(n);if(!s)return;let a=t.get(s)??[];a.push(r),t.set(s,a)}),t}function _e(e,t){let n=He(e),r=He(t);return!n||!r?n===r:n.split(":",1)[0]===r.split(":",1)[0]}function He(e){let t=J(e),n=[["function",/^(?:(?:export|default)\s+)*(?:async\s+)?function\s*\*?\s*([\p{L}_$][\p{L}\p{N}_$]*)\s*\(/u],["function",/^(?:async\s+)?def\s+([\p{L}_][\p{L}\p{N}_]*)\s*\(/u],["function",/^(?:pub(?:\([^)]*\))?\s+)?(?:async\s+)?fn\s+([\p{L}_][\p{L}\p{N}_]*)\s*(?:<[^>]*>)?\s*\(/u],["function",/^func\s+(?:\([^)]*\)\s*)?([\p{L}_][\p{L}\p{N}_]*)\s*\(/u],["class",/^(?:(?:export|default|abstract|public)\s+)*class\s+([\p{L}_$][\p{L}\p{N}_$]*)\b/u]];for(let[r,s]of n){let a=t.match(s);if(a)return`${r}:${a[1]}`}return null}function ue(e){return e.length<3?!1:/[\p{L}\p{N}_$]/u.test(e)&&!/^[\s()[\]{};,.:+\-*/=>|&!?'"`]+$/.test(e)}function Pe(e){return e.toLowerCase().match(/[\p{L}_$][\p{L}\p{N}_$]*|\p{N}+(?:\.\p{N}+)?|[^\s\p{L}\p{N}_$]/gu)??[]}function In(e,t){if(e.length+t.length===0)return 1;let n=new Map;e.forEach(s=>n.set(s,(n.get(s)??0)+1));let r=0;for(let s of t){let a=n.get(s)??0;a>0&&(r++,n.set(s,a-1))}return 2*r/(e.length+t.length)}function xn(e,t){if(e.length===0||t.length===0)return 0;let n=e[0]===t[0]?.5:0,r=e[e.length-1]===t[t.length-1]?.5:0;return n+r}function vn(e,t){let n=e.length+t.length;return n===0?1:2*Ze(e,t).filter(s=>!s.added&&!s.removed).reduce((s,a)=>s+a.value.length,0)/n}function En(e,t){if(e.content.length>nt||t.content.length>nt)return;let{leftSegments:n,rightSegments:r,hasInlineChanges:s}=Sn(e.content,t.content);s&&(e.segments=n,t.segments=r)}function Sn(e,t){let n=Qe(e,t),r=[],s=[],a=!1;for(let l of n){let i=l.value;if(!l.added&&!l.removed){let d={kind:"context",text:i,emphasis:!1};r.push(d),s.push(d);continue}let u=/[^\s]/.test(i);a=a||u,l.removed&&r.push({kind:"removed",text:i,emphasis:u}),l.added&&s.push({kind:"added",text:i,emphasis:u})}return{leftSegments:r,rightSegments:s,hasInlineChanges:a}}function ne(){return{kind:"placeholder",content:"",lineNumber:null}}function X(e,t,n){return{kind:e,content:t,lineNumber:n}}function Y(e,t,n){return{kind:e,content:t,lineNumber:n}}function re(e,t){return{left:e,right:t}}function Se(e,t,n,r,s){return{kind:e,leftStart:t,leftEnd:n,rightStart:r,rightEnd:s}}function wt(e,t){let n=typeof process<"u"?process.env?.[e]:void 0,r=Number.parseInt(n??"",10);return Number.isFinite(r)&&r>0?r:t}function yt(){return{leftFileName:"test-file-1.js",rightFileName:"test-file-2.js",leftContent:`// Test File 1 - Example JavaScript Code
4
+ `);return t[t.length-1]===""&&t.pop(),t}var ht=1e4,it=2e3,sn=.52,an=.35,gt=.38,ln=.33,mt=.86,Ee=.08,xe=.05,ve=-.12,ot=5e3,cn=2e3,st=4,un=8,Fe=4;function pt(e,t){if(e.length===0)return t.map(u=>({right:u}));if(t.length===0)return e.map(u=>({left:u}));if(e.length===1&&t.length===1){let u=Oe(e[0],t[0]);return(u.eligible||u.score>=an)&&_e(e[0],t[0])&&ue(J(e[0]))&&ue(J(t[0]))?[{left:e[0],right:t[0]}]:[{left:e[0]},{right:t[0]}]}if(e.length*t.length>ht)return mn(e,t);let n=dn(e,t),r=Array.from({length:e.length+1},()=>new Array(t.length+1).fill(Number.NEGATIVE_INFINITY)),s=Array.from({length:e.length+1},()=>new Array(t.length+1).fill(null));r[0][0]=0;for(let u=1;u<=e.length;u++)r[u][0]=r[u-1][0]+ve,s[u][0]="left";for(let u=1;u<=t.length;u++)r[0][u]=r[0][u-1]+ve,s[0][u]="right";for(let u=1;u<=e.length;u++)for(let d=1;d<=t.length;d++){let g=n[u-1][d-1],E=[{move:"left",score:r[u-1][d]+ve},{move:"right",score:r[u][d-1]+ve},{move:"match",score:g===null?Number.NEGATIVE_INFINITY:r[u-1][d-1]+g}].reduce((L,C)=>C.score>L.score?C:L);r[u][d]=E.score,s[u][d]=E.move}let a=[],c=e.length,i=t.length;for(;c>0||i>0;){let u=s[c][i];u==="match"?a.push({left:e[--c],right:t[--i]}):u==="left"?a.push({left:e[--c]}):a.push({right:t[--i]})}return a.reverse()}function Oe(e,t){let n=J(e),r=J(t),s=ue(n),a=ue(r);if(!s||!a||n.length>it||r.length>it)return{score:0,eligible:!1,characterSimilarity:0,tokenSimilarity:0,lengthSimilarity:0};if(n===r)return{score:1,eligible:!0,characterSimilarity:1,tokenSimilarity:1,lengthSimilarity:1};let c=He(n),i=He(r),u=Tn(n,r),d=xn(c,i),g=Math.min(n.length,r.length)/Math.max(n.length,r.length),h=vn(c,i),E=u*.52+d*.32+g*.1+h*.06,L=u>=.52||d>=.45||u>=.48&&d>=.28;return{score:E,eligible:L&&E>=sn,characterSimilarity:u,tokenSimilarity:d,lengthSimilarity:g}}function dn(e,t){let n=e.map(I=>t.map(w=>Oe(I,w))),r=bt(e,t),s=n.map(I=>De(I)),a=t.map((I,w)=>De(n.map(b=>b[w]))),c=n.map((I,w)=>I.map((b,x)=>{if(r.has(`${w}:${x}`))return Math.max(b.score,1);if(!b.eligible)return null;let k=s[w],N=a[x],_=b.score===k.best&&b.score===N.best,F=b.score>=mt?Ee/2:Ee,O=k.best-k.second>=F,B=N.best-N.second>=F;return _&&O&&B?b.score:null}));if(Math.max(e.length,t.length)>un||Math.abs(e.length-t.length)>Fe)return c;let i=(I,w,b)=>I.score>=gt&&_e(e[w],t[b])&&Math.abs(w-b)<=Fe,u=n.map((I,w)=>Te(I,(b,x)=>i(b,w,x))),d=t.map((I,w)=>Te(n.map(b=>b[w]),(b,x)=>i(b,x,w))),g=(I,w,b)=>I.score>=ln&&_e(e[w],t[b])&&Math.abs(w-b)<=Fe,h=n.map((I,w)=>Te(I,(b,x)=>g(b,w,x))),E=t.map((I,w)=>Te(n.map(b=>b[w]),(b,x)=>g(b,x,w))),L=(I,w)=>{let b=n[I][w];if(!i(b,I,w))return!1;let x=u[I],k=d[w];return b.score===x.best&&b.score===k.best&&x.best-x.second>=xe&&k.best-k.second>=xe},C=(I,w)=>{let b=n[I][w];if(!g(b,I,w))return!1;let x=h[I],k=E[w];return b.score===x.best&&b.score===k.best&&x.best-x.second>=xe&&k.best-k.second>=xe};return c.map((I,w)=>I.map((b,x)=>{if(b!==null)return b;let k=L(w,x)&&(fn(c,w,x)||hn(n,w,x,L)),N=gn(n,w,x,(_,F)=>g(n[_][F],_,F),C);return!k&&!N?null:n[w][x].score}))}function fn(e,t,n){return t>0&&n>0&&e[t-1][n-1]!==null||t+1<e.length&&n+1<e[t+1].length&&e[t+1][n+1]!==null}function hn(e,t,n,r){return t>0&&n>0&&r(t-1,n-1)||t+1<e.length&&n+1<e[t+1].length&&r(t+1,n+1)}function gn(e,t,n,r,s){let a=t,c=n;for(;a>0&&c>0&&r(a-1,c-1);)a--,c--;let i=t,u=n,d=e[t][n].score,g=1;for(;i+1<e.length&&u+1<e[i+1].length&&r(i+1,u+1);)i++,u++,d+=e[i][u].score,g++;for(let h=t-1,E=n-1;h>=a&&E>=c;h--,E--)d+=e[h][E].score,g++;return g>=3&&d/g>=gt&&s(a,c)&&s(i,u)}function Te(e,t){let n=Number.NEGATIVE_INFINITY,r=Number.NEGATIVE_INFINITY;return e.forEach((s,a)=>{t(s,a)&&(s.score>n?(r=n,n=s.score):s.score>r&&(r=s.score))}),{best:n,second:r}}function De(e){let t=Number.NEGATIVE_INFINITY,n=Number.NEGATIVE_INFINITY;for(let r of e)r.eligible&&(r.score>t?(n=t,t=r.score):r.score>n&&(n=r.score));return{best:t,second:n}}function mn(e,t){let n=pn(e,t),r=[],s=0,a=0;for(let c of n)dt(r,e.slice(s,c.leftIndex),t.slice(a,c.rightIndex)),r.push({left:e[c.leftIndex],right:t[c.rightIndex]}),s=c.leftIndex+1,a=c.rightIndex+1;return dt(r,e.slice(s),t.slice(a)),r}function pn(e,t){let n=bn(e,t);if(n===null)return[];let r=bt(e,t),s=n.map(({leftIndex:d,rightIndex:g,exact:h})=>({leftIndex:d,rightIndex:g,exact:h,structural:r.has(`${d}:${g}`),match:Oe(e[d],t[g])})).filter(d=>d.exact||d.structural||d.match.eligible),a=ct(s,"leftIndex"),c=ct(s,"rightIndex"),i=s.filter(d=>{if(d.exact||d.structural)return!0;let g=a.get(d.leftIndex),h=c.get(d.rightIndex);if(!g||!h||d.match.score!==g.best||d.match.score!==h.best)return!1;let E=d.match.score>=mt?Ee/2:Ee;return g.best-g.second>=E&&h.best-h.second>=E}),u=yn(i,t.length);return u.length<=cn?u:[]}function bn(e,t){let n=at(e,J),r=at(t,J),s=new Map;for(let[i,u]of n){let d=r.get(i);if(!ue(i)||u.length!==1||d?.length!==1)continue;let g=u[0],h=d[0];if(s.set(`${g}:${h}`,{leftIndex:g,rightIndex:h,exact:!0}),s.size>ot)return null}let a=lt(e),c=lt(t);for(let[i,u]of a){let d=c.get(i);if(!(!d||u.length>st||d.length>st))for(let g of u)for(let h of d){let E=`${g}:${h}`;if(!s.has(E)&&(s.set(E,{leftIndex:g,rightIndex:h,exact:!1}),s.size>ot))return null}}return[...s.values()]}function at(e,t){let n=new Map;return e.forEach((r,s)=>{let a=t(r),c=n.get(a)??[];c.push(s),n.set(a,c)}),n}function lt(e){let t=new Map;return e.forEach((n,r)=>{let s=new Set(He(J(n)).filter(wn));for(let a of s){let c=t.get(a)??[];c.push(r),t.set(a,c)}}),t}function wn(e){return e.length>=2&&/[\p{L}\p{N}_$]/u.test(e)}function ct(e,t){let n=new Map;for(let r of e){let s=n.get(r[t])??[];s.push(r.match),n.set(r[t],s)}return new Map([...n].map(([r,s])=>[r,De(s)]))}function yn(e,t){let n=[...e].sort((d,g)=>d.leftIndex-g.leftIndex||d.rightIndex-g.rightIndex),r=new Array(t+2).fill(0),s=new Array(t+2).fill(-1),a=new Array(n.length).fill(0),c=new Array(n.length).fill(-1);for(let d=0;d<n.length;){let g=d+1;for(;g<n.length&&n[g].leftIndex===n[d].leftIndex;)g++;for(let h=d;h<g;h++){let E=ut(r,s,n[h].rightIndex),L=n[h].exact||n[h].structural?.5:0;a[h]=E.score+n[h].match.score+L,c[h]=E.candidateIndex}for(let h=d;h<g;h++)In(r,s,n[h].rightIndex+1,a[h],h);d=g}let i=ut(r,s,t+1),u=[];for(let d=i.candidateIndex;d>=0;d=c[d])u.push({leftIndex:n[d].leftIndex,rightIndex:n[d].rightIndex});return u.reverse()}function ut(e,t,n){let r=0,s=-1;for(let a=n;a>0;a-=a&-a)e[a]>r&&(r=e[a],s=t[a]);return{score:r,candidateIndex:s}}function In(e,t,n,r,s){for(let a=n;a<e.length;a+=a&-a)r>e[a]&&(e[a]=r,t[a]=s)}function dt(e,t,n){if(t.length*n.length<=ht){e.push(...pt(t,n));return}e.push(...t.map(r=>({left:r}))),e.push(...n.map(r=>({right:r})))}function J(e){return e.trim().replace(/\s+/g," ")}function bt(e,t){let n=ft(e),r=ft(t),s=new Set;for(let[a,c]of n){let i=r.get(a);c.length===1&&i?.length===1&&s.add(`${c[0]}:${i[0]}`)}return s}function ft(e){let t=new Map;return e.forEach((n,r)=>{let s=Pe(n);if(!s)return;let a=t.get(s)??[];a.push(r),t.set(s,a)}),t}function _e(e,t){let n=Pe(e),r=Pe(t);return!n||!r?n===r:n.split(":",1)[0]===r.split(":",1)[0]}function Pe(e){let t=J(e),n=[["function",/^(?:(?:export|default)\s+)*(?:async\s+)?function\s*\*?\s*([\p{L}_$][\p{L}\p{N}_$]*)\s*\(/u],["function",/^(?:async\s+)?def\s+([\p{L}_][\p{L}\p{N}_]*)\s*\(/u],["function",/^(?:pub(?:\([^)]*\))?\s+)?(?:async\s+)?fn\s+([\p{L}_][\p{L}\p{N}_]*)\s*(?:<[^>]*>)?\s*\(/u],["function",/^func\s+(?:\([^)]*\)\s*)?([\p{L}_][\p{L}\p{N}_]*)\s*\(/u],["class",/^(?:(?:export|default|abstract|public)\s+)*class\s+([\p{L}_$][\p{L}\p{N}_$]*)\b/u]];for(let[r,s]of n){let a=t.match(s);if(a)return`${r}:${a[1]}`}return null}function ue(e){return e.length<3?!1:/[\p{L}\p{N}_$]/u.test(e)&&!/^[\s()[\]{};,.:+\-*/=>|&!?'"`]+$/.test(e)}function He(e){return e.toLowerCase().match(/[\p{L}_$][\p{L}\p{N}_$]*|\p{N}+(?:\.\p{N}+)?|[^\s\p{L}\p{N}_$]/gu)??[]}function xn(e,t){if(e.length+t.length===0)return 1;let n=new Map;e.forEach(s=>n.set(s,(n.get(s)??0)+1));let r=0;for(let s of t){let a=n.get(s)??0;a>0&&(r++,n.set(s,a-1))}return 2*r/(e.length+t.length)}function vn(e,t){if(e.length===0||t.length===0)return 0;let n=e[0]===t[0]?.5:0,r=e[e.length-1]===t[t.length-1]?.5:0;return n+r}function Tn(e,t){let n=e.length+t.length;return n===0?1:2*Ze(e,t).filter(s=>!s.added&&!s.removed).reduce((s,a)=>s+a.value.length,0)/n}function Sn(e,t){if(e.content.length>nt||t.content.length>nt)return;let{leftSegments:n,rightSegments:r,hasInlineChanges:s}=En(e.content,t.content);s&&(e.segments=n,t.segments=r)}function En(e,t){let n=Qe(e,t),r=[],s=[],a=!1;for(let c of n){let i=c.value;if(!c.added&&!c.removed){let d={kind:"context",text:i,emphasis:!1};r.push(d),s.push(d);continue}let u=/[^\s]/.test(i);a=a||u,c.removed&&r.push({kind:"removed",text:i,emphasis:u}),c.added&&s.push({kind:"added",text:i,emphasis:u})}return{leftSegments:r,rightSegments:s,hasInlineChanges:a}}function ne(){return{kind:"placeholder",content:"",lineNumber:null}}function X(e,t,n){return{kind:e,content:t,lineNumber:n}}function Y(e,t,n){return{kind:e,content:t,lineNumber:n}}function re(e,t){return{left:e,right:t}}function Se(e,t,n,r,s){return{kind:e,leftStart:t,leftEnd:n,rightStart:r,rightEnd:s}}function wt(e,t){let n=typeof process<"u"?process.env?.[e]:void 0,r=Number.parseInt(n??"",10);return Number.isFinite(r)&&r>0?r:t}function yt(){return{leftFileName:"test-file-1.js",rightFileName:"test-file-2.js",leftContent:`// Test File 1 - Example JavaScript Code
5
5
  const fs = require('fs');
6
6
  const path = require('path');
7
7
 
@@ -145,7 +145,7 @@ if (require.main === module) {
145
145
  }
146
146
 
147
147
  module.exports = FileProcessor;
148
- `}}function It(e){if(!H(e)||e.version!==1)throw new Error("Unsupported or missing change-tour manifest version.");if(A(e.title,"title"),A(e.generatedAt,"generatedAt"),e.sourceUrl!==void 0&&A(e.sourceUrl,"sourceUrl"),!H(e.range))throw new Error("Change-tour manifest range must be an object.");for(let r of["baseRef","headRef","mergeBaseOid","headOid"])A(e.range[r],`range.${r}`);if(!H(e.summary))throw new Error("Change-tour manifest summary must be an object.");for(let r of["changedFiles","includedScenes","additions","deletions","commitCount"])ee(e.summary[r],`summary.${r}`);if(de(e.summary.omittedFiles,"summary.omittedFiles"),!Array.isArray(e.commits)||!Array.isArray(e.chapters)||!Array.isArray(e.scenes))throw new Error("Change-tour manifest commits, chapters, and scenes must be arrays.");if(e.files!==void 0&&!Array.isArray(e.files))throw new Error("Change-tour manifest files must be an array.");let t=new Set;for(let[r,s]of e.scenes.entries()){if(Ue(s,r),t.has(s.id))throw new Error(`Duplicate change-tour scene id: ${s.id}`);t.add(s.id)}for(let[r,s]of e.chapters.entries()){if(!H(s))throw new Error(`chapters[${r}] must be an object.`);A(s.id,`chapters[${r}].id`),A(s.title,`chapters[${r}].title`),de(s.sceneIds,`chapters[${r}].sceneIds`);for(let a of s.sceneIds)if(!t.has(a))throw new Error(`Chapter references unknown scene id: ${a}`)}if(e.summary.includedScenes!==e.scenes.length)throw new Error("summary.includedScenes must match the number of scenes.");let n=e.files===void 0?kn(e.scenes):e.files.map((r,s)=>(Ln(r,s),r));if(e.files!==void 0&&e.summary.changedFiles!==n.length)throw new Error("summary.changedFiles must match the number of files.");return{...e,files:n}}function Ue(e,t){if(!H(e)||!["text-diff","discussion","walkthrough","stacked-diff","deconstructed-diff"].includes(String(e.kind)))throw new Error(`scenes[${t}] must be a text-diff, discussion, walkthrough, stacked-diff, or deconstructed-diff scene.`);for(let n of["id","title"])A(e[n],`scenes[${t}].${n}`);if(Nn(e,`scenes[${t}]`),e.kind!=="discussion"){if(e.kind==="walkthrough"){if(!Array.isArray(e.steps)||e.steps.length===0)throw new Error(`scenes[${t}].steps must be a non-empty array.`);for(let[n,r]of e.steps.entries()){let s=`scenes[${t}].steps[${n}]`;if(!H(r)||!H(r.focus)||!H(r.diff))throw new Error(`${s} must contain focus and diff objects.`);for(let a of["id","title","body"])A(r[a],`${s}.${a}`);if(r.depth!==void 0&&!["mentioned","explained","contextualized"].includes(String(r.depth)))throw new Error(`${s}.depth must be mentioned, explained, or contextualized.`);if(Be(r.focus,`${s}.focus`),Ue(r.diff,t),r.diff.kind!=="text-diff")throw new Error(`${s}.diff must be a text-diff scene.`);if(r.connection!==void 0){if(!H(r.connection))throw new Error(`${s}.connection must be an object.`);A(r.connection.id,`${s}.connection.id`),A(r.connection.label,`${s}.connection.label`),Be(r.connection.from,`${s}.connection.from`),Be(r.connection.to,`${s}.connection.to`)}}return}if(e.kind==="stacked-diff"){Tn(e,t);return}if(e.kind==="deconstructed-diff"){Cn(e,t);return}for(let n of["path","leftLabel","rightLabel","leftContent","rightContent"])A(e[n],`scenes[${t}].${n}`);e.previousPath!==void 0&&A(e.previousPath,`scenes[${t}].previousPath`),A(e.changeKind,`scenes[${t}].changeKind`),ee(e.additions,`scenes[${t}].additions`),ee(e.deletions,`scenes[${t}].deletions`),e.focusChangeIndex!==void 0&&ee(e.focusChangeIndex,`scenes[${t}].focusChangeIndex`)}}function Tn(e,t){if(!Array.isArray(e.stack)||e.stack.length<3||e.stack.length>6)throw new Error(`scenes[${t}].stack must contain between 3 and 6 revisions.`);for(let[n,r]of e.stack.entries()){if(!H(r))throw new Error(`scenes[${t}].stack[${n}] must be an object.`);for(let s of["id","ref","oid","label"])A(r[s],`scenes[${t}].stack[${n}].${s}`)}xt(e.files,e.stack.length,t),vt(e.steps,e.stack.length,t,!1)}function Cn(e,t){if(e.stageLabel!=="Explanation stages")throw new Error(`scenes[${t}].stageLabel must be Explanation stages.`);if(!H(e.realRange))throw new Error(`scenes[${t}].realRange must be an object.`);for(let r of["baseRef","targetRef","baseOid","targetOid"])A(e.realRange[r],`scenes[${t}].realRange.${r}`);if(!Array.isArray(e.panels)||e.panels.length<2||e.panels.length>13)throw new Error(`scenes[${t}].panels must contain a baseline and between 1 and 12 stages.`);let n=e.panels;for(let[r,s]of n.entries()){if(!H(s))throw new Error(`scenes[${t}].panels[${r}] must be an object.`);for(let l of["id","label","role"])A(s[l],`scenes[${t}].panels[${r}].${l}`);let a=r===0?"baseline":"stage";if(s.role!==a)throw new Error(`scenes[${t}].panels[${r}].role must be ${a}.`);r>0&&A(s.stageId,`scenes[${t}].panels[${r}].stageId`)}if(xt(e.files,n.length,t),vt(e.steps,n.length,t,!0),Array.isArray(e.steps)&&e.steps.length!==n.length-1)throw new Error(`scenes[${t}].steps must match the number of explanation stages.`);Array.isArray(e.steps)&&e.steps.forEach((r,s)=>{let a=n[s+1];if(!H(r)||!H(a)||a.stageId!==r.id)throw new Error(`scenes[${t}].panels must align with explanation stage ids.`)})}function xt(e,t,n){if(!Array.isArray(e)||e.length===0)throw new Error(`scenes[${n}].files must be non-empty.`);for(let[r,s]of e.entries()){if(!H(s))throw new Error(`scenes[${n}].files[${r}] must be an object.`);if(A(s.path,`scenes[${n}].files[${r}].path`),!Array.isArray(s.panels)||s.panels.length!==t)throw new Error(`scenes[${n}].files[${r}].panels must match panel count.`);for(let[a,l]of s.panels.entries()){if(!H(l))throw new Error(`scenes[${n}].files[${r}].panels[${a}] must be an object.`);for(let i of["id","label","content"])A(l[i],`scenes[${n}].files[${r}].panels[${a}].${i}`);if(l.path!==void 0&&A(l.path,`scenes[${n}].files[${r}].panels[${a}].path`),typeof l.exists!="boolean")throw new Error(`scenes[${n}].files[${r}].panels[${a}].exists must be boolean.`)}}}function vt(e,t,n,r){if(!Array.isArray(e)||e.length===0)throw new Error(`scenes[${n}].steps must be non-empty.`);for(let[s,a]of e.entries()){if(!H(a))throw new Error(`scenes[${n}].steps[${s}] must be an object.`);for(let l of["id","title","body","file","side"])A(a[l],`scenes[${n}].steps[${s}].${l}`);if(ee(a.pairIndex,`scenes[${n}].steps[${s}].pairIndex`),Number(a.pairIndex)>=t-1)throw new Error(`scenes[${n}].steps[${s}].pairIndex is outside the panels.`);if(r){if(de(a.introducedHunks,`scenes[${n}].steps[${s}].introducedHunks`),a.introducedHunks.length===0)throw new Error(`scenes[${n}].steps[${s}].introducedHunks must be non-empty.`);if(Number(a.pairIndex)!==s)throw new Error(`scenes[${n}].steps[${s}].pairIndex must match its explanation stage.`)}if(a.side!=="left"&&a.side!=="right")throw new Error(`scenes[${n}].steps[${s}].side must be left or right.`);a.startLine!==void 0&&Ce(a.startLine,`scenes[${n}].steps[${s}].startLine`),a.endLine!==void 0&&Ce(a.endLine,`scenes[${n}].steps[${s}].endLine`)}}function Ln(e,t){if(!H(e))throw new Error(`files[${t}] must be an object.`);if(e.kind==="text-diff"){Ue(e,t);return}if(e.kind!=="omitted")throw new Error(`files[${t}].kind must be text-diff or omitted.`);for(let n of["id","title","path","changeKind","reason"])A(e[n],`files[${t}].${n}`);e.previousPath!==void 0&&A(e.previousPath,`files[${t}].previousPath`),ee(e.additions,`files[${t}].additions`),ee(e.deletions,`files[${t}].deletions`)}function kn(e){let t=new Map;for(let n of e){if(n.kind==="text-diff"){t.has(n.path)||t.set(n.path,n);continue}if(n.kind==="walkthrough")for(let r of n.steps)t.has(r.diff.path)||t.set(r.diff.path,r.diff)}return[...t.values()].sort((n,r)=>n.path.localeCompare(r.path))}function Be(e,t){if(!H(e))throw new Error(`${t} must be an object.`);for(let n of["id","path","revision","excerpt"])A(e[n],`${t}.${n}`);if(e.revision!=="base"&&e.revision!=="head")throw new Error(`${t}.revision must be base or head.`);if(Ce(e.startLine,`${t}.startLine`),Ce(e.endLine,`${t}.endLine`),Number(e.endLine)<Number(e.startLine))throw new Error(`${t}.endLine must not precede startLine.`)}function Nn(e,t){A(e.summary,`${t}.summary`),de(e.bullets,`${t}.bullets`),de(e.tags,`${t}.tags`),A(e.takeaway,`${t}.takeaway`)}function H(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function A(e,t){if(typeof e!="string")throw new Error(`${t} must be a string.`)}function de(e,t){if(!Array.isArray(e)||e.some(n=>typeof n!="string"))throw new Error(`${t} must be an array of strings.`)}function ee(e,t){if(!Number.isInteger(e)||Number(e)<0)throw new Error(`${t} must be a non-negative integer.`)}function Ce(e,t){if(!Number.isInteger(e)||Number(e)<1)throw new Error(`${t} must be a positive integer.`)}function St(e,t,n){let r=e.findIndex(i=>i.id===t),s=r>=0?r:0,a=e[s];if(!a||a.kind!=="walkthrough"&&a.kind!=="stacked-diff"&&a.kind!=="deconstructed-diff"||!n)return{sceneIndex:s,stepIndex:0};let l=a.steps.findIndex(i=>i.id===n);return{sceneIndex:s,stepIndex:l>=0?l:0}}function Tt(e,t,n){let r=e[t.sceneIndex];if(!r)return null;if(n>0)return(r.kind==="walkthrough"||r.kind==="stacked-diff"||r.kind==="deconstructed-diff")&&t.stepIndex<r.steps.length-1?{sceneIndex:t.sceneIndex,stepIndex:t.stepIndex+1}:t.sceneIndex<e.length-1?{sceneIndex:t.sceneIndex+1,stepIndex:0}:null;if((r.kind==="walkthrough"||r.kind==="stacked-diff"||r.kind==="deconstructed-diff")&&t.stepIndex>0)return{sceneIndex:t.sceneIndex,stepIndex:t.stepIndex-1};if(t.sceneIndex===0)return null;let s=e[t.sceneIndex-1];return{sceneIndex:t.sceneIndex-1,stepIndex:s.kind==="walkthrough"||s.kind==="stacked-diff"||s.kind==="deconstructed-diff"?s.steps.length-1:0}}function Ct(e,t,n){if(!t)return null;let r=e.map((i,u)=>({file:i,fileIndex:u})).filter(({file:i})=>i.kind==="text-diff"),s=r.findIndex(({file:i})=>i.path===t),a=s+n,l=s>=0?r[a]:null;return l?{fileIndex:l.fileIndex,path:l.file.path}:null}function Lt(e,t,n){let r=e[t.sceneIndex],s=Et(r,t.sceneIndex,t.stepIndex,n);if(s)return s;for(let a=0;a<e.length;a+=1){if(a===t.sceneIndex)continue;let l=Et(e[a],a,0,n);if(l)return l}return null}function Et(e,t,n,r){if(!e||e.kind!=="stacked-diff"&&e.kind!=="deconstructed-diff"||!e.files.some(l=>l.path===r))return null;let a=e.steps[n]?.file===r?n:e.steps.findIndex(l=>l.file===r);return{sceneIndex:t,stepIndex:a>=0?a:Math.max(n,0)}}function Nt(e,t,n="all",r=300){let s=t.trim().toLocaleLowerCase();if(!s||r<=0)return[];let a=[];if(n!=="code"){let l=new Map;e.chapters.forEach(i=>i.sceneIds.forEach(u=>l.set(u,i.title))),e.scenes.forEach((i,u)=>{let d=[l.get(i.id),i.title,i.summary,...i.bullets,...i.tags,i.takeaway],g=kt(d,s);g&&a.push({kind:"narrative",sceneIndex:u,label:i.title,preview:g}),An(i)&&i.steps.forEach((h,T)=>{let L=kt([h.title,h.body,"connection"in h?h.connection?.label:void 0],s);L&&a.push({kind:"narrative",sceneIndex:u,stepIndex:T,label:`${i.title} \xB7 ${h.title}`,preview:L})})})}if(n!=="narrative"&&a.length<r)for(let l=0;l<e.files.length;l+=1){let i=e.files[l];if(i.kind==="text-diff"){for(let[u,d]of[[0,i.leftContent],[1,i.rightContent]])for(let g of $n(d,s))if(a.push({kind:"code",fileIndex:l,sideIndex:u,label:`${i.path} \xB7 ${u===0?"base":"head"}`,...g}),a.length>=r)return a}}return a.slice(0,r)}function kt(e,t){return e.find(n=>n?.toLocaleLowerCase().includes(t))}function $n(e,t){let n=[];return e.replace(/\r\n/g,`
148
+ `}}function It(e){if(!P(e)||e.version!==1)throw new Error("Unsupported or missing change-tour manifest version.");if($(e.title,"title"),$(e.generatedAt,"generatedAt"),e.windowTitle!==void 0&&$(e.windowTitle,"windowTitle"),e.sourceUrl!==void 0&&$(e.sourceUrl,"sourceUrl"),!P(e.range))throw new Error("Change-tour manifest range must be an object.");for(let r of["baseRef","headRef","mergeBaseOid","headOid"])$(e.range[r],`range.${r}`);if(!P(e.summary))throw new Error("Change-tour manifest summary must be an object.");for(let r of["changedFiles","includedScenes","additions","deletions","commitCount"])ee(e.summary[r],`summary.${r}`);if(de(e.summary.omittedFiles,"summary.omittedFiles"),!Array.isArray(e.commits)||!Array.isArray(e.chapters)||!Array.isArray(e.scenes))throw new Error("Change-tour manifest commits, chapters, and scenes must be arrays.");if(e.files!==void 0&&!Array.isArray(e.files))throw new Error("Change-tour manifest files must be an array.");let t=new Set;for(let[r,s]of e.scenes.entries()){if(We(s,r),t.has(s.id))throw new Error(`Duplicate change-tour scene id: ${s.id}`);t.add(s.id)}for(let[r,s]of e.chapters.entries()){if(!P(s))throw new Error(`chapters[${r}] must be an object.`);$(s.id,`chapters[${r}].id`),$(s.title,`chapters[${r}].title`),de(s.sceneIds,`chapters[${r}].sceneIds`);for(let a of s.sceneIds)if(!t.has(a))throw new Error(`Chapter references unknown scene id: ${a}`)}if(e.summary.includedScenes!==e.scenes.length)throw new Error("summary.includedScenes must match the number of scenes.");let n=e.files===void 0?$n(e.scenes):e.files.map((r,s)=>(kn(r,s),r));if(e.files!==void 0&&e.summary.changedFiles!==n.length)throw new Error("summary.changedFiles must match the number of files.");return{...e,files:n}}function We(e,t){if(!P(e)||!["text-diff","discussion","walkthrough","stacked-diff","deconstructed-diff"].includes(String(e.kind)))throw new Error(`scenes[${t}] must be a text-diff, discussion, walkthrough, stacked-diff, or deconstructed-diff scene.`);for(let n of["id","title"])$(e[n],`scenes[${t}].${n}`);if(Nn(e,`scenes[${t}]`),e.kind!=="discussion"){if(e.kind==="walkthrough"){if(!Array.isArray(e.steps)||e.steps.length===0)throw new Error(`scenes[${t}].steps must be a non-empty array.`);for(let[n,r]of e.steps.entries()){let s=`scenes[${t}].steps[${n}]`;if(!P(r)||!P(r.focus)||!P(r.diff))throw new Error(`${s} must contain focus and diff objects.`);for(let a of["id","title","body"])$(r[a],`${s}.${a}`);if(r.depth!==void 0&&!["mentioned","explained","contextualized"].includes(String(r.depth)))throw new Error(`${s}.depth must be mentioned, explained, or contextualized.`);if(Be(r.focus,`${s}.focus`),We(r.diff,t),r.diff.kind!=="text-diff")throw new Error(`${s}.diff must be a text-diff scene.`);if(r.connection!==void 0){if(!P(r.connection))throw new Error(`${s}.connection must be an object.`);$(r.connection.id,`${s}.connection.id`),$(r.connection.label,`${s}.connection.label`),Be(r.connection.from,`${s}.connection.from`),Be(r.connection.to,`${s}.connection.to`)}}return}if(e.kind==="stacked-diff"){Cn(e,t);return}if(e.kind==="deconstructed-diff"){Ln(e,t);return}for(let n of["path","leftLabel","rightLabel","leftContent","rightContent"])$(e[n],`scenes[${t}].${n}`);e.previousPath!==void 0&&$(e.previousPath,`scenes[${t}].previousPath`),$(e.changeKind,`scenes[${t}].changeKind`),ee(e.additions,`scenes[${t}].additions`),ee(e.deletions,`scenes[${t}].deletions`),e.focusChangeIndex!==void 0&&ee(e.focusChangeIndex,`scenes[${t}].focusChangeIndex`)}}function Cn(e,t){if(!Array.isArray(e.stack)||e.stack.length<3||e.stack.length>6)throw new Error(`scenes[${t}].stack must contain between 3 and 6 revisions.`);for(let[n,r]of e.stack.entries()){if(!P(r))throw new Error(`scenes[${t}].stack[${n}] must be an object.`);for(let s of["id","ref","oid","label"])$(r[s],`scenes[${t}].stack[${n}].${s}`)}xt(e.files,e.stack.length,t),vt(e.steps,e.stack.length,t,!1)}function Ln(e,t){if(e.stageLabel!=="Explanation stages")throw new Error(`scenes[${t}].stageLabel must be Explanation stages.`);if(!P(e.realRange))throw new Error(`scenes[${t}].realRange must be an object.`);for(let r of["baseRef","targetRef","baseOid","targetOid"])$(e.realRange[r],`scenes[${t}].realRange.${r}`);if(!Array.isArray(e.panels)||e.panels.length<2||e.panels.length>13)throw new Error(`scenes[${t}].panels must contain a baseline and between 1 and 12 stages.`);let n=e.panels;for(let[r,s]of n.entries()){if(!P(s))throw new Error(`scenes[${t}].panels[${r}] must be an object.`);for(let c of["id","label","role"])$(s[c],`scenes[${t}].panels[${r}].${c}`);let a=r===0?"baseline":"stage";if(s.role!==a)throw new Error(`scenes[${t}].panels[${r}].role must be ${a}.`);r>0&&$(s.stageId,`scenes[${t}].panels[${r}].stageId`)}if(xt(e.files,n.length,t),vt(e.steps,n.length,t,!0),Array.isArray(e.steps)&&e.steps.length!==n.length-1)throw new Error(`scenes[${t}].steps must match the number of explanation stages.`);Array.isArray(e.steps)&&e.steps.forEach((r,s)=>{let a=n[s+1];if(!P(r)||!P(a)||a.stageId!==r.id)throw new Error(`scenes[${t}].panels must align with explanation stage ids.`)})}function xt(e,t,n){if(!Array.isArray(e)||e.length===0)throw new Error(`scenes[${n}].files must be non-empty.`);for(let[r,s]of e.entries()){if(!P(s))throw new Error(`scenes[${n}].files[${r}] must be an object.`);if($(s.path,`scenes[${n}].files[${r}].path`),!Array.isArray(s.panels)||s.panels.length!==t)throw new Error(`scenes[${n}].files[${r}].panels must match panel count.`);for(let[a,c]of s.panels.entries()){if(!P(c))throw new Error(`scenes[${n}].files[${r}].panels[${a}] must be an object.`);for(let i of["id","label","content"])$(c[i],`scenes[${n}].files[${r}].panels[${a}].${i}`);if(c.path!==void 0&&$(c.path,`scenes[${n}].files[${r}].panels[${a}].path`),typeof c.exists!="boolean")throw new Error(`scenes[${n}].files[${r}].panels[${a}].exists must be boolean.`)}}}function vt(e,t,n,r){if(!Array.isArray(e)||e.length===0)throw new Error(`scenes[${n}].steps must be non-empty.`);for(let[s,a]of e.entries()){if(!P(a))throw new Error(`scenes[${n}].steps[${s}] must be an object.`);for(let c of["id","title","body","file","side"])$(a[c],`scenes[${n}].steps[${s}].${c}`);if(ee(a.pairIndex,`scenes[${n}].steps[${s}].pairIndex`),Number(a.pairIndex)>=t-1)throw new Error(`scenes[${n}].steps[${s}].pairIndex is outside the panels.`);if(r){if(de(a.introducedHunks,`scenes[${n}].steps[${s}].introducedHunks`),a.introducedHunks.length===0)throw new Error(`scenes[${n}].steps[${s}].introducedHunks must be non-empty.`);if(Number(a.pairIndex)!==s)throw new Error(`scenes[${n}].steps[${s}].pairIndex must match its explanation stage.`)}if(a.side!=="left"&&a.side!=="right")throw new Error(`scenes[${n}].steps[${s}].side must be left or right.`);a.startLine!==void 0&&Ce(a.startLine,`scenes[${n}].steps[${s}].startLine`),a.endLine!==void 0&&Ce(a.endLine,`scenes[${n}].steps[${s}].endLine`)}}function kn(e,t){if(!P(e))throw new Error(`files[${t}] must be an object.`);if(e.kind==="text-diff"){We(e,t);return}if(e.kind!=="omitted")throw new Error(`files[${t}].kind must be text-diff or omitted.`);for(let n of["id","title","path","changeKind","reason"])$(e[n],`files[${t}].${n}`);e.previousPath!==void 0&&$(e.previousPath,`files[${t}].previousPath`),ee(e.additions,`files[${t}].additions`),ee(e.deletions,`files[${t}].deletions`)}function $n(e){let t=new Map;for(let n of e){if(n.kind==="text-diff"){t.has(n.path)||t.set(n.path,n);continue}if(n.kind==="walkthrough")for(let r of n.steps)t.has(r.diff.path)||t.set(r.diff.path,r.diff)}return[...t.values()].sort((n,r)=>n.path.localeCompare(r.path))}function Be(e,t){if(!P(e))throw new Error(`${t} must be an object.`);for(let n of["id","path","revision","excerpt"])$(e[n],`${t}.${n}`);if(e.revision!=="base"&&e.revision!=="head")throw new Error(`${t}.revision must be base or head.`);if(Ce(e.startLine,`${t}.startLine`),Ce(e.endLine,`${t}.endLine`),Number(e.endLine)<Number(e.startLine))throw new Error(`${t}.endLine must not precede startLine.`)}function Nn(e,t){$(e.summary,`${t}.summary`),de(e.bullets,`${t}.bullets`),de(e.tags,`${t}.tags`),$(e.takeaway,`${t}.takeaway`)}function P(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function $(e,t){if(typeof e!="string")throw new Error(`${t} must be a string.`)}function de(e,t){if(!Array.isArray(e)||e.some(n=>typeof n!="string"))throw new Error(`${t} must be an array of strings.`)}function ee(e,t){if(!Number.isInteger(e)||Number(e)<0)throw new Error(`${t} must be a non-negative integer.`)}function Ce(e,t){if(!Number.isInteger(e)||Number(e)<1)throw new Error(`${t} must be a positive integer.`)}function St(e,t,n){let r=e.findIndex(i=>i.id===t),s=r>=0?r:0,a=e[s];if(!a||a.kind!=="walkthrough"&&a.kind!=="stacked-diff"&&a.kind!=="deconstructed-diff"||!n)return{sceneIndex:s,stepIndex:0};let c=a.steps.findIndex(i=>i.id===n);return{sceneIndex:s,stepIndex:c>=0?c:0}}function Et(e,t,n){let r=e[t.sceneIndex];if(!r)return null;if(n>0)return(r.kind==="walkthrough"||r.kind==="stacked-diff"||r.kind==="deconstructed-diff")&&t.stepIndex<r.steps.length-1?{sceneIndex:t.sceneIndex,stepIndex:t.stepIndex+1}:t.sceneIndex<e.length-1?{sceneIndex:t.sceneIndex+1,stepIndex:0}:null;if((r.kind==="walkthrough"||r.kind==="stacked-diff"||r.kind==="deconstructed-diff")&&t.stepIndex>0)return{sceneIndex:t.sceneIndex,stepIndex:t.stepIndex-1};if(t.sceneIndex===0)return null;let s=e[t.sceneIndex-1];return{sceneIndex:t.sceneIndex-1,stepIndex:s.kind==="walkthrough"||s.kind==="stacked-diff"||s.kind==="deconstructed-diff"?s.steps.length-1:0}}function Ct(e,t,n){if(!t)return null;let r=e.map((i,u)=>({file:i,fileIndex:u})).filter(({file:i})=>i.kind==="text-diff"),s=r.findIndex(({file:i})=>i.path===t),a=s+n,c=s>=0?r[a]:null;return c?{fileIndex:c.fileIndex,path:c.file.path}:null}function Lt(e,t,n){let r=e[t.sceneIndex],s=Tt(r,t.sceneIndex,t.stepIndex,n);if(s)return s;for(let a=0;a<e.length;a+=1){if(a===t.sceneIndex)continue;let c=Tt(e[a],a,0,n);if(c)return c}return null}function Tt(e,t,n,r){if(!e||e.kind!=="stacked-diff"&&e.kind!=="deconstructed-diff"||!e.files.some(c=>c.path===r))return null;let a=e.steps[n]?.file===r?n:e.steps.findIndex(c=>c.file===r);return{sceneIndex:t,stepIndex:a>=0?a:Math.max(n,0)}}function $t(e,t,n="all",r=300){let s=t.trim().toLocaleLowerCase();if(!s||r<=0)return[];let a=[];if(n!=="code"){let c=new Map;e.chapters.forEach(i=>i.sceneIds.forEach(u=>c.set(u,i.title))),e.scenes.forEach((i,u)=>{let d=[c.get(i.id),i.title,i.summary,...i.bullets,...i.tags,i.takeaway],g=kt(d,s);g&&a.push({kind:"narrative",sceneIndex:u,label:i.title,preview:g}),Rn(i)&&i.steps.forEach((h,E)=>{let L=kt([h.title,h.body,"connection"in h?h.connection?.label:void 0],s);L&&a.push({kind:"narrative",sceneIndex:u,stepIndex:E,label:`${i.title} \xB7 ${h.title}`,preview:L})})})}if(n!=="narrative"&&a.length<r)for(let c=0;c<e.files.length;c+=1){let i=e.files[c];if(i.kind==="text-diff"){for(let[u,d]of[[0,i.leftContent],[1,i.rightContent]])for(let g of An(d,s))if(a.push({kind:"code",fileIndex:c,sideIndex:u,label:`${i.path} \xB7 ${u===0?"base":"head"}`,...g}),a.length>=r)return a}}return a.slice(0,r)}function kt(e,t){return e.find(n=>n?.toLocaleLowerCase().includes(t))}function An(e,t){let n=[];return e.replace(/\r\n/g,`
149
149
  `).split(`
150
- `).forEach((r,s)=>{let a=r.toLocaleLowerCase(),l=0;for(;l<=a.length-t.length;){let i=a.indexOf(t,l);if(i<0)break;n.push({lineNumber:s+1,startColumn:i+1,endColumn:i+t.length+1,preview:r}),l=i+Math.max(t.length,1)}}),n}function An(e){return e.kind==="walkthrough"||e.kind==="stacked-diff"||e.kind==="deconstructed-diff"}function $t(e,t){let n=e?.blocks[0],r=t==="left"?e?.leftLines:e?.rightLines;if(!n||!r?.length)return;let s=t==="left"?n.leftStart:n.rightStart,a=t==="left"?n.leftEnd:n.rightEnd,l=r.slice(s,a),i=l[0]?.lineNumber??r[Math.min(s,r.length-1)]?.lineNumber;if(Number.isInteger(i))return{startLine:i,endLine:l.at(-1)?.lineNumber??i}}function At(e,t,n,r){let s=[];return e.scenes.forEach((a,l)=>{a.kind==="walkthrough"&&a.steps.forEach((i,u)=>{i.diff.path===t&&s.push({side:i.focus.revision==="base"?"left":"right",startLine:i.focus.startLine,endLine:i.focus.endLine,label:`${a.title} \xB7 ${i.title}: ${i.body}`,active:l===n&&u===r,jumpTarget:{sceneIndex:l,stepIndex:u}})})}),s}function Rt(e,t,n,r,s){let a=[];return e.scenes.forEach((l,i)=>{l.kind==="stacked-diff"&&l.steps.forEach((u,d)=>{if(u.file!==t)return;let g=u.startLine===void 0?s?.(u.pairIndex,u.side):{startLine:u.startLine,endLine:u.endLine??u.startLine};if(!g)return;let h=u.pairIndex+(u.side==="right"?1:0);a.push({pairIndex:u.pairIndex,panelIndex:h,side:u.side,startLine:g.startLine,endLine:g.endLine,label:`${l.title} \xB7 ${u.title}: ${u.body}`,active:i===n&&d===r,jumpTarget:{sceneIndex:i,stepIndex:d}})})}),a}(function(){let t="bygone.tourSidebarWidth",s="bygone.tourNarrativeHeight",i={mode:"empty",left:null,right:null,comparisonId:0,tour:null,activeSceneIndex:-1,activeStepIndex:0,activeTourFilePath:null,tourFocusFilePath:null,tourSidebarWidth:I(),tourSidebarHidden:!1,tourNarrativeHeight:_()};window.__BYGONE_HOST__={environment:"web",editorWorkerUrl:"/media/editor.worker.js",postMessage(o){d(o)}},window.addEventListener("DOMContentLoaded",()=>{g(),j("Browser host ready.")});function u(o){window.dispatchEvent(new window.CustomEvent("bygone:host-message",{detail:o}))}async function d(o){if(!(!o||typeof o!="object")){if(o.type==="ready"){let c=new URLSearchParams(window.location.search),m=c.get("manifest");m?fe(m):c.get("demo")==="1"&&Xe();return}if(o.type==="navigateFile"&&i.mode==="tour"){Dt(o.direction==="previous"?-1:1);return}if(o.type==="navigateTourStep"&&i.mode==="tour"){let c=o.sceneIndex,m=o.stepIndex;Number.isInteger(c)&&Number.isInteger(m)&&oe(c,m);return}o.type==="recomputeDiff"&&i.mode==="diff"&&i.left&&i.right&&(i.left.content=o.leftContent,i.right.content=o.rightContent,u({type:"showDiff",file1:i.left.name,file2:i.right.name,comparisonId:`web-${i.comparisonId}`,leftContent:i.left.content,rightContent:i.right.content,diffModel:Q(i.left.content,i.right.content),history:null}))}}function g(){let o=document.getElementById("web-compare-test"),c=document.getElementById("web-open-diff"),m=document.getElementById("web-open-diff3"),f=document.getElementById("web-diff-input"),p=document.getElementById("web-diff3-input"),E=document.getElementById("tour-previous"),S=document.getElementById("tour-next"),$=document.getElementById("tour-return-focus"),R=document.getElementById("tour-search-input"),U=document.getElementById("tour-search-scope");C(),N(),o?.addEventListener("click",()=>{Xe()}),c?.addEventListener("click",()=>{f.value="",f.click()}),m?.addEventListener("click",()=>{p.value="",p.click()}),f?.addEventListener("change",async()=>{let y=Array.from(f.files||[]);if(y.length!==2){j("Select exactly 2 files for a diff.");return}await zt(y)}),p?.addEventListener("change",async()=>{let y=Array.from(p.files||[]);if(y.length<1){j("Select one or more files.");return}await qt(y)}),E?.addEventListener("click",()=>me(-1)),S?.addEventListener("click",()=>me(1)),$?.addEventListener("click",_t),R?.addEventListener("input",T),U?.addEventListener("change",T),document.getElementById("tour-search-results")?.addEventListener("click",y=>{let W=y.target instanceof Element?y.target.closest("[data-tour-search-result]"):null;W&&L(Number(W.getAttribute("data-tour-search-result")))}),window.addEventListener("keydown",y=>{if(i.mode==="tour"&&(y.metaKey||y.ctrlKey)&&y.shiftKey&&y.key.toLocaleLowerCase()==="f"){y.preventDefault(),y.stopImmediatePropagation(),i.tourSidebarHidden&&k(!1),R?.focus(),R?.select();return}i.mode!=="tour"||y.metaKey||y.ctrlKey||y.altKey||Wt(y.target)||(y.key==="PageUp"||y.key==="ArrowLeft"?(y.preventDefault(),me(-1)):(y.key==="PageDown"||y.key==="ArrowRight")&&(y.preventDefault(),me(1)))},!0)}let h=[];function T(){let o=document.getElementById("tour-search-input"),c=document.getElementById("tour-search-scope"),m=document.getElementById("tour-search-status"),f=document.getElementById("tour-search-results");if(!(!i.tour||!o||!c||!m||!f)){if(h=Nt(i.tour,o.value,c.value),!o.value.trim()){m.textContent="Cmd/Ctrl+Shift+F",f.replaceChildren();return}m.textContent=`${h.length} result${h.length===1?"":"s"}`,f.replaceChildren(...h.map((p,E)=>{let S=document.createElement("button");S.type="button",S.className="tour-search-result",S.setAttribute("role","option"),S.dataset.tourSearchResult=String(E),S.title=`Open ${p.kind==="code"?`${p.label}:${p.lineNumber}`:p.label}`;let $=document.createElement("span");$.className="tour-search-location",$.textContent=p.kind==="code"?`${p.label}:${p.lineNumber}`:p.label;let R=document.createElement("span");return R.className="tour-search-preview",R.textContent=p.preview.trim(),S.append($,R),S}))}}function L(o){let c=h[o];if(c){if(c.kind==="narrative"){oe(c.sceneIndex,c.stepIndex??0);return}je(c.fileIndex)&&window.requestAnimationFrame(()=>u({type:"revealSearchResult",sideIndex:c.sideIndex,lineNumber:c.lineNumber,startColumn:c.startColumn,endColumn:c.endColumn}))}}function C(){let o=document.getElementById("tour-shell"),c=document.getElementById("tour-sidebar-resizer"),m=document.getElementById("tour-sidebar-hide"),f=document.getElementById("tour-sidebar-show");!o||!c||!m||!f||(x(),m.addEventListener("click",()=>k(!0)),f.addEventListener("click",()=>k(!1)),c.addEventListener("pointerdown",p=>{p.preventDefault(),document.body.classList.add("is-resizing-tour-sidebar"),c.setPointerCapture?.(p.pointerId);let E=$=>b($.clientX),S=()=>{document.body.classList.remove("is-resizing-tour-sidebar"),window.removeEventListener("pointermove",E),window.removeEventListener("pointerup",S),window.removeEventListener("pointercancel",S),window.localStorage.setItem(t,String(i.tourSidebarWidth))};window.addEventListener("pointermove",E),window.addEventListener("pointerup",S),window.addEventListener("pointercancel",S)}),c.addEventListener("keydown",p=>{if(!["ArrowLeft","ArrowRight","Home","End"].includes(p.key))return;p.preventDefault();let E=i.tourSidebarWidth;p.key==="Home"?E=240:p.key==="End"?E=w():E+=p.key==="ArrowLeft"?-16:16,b(E),window.localStorage.setItem(t,String(i.tourSidebarWidth))}))}function I(){let o=Number.parseInt(window.localStorage.getItem(t)||"",10);return Number.isFinite(o)?Math.min(600,Math.max(240,o)):360}function w(){return Math.max(240,Math.min(600,Math.floor(window.innerWidth*.6)))}function b(o){i.tourSidebarWidth=Math.min(w(),Math.max(240,Math.round(o))),x(),window.dispatchEvent(new Event("resize"))}function x(){document.documentElement.style.setProperty("--tour-rail-width",`${i.tourSidebarWidth}px`);let o=document.getElementById("tour-sidebar-resizer");o?.setAttribute("aria-valuemax",String(w())),o?.setAttribute("aria-valuenow",String(i.tourSidebarWidth))}function k(o){i.tourSidebarHidden=o,document.body.classList.toggle("tour-sidebar-hidden",o);let c=document.getElementById("tour-sidebar-show");c&&(c.hidden=!o),window.dispatchEvent(new Event("resize"))}function N(){let o=document.getElementById("tour-narrative-resizer");o&&(B(),o.addEventListener("pointerdown",c=>{c.preventDefault(),document.body.classList.add("is-resizing-tour-narrative"),o.setPointerCapture?.(c.pointerId),window.dispatchEvent(new CustomEvent("bygone:workspace-resize-start"));let m=document.getElementById("tour-narrative")?.getBoundingClientRect().top||0,f=E=>O(E.clientY-m),p=()=>{document.body.classList.remove("is-resizing-tour-narrative"),window.removeEventListener("pointermove",f),window.removeEventListener("pointerup",p),window.removeEventListener("pointercancel",p),window.dispatchEvent(new CustomEvent("bygone:workspace-resize-end")),ie()};window.addEventListener("pointermove",f),window.addEventListener("pointerup",p),window.addEventListener("pointercancel",p)}),o.addEventListener("keydown",c=>{if(!["ArrowUp","ArrowDown","Home","End"].includes(c.key))return;c.preventDefault();let m=c.key==="Home"?180:c.key==="End"?M():i.tourNarrativeHeight+(c.key==="ArrowUp"?-16:16);O(m),ie()}),window.addEventListener("resize",()=>{i.tourNarrativeHeight=Math.min(M(),i.tourNarrativeHeight),B()}))}function _(){let o=Number.parseInt(window.localStorage.getItem(s)||"",10);if(Number.isFinite(o))return Math.max(180,o);let c=Number.parseInt(window.getComputedStyle(document.documentElement).getPropertyValue("--tour-narrative-height"),10);return Number.isFinite(c)?c:296}function M(){let o=document.getElementById("tour-narrative")?.getBoundingClientRect().top||0;return Math.max(180,window.innerHeight-o-180)}function O(o){i.tourNarrativeHeight=Math.min(M(),Math.max(180,Math.round(o))),B(),window.dispatchEvent(new Event("resize"))}function B(){document.documentElement.style.setProperty("--tour-narrative-height",`${i.tourNarrativeHeight}px`);let o=document.getElementById("tour-narrative-resizer");o?.setAttribute("aria-valuemax",String(M())),o?.setAttribute("aria-valuenow",String(i.tourNarrativeHeight))}function ie(){window.localStorage.setItem(s,String(i.tourNarrativeHeight))}async function fe(o){j("Loading change tour\u2026");try{let c=await fetch(o,{cache:"no-store"});if(!c.ok)throw new Error(`Manifest request failed (${c.status}).`);i.tour=It(await c.json()),i.mode="tour",document.body.classList.add("tour-mode"),Ft(),T();let m=new URLSearchParams(window.location.search),f=St(i.tour.scenes,m.get("scene"),m.get("step"));oe(f.sceneIndex,f.stepIndex),j("")}catch(c){j(`Could not load change tour: ${c instanceof Error?c.message:String(c)}`)}}function Ft(){let o=i.tour;if(!o)return;let c=document.getElementById("tour-shell"),m=document.getElementById("tour-title"),f=document.getElementById("tour-source"),p=document.getElementById("tour-range"),E=document.getElementById("tour-stats"),S=document.getElementById("tour-scenes"),$=document.getElementById("tour-scene-count"),R=document.getElementById("tour-files"),U=document.getElementById("tour-file-count"),y=document.getElementById("tour-commits"),W=document.getElementById("tour-commits-summary");if(!c||!m||!f||!p||!E||!S||!$||!R||!U||!y||!W)throw new Error("Presenter UI is incomplete.");c.hidden=!1,m.textContent=o.title,o.sourceUrl?(f.href=o.sourceUrl,f.hidden=!1):f.hidden=!0;let K=be(o.range.baseRef),F=be(o.range.headRef),z=o.range.headOid.slice(0,7);p.textContent=`${K} \u2192 ${F}${F===z?"":` \xB7 ${z}`}`,E.textContent=`${ce(o.summary.changedFiles,"file")} \xB7 +${o.summary.additions} \u2212${o.summary.deletions} \xB7 ${ce(o.summary.commitCount,"commit")}`,$.textContent=String(o.scenes.length),U.textContent=String(o.files.length),W.textContent=ce(o.summary.commitCount,"commit"),S.replaceChildren();let we=new Map(o.scenes.map(v=>[v.id,v]));for(let v of o.chapters){let G=document.createElement("h2");G.className="tour-chapter-title",G.textContent=v.title,S.append(G);for(let D of v.sceneIds){let P=we.get(D);if(!P)continue;let te=o.scenes.indexOf(P),q=document.createElement("button");q.type="button",q.className="tour-scene",q.dataset.sceneId=P.id,q.title=`Open scene: ${P.kind==="text-diff"?P.path:P.title}`,q.addEventListener("click",()=>oe(te));let Z=document.createElement("span");Z.className="tour-scene-number",Z.textContent=String(te+1).padStart(2,"0");let $e=document.createElement("span");$e.className="tour-scene-copy";for(let[jt,Kt]of[["tour-scene-title",P.title],["tour-scene-path",P.kind==="text-diff"?P.path:P.kind==="deconstructed-diff"?ce(P.steps.length,"explanation stage"):ae(P)?ce(P.steps.length,"code step"):"Discussion"],["tour-scene-note",P.takeaway]]){let Ae=document.createElement("span");Ae.className=jt,Ae.textContent=Kt,$e.append(Ae)}q.append(Z,$e),S.append(q)}}R.replaceChildren(...o.files.map((v,G)=>{let D=document.createElement("button");D.type="button",D.className=`tour-file${v.kind==="omitted"?" is-omitted":""}`,D.dataset.filePath=v.path,D.disabled=v.kind==="omitted",D.title=v.kind==="omitted"?`${v.path}: ${v.reason}`:`Open file: ${v.path}`,v.kind==="text-diff"&&D.addEventListener("click",()=>Ke(G));let P=document.createElement("span");P.className="tour-file-marker",P.textContent=v.kind==="omitted"?"\xD7":Pt(v.changeKind);let te=document.createElement("span");te.className="tour-file-copy";let q=document.createElement("span");q.className="tour-file-path",q.textContent=v.path;let Z=document.createElement("span");return Z.className="tour-file-meta",Z.textContent=v.kind==="omitted"?`Not rendered \xB7 ${v.reason}`:`${Ot(v.changeKind)} \xB7 +${v.additions} \u2212${v.deletions}`,te.append(q,Z),D.append(P,te),D})),y.replaceChildren(...o.commits.map(v=>{let G=document.createElement("li"),D=document.createElement("span");return D.className="tour-commit-oid",D.textContent=v.shortOid,G.append(D,document.createTextNode(v.summary)),G}))}function oe(o,c=0){let m=i.tour;if(!m||o<0||o>=m.scenes.length)return;let f=m.scenes[o];i.activeSceneIndex=o,i.activeStepIndex=ae(f)?Math.min(Math.max(c,0),Math.max(f.steps.length-1,0)):0,i.tourFocusFilePath=f.kind==="text-diff"?f.path:f.kind==="walkthrough"?f.steps[i.activeStepIndex]?.diff.path??null:pe(f)?f.steps[i.activeStepIndex]?.file??null:null;let p=Bt(m,o);document.querySelectorAll(".tour-scene").forEach(S=>{S.classList.toggle("is-active",S.dataset.sceneId===f.id)}),document.querySelector(`.tour-scene[data-scene-id="${f.id}"]`)?.scrollIntoView({block:"nearest"}),Gt(f,p);let E=new URLSearchParams(window.location.search);if(E.set("scene",f.id),ae(f)?E.set("step",f.steps[i.activeStepIndex].id):E.delete("step"),window.history.replaceState(null,"",`${window.location.pathname}?${E.toString()}`),f.kind==="discussion"){document.body.classList.add("tour-discussion"),Ne();return}if(document.body.classList.remove("tour-discussion"),f.kind==="walkthrough"){Ge(f);return}if(pe(f)){ze(f);return}ge(f,he(f.path))}function he(o){let c=i.tour;return!c||!o?[]:At(c,o,i.activeSceneIndex,i.activeStepIndex)}function Mt(o,c){let m=i.tour;return!m||!o?[]:Rt(m,o,i.activeSceneIndex,i.activeStepIndex,(f,p)=>$t(c?.[f]?.diffModel,p))}function Le(o){return`file::${o}`}function ge(o,c=[],m=Le(o.path)){if(!i.tour)return;i.activeTourFilePath=o.path,Ne();let p=Q(o.leftContent,o.rightContent),E=We(o,o.leftLabel,"base"),S=We(o,o.rightLabel,"head"),$=c.find(R=>R.active);u({type:"showDiff",file1:E,file2:S,comparisonId:`tour-${m}`,leftContent:o.leftContent,rightContent:o.rightContent,sourceInfo:{leftPath:o.path,rightPath:o.path},diffModel:p,history:null,fileNavigation:{canGoPrevious:!!se(-1),canGoNext:!!se(1)},editableSides:{left:!1,right:!1},comparisonSummary:`${o.path} \xB7 ${o.takeaway}`,initialChangeIndex:$?Ve(p,$.side,$.startLine):o.focusChangeIndex,tourAnnotations:c})}function We(o,c,m){let f=c.startsWith(o.path)?c.slice(o.path.length).trim():c.trim();return f?`${m} ${f}`:m}function Ge(o){let c=o.steps[i.activeStepIndex];c&&ge(c.diff,he(c.diff.path),Le(c.diff.path))}function ze(o){let c=o.steps[i.activeStepIndex];c&&qe(o,c.file,c)}function qe(o,c,m){let f=o.files.find(F=>F.path===c);if(!m||!f)return;i.activeTourFilePath=f.path,Ne();let p=f.panels.map((F,z)=>({id:`${o.id}-${f.path}-${F.id}`,label:F.label,path:F.path||f.path,content:F.content,savedContent:F.content,dirty:!1,editable:!1,stackId:Ht(o)[z].id})),E=p.slice(0,-1).map((F,z)=>({leftIndex:z,rightIndex:z+1,diffModel:Q(F.content,p[z+1].content)})),S=o.kind==="stacked-diff"?Mt(f.path,E):[],$=S.find(F=>F.active),R=$?.pairIndex??m.pairIndex,U=$?.side??m.side,y=$?.startLine??m.startLine,W=E[R]?.diffModel,K=W&&y?Ve(W,U,y):0;u({type:"showMultiDiff",panels:p,pairs:E,activePanelId:p[R+(U==="right"?1:0)]?.id,activePairIndex:R,initialChangeIndex:K,revealFirstChangeInEachPanel:o.kind==="deconstructed-diff",history:null,fileNavigation:{canGoPrevious:!!se(-1),canGoNext:!!se(1)},mutationEnabled:!1,comparisonSummary:o.kind==="deconstructed-diff"?`${o.stageLabel} \xB7 ${f.path} \xB7 ${be(o.realRange.baseRef)} \u2192 ${be(o.realRange.targetRef)}`:`${f.path} \xB7 ${o.takeaway}`,tourAnnotations:S})}function ke(o){let c=i.tour;return!c||o!==-1&&o!==1?null:Tt(c.scenes,{sceneIndex:i.activeSceneIndex,stepIndex:i.activeStepIndex},o)}function me(o){let c=ke(o);return c?(oe(c.sceneIndex,c.stepIndex),!0):!1}function se(o){let c=i.tour;return!c||o!==-1&&o!==1?null:Ct(c.files,i.activeTourFilePath,o)}function Dt(o){let c=se(o);return c?Ke(c.fileIndex):!1}function je(o){let c=i.tour?.files[o];return!c||c.kind!=="text-diff"?!1:(ge(c,he(c.path),Le(c.path)),!0)}function Ke(o){let c=i.tour?.files[o];if(c?.kind==="text-diff"&&i.tour){let m=Lt(i.tour.scenes,{sceneIndex:i.activeSceneIndex,stepIndex:i.activeStepIndex},c.path);if(m){let f=i.tour.scenes[m.sceneIndex],p=pe(f)?f.steps[m.stepIndex]:null;if(p)return qe(f,c.path,p),!0}}return je(o)}function _t(){let o=i.tour?.scenes[i.activeSceneIndex];if(!o||!i.tourFocusFilePath)return!1;if(o.kind==="walkthrough")Ge(o);else if(pe(o))ze(o);else if(o.kind==="text-diff")ge(o,he(o.path));else return!1;return!0}function Ne(){document.querySelectorAll(".tour-file").forEach(c=>{c.classList.toggle("is-active",c.dataset.filePath===i.activeTourFilePath),c.classList.toggle("is-tour-focus",c.dataset.filePath===i.tourFocusFilePath)}),document.querySelector(".tour-file.is-active")?.scrollIntoView({block:"nearest"});let o=document.getElementById("tour-return-focus");o&&(o.hidden=!i.tourFocusFilePath||i.activeTourFilePath===i.tourFocusFilePath)}function ae(o){return o.kind==="walkthrough"||o.kind==="stacked-diff"||o.kind==="deconstructed-diff"}function pe(o){return o.kind==="stacked-diff"||o.kind==="deconstructed-diff"}function Ht(o){return o.kind==="deconstructed-diff"?o.panels:o.stack}function Pt(o){return{added:"+",deleted:"\u2212",renamed:"\u2192",modified:"\u2022"}[o]||"\u2022"}function Ot(o){return`${o.charAt(0).toUpperCase()}${o.slice(1)}`}function Bt(o,c){let m=o.scenes[c],f=o.chapters.findIndex($=>$.sceneIds.includes(m.id)),p=f>=0?o.chapters[f]:null,E=p?p.sceneIds.indexOf(m.id)+1:c+1,S=p?p.sceneIds.length:o.scenes.length;return{chapter:p,chapterIndex:f,chapterNumber:f>=0?f+1:c+1,sceneInChapter:E,scenesInChapter:S}}function Ut(o,c,m){let f=[`Ch ${o.chapterNumber}`,`Scene ${o.sceneInChapter}/${o.scenesInChapter}`];return ae(c)&&f.push(`Step ${m+1}/${c.steps.length}`),f.join(" \xB7 ")}function Ve(o,c,m){let p=(c==="left"?o.leftLines:o.rightLines).findIndex(y=>y.lineNumber===m);if(p<0)return 0;let E=c==="left"?"leftStart":"rightStart",S=c==="left"?"leftEnd":"rightEnd",$=o.blocks.findIndex(y=>p>=y[E]&&p<y[S]);if($>=0)return $;let R=0,U=Number.POSITIVE_INFINITY;return o.blocks.forEach((y,W)=>{let K=Math.min(Math.abs(p-y[E]),Math.abs(p-y[S]));K<U&&(R=W,U=K)}),R}function be(o){return/^[0-9a-f]{40}$/i.test(o)?o.slice(0,7):o}function ce(o,c){return`${o} ${o===1?c:`${c}s`}`}function Wt(o){return o instanceof Element&&!!o.closest('a, button, input, select, summary, textarea, [contenteditable="true"], [role="textbox"], .monaco-editor')}function Gt(o,c){let m=document.getElementById("tour-narrative"),f=document.getElementById("tour-breadcrumb"),p=document.getElementById("tour-narrative-chapter"),E=document.getElementById("tour-narrative-title"),S=document.getElementById("tour-narrative-summary"),$=document.getElementById("tour-narrative-bullets"),R=document.getElementById("tour-narrative-tags"),U=document.getElementById("tour-narrative-takeaway"),y=document.getElementById("tour-step"),W=document.getElementById("tour-step-title"),K=document.getElementById("tour-step-body"),F=document.getElementById("tour-connection"),z=document.getElementById("tour-previous"),we=document.getElementById("tour-next");if(!m||!f||!p||!E||!S||!$||!R||!U||!y||!W||!K||!F||!z||!we)throw new Error("Tour narrative UI is incomplete.");m.hidden=!1,f.textContent=Ut(c,o,i.activeStepIndex),p.textContent=o.kind==="deconstructed-diff"?`${c.chapter?.title||"Change tour"} \xB7 ${o.stageLabel}`:c.chapter?.title||"Change tour",E.textContent=o.title,S.textContent=o.summary,$.replaceChildren(...o.bullets.map(G=>{let D=document.createElement("li");return D.textContent=G,D})),R.replaceChildren(...o.tags.map(G=>{let D=document.createElement("span");return D.textContent=G,D})),U.textContent=o.takeaway;let v=ae(o)?o.steps[i.activeStepIndex]:null;y.hidden=!v,v?(W.textContent=o.kind==="deconstructed-diff"?`Stage ${i.activeStepIndex+1}: ${v.title}`:v.title,K.textContent=v.body,"connection"in v&&v.connection?(F.hidden=!1,F.textContent=`${v.connection.from.path} \u2192 ${v.connection.to.path} \xB7 ${v.connection.label}`):(F.hidden=!0,F.textContent="")):(F.hidden=!0,F.textContent=""),z.disabled=!ke(-1),we.disabled=!ke(1)}function Xe(){let o=yt();i.mode="diff",i.comparisonId+=1,i.left={name:o.leftFileName,content:o.leftContent},i.right={name:o.rightFileName,content:o.rightContent},j("Loaded sample diff."),u({type:"showDiff",file1:i.left.name,file2:i.right.name,comparisonId:`web-${i.comparisonId}`,leftContent:i.left.content,rightContent:i.right.content,diffModel:Q(i.left.content,i.right.content),history:null})}async function zt(o){let[c,m]=o,[f,p]=await Promise.all([c.text(),m.text()]);i.mode="diff",i.comparisonId+=1,i.left={name:c.name,content:f},i.right={name:m.name,content:p},j(`Loaded ${c.name} and ${m.name}.`),u({type:"showDiff",file1:c.name,file2:m.name,comparisonId:`web-${i.comparisonId}`,leftContent:f,rightContent:p,diffModel:Q(f,p),history:null})}async function qt(o){let c=await Promise.all(o.map(async(m,f)=>{let p=await m.text();return{id:`web-panel-${f}`,label:m.name,content:p,savedContent:p,dirty:!1,editable:!0}}));i.mode="multi-diff",j(`Loaded ${c.length}-panel diff for ${c.map(m=>m.label).join(", ")}.`),u({type:"showMultiDiff",panels:c,pairs:c.slice(0,-1).map((m,f)=>({leftIndex:f,rightIndex:f+1,diffModel:Q(m.content,c[f+1].content)}))})}function j(o){let c=document.getElementById("web-status");c&&(c.textContent=o)}})();})();
150
+ `).forEach((r,s)=>{let a=r.toLocaleLowerCase(),c=0;for(;c<=a.length-t.length;){let i=a.indexOf(t,c);if(i<0)break;n.push({lineNumber:s+1,startColumn:i+1,endColumn:i+t.length+1,preview:r}),c=i+Math.max(t.length,1)}}),n}function Rn(e){return e.kind==="walkthrough"||e.kind==="stacked-diff"||e.kind==="deconstructed-diff"}function Nt(e,t){let n=e?.blocks[0],r=t==="left"?e?.leftLines:e?.rightLines;if(!n||!r?.length)return;let s=t==="left"?n.leftStart:n.rightStart,a=t==="left"?n.leftEnd:n.rightEnd,c=r.slice(s,a),i=c[0]?.lineNumber??r[Math.min(s,r.length-1)]?.lineNumber;if(Number.isInteger(i))return{startLine:i,endLine:c.at(-1)?.lineNumber??i}}function At(e,t,n,r){let s=[];return e.scenes.forEach((a,c)=>{a.kind==="walkthrough"&&a.steps.forEach((i,u)=>{i.diff.path===t&&s.push({side:i.focus.revision==="base"?"left":"right",startLine:i.focus.startLine,endLine:i.focus.endLine,label:`${a.title} \xB7 ${i.title}: ${i.body}`,active:c===n&&u===r,jumpTarget:{sceneIndex:c,stepIndex:u}})})}),s}function Rt(e,t,n,r,s){let a=[];return e.scenes.forEach((c,i)=>{c.kind==="stacked-diff"&&c.steps.forEach((u,d)=>{if(u.file!==t)return;let g=u.startLine===void 0?s?.(u.pairIndex,u.side):{startLine:u.startLine,endLine:u.endLine??u.startLine};if(!g)return;let h=u.pairIndex+(u.side==="right"?1:0);a.push({pairIndex:u.pairIndex,panelIndex:h,side:u.side,startLine:g.startLine,endLine:g.endLine,label:`${c.title} \xB7 ${u.title}: ${u.body}`,active:i===n&&d===r,jumpTarget:{sceneIndex:i,stepIndex:d}})})}),a}function Mn(e,t=120){return e.length<=t?e:`${e.slice(0,t-1)}\u2026`}function Mt(e,t="Bygone"){let n=e?.windowTitle?.trim()||e?.title?.trim();return n?Mn(n):`${t} Tour`}(function(){let t="bygone.tourSidebarWidth",s="bygone.tourNarrativeHeight",i={mode:"empty",left:null,right:null,comparisonId:0,tour:null,activeSceneIndex:-1,activeStepIndex:0,activeTourFilePath:null,tourFocusFilePath:null,tourSidebarWidth:I(),tourSidebarHidden:!1,tourNarrativeHeight:_()};window.__BYGONE_HOST__={environment:"web",editorWorkerUrl:"/media/editor.worker.js",postMessage(o){d(o)}},window.addEventListener("DOMContentLoaded",()=>{g(),q("Browser host ready.")});function u(o){window.dispatchEvent(new window.CustomEvent("bygone:host-message",{detail:o}))}async function d(o){if(!(!o||typeof o!="object")){if(o.type==="ready"){let l=new URLSearchParams(window.location.search),m=l.get("manifest");m?fe(m):l.get("demo")==="1"&&Xe();return}if(o.type==="navigateFile"&&i.mode==="tour"){_t(o.direction==="previous"?-1:1);return}if(o.type==="navigateTourStep"&&i.mode==="tour"){let l=o.sceneIndex,m=o.stepIndex;Number.isInteger(l)&&Number.isInteger(m)&&oe(l,m);return}o.type==="recomputeDiff"&&i.mode==="diff"&&i.left&&i.right&&(i.left.content=o.leftContent,i.right.content=o.rightContent,u({type:"showDiff",file1:i.left.name,file2:i.right.name,comparisonId:`web-${i.comparisonId}`,leftContent:i.left.content,rightContent:i.right.content,diffModel:Q(i.left.content,i.right.content),history:null}))}}function g(){let o=document.getElementById("web-compare-test"),l=document.getElementById("web-open-diff"),m=document.getElementById("web-open-diff3"),f=document.getElementById("web-diff-input"),p=document.getElementById("web-diff3-input"),T=document.getElementById("tour-previous"),S=document.getElementById("tour-next"),A=document.getElementById("tour-return-focus"),R=document.getElementById("tour-search-input"),W=document.getElementById("tour-search-scope");C(),N(),o?.addEventListener("click",()=>{Xe()}),l?.addEventListener("click",()=>{f.value="",f.click()}),m?.addEventListener("click",()=>{p.value="",p.click()}),f?.addEventListener("change",async()=>{let y=Array.from(f.files||[]);if(y.length!==2){q("Select exactly 2 files for a diff.");return}await jt(y)}),p?.addEventListener("change",async()=>{let y=Array.from(p.files||[]);if(y.length<1){q("Select one or more files.");return}await qt(y)}),T?.addEventListener("click",()=>me(-1)),S?.addEventListener("click",()=>me(1)),A?.addEventListener("click",Pt),R?.addEventListener("input",E),W?.addEventListener("change",E),document.getElementById("tour-search-results")?.addEventListener("click",y=>{let U=y.target instanceof Element?y.target.closest("[data-tour-search-result]"):null;U&&L(Number(U.getAttribute("data-tour-search-result")))}),window.addEventListener("keydown",y=>{if(i.mode==="tour"&&(y.metaKey||y.ctrlKey)&&y.shiftKey&&y.key.toLocaleLowerCase()==="f"){y.preventDefault(),y.stopImmediatePropagation(),i.tourSidebarHidden&&k(!1),R?.focus(),R?.select();return}i.mode!=="tour"||y.metaKey||y.ctrlKey||y.altKey||Gt(y.target)||(y.key==="PageUp"||y.key==="ArrowLeft"?(y.preventDefault(),me(-1)):(y.key==="PageDown"||y.key==="ArrowRight")&&(y.preventDefault(),me(1)))},!0)}let h=[];function E(){let o=document.getElementById("tour-search-input"),l=document.getElementById("tour-search-scope"),m=document.getElementById("tour-search-status"),f=document.getElementById("tour-search-results");if(!(!i.tour||!o||!l||!m||!f)){if(h=$t(i.tour,o.value,l.value),!o.value.trim()){m.textContent="Cmd/Ctrl+Shift+F",f.replaceChildren();return}m.textContent=`${h.length} result${h.length===1?"":"s"}`,f.replaceChildren(...h.map((p,T)=>{let S=document.createElement("button");S.type="button",S.className="tour-search-result",S.setAttribute("role","option"),S.dataset.tourSearchResult=String(T),S.title=`Open ${p.kind==="code"?`${p.label}:${p.lineNumber}`:p.label}`;let A=document.createElement("span");A.className="tour-search-location",A.textContent=p.kind==="code"?`${p.label}:${p.lineNumber}`:p.label;let R=document.createElement("span");return R.className="tour-search-preview",R.textContent=p.preview.trim(),S.append(A,R),S}))}}function L(o){let l=h[o];if(l){if(l.kind==="narrative"){oe(l.sceneIndex,l.stepIndex??0);return}qe(l.fileIndex)&&window.requestAnimationFrame(()=>u({type:"revealSearchResult",sideIndex:l.sideIndex,lineNumber:l.lineNumber,startColumn:l.startColumn,endColumn:l.endColumn}))}}function C(){let o=document.getElementById("tour-shell"),l=document.getElementById("tour-sidebar-resizer"),m=document.getElementById("tour-sidebar-hide"),f=document.getElementById("tour-sidebar-show");!o||!l||!m||!f||(x(),m.addEventListener("click",()=>k(!0)),f.addEventListener("click",()=>k(!1)),l.addEventListener("pointerdown",p=>{p.preventDefault(),document.body.classList.add("is-resizing-tour-sidebar"),l.setPointerCapture?.(p.pointerId);let T=A=>b(A.clientX),S=()=>{document.body.classList.remove("is-resizing-tour-sidebar"),window.removeEventListener("pointermove",T),window.removeEventListener("pointerup",S),window.removeEventListener("pointercancel",S),window.localStorage.setItem(t,String(i.tourSidebarWidth))};window.addEventListener("pointermove",T),window.addEventListener("pointerup",S),window.addEventListener("pointercancel",S)}),l.addEventListener("keydown",p=>{if(!["ArrowLeft","ArrowRight","Home","End"].includes(p.key))return;p.preventDefault();let T=i.tourSidebarWidth;p.key==="Home"?T=240:p.key==="End"?T=w():T+=p.key==="ArrowLeft"?-16:16,b(T),window.localStorage.setItem(t,String(i.tourSidebarWidth))}))}function I(){let o=Number.parseInt(window.localStorage.getItem(t)||"",10);return Number.isFinite(o)?Math.min(600,Math.max(240,o)):360}function w(){return Math.max(240,Math.min(600,Math.floor(window.innerWidth*.6)))}function b(o){i.tourSidebarWidth=Math.min(w(),Math.max(240,Math.round(o))),x(),window.dispatchEvent(new Event("resize"))}function x(){document.documentElement.style.setProperty("--tour-rail-width",`${i.tourSidebarWidth}px`);let o=document.getElementById("tour-sidebar-resizer");o?.setAttribute("aria-valuemax",String(w())),o?.setAttribute("aria-valuenow",String(i.tourSidebarWidth))}function k(o){i.tourSidebarHidden=o,document.body.classList.toggle("tour-sidebar-hidden",o);let l=document.getElementById("tour-sidebar-show");l&&(l.hidden=!o),window.dispatchEvent(new Event("resize"))}function N(){let o=document.getElementById("tour-narrative-resizer");o&&(B(),o.addEventListener("pointerdown",l=>{l.preventDefault(),document.body.classList.add("is-resizing-tour-narrative"),o.setPointerCapture?.(l.pointerId),window.dispatchEvent(new CustomEvent("bygone:workspace-resize-start"));let m=document.getElementById("tour-narrative")?.getBoundingClientRect().top||0,f=T=>O(T.clientY-m),p=()=>{document.body.classList.remove("is-resizing-tour-narrative"),window.removeEventListener("pointermove",f),window.removeEventListener("pointerup",p),window.removeEventListener("pointercancel",p),window.dispatchEvent(new CustomEvent("bygone:workspace-resize-end")),ie()};window.addEventListener("pointermove",f),window.addEventListener("pointerup",p),window.addEventListener("pointercancel",p)}),o.addEventListener("keydown",l=>{if(!["ArrowUp","ArrowDown","Home","End"].includes(l.key))return;l.preventDefault();let m=l.key==="Home"?180:l.key==="End"?F():i.tourNarrativeHeight+(l.key==="ArrowUp"?-16:16);O(m),ie()}),window.addEventListener("resize",()=>{i.tourNarrativeHeight=Math.min(F(),i.tourNarrativeHeight),B()}))}function _(){let o=Number.parseInt(window.localStorage.getItem(s)||"",10);if(Number.isFinite(o))return Math.max(180,o);let l=Number.parseInt(window.getComputedStyle(document.documentElement).getPropertyValue("--tour-narrative-height"),10);return Number.isFinite(l)?l:296}function F(){let o=document.getElementById("tour-narrative")?.getBoundingClientRect().top||0;return Math.max(180,window.innerHeight-o-180)}function O(o){i.tourNarrativeHeight=Math.min(F(),Math.max(180,Math.round(o))),B(),window.dispatchEvent(new Event("resize"))}function B(){document.documentElement.style.setProperty("--tour-narrative-height",`${i.tourNarrativeHeight}px`);let o=document.getElementById("tour-narrative-resizer");o?.setAttribute("aria-valuemax",String(F())),o?.setAttribute("aria-valuenow",String(i.tourNarrativeHeight))}function ie(){window.localStorage.setItem(s,String(i.tourNarrativeHeight))}async function fe(o){q("Loading change tour\u2026");try{let l=await fetch(o,{cache:"no-store"});if(!l.ok)throw new Error(`Manifest request failed (${l.status}).`);i.tour=It(await l.json()),i.mode="tour",document.body.classList.add("tour-mode"),Ft(),E();let m=new URLSearchParams(window.location.search),f=St(i.tour.scenes,m.get("scene"),m.get("step"));oe(f.sceneIndex,f.stepIndex),q("")}catch(l){q(`Could not load change tour: ${l instanceof Error?l.message:String(l)}`)}}function Ft(){let o=i.tour;if(!o)return;let l=document.getElementById("tour-shell"),m=document.getElementById("tour-title"),f=document.getElementById("tour-source"),p=document.getElementById("tour-range"),T=document.getElementById("tour-stats"),S=document.getElementById("tour-scenes"),A=document.getElementById("tour-scene-count"),R=document.getElementById("tour-files"),W=document.getElementById("tour-file-count"),y=document.getElementById("tour-commits"),U=document.getElementById("tour-commits-summary");if(!l||!m||!f||!p||!T||!S||!A||!R||!W||!y||!U)throw new Error("Presenter UI is incomplete.");l.hidden=!1,m.textContent=o.title,document.title=Mt(o),o.sourceUrl?(f.href=o.sourceUrl,f.hidden=!1):f.hidden=!0;let K=be(o.range.baseRef),M=be(o.range.headRef),z=o.range.headOid.slice(0,7);p.textContent=`${K} \u2192 ${M}${M===z?"":` \xB7 ${z}`}`,T.textContent=`${le(o.summary.changedFiles,"file")} \xB7 +${o.summary.additions} \u2212${o.summary.deletions} \xB7 ${le(o.summary.commitCount,"commit")}`,A.textContent=String(o.scenes.length),W.textContent=String(o.files.length),U.textContent=le(o.summary.commitCount,"commit"),S.replaceChildren();let we=new Map(o.scenes.map(v=>[v.id,v]));for(let v of o.chapters){let G=document.createElement("h2");G.className="tour-chapter-title",G.textContent=v.title,S.append(G);for(let D of v.sceneIds){let H=we.get(D);if(!H)continue;let te=o.scenes.indexOf(H),j=document.createElement("button");j.type="button",j.className="tour-scene",j.dataset.sceneId=H.id,j.title=`Open scene: ${H.kind==="text-diff"?H.path:H.title}`,j.addEventListener("click",()=>oe(te));let Z=document.createElement("span");Z.className="tour-scene-number",Z.textContent=String(te+1).padStart(2,"0");let Ne=document.createElement("span");Ne.className="tour-scene-copy";for(let[Kt,Vt]of[["tour-scene-title",H.title],["tour-scene-path",H.kind==="text-diff"?H.path:H.kind==="deconstructed-diff"?le(H.steps.length,"explanation stage"):ae(H)?le(H.steps.length,"code step"):"Discussion"],["tour-scene-note",H.takeaway]]){let Ae=document.createElement("span");Ae.className=Kt,Ae.textContent=Vt,Ne.append(Ae)}j.append(Z,Ne),S.append(j)}}R.replaceChildren(...o.files.map((v,G)=>{let D=document.createElement("button");D.type="button",D.className=`tour-file${v.kind==="omitted"?" is-omitted":""}`,D.dataset.filePath=v.path,D.disabled=v.kind==="omitted",D.title=v.kind==="omitted"?`${v.path}: ${v.reason}`:`Open file: ${v.path}`,v.kind==="text-diff"&&D.addEventListener("click",()=>Ke(G));let H=document.createElement("span");H.className="tour-file-marker",H.textContent=v.kind==="omitted"?"\xD7":Ot(v.changeKind);let te=document.createElement("span");te.className="tour-file-copy";let j=document.createElement("span");j.className="tour-file-path",j.textContent=v.path;let Z=document.createElement("span");return Z.className="tour-file-meta",Z.textContent=v.kind==="omitted"?`Not rendered \xB7 ${v.reason}`:`${Bt(v.changeKind)} \xB7 +${v.additions} \u2212${v.deletions}`,te.append(j,Z),D.append(H,te),D})),y.replaceChildren(...o.commits.map(v=>{let G=document.createElement("li"),D=document.createElement("span");return D.className="tour-commit-oid",D.textContent=v.shortOid,G.append(D,document.createTextNode(v.summary)),G}))}function oe(o,l=0){let m=i.tour;if(!m||o<0||o>=m.scenes.length)return;let f=m.scenes[o];i.activeSceneIndex=o,i.activeStepIndex=ae(f)?Math.min(Math.max(l,0),Math.max(f.steps.length-1,0)):0,i.tourFocusFilePath=f.kind==="text-diff"?f.path:f.kind==="walkthrough"?f.steps[i.activeStepIndex]?.diff.path??null:pe(f)?f.steps[i.activeStepIndex]?.file??null:null;let p=Wt(m,o);document.querySelectorAll(".tour-scene").forEach(S=>{S.classList.toggle("is-active",S.dataset.sceneId===f.id)}),document.querySelector(`.tour-scene[data-scene-id="${f.id}"]`)?.scrollIntoView({block:"nearest"}),zt(f,p);let T=new URLSearchParams(window.location.search);if(T.set("scene",f.id),ae(f)?T.set("step",f.steps[i.activeStepIndex].id):T.delete("step"),window.history.replaceState(null,"",`${window.location.pathname}?${T.toString()}`),f.kind==="discussion"){document.body.classList.add("tour-discussion"),$e();return}if(document.body.classList.remove("tour-discussion"),f.kind==="walkthrough"){Ge(f);return}if(pe(f)){ze(f);return}ge(f,he(f.path))}function he(o){let l=i.tour;return!l||!o?[]:At(l,o,i.activeSceneIndex,i.activeStepIndex)}function Dt(o,l){let m=i.tour;return!m||!o?[]:Rt(m,o,i.activeSceneIndex,i.activeStepIndex,(f,p)=>Nt(l?.[f]?.diffModel,p))}function Le(o){return`file::${o}`}function ge(o,l=[],m=Le(o.path)){if(!i.tour)return;i.activeTourFilePath=o.path,$e();let p=Q(o.leftContent,o.rightContent),T=Ue(o,o.leftLabel,"base"),S=Ue(o,o.rightLabel,"head"),A=l.find(R=>R.active);u({type:"showDiff",file1:T,file2:S,comparisonId:`tour-${m}`,leftContent:o.leftContent,rightContent:o.rightContent,sourceInfo:{leftPath:o.path,rightPath:o.path},diffModel:p,history:null,fileNavigation:{canGoPrevious:!!se(-1),canGoNext:!!se(1)},editableSides:{left:!1,right:!1},comparisonSummary:`${o.path} \xB7 ${o.takeaway}`,initialChangeIndex:A?Ve(p,A.side,A.startLine):o.focusChangeIndex,tourAnnotations:l})}function Ue(o,l,m){let f=l.startsWith(o.path)?l.slice(o.path.length).trim():l.trim();return f?`${m} ${f}`:m}function Ge(o){let l=o.steps[i.activeStepIndex];l&&ge(l.diff,he(l.diff.path),Le(l.diff.path))}function ze(o){let l=o.steps[i.activeStepIndex];l&&je(o,l.file,l)}function je(o,l,m){let f=o.files.find(M=>M.path===l);if(!m||!f)return;i.activeTourFilePath=f.path,$e();let p=f.panels.map((M,z)=>({id:`${o.id}-${f.path}-${M.id}`,label:M.label,path:M.path||f.path,content:M.content,savedContent:M.content,dirty:!1,editable:!1,stackId:Ht(o)[z].id})),T=p.slice(0,-1).map((M,z)=>({leftIndex:z,rightIndex:z+1,diffModel:Q(M.content,p[z+1].content)})),S=o.kind==="stacked-diff"?Dt(f.path,T):[],A=S.find(M=>M.active),R=A?.pairIndex??m.pairIndex,W=A?.side??m.side,y=A?.startLine??m.startLine,U=T[R]?.diffModel,K=U&&y?Ve(U,W,y):0;u({type:"showMultiDiff",panels:p,pairs:T,activePanelId:p[R+(W==="right"?1:0)]?.id,activePairIndex:R,initialChangeIndex:K,revealFirstChangeInEachPanel:o.kind==="deconstructed-diff",history:null,fileNavigation:{canGoPrevious:!!se(-1),canGoNext:!!se(1)},mutationEnabled:!1,comparisonSummary:o.kind==="deconstructed-diff"?`${o.stageLabel} \xB7 ${f.path} \xB7 ${be(o.realRange.baseRef)} \u2192 ${be(o.realRange.targetRef)}`:`${f.path} \xB7 ${o.takeaway}`,tourAnnotations:S})}function ke(o){let l=i.tour;return!l||o!==-1&&o!==1?null:Et(l.scenes,{sceneIndex:i.activeSceneIndex,stepIndex:i.activeStepIndex},o)}function me(o){let l=ke(o);return l?(oe(l.sceneIndex,l.stepIndex),!0):!1}function se(o){let l=i.tour;return!l||o!==-1&&o!==1?null:Ct(l.files,i.activeTourFilePath,o)}function _t(o){let l=se(o);return l?Ke(l.fileIndex):!1}function qe(o){let l=i.tour?.files[o];return!l||l.kind!=="text-diff"?!1:(ge(l,he(l.path),Le(l.path)),!0)}function Ke(o){let l=i.tour?.files[o];if(l?.kind==="text-diff"&&i.tour){let m=Lt(i.tour.scenes,{sceneIndex:i.activeSceneIndex,stepIndex:i.activeStepIndex},l.path);if(m){let f=i.tour.scenes[m.sceneIndex],p=pe(f)?f.steps[m.stepIndex]:null;if(p)return je(f,l.path,p),!0}}return qe(o)}function Pt(){let o=i.tour?.scenes[i.activeSceneIndex];if(!o||!i.tourFocusFilePath)return!1;if(o.kind==="walkthrough")Ge(o);else if(pe(o))ze(o);else if(o.kind==="text-diff")ge(o,he(o.path));else return!1;return!0}function $e(){document.querySelectorAll(".tour-file").forEach(l=>{l.classList.toggle("is-active",l.dataset.filePath===i.activeTourFilePath),l.classList.toggle("is-tour-focus",l.dataset.filePath===i.tourFocusFilePath)}),document.querySelector(".tour-file.is-active")?.scrollIntoView({block:"nearest"});let o=document.getElementById("tour-return-focus");o&&(o.hidden=!i.tourFocusFilePath||i.activeTourFilePath===i.tourFocusFilePath)}function ae(o){return o.kind==="walkthrough"||o.kind==="stacked-diff"||o.kind==="deconstructed-diff"}function pe(o){return o.kind==="stacked-diff"||o.kind==="deconstructed-diff"}function Ht(o){return o.kind==="deconstructed-diff"?o.panels:o.stack}function Ot(o){return{added:"+",deleted:"\u2212",renamed:"\u2192",modified:"\u2022"}[o]||"\u2022"}function Bt(o){return`${o.charAt(0).toUpperCase()}${o.slice(1)}`}function Wt(o,l){let m=o.scenes[l],f=o.chapters.findIndex(A=>A.sceneIds.includes(m.id)),p=f>=0?o.chapters[f]:null,T=p?p.sceneIds.indexOf(m.id)+1:l+1,S=p?p.sceneIds.length:o.scenes.length;return{chapter:p,chapterIndex:f,chapterNumber:f>=0?f+1:l+1,sceneInChapter:T,scenesInChapter:S}}function Ut(o,l,m){let f=[`Ch ${o.chapterNumber}`,`Scene ${o.sceneInChapter}/${o.scenesInChapter}`];return ae(l)&&f.push(`Step ${m+1}/${l.steps.length}`),f.join(" \xB7 ")}function Ve(o,l,m){let p=(l==="left"?o.leftLines:o.rightLines).findIndex(y=>y.lineNumber===m);if(p<0)return 0;let T=l==="left"?"leftStart":"rightStart",S=l==="left"?"leftEnd":"rightEnd",A=o.blocks.findIndex(y=>p>=y[T]&&p<y[S]);if(A>=0)return A;let R=0,W=Number.POSITIVE_INFINITY;return o.blocks.forEach((y,U)=>{let K=Math.min(Math.abs(p-y[T]),Math.abs(p-y[S]));K<W&&(R=U,W=K)}),R}function be(o){return/^[0-9a-f]{40}$/i.test(o)?o.slice(0,7):o}function le(o,l){return`${o} ${o===1?l:`${l}s`}`}function Gt(o){return o instanceof Element&&!!o.closest('a, button, input, select, summary, textarea, [contenteditable="true"], [role="textbox"], .monaco-editor')}function zt(o,l){let m=document.getElementById("tour-narrative"),f=document.getElementById("tour-breadcrumb"),p=document.getElementById("tour-narrative-chapter"),T=document.getElementById("tour-narrative-title"),S=document.getElementById("tour-narrative-summary"),A=document.getElementById("tour-narrative-bullets"),R=document.getElementById("tour-narrative-tags"),W=document.getElementById("tour-narrative-takeaway"),y=document.getElementById("tour-step"),U=document.getElementById("tour-step-title"),K=document.getElementById("tour-step-body"),M=document.getElementById("tour-connection"),z=document.getElementById("tour-previous"),we=document.getElementById("tour-next");if(!m||!f||!p||!T||!S||!A||!R||!W||!y||!U||!K||!M||!z||!we)throw new Error("Tour narrative UI is incomplete.");m.hidden=!1,f.textContent=Ut(l,o,i.activeStepIndex),p.textContent=o.kind==="deconstructed-diff"?`${l.chapter?.title||"Change tour"} \xB7 ${o.stageLabel}`:l.chapter?.title||"Change tour",T.textContent=o.title,S.textContent=o.summary,A.replaceChildren(...o.bullets.map(G=>{let D=document.createElement("li");return D.textContent=G,D})),R.replaceChildren(...o.tags.map(G=>{let D=document.createElement("span");return D.textContent=G,D})),W.textContent=o.takeaway;let v=ae(o)?o.steps[i.activeStepIndex]:null;y.hidden=!v,v?(U.textContent=o.kind==="deconstructed-diff"?`Stage ${i.activeStepIndex+1}: ${v.title}`:v.title,K.textContent=v.body,"connection"in v&&v.connection?(M.hidden=!1,M.textContent=`${v.connection.from.path} \u2192 ${v.connection.to.path} \xB7 ${v.connection.label}`):(M.hidden=!0,M.textContent="")):(M.hidden=!0,M.textContent=""),z.disabled=!ke(-1),we.disabled=!ke(1)}function Xe(){let o=yt();i.mode="diff",i.comparisonId+=1,i.left={name:o.leftFileName,content:o.leftContent},i.right={name:o.rightFileName,content:o.rightContent},q("Loaded sample diff."),u({type:"showDiff",file1:i.left.name,file2:i.right.name,comparisonId:`web-${i.comparisonId}`,leftContent:i.left.content,rightContent:i.right.content,diffModel:Q(i.left.content,i.right.content),history:null})}async function jt(o){let[l,m]=o,[f,p]=await Promise.all([l.text(),m.text()]);i.mode="diff",i.comparisonId+=1,i.left={name:l.name,content:f},i.right={name:m.name,content:p},q(`Loaded ${l.name} and ${m.name}.`),u({type:"showDiff",file1:l.name,file2:m.name,comparisonId:`web-${i.comparisonId}`,leftContent:f,rightContent:p,diffModel:Q(f,p),history:null})}async function qt(o){let l=await Promise.all(o.map(async(m,f)=>{let p=await m.text();return{id:`web-panel-${f}`,label:m.name,content:p,savedContent:p,dirty:!1,editable:!0}}));i.mode="multi-diff",q(`Loaded ${l.length}-panel diff for ${l.map(m=>m.label).join(", ")}.`),u({type:"showMultiDiff",panels:l,pairs:l.slice(0,-1).map((m,f)=>({leftIndex:f,rightIndex:f+1,diffModel:Q(m.content,l[f+1].content)}))})}function q(o){let l=document.getElementById("web-status");l&&(l.textContent=o)}})();})();
151
151
  //# sourceMappingURL=web-host.js.map