@pierre/diffs 1.3.0-beta.3 → 1.3.0-beta.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (132) hide show
  1. package/dist/components/CodeView.d.ts.map +1 -1
  2. package/dist/components/File.d.ts +2 -2
  3. package/dist/components/File.d.ts.map +1 -1
  4. package/dist/components/File.js +11 -11
  5. package/dist/components/File.js.map +1 -1
  6. package/dist/components/FileDiff.d.ts +7 -4
  7. package/dist/components/FileDiff.d.ts.map +1 -1
  8. package/dist/components/FileDiff.js +56 -47
  9. package/dist/components/FileDiff.js.map +1 -1
  10. package/dist/components/UnresolvedFile.d.ts.map +1 -1
  11. package/dist/components/UnresolvedFile.js +1 -1
  12. package/dist/components/VirtualizedFile.d.ts +1 -1
  13. package/dist/components/VirtualizedFile.d.ts.map +1 -1
  14. package/dist/components/VirtualizedFile.js +7 -3
  15. package/dist/components/VirtualizedFile.js.map +1 -1
  16. package/dist/components/VirtualizedFileDiff.d.ts +2 -1
  17. package/dist/components/VirtualizedFileDiff.d.ts.map +1 -1
  18. package/dist/components/VirtualizedFileDiff.js +14 -0
  19. package/dist/components/VirtualizedFileDiff.js.map +1 -1
  20. package/dist/components/VirtulizerDevelopment.d.ts.map +1 -1
  21. package/dist/editor/editStack.d.ts +1 -1
  22. package/dist/editor/editor.d.ts +10 -8
  23. package/dist/editor/editor.d.ts.map +1 -1
  24. package/dist/editor/editor.js +386 -339
  25. package/dist/editor/editor.js.map +1 -1
  26. package/dist/editor/editor2.js +1 -1
  27. package/dist/editor/editor2.js.map +1 -1
  28. package/dist/editor/lineAnnotations.d.ts +2 -1
  29. package/dist/editor/lineAnnotations.d.ts.map +1 -1
  30. package/dist/editor/lineAnnotations.js +111 -1
  31. package/dist/editor/lineAnnotations.js.map +1 -1
  32. package/dist/editor/marker.d.ts +33 -0
  33. package/dist/editor/marker.d.ts.map +1 -0
  34. package/dist/editor/marker.js +185 -0
  35. package/dist/editor/marker.js.map +1 -0
  36. package/dist/editor/pieceTable.d.ts +2 -2
  37. package/dist/editor/pieceTable.d.ts.map +1 -1
  38. package/dist/editor/pieceTable.js +42 -11
  39. package/dist/editor/pieceTable.js.map +1 -1
  40. package/dist/editor/searchPanel.js +2 -2
  41. package/dist/editor/searchPanel.js.map +1 -1
  42. package/dist/editor/selection.d.ts +19 -3
  43. package/dist/editor/selection.d.ts.map +1 -1
  44. package/dist/editor/selection.js +188 -37
  45. package/dist/editor/selection.js.map +1 -1
  46. package/dist/editor/{quickEdit.d.ts → selectionAction.d.ts} +8 -8
  47. package/dist/editor/selectionAction.d.ts.map +1 -0
  48. package/dist/editor/{quickEdit.js → selectionAction.js} +18 -18
  49. package/dist/editor/selectionAction.js.map +1 -0
  50. package/dist/editor/sprite.d.ts +3 -2
  51. package/dist/editor/sprite.d.ts.map +1 -1
  52. package/dist/editor/sprite.js +9 -2
  53. package/dist/editor/sprite.js.map +1 -1
  54. package/dist/editor/textDocument.d.ts +4 -4
  55. package/dist/editor/textDocument.d.ts.map +1 -1
  56. package/dist/editor/textDocument.js +7 -7
  57. package/dist/editor/textDocument.js.map +1 -1
  58. package/dist/editor/tokenzier.js +11 -3
  59. package/dist/editor/tokenzier.js.map +1 -1
  60. package/dist/editor/utils.d.ts +3 -1
  61. package/dist/editor/utils.d.ts.map +1 -1
  62. package/dist/editor/utils.js +16 -1
  63. package/dist/editor/utils.js.map +1 -1
  64. package/dist/highlighter/shared_highlighter.js +3 -29
  65. package/dist/highlighter/shared_highlighter.js.map +1 -1
  66. package/dist/highlighter/themes/attachResolvedThemes.js +4 -3
  67. package/dist/highlighter/themes/attachResolvedThemes.js.map +1 -1
  68. package/dist/highlighter/themes/cleanUpResolvedThemes.js +3 -2
  69. package/dist/highlighter/themes/cleanUpResolvedThemes.js.map +1 -1
  70. package/dist/highlighter/themes/constants.d.ts +1 -7
  71. package/dist/highlighter/themes/constants.d.ts.map +1 -1
  72. package/dist/highlighter/themes/constants.js +1 -4
  73. package/dist/highlighter/themes/constants.js.map +1 -1
  74. package/dist/highlighter/themes/getResolvedOrResolveTheme.js +2 -2
  75. package/dist/highlighter/themes/getResolvedOrResolveTheme.js.map +1 -1
  76. package/dist/highlighter/themes/getResolvedThemes.js +2 -8
  77. package/dist/highlighter/themes/getResolvedThemes.js.map +1 -1
  78. package/dist/highlighter/themes/hasResolvedThemes.js +2 -3
  79. package/dist/highlighter/themes/hasResolvedThemes.js.map +1 -1
  80. package/dist/highlighter/themes/registerCustomCSSVariableTheme.js +1 -1
  81. package/dist/highlighter/themes/registerCustomTheme.d.ts +5 -3
  82. package/dist/highlighter/themes/registerCustomTheme.d.ts.map +1 -1
  83. package/dist/highlighter/themes/registerCustomTheme.js +15 -5
  84. package/dist/highlighter/themes/registerCustomTheme.js.map +1 -1
  85. package/dist/highlighter/themes/resolveTheme.js +6 -27
  86. package/dist/highlighter/themes/resolveTheme.js.map +1 -1
  87. package/dist/highlighter/themes/resolveThemes.js +5 -12
  88. package/dist/highlighter/themes/resolveThemes.js.map +1 -1
  89. package/dist/highlighter/themes/themeResolution.d.ts +8 -0
  90. package/dist/highlighter/themes/themeResolution.d.ts.map +1 -0
  91. package/dist/highlighter/themes/themeResolution.js +22 -0
  92. package/dist/highlighter/themes/themeResolution.js.map +1 -0
  93. package/dist/highlighter/themes/themeResolver.d.ts +8 -0
  94. package/dist/highlighter/themes/themeResolver.d.ts.map +1 -0
  95. package/dist/highlighter/themes/themeResolver.js +8 -0
  96. package/dist/highlighter/themes/themeResolver.js.map +1 -0
  97. package/dist/index.d.ts +4 -4
  98. package/dist/index.js +3 -3
  99. package/dist/react/index.d.ts +2 -2
  100. package/dist/react/jsx.d.ts.map +1 -1
  101. package/dist/react/utils/useFileDiffInstance.js +1 -0
  102. package/dist/react/utils/useFileDiffInstance.js.map +1 -1
  103. package/dist/renderers/DiffHunksRenderer.d.ts +4 -1
  104. package/dist/renderers/DiffHunksRenderer.d.ts.map +1 -1
  105. package/dist/renderers/DiffHunksRenderer.js +134 -10
  106. package/dist/renderers/DiffHunksRenderer.js.map +1 -1
  107. package/dist/renderers/FileRenderer.d.ts +2 -2
  108. package/dist/renderers/FileRenderer.d.ts.map +1 -1
  109. package/dist/renderers/FileRenderer.js +5 -5
  110. package/dist/renderers/FileRenderer.js.map +1 -1
  111. package/dist/ssr/index.d.ts +2 -2
  112. package/dist/types.d.ts +9 -7
  113. package/dist/types.d.ts.map +1 -1
  114. package/dist/utils/getHighlighterThemeStyles.js +16 -12
  115. package/dist/utils/getHighlighterThemeStyles.js.map +1 -1
  116. package/dist/utils/parsePatchFiles.js +93 -4
  117. package/dist/utils/parsePatchFiles.js.map +1 -1
  118. package/dist/utils/updateDiffHunks.d.ts +13 -0
  119. package/dist/utils/updateDiffHunks.d.ts.map +1 -0
  120. package/dist/utils/updateDiffHunks.js +171 -0
  121. package/dist/utils/updateDiffHunks.js.map +1 -0
  122. package/dist/utils/virtualDiffLayout.d.ts +2 -1
  123. package/dist/utils/virtualDiffLayout.d.ts.map +1 -1
  124. package/dist/utils/virtualDiffLayout.js +9 -1
  125. package/dist/utils/virtualDiffLayout.js.map +1 -1
  126. package/dist/worker/worker-portable.js +727 -22
  127. package/dist/worker/worker-portable.js.map +1 -1
  128. package/dist/worker/worker.js +23 -15
  129. package/dist/worker/worker.js.map +1 -1
  130. package/package.json +2 -1
  131. package/dist/editor/quickEdit.d.ts.map +0 -1
  132. package/dist/editor/quickEdit.js.map +0 -1
@@ -8133,11 +8133,11 @@ var JavaScriptScanner = class {
8133
8133
  constructor(patterns, options = {}) {
8134
8134
  this.patterns = patterns;
8135
8135
  this.options = options;
8136
- const { forgiving = false, cache, regexConstructor } = options;
8136
+ const { forgiving = false, cache: cache$1, regexConstructor } = options;
8137
8137
  if (!regexConstructor) throw new Error("Option `regexConstructor` is not provided");
8138
8138
  this.regexps = patterns.map((p$1) => {
8139
8139
  if (typeof p$1 !== "string") return p$1;
8140
- const cached = cache?.get(p$1);
8140
+ const cached = cache$1?.get(p$1);
8141
8141
  if (cached) {
8142
8142
  if (cached instanceof RegExp) return cached;
8143
8143
  if (forgiving) return null;
@@ -8145,10 +8145,10 @@ var JavaScriptScanner = class {
8145
8145
  }
8146
8146
  try {
8147
8147
  const regex = regexConstructor(p$1);
8148
- cache?.set(p$1, regex);
8148
+ cache$1?.set(p$1, regex);
8149
8149
  return regex;
8150
8150
  } catch (e) {
8151
- cache?.set(p$1, e);
8151
+ cache$1?.set(p$1, e);
8152
8152
  if (forgiving) return null;
8153
8153
  throw e;
8154
8154
  }
@@ -12234,11 +12234,500 @@ function attachResolvedLanguages(resolvedLanguages, highlighter$1) {
12234
12234
 
12235
12235
  //#endregion
12236
12236
  //#region src/highlighter/themes/constants.ts
12237
- const ResolvedThemes = new Map();
12238
- const ResolvingThemes = new Map();
12239
- const RegisteredCustomThemes = new Map();
12240
12237
  const AttachedThemes = new Set();
12241
12238
 
12239
+ //#endregion
12240
+ //#region ../theming/dist/modules/createThemeCollection.js
12241
+ function createThemeCollection(options) {
12242
+ const descriptors = [];
12243
+ const seen = /* @__PURE__ */ new Set();
12244
+ for (const entry of getCollectionEntries(options.themes)) {
12245
+ const themes = isThemeCollectionSource(entry) ? entry.getThemes() : [entry];
12246
+ for (const descriptor of themes) {
12247
+ if (seen.has(descriptor.name)) throw new Error(`Theme collection already contains theme "${descriptor.name}"`);
12248
+ seen.add(descriptor.name);
12249
+ descriptors.push(descriptor);
12250
+ }
12251
+ }
12252
+ const allThemes = Object.freeze([...descriptors]);
12253
+ const lightThemes = Object.freeze(allThemes.filter((descriptor) => descriptor.colorScheme === "light"));
12254
+ const darkThemes = Object.freeze(allThemes.filter((descriptor) => descriptor.colorScheme === "dark"));
12255
+ const themesByName = new Map(allThemes.map((descriptor) => [descriptor.name, descriptor]));
12256
+ const allNames = Object.freeze(allThemes.map((descriptor) => descriptor.name));
12257
+ const lightNames = Object.freeze(lightThemes.map((descriptor) => descriptor.name));
12258
+ const darkNames = Object.freeze(darkThemes.map((descriptor) => descriptor.name));
12259
+ function filteredThemes(filterOptions) {
12260
+ if (filterOptions == null) return allThemes;
12261
+ const { colorScheme, collection } = filterOptions;
12262
+ if (collection == null) {
12263
+ if (colorScheme === "light") return lightThemes;
12264
+ if (colorScheme === "dark") return darkThemes;
12265
+ return allThemes;
12266
+ }
12267
+ return allThemes.filter((descriptor) => {
12268
+ if (descriptor.collection !== collection) return false;
12269
+ return colorScheme == null || descriptor.colorScheme === colorScheme;
12270
+ });
12271
+ }
12272
+ return {
12273
+ getTheme(name) {
12274
+ return themesByName.get(name);
12275
+ },
12276
+ getThemes(themeOptions) {
12277
+ return filteredThemes(themeOptions);
12278
+ },
12279
+ getThemeNames(namesOptions) {
12280
+ if (namesOptions?.collection == null) {
12281
+ if (namesOptions?.colorScheme === "light") return lightNames;
12282
+ if (namesOptions?.colorScheme === "dark") return darkNames;
12283
+ return allNames;
12284
+ }
12285
+ return filteredThemes(namesOptions).map((descriptor) => descriptor.name);
12286
+ },
12287
+ hasTheme(name) {
12288
+ return themesByName.has(name);
12289
+ },
12290
+ orderBy(compare) {
12291
+ return createThemeCollection({ themes: allThemes.map((descriptor, index) => ({
12292
+ descriptor,
12293
+ index
12294
+ })).sort((a$1, b$2) => {
12295
+ const result = compare(a$1.descriptor, b$2.descriptor);
12296
+ if (result !== 0) return result;
12297
+ return a$1.index - b$2.index;
12298
+ }).map((entry) => entry.descriptor) });
12299
+ },
12300
+ pick(names) {
12301
+ const picked = [];
12302
+ const pickedNames = /* @__PURE__ */ new Set();
12303
+ for (const name of names) {
12304
+ if (pickedNames.has(name)) throw new Error(`Theme collection pick already includes theme "${name}"`);
12305
+ pickedNames.add(name);
12306
+ const descriptor = themesByName.get(name);
12307
+ if (descriptor == null) throw new Error(`Theme collection does not contain theme "${name}"`);
12308
+ picked.push(descriptor);
12309
+ }
12310
+ return createThemeCollection({ themes: picked });
12311
+ },
12312
+ registerInto(resolver) {
12313
+ for (const descriptor of allThemes) resolver.registerThemeIfAbsent(descriptor.name, descriptor.load);
12314
+ }
12315
+ };
12316
+ }
12317
+ function getCollectionEntries(input) {
12318
+ if (isThemeCollectionEntry(input)) return [input];
12319
+ return input;
12320
+ }
12321
+ function isThemeCollectionEntry(input) {
12322
+ return isThemeCollectionSource(input) || isThemeDescriptor(input);
12323
+ }
12324
+ function isThemeDescriptor(input) {
12325
+ return typeof input.name === "string" && typeof input.load === "function";
12326
+ }
12327
+ function isThemeCollectionSource(entry) {
12328
+ return typeof entry.getThemes === "function";
12329
+ }
12330
+
12331
+ //#endregion
12332
+ //#region ../theming/dist/modules/createThemeCatalog.js
12333
+ function createThemeCatalog(options) {
12334
+ const collection = createThemeCollection({ themes: options.themes });
12335
+ if (!collection.hasTheme(options.defaultLightThemeName)) throw new Error(`Default light theme "${options.defaultLightThemeName}" is not in the catalog`);
12336
+ if (!collection.hasTheme(options.defaultDarkThemeName)) throw new Error(`Default dark theme "${options.defaultDarkThemeName}" is not in the catalog`);
12337
+ return {
12338
+ ...collection,
12339
+ defaultLightThemeName: options.defaultLightThemeName,
12340
+ defaultDarkThemeName: options.defaultDarkThemeName
12341
+ };
12342
+ }
12343
+
12344
+ //#endregion
12345
+ //#region ../theming/dist/modules/unwrapDefault.js
12346
+ function unwrapDefault(value) {
12347
+ return value !== null && typeof value === "object" && "default" in value ? value.default : value;
12348
+ }
12349
+
12350
+ //#endregion
12351
+ //#region ../theming/dist/modules/createThemeResolver.js
12352
+ var DuplicateThemeError = class extends Error {
12353
+ constructor(name) {
12354
+ super(`Theme "${name}" is already registered`);
12355
+ this.name = "DuplicateThemeError";
12356
+ }
12357
+ };
12358
+ var UnregisteredThemeError = class extends Error {
12359
+ constructor(name) {
12360
+ super(`No loader registered for theme "${name}"`);
12361
+ this.name = "UnregisteredThemeError";
12362
+ }
12363
+ };
12364
+ var UnresolvedThemeError = class extends Error {
12365
+ constructor(name) {
12366
+ super(`Theme "${name}" has not been resolved`);
12367
+ this.name = "UnresolvedThemeError";
12368
+ }
12369
+ };
12370
+ function createThemeResolver() {
12371
+ const loaders = /* @__PURE__ */ new Map();
12372
+ const resolved = /* @__PURE__ */ new Map();
12373
+ const inflight = /* @__PURE__ */ new Map();
12374
+ let cacheGeneration = 0;
12375
+ function registerTheme(name, loader) {
12376
+ if (loaders.has(name)) throw new DuplicateThemeError(name);
12377
+ loaders.set(name, loader);
12378
+ }
12379
+ function registerThemeIfAbsent(name, loader) {
12380
+ if (loaders.has(name)) return false;
12381
+ loaders.set(name, loader);
12382
+ return true;
12383
+ }
12384
+ function hasRegisteredTheme(name) {
12385
+ return loaders.has(name);
12386
+ }
12387
+ function resolveTheme(name) {
12388
+ const cached = resolved.get(name);
12389
+ if (cached !== void 0) return Promise.resolve(cached);
12390
+ const existing = inflight.get(name);
12391
+ if (existing !== void 0) return existing;
12392
+ const loader = loaders.get(name);
12393
+ if (loader === void 0) return Promise.reject(new UnregisteredThemeError(name));
12394
+ const generation = cacheGeneration;
12395
+ const promise = loader().then((result) => {
12396
+ const theme = unwrapDefault(result);
12397
+ if (generation === cacheGeneration) resolved.set(name, theme);
12398
+ if (inflight.get(name) === promise) inflight.delete(name);
12399
+ return theme;
12400
+ }).catch((err) => {
12401
+ if (inflight.get(name) === promise) inflight.delete(name);
12402
+ throw err;
12403
+ });
12404
+ inflight.set(name, promise);
12405
+ return promise;
12406
+ }
12407
+ function resolveThemes$1(names) {
12408
+ return Promise.all(names.map((name) => resolveTheme(name)));
12409
+ }
12410
+ function seedResolvedTheme(name, theme) {
12411
+ resolved.set(name, theme);
12412
+ }
12413
+ function seedResolvedThemes(entries) {
12414
+ for (const [name, theme] of entries) seedResolvedTheme(name, theme);
12415
+ }
12416
+ function getResolvedTheme(name) {
12417
+ return resolved.get(name);
12418
+ }
12419
+ function getResolvedThemes(names) {
12420
+ const themes = [];
12421
+ for (const name of names) {
12422
+ const theme = resolved.get(name);
12423
+ if (theme === void 0) throw new UnresolvedThemeError(name);
12424
+ themes.push(theme);
12425
+ }
12426
+ return themes;
12427
+ }
12428
+ function hasResolvedTheme(name) {
12429
+ return resolved.has(name);
12430
+ }
12431
+ function hasResolvedThemes(names) {
12432
+ for (const name of names) if (!resolved.has(name)) return false;
12433
+ return true;
12434
+ }
12435
+ function getResolvedOrResolveTheme(name) {
12436
+ const cached = resolved.get(name);
12437
+ if (cached !== void 0) return cached;
12438
+ return resolveTheme(name);
12439
+ }
12440
+ function clearResolvedThemes() {
12441
+ cacheGeneration++;
12442
+ resolved.clear();
12443
+ inflight.clear();
12444
+ }
12445
+ return {
12446
+ clearResolvedThemes,
12447
+ getResolvedOrResolveTheme,
12448
+ getResolvedTheme,
12449
+ getResolvedThemes,
12450
+ hasRegisteredTheme,
12451
+ hasResolvedTheme,
12452
+ hasResolvedThemes,
12453
+ registerTheme,
12454
+ registerThemeIfAbsent,
12455
+ resolveTheme,
12456
+ resolveThemes: resolveThemes$1,
12457
+ seedResolvedTheme,
12458
+ seedResolvedThemes
12459
+ };
12460
+ }
12461
+
12462
+ //#endregion
12463
+ //#region ../theming/dist/modules/createThemeController.js
12464
+ const FALLBACK_LIGHT_THEME = "pierre-light";
12465
+ const FALLBACK_DARK_THEME = "pierre-dark";
12466
+ function getStorage() {
12467
+ try {
12468
+ if (typeof globalThis !== "undefined" && globalThis.localStorage != null) return globalThis.localStorage;
12469
+ } catch {}
12470
+ }
12471
+ function createLocalStorageAdapter(storageKey, defaults) {
12472
+ return {
12473
+ load() {
12474
+ const raw$1 = getStorage()?.getItem(storageKey);
12475
+ if (raw$1 == null) return null;
12476
+ try {
12477
+ const parsed = JSON.parse(raw$1);
12478
+ if (parsed.mode == null) return null;
12479
+ return {
12480
+ darkThemeName: parsed.darkThemeName ?? defaults.darkThemeName,
12481
+ lightThemeName: parsed.lightThemeName ?? defaults.lightThemeName,
12482
+ mode: parsed.mode
12483
+ };
12484
+ } catch {
12485
+ return null;
12486
+ }
12487
+ },
12488
+ save(selection) {
12489
+ const storage = getStorage();
12490
+ try {
12491
+ storage?.setItem(storageKey, JSON.stringify(selection));
12492
+ } catch {}
12493
+ }
12494
+ };
12495
+ }
12496
+ function systemPrefersDark() {
12497
+ try {
12498
+ if (typeof globalThis !== "undefined" && globalThis.matchMedia != null) return globalThis.matchMedia("(prefers-color-scheme: dark)").matches;
12499
+ } catch {}
12500
+ return false;
12501
+ }
12502
+ function resolveColorScheme(mode) {
12503
+ if (mode === "dark") return "dark";
12504
+ if (mode === "light") return "light";
12505
+ return systemPrefersDark() ? "dark" : "light";
12506
+ }
12507
+ function createThemeController(options) {
12508
+ const { storageKey, preloadInactive = false } = options;
12509
+ const catalog = "catalog" in options && options.catalog != null ? options.catalog : void 0;
12510
+ const selectedResolver = options.resolver ?? (catalog != null ? createThemeResolver() : void 0);
12511
+ if (selectedResolver == null) throw new Error("createThemeController requires a catalog or resolver");
12512
+ const resolver = selectedResolver;
12513
+ catalog?.registerInto(resolver);
12514
+ const defaultDarkThemeName = options.defaultDarkThemeName ?? catalog?.defaultDarkThemeName ?? FALLBACK_DARK_THEME;
12515
+ const defaultLightThemeName = options.defaultLightThemeName ?? catalog?.defaultLightThemeName ?? FALLBACK_LIGHT_THEME;
12516
+ const persistence = options.persistence ?? (storageKey != null ? createLocalStorageAdapter(storageKey, {
12517
+ darkThemeName: defaultDarkThemeName,
12518
+ lightThemeName: defaultLightThemeName
12519
+ }) : void 0);
12520
+ const initialMode = options.defaultMode ?? "system";
12521
+ let state = {
12522
+ darkThemeName: defaultDarkThemeName,
12523
+ lightThemeName: defaultLightThemeName,
12524
+ mode: initialMode,
12525
+ resolvedTheme: void 0,
12526
+ resolvedColorScheme: resolveColorScheme(initialMode)
12527
+ };
12528
+ const listeners = /* @__PURE__ */ new Set();
12529
+ let activeResolutionId = 0;
12530
+ let pendingSelectionPatch;
12531
+ function notify() {
12532
+ for (const listener of listeners) listener();
12533
+ }
12534
+ function hydrateFromStorage() {
12535
+ const loaded = persistence?.load();
12536
+ if (loaded == null) return;
12537
+ state = {
12538
+ ...state,
12539
+ darkThemeName: loaded.darkThemeName,
12540
+ lightThemeName: loaded.lightThemeName,
12541
+ mode: loaded.mode,
12542
+ resolvedColorScheme: resolveColorScheme(loaded.mode)
12543
+ };
12544
+ }
12545
+ function persist() {
12546
+ persistence?.save({
12547
+ darkThemeName: state.darkThemeName,
12548
+ lightThemeName: state.lightThemeName,
12549
+ mode: state.mode
12550
+ });
12551
+ }
12552
+ function activeThemeNameFor(selection) {
12553
+ return selection.resolvedColorScheme === "dark" ? selection.darkThemeName : selection.lightThemeName;
12554
+ }
12555
+ function intendedState(patch = {}) {
12556
+ return {
12557
+ ...state,
12558
+ ...pendingSelectionPatch,
12559
+ ...patch
12560
+ };
12561
+ }
12562
+ function reportResolutionError(error, context) {
12563
+ if (options.onResolutionError != null) {
12564
+ options.onResolutionError(error, context);
12565
+ return;
12566
+ }
12567
+ console.error(`[theming] Failed to resolve theme "${context.name}" for ${context.colorScheme} color scheme`, error);
12568
+ }
12569
+ function preloadInactiveFor(selection) {
12570
+ if (!preloadInactive) return;
12571
+ const activeName = activeThemeNameFor(selection);
12572
+ const inactive = selection.resolvedColorScheme === "dark" ? selection.lightThemeName : selection.darkThemeName;
12573
+ if (inactive !== activeName && resolver.getResolvedTheme(inactive) === void 0) resolver.resolveTheme(inactive).catch(() => {});
12574
+ }
12575
+ function resolveActive(patch = {}, { notifyPending = false, persistOnSuccess = false } = {}) {
12576
+ const selectionPatch = {
12577
+ ...pendingSelectionPatch,
12578
+ ...patch
12579
+ };
12580
+ const next = intendedState(patch);
12581
+ const name = activeThemeNameFor(next);
12582
+ const colorScheme = next.resolvedColorScheme;
12583
+ const cached = resolver.getResolvedTheme(name);
12584
+ if (cached !== void 0) {
12585
+ activeResolutionId++;
12586
+ pendingSelectionPatch = void 0;
12587
+ state = {
12588
+ ...state,
12589
+ ...selectionPatch,
12590
+ pendingThemeResolution: void 0,
12591
+ resolutionError: void 0,
12592
+ resolvedTheme: cached
12593
+ };
12594
+ if (persistOnSuccess) persist();
12595
+ notify();
12596
+ preloadInactiveFor(state);
12597
+ return;
12598
+ }
12599
+ const resolutionId = ++activeResolutionId;
12600
+ pendingSelectionPatch = selectionPatch;
12601
+ state = {
12602
+ ...state,
12603
+ pendingThemeResolution: {
12604
+ colorScheme,
12605
+ name
12606
+ },
12607
+ resolutionError: void 0
12608
+ };
12609
+ if (notifyPending) notify();
12610
+ resolver.resolveTheme(name).then((theme) => {
12611
+ if (resolutionId !== activeResolutionId) return;
12612
+ const latestIntended = intendedState();
12613
+ if (latestIntended.resolvedColorScheme !== colorScheme || activeThemeNameFor(latestIntended) !== name) return;
12614
+ const patchToCommit = pendingSelectionPatch ?? {};
12615
+ pendingSelectionPatch = void 0;
12616
+ state = {
12617
+ ...state,
12618
+ ...patchToCommit,
12619
+ pendingThemeResolution: void 0,
12620
+ resolutionError: void 0,
12621
+ resolvedTheme: theme
12622
+ };
12623
+ if (persistOnSuccess) persist();
12624
+ notify();
12625
+ preloadInactiveFor(state);
12626
+ }).catch((error) => {
12627
+ if (resolutionId !== activeResolutionId) return;
12628
+ pendingSelectionPatch = void 0;
12629
+ state = {
12630
+ ...state,
12631
+ pendingThemeResolution: void 0,
12632
+ resolutionError: {
12633
+ colorScheme,
12634
+ error,
12635
+ name
12636
+ }
12637
+ };
12638
+ reportResolutionError(error, {
12639
+ colorScheme,
12640
+ name
12641
+ });
12642
+ notify();
12643
+ });
12644
+ }
12645
+ function updateInactiveThemeName(key$1, name) {
12646
+ state = {
12647
+ ...state,
12648
+ [key$1]: name,
12649
+ resolutionError: void 0
12650
+ };
12651
+ persist();
12652
+ notify();
12653
+ preloadInactiveFor(state);
12654
+ }
12655
+ function isSchemeActiveInIntendedState(scheme, patch = {}) {
12656
+ return intendedState(patch).resolvedColorScheme === scheme;
12657
+ }
12658
+ function setActiveSelection(patch) {
12659
+ resolveActive(patch, {
12660
+ notifyPending: true,
12661
+ persistOnSuccess: true
12662
+ });
12663
+ }
12664
+ function setInactiveThemeName(scheme, key$1, name) {
12665
+ if (isSchemeActiveInIntendedState(scheme, { [key$1]: name })) setActiveSelection({ [key$1]: name });
12666
+ else updateInactiveThemeName(key$1, name);
12667
+ }
12668
+ function setMode(mode) {
12669
+ setActiveSelection({
12670
+ mode,
12671
+ resolvedColorScheme: resolveColorScheme(mode)
12672
+ });
12673
+ }
12674
+ function maybeUpdateSystemColorScheme() {
12675
+ if (intendedState().mode !== "system") return;
12676
+ const next = resolveColorScheme("system");
12677
+ if (next !== intendedState().resolvedColorScheme) resolveActive({ resolvedColorScheme: next }, { notifyPending: true });
12678
+ }
12679
+ function isSelectedValue(key$1, value) {
12680
+ return intendedState()[key$1] === value;
12681
+ }
12682
+ let mediaQuery;
12683
+ const handleMediaChange = () => {
12684
+ maybeUpdateSystemColorScheme();
12685
+ };
12686
+ function attachMediaListener() {
12687
+ try {
12688
+ if (typeof globalThis !== "undefined" && globalThis.matchMedia != null) {
12689
+ mediaQuery = globalThis.matchMedia("(prefers-color-scheme: dark)");
12690
+ mediaQuery.addEventListener("change", handleMediaChange);
12691
+ }
12692
+ } catch {}
12693
+ }
12694
+ hydrateFromStorage();
12695
+ attachMediaListener();
12696
+ resolveActive();
12697
+ return {
12698
+ resolver,
12699
+ destroy() {
12700
+ if (mediaQuery != null) {
12701
+ mediaQuery.removeEventListener("change", handleMediaChange);
12702
+ mediaQuery = void 0;
12703
+ }
12704
+ listeners.clear();
12705
+ },
12706
+ getState() {
12707
+ return state;
12708
+ },
12709
+ setColorMode(mode) {
12710
+ if (isSelectedValue("mode", mode)) return;
12711
+ setMode(mode);
12712
+ },
12713
+ setThemeNameForScheme(scheme, name) {
12714
+ const key$1 = scheme === "light" ? "lightThemeName" : "darkThemeName";
12715
+ if (isSelectedValue(key$1, name)) return;
12716
+ setInactiveThemeName(scheme, key$1, name);
12717
+ },
12718
+ subscribe(listener) {
12719
+ listeners.add(listener);
12720
+ return () => {
12721
+ listeners.delete(listener);
12722
+ };
12723
+ }
12724
+ };
12725
+ }
12726
+
12727
+ //#endregion
12728
+ //#region src/highlighter/themes/themeResolver.ts
12729
+ const themeResolver = createThemeResolver();
12730
+
12242
12731
  //#endregion
12243
12732
  //#region src/highlighter/themes/attachResolvedThemes.ts
12244
12733
  function attachResolvedThemes(themes, highlighter$1) {
@@ -12246,15 +12735,15 @@ function attachResolvedThemes(themes, highlighter$1) {
12246
12735
  for (let themeRef of themes) {
12247
12736
  let resolvedTheme;
12248
12737
  if (typeof themeRef === "string") {
12249
- resolvedTheme = ResolvedThemes.get(themeRef);
12738
+ resolvedTheme = themeResolver.getResolvedTheme(themeRef);
12250
12739
  if (resolvedTheme == null) {
12251
12740
  throw new Error(`loadResolvedThemes: ${themeRef} is not resolved, you must resolve it before calling loadResolvedThemes`);
12252
12741
  }
12253
12742
  } else {
12254
12743
  resolvedTheme = themeRef;
12255
12744
  themeRef = themeRef.name;
12256
- if (!ResolvedThemes.has(themeRef)) {
12257
- ResolvedThemes.set(themeRef, resolvedTheme);
12745
+ if (themeResolver.getResolvedTheme(themeRef) == null) {
12746
+ themeResolver.seedResolvedTheme(themeRef, resolvedTheme);
12258
12747
  }
12259
12748
  }
12260
12749
  if (AttachedThemes.has(themeRef)) continue;
@@ -15069,30 +15558,234 @@ function formatCSSVariablePrefix(type) {
15069
15558
  return `--${type === "token" ? "diffs-token" : "diffs"}-`;
15070
15559
  }
15071
15560
 
15561
+ //#endregion
15562
+ //#region ../theming/dist/modules/color.js
15563
+ /**
15564
+ * Canonical color/contrast primitives
15565
+ */
15566
+ const MIN_READABLE_RATIO = 3;
15567
+ const MIN_MUTED_RATIO = 4.5;
15568
+ const HEX_TRANSPARENT_RE = /^#(?:[0-9a-f]{3}0|[0-9a-f]{6}00)$/i;
15569
+ const ALPHA_ZERO_RE = /^0(?:\.0+)?%?$/;
15570
+ function getFunctionalAlpha(color) {
15571
+ const openParen = color.indexOf("(");
15572
+ if (openParen <= 0 || !color.endsWith(")")) return;
15573
+ const fn = color.slice(0, openParen).trim();
15574
+ if (!/^(?:rgb|rgba|hsl|hsla|hwb|lab|lch|oklab|oklch|color)$/i.test(fn)) return;
15575
+ const inner = color.slice(openParen + 1, -1).trim();
15576
+ if (inner.length === 0) return;
15577
+ const slashIndex = inner.lastIndexOf("/");
15578
+ if (slashIndex !== -1) return inner.slice(slashIndex + 1).trim();
15579
+ if (/^(?:rgba|hsla)$/i.test(fn)) {
15580
+ const parts = inner.split(",");
15581
+ if (parts.length === 4) return parts[3]?.trim();
15582
+ }
15583
+ }
15584
+ function parseHexRgba(color) {
15585
+ const match = /^#([0-9a-f]{3}|[0-9a-f]{6}|[0-9a-f]{8})\b/i.exec(color.trim());
15586
+ if (match == null) return null;
15587
+ const hex = match[1];
15588
+ let expanded;
15589
+ let alpha = 1;
15590
+ if (hex.length === 3) expanded = hex.split("").map((c) => c + c).join("");
15591
+ else if (hex.length === 6) expanded = hex;
15592
+ else {
15593
+ expanded = hex.slice(0, 6);
15594
+ alpha = parseInt(hex.slice(6, 8), 16) / 255;
15595
+ }
15596
+ return [
15597
+ parseInt(expanded.slice(0, 2), 16),
15598
+ parseInt(expanded.slice(2, 4), 16),
15599
+ parseInt(expanded.slice(4, 6), 16),
15600
+ alpha
15601
+ ];
15602
+ }
15603
+ function relativeLuminance(color) {
15604
+ if (color == null) return null;
15605
+ const rgba = parseHexRgba(color);
15606
+ if (rgba == null) return null;
15607
+ const r$3 = rgba[0] / 255;
15608
+ const g = rgba[1] / 255;
15609
+ const b$2 = rgba[2] / 255;
15610
+ const channel = (v$1) => v$1 <= .03928 ? v$1 / 12.92 : ((v$1 + .055) / 1.055) ** 2.4;
15611
+ return .2126 * channel(r$3) + .7152 * channel(g) + .0722 * channel(b$2);
15612
+ }
15613
+ function contrastRatio(a$1, b$2) {
15614
+ const [hi, lo] = a$1 > b$2 ? [a$1, b$2] : [b$2, a$1];
15615
+ return (hi + .05) / (lo + .05);
15616
+ }
15617
+ function compositeOverBg(fgColor, bgColor) {
15618
+ if (bgColor == null) return void 0;
15619
+ const fgParts = parseHexRgba(fgColor);
15620
+ const bgParts = parseHexRgba(bgColor);
15621
+ if (fgParts == null || bgParts == null) return void 0;
15622
+ const [fr, fg, fb, fa] = fgParts;
15623
+ const [br, bg, bb] = bgParts;
15624
+ return "#" + [
15625
+ Math.round(fr * fa + br * (1 - fa)),
15626
+ Math.round(fg * fa + bg * (1 - fa)),
15627
+ Math.round(fb * fa + bb * (1 - fa))
15628
+ ].map((v$1) => v$1.toString(16).padStart(2, "0")).join("");
15629
+ }
15630
+ function isFullyTransparent(color) {
15631
+ if (color == null) return false;
15632
+ const normalized = color.trim().toLowerCase();
15633
+ if (normalized === "transparent") return true;
15634
+ if (HEX_TRANSPARENT_RE.test(normalized)) return true;
15635
+ const alpha = getFunctionalAlpha(normalized);
15636
+ return alpha != null && ALPHA_ZERO_RE.test(alpha);
15637
+ }
15638
+ function isDarkSurface(bg, fgHint) {
15639
+ const fromBg = relativeLuminance(bg);
15640
+ if (fromBg != null) return fromBg < .4;
15641
+ const fromFg = relativeLuminance(fgHint);
15642
+ return fromFg != null ? fromFg > .6 : false;
15643
+ }
15644
+ function surfacesMatch(a$1, b$2) {
15645
+ if (a$1 == null || b$2 == null) return false;
15646
+ if (a$1.trim().toLowerCase() === b$2.trim().toLowerCase()) return true;
15647
+ const la = relativeLuminance(a$1);
15648
+ const lb = relativeLuminance(b$2);
15649
+ if (la == null || lb == null) return false;
15650
+ return Math.abs(la - lb) < .06;
15651
+ }
15652
+ function hoverWouldEraseText(hover, bg, fg) {
15653
+ if (bg == null || fg == null) return false;
15654
+ const hoverL = relativeLuminance(hover);
15655
+ const bgL = relativeLuminance(bg);
15656
+ const fgL = relativeLuminance(fg);
15657
+ if (hoverL == null || bgL == null || fgL == null) return false;
15658
+ return Math.abs(hoverL - fgL) < Math.abs(hoverL - bgL);
15659
+ }
15660
+ function pickReadableForeground(bg, candidates) {
15661
+ const bgL = relativeLuminance(bg);
15662
+ const firstDefined = candidates.find((candidate) => candidate != null && candidate !== "");
15663
+ if (bgL == null) return firstDefined;
15664
+ let best;
15665
+ let bestRatio = -1;
15666
+ for (const candidate of candidates) {
15667
+ if (candidate == null || candidate === "") continue;
15668
+ const candidateL = relativeLuminance(candidate);
15669
+ if (candidateL == null) continue;
15670
+ const ratio = contrastRatio(bgL, candidateL);
15671
+ if (ratio >= MIN_READABLE_RATIO) return candidate;
15672
+ if (ratio > bestRatio) {
15673
+ best = candidate;
15674
+ bestRatio = ratio;
15675
+ }
15676
+ }
15677
+ return best ?? firstDefined;
15678
+ }
15679
+ function deriveMutedFg(primaryFg, bg) {
15680
+ if (bg == null) return primaryFg;
15681
+ const fgParts = parseHexRgba(primaryFg);
15682
+ const bgParts = parseHexRgba(bg);
15683
+ const bgL = relativeLuminance(bg);
15684
+ if (fgParts == null || bgParts == null || bgL == null) return `color-mix(in srgb, ${primaryFg} 70%, ${bg})`;
15685
+ const [fr, fg2, fb] = fgParts;
15686
+ const [br, bg3, bb] = bgParts;
15687
+ for (const weight of [
15688
+ .6,
15689
+ .7,
15690
+ .8,
15691
+ .9
15692
+ ]) {
15693
+ const hex = "#" + [
15694
+ Math.round(fr * weight + br * (1 - weight)),
15695
+ Math.round(fg2 * weight + bg3 * (1 - weight)),
15696
+ Math.round(fb * weight + bb * (1 - weight))
15697
+ ].map((v$1) => v$1.toString(16).padStart(2, "0")).join("");
15698
+ const L$2 = relativeLuminance(hex);
15699
+ if (L$2 != null && contrastRatio(bgL, L$2) >= MIN_MUTED_RATIO) return hex;
15700
+ }
15701
+ return primaryFg;
15702
+ }
15703
+
15704
+ //#endregion
15705
+ //#region ../theming/dist/modules/normalizeThemeColors.js
15706
+ const cache = /* @__PURE__ */ new WeakMap();
15707
+ function normalizeThemeColors(theme) {
15708
+ const cached = cache.get(theme);
15709
+ if (cached != null) return cached;
15710
+ const originalColors = theme.colors ?? {};
15711
+ const colors = { ...originalColors };
15712
+ const editorBackground = originalColors["editor.background"] ?? theme.bg;
15713
+ const editorForeground = originalColors["editor.foreground"] ?? theme.fg;
15714
+ const sidebarBackground = originalColors["sideBar.background"] ?? editorBackground;
15715
+ const sidebarForeground = originalColors["sideBar.foreground"] ?? editorForeground;
15716
+ fill(colors, "editor.background", editorBackground);
15717
+ fill(colors, "editor.foreground", editorForeground);
15718
+ fill(colors, "sideBar.background", sidebarBackground);
15719
+ fill(colors, "sideBar.foreground", sidebarForeground);
15720
+ fill(colors, "input.background", originalColors["input.background"] ?? sidebarBackground);
15721
+ fill(colors, "sideBarSectionHeader.foreground", originalColors["sideBarSectionHeader.foreground"] ?? sidebarForeground);
15722
+ fill(colors, "list.activeSelectionForeground", originalColors["list.activeSelectionForeground"] ?? sidebarForeground);
15723
+ fill(colors, "gitDecoration.addedResourceForeground", firstColor(originalColors["gitDecoration.addedResourceForeground"], originalColors["terminal.ansiGreen"], originalColors["editorGutter.addedBackground"]));
15724
+ fill(colors, "gitDecoration.modifiedResourceForeground", firstColor(originalColors["gitDecoration.modifiedResourceForeground"], originalColors["terminal.ansiBlue"], originalColors["editorGutter.modifiedBackground"]));
15725
+ fill(colors, "gitDecoration.deletedResourceForeground", firstColor(originalColors["gitDecoration.deletedResourceForeground"], originalColors["terminal.ansiRed"], originalColors["editorGutter.deletedBackground"]));
15726
+ const focusRing = (isFullyTransparent(originalColors["list.focusOutline"]) ? void 0 : originalColors["list.focusOutline"]) ?? (isFullyTransparent(originalColors["focusBorder"]) ? void 0 : originalColors["focusBorder"]);
15727
+ if (focusRing != null) colors["list.focusOutline"] = focusRing;
15728
+ else delete colors["list.focusOutline"];
15729
+ const hover = originalColors["list.hoverBackground"];
15730
+ if (hover != null && (matchesSurface(hover, sidebarBackground) || hoverWouldEraseText(hover, sidebarBackground, sidebarForeground))) delete colors["list.hoverBackground"];
15731
+ const result = Object.freeze({
15732
+ ...theme,
15733
+ colors: Object.freeze(colors)
15734
+ });
15735
+ cache.set(theme, result);
15736
+ return result;
15737
+ }
15738
+ function fill(colors, key$1, value) {
15739
+ if (value != null && value !== "") colors[key$1] = value;
15740
+ }
15741
+ function firstColor(...candidates) {
15742
+ for (const candidate of candidates) if (candidate != null && candidate !== "") return candidate;
15743
+ }
15744
+ function matchesSurface(color, surface) {
15745
+ return surface != null && color.toLowerCase() === surface.toLowerCase();
15746
+ }
15747
+
15748
+ //#endregion
15749
+ //#region ../theming/dist/color.js
15750
+ const colorUtils = {
15751
+ compositeOverBg,
15752
+ contrastRatio,
15753
+ deriveMutedFg,
15754
+ hoverWouldEraseText,
15755
+ isDarkSurface,
15756
+ isFullyTransparent,
15757
+ pickReadableForeground,
15758
+ relativeLuminance,
15759
+ surfacesMatch
15760
+ };
15761
+
15072
15762
  //#endregion
15073
15763
  //#region src/utils/getHighlighterThemeStyles.ts
15074
15764
  function getHighlighterThemeStyles({ theme = DEFAULT_THEMES, highlighter: highlighter$1, prefix }) {
15075
15765
  let styles = "";
15076
15766
  if (typeof theme === "string") {
15077
15767
  const themeData = highlighter$1.getTheme(theme);
15078
- styles += `color:${themeData.fg};`;
15079
- styles += `background-color:${themeData.bg};`;
15080
- styles += `${formatCSSVariablePrefix("global")}fg:${themeData.fg};`;
15081
- styles += `${formatCSSVariablePrefix("global")}bg:${themeData.bg};`;
15082
- styles += getThemeVariables(themeData, prefix);
15768
+ const normalized = normalizeThemeColors(themeData);
15769
+ styles += `color:${normalized.fg};`;
15770
+ styles += `background-color:${normalized.bg};`;
15771
+ styles += `${formatCSSVariablePrefix("global")}fg:${normalized.fg};`;
15772
+ styles += `${formatCSSVariablePrefix("global")}bg:${normalized.bg};`;
15773
+ styles += getGitVariables(themeData, prefix);
15083
15774
  } else {
15084
15775
  let themeData = highlighter$1.getTheme(theme.dark);
15085
- styles += `${formatCSSVariablePrefix("global")}dark:${themeData.fg};`;
15086
- styles += `${formatCSSVariablePrefix("global")}dark-bg:${themeData.bg};`;
15087
- styles += getThemeVariables(themeData, "dark");
15776
+ let normalized = normalizeThemeColors(themeData);
15777
+ styles += `${formatCSSVariablePrefix("global")}dark:${normalized.fg};`;
15778
+ styles += `${formatCSSVariablePrefix("global")}dark-bg:${normalized.bg};`;
15779
+ styles += getGitVariables(themeData, "dark");
15088
15780
  themeData = highlighter$1.getTheme(theme.light);
15089
- styles += `${formatCSSVariablePrefix("global")}light:${themeData.fg};`;
15090
- styles += `${formatCSSVariablePrefix("global")}light-bg:${themeData.bg};`;
15091
- styles += getThemeVariables(themeData, "light");
15781
+ normalized = normalizeThemeColors(themeData);
15782
+ styles += `${formatCSSVariablePrefix("global")}light:${normalized.fg};`;
15783
+ styles += `${formatCSSVariablePrefix("global")}light-bg:${normalized.bg};`;
15784
+ styles += getGitVariables(themeData, "light");
15092
15785
  }
15093
15786
  return styles;
15094
15787
  }
15095
- function getThemeVariables(themeData, modePrefix) {
15788
+ function getGitVariables(themeData, modePrefix) {
15096
15789
  modePrefix = modePrefix != null ? `${modePrefix}-` : "";
15097
15790
  let styles = "";
15098
15791
  const additionGreen = themeData.colors?.["gitDecoration.addedResourceForeground"] ?? themeData.colors?.["terminal.ansiGreen"];
@@ -15200,6 +15893,18 @@ function hasTrailingContext(fileDiff) {
15200
15893
  const deletionRemaining = fileDiff.deletionLines.length - (lastHunk.deletionLineIndex + lastHunk.deletionCount);
15201
15894
  return additionRemaining > 0 || deletionRemaining > 0;
15202
15895
  }
15896
+ function hasTrailingContextMismatch(fileDiff) {
15897
+ const lastHunk = fileDiff.hunks[fileDiff.hunks.length - 1];
15898
+ if (lastHunk == null || fileDiff.isPartial || fileDiff.additionLines.length === 0 || fileDiff.deletionLines.length === 0) {
15899
+ return false;
15900
+ }
15901
+ const additionRemaining = fileDiff.additionLines.length - (lastHunk.additionLineIndex + lastHunk.additionCount);
15902
+ const deletionRemaining = fileDiff.deletionLines.length - (lastHunk.deletionLineIndex + lastHunk.deletionCount);
15903
+ if (additionRemaining <= 0 && deletionRemaining <= 0) {
15904
+ return false;
15905
+ }
15906
+ return additionRemaining !== deletionRemaining;
15907
+ }
15203
15908
  function getTrailingContextRangeSize({ fileDiff, errorPrefix }) {
15204
15909
  const lastHunk = fileDiff.hunks[fileDiff.hunks.length - 1];
15205
15910
  if (lastHunk == null || fileDiff.isPartial || fileDiff.additionLines.length === 0 || fileDiff.deletionLines.length === 0) {