Sign In

node-diff3

Package Overview
Dependencies
Maintainers
1
Versions
13
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

node-diff3 - npm Package Compare versions

Comparing version
3.1.2
to
3.2.0
+445
dist/diff3.cjs
var __defProp = Object.defineProperty;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __moduleCache = /* @__PURE__ */ new WeakMap;
var __toCommonJS = (from) => {
var entry = __moduleCache.get(from), desc;
if (entry)
return entry;
entry = __defProp({}, "__esModule", { value: true });
if (from && typeof from === "object" || typeof from === "function")
__getOwnPropNames(from).map((key) => !__hasOwnProp.call(entry, key) && __defProp(entry, key, {
get: () => from[key],
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
}));
__moduleCache.set(from, entry);
return entry;
};
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, {
get: all[name],
enumerable: true,
configurable: true,
set: (newValue) => all[name] = () => newValue
});
};
// src/diff3.mjs
var exports_diff3 = {};
__export(exports_diff3, {
stripPatch: () => stripPatch,
patch: () => patch,
mergeDigIn: () => mergeDigIn,
mergeDiff3: () => mergeDiff3,
merge: () => merge,
invertPatch: () => invertPatch,
diffPatch: () => diffPatch,
diffIndices: () => diffIndices,
diffComm: () => diffComm,
diff3MergeRegions: () => diff3MergeRegions,
diff3Merge: () => diff3Merge,
LCS: () => LCS
});
module.exports = __toCommonJS(exports_diff3);
function LCS(buffer1, buffer2) {
let equivalenceClasses = {};
for (let j = 0;j < buffer2.length; j++) {
const item = buffer2[j];
if (equivalenceClasses[item]) {
equivalenceClasses[item].push(j);
} else {
equivalenceClasses[item] = [j];
}
}
const NULLRESULT = { buffer1index: -1, buffer2index: -1, chain: null };
let candidates = [NULLRESULT];
for (let i = 0;i < buffer1.length; i++) {
const item = buffer1[i];
const buffer2indices = equivalenceClasses[item] || [];
let r = 0;
let c = candidates[0];
for (let jx = 0;jx < buffer2indices.length; jx++) {
const j = buffer2indices[jx];
let s;
for (s = r;s < candidates.length; s++) {
if (candidates[s].buffer2index < j && (s === candidates.length - 1 || candidates[s + 1].buffer2index > j)) {
break;
}
}
if (s < candidates.length) {
const newCandidate = { buffer1index: i, buffer2index: j, chain: candidates[s] };
if (r === candidates.length) {
candidates.push(c);
} else {
candidates[r] = c;
}
r = s + 1;
c = newCandidate;
if (r === candidates.length) {
break;
}
}
}
candidates[r] = c;
}
return candidates[candidates.length - 1];
}
function diffComm(buffer1, buffer2) {
const lcs = LCS(buffer1, buffer2);
let result = [];
let tail1 = buffer1.length;
let tail2 = buffer2.length;
let common = { common: [] };
function processCommon() {
if (common.common.length) {
common.common.reverse();
result.push(common);
common = { common: [] };
}
}
for (let candidate = lcs;candidate !== null; candidate = candidate.chain) {
let different = { buffer1: [], buffer2: [] };
while (--tail1 > candidate.buffer1index) {
different.buffer1.push(buffer1[tail1]);
}
while (--tail2 > candidate.buffer2index) {
different.buffer2.push(buffer2[tail2]);
}
if (different.buffer1.length || different.buffer2.length) {
processCommon();
different.buffer1.reverse();
different.buffer2.reverse();
result.push(different);
}
if (tail1 >= 0) {
common.common.push(buffer1[tail1]);
}
}
processCommon();
result.reverse();
return result;
}
function diffIndices(buffer1, buffer2) {
const lcs = LCS(buffer1, buffer2);
let result = [];
let tail1 = buffer1.length;
let tail2 = buffer2.length;
for (let candidate = lcs;candidate !== null; candidate = candidate.chain) {
const mismatchLength1 = tail1 - candidate.buffer1index - 1;
const mismatchLength2 = tail2 - candidate.buffer2index - 1;
tail1 = candidate.buffer1index;
tail2 = candidate.buffer2index;
if (mismatchLength1 || mismatchLength2) {
result.push({
buffer1: [tail1 + 1, mismatchLength1],
buffer1Content: buffer1.slice(tail1 + 1, tail1 + 1 + mismatchLength1),
buffer2: [tail2 + 1, mismatchLength2],
buffer2Content: buffer2.slice(tail2 + 1, tail2 + 1 + mismatchLength2)
});
}
}
result.reverse();
return result;
}
function diffPatch(buffer1, buffer2) {
const lcs = LCS(buffer1, buffer2);
let result = [];
let tail1 = buffer1.length;
let tail2 = buffer2.length;
function chunkDescription(buffer, offset, length) {
let chunk = [];
for (let i = 0;i < length; i++) {
chunk.push(buffer[offset + i]);
}
return {
offset,
length,
chunk
};
}
for (let candidate = lcs;candidate !== null; candidate = candidate.chain) {
const mismatchLength1 = tail1 - candidate.buffer1index - 1;
const mismatchLength2 = tail2 - candidate.buffer2index - 1;
tail1 = candidate.buffer1index;
tail2 = candidate.buffer2index;
if (mismatchLength1 || mismatchLength2) {
result.push({
buffer1: chunkDescription(buffer1, candidate.buffer1index + 1, mismatchLength1),
buffer2: chunkDescription(buffer2, candidate.buffer2index + 1, mismatchLength2)
});
}
}
result.reverse();
return result;
}
function diff3MergeRegions(a, o, b) {
let hunks = [];
function addHunk(h, ab) {
hunks.push({
ab,
oStart: h.buffer1[0],
oLength: h.buffer1[1],
abStart: h.buffer2[0],
abLength: h.buffer2[1]
});
}
diffIndices(o, a).forEach((item) => addHunk(item, "a"));
diffIndices(o, b).forEach((item) => addHunk(item, "b"));
hunks.sort((x, y) => x.oStart - y.oStart);
let results = [];
let currOffset = 0;
function advanceTo(endOffset) {
if (endOffset > currOffset) {
results.push({
stable: true,
buffer: "o",
bufferStart: currOffset,
bufferLength: endOffset - currOffset,
bufferContent: o.slice(currOffset, endOffset)
});
currOffset = endOffset;
}
}
while (hunks.length) {
let hunk = hunks.shift();
let regionStart = hunk.oStart;
let regionEnd = hunk.oStart + hunk.oLength;
let regionHunks = [hunk];
advanceTo(regionStart);
while (hunks.length) {
const nextHunk = hunks[0];
const nextHunkStart = nextHunk.oStart;
if (nextHunkStart > regionEnd)
break;
regionEnd = Math.max(regionEnd, nextHunkStart + nextHunk.oLength);
regionHunks.push(hunks.shift());
}
if (regionHunks.length === 1) {
if (hunk.abLength > 0) {
const buffer = hunk.ab === "a" ? a : b;
results.push({
stable: true,
buffer: hunk.ab,
bufferStart: hunk.abStart,
bufferLength: hunk.abLength,
bufferContent: buffer.slice(hunk.abStart, hunk.abStart + hunk.abLength)
});
}
} else {
let bounds = {
a: [a.length, -1, o.length, -1],
b: [b.length, -1, o.length, -1]
};
while (regionHunks.length) {
hunk = regionHunks.shift();
const oStart = hunk.oStart;
const oEnd = oStart + hunk.oLength;
const abStart = hunk.abStart;
const abEnd = abStart + hunk.abLength;
let b2 = bounds[hunk.ab];
b2[0] = Math.min(abStart, b2[0]);
b2[1] = Math.max(abEnd, b2[1]);
b2[2] = Math.min(oStart, b2[2]);
b2[3] = Math.max(oEnd, b2[3]);
}
const aStart = bounds.a[0] + (regionStart - bounds.a[2]);
const aEnd = bounds.a[1] + (regionEnd - bounds.a[3]);
const bStart = bounds.b[0] + (regionStart - bounds.b[2]);
const bEnd = bounds.b[1] + (regionEnd - bounds.b[3]);
let result = {
stable: false,
aStart,
aLength: aEnd - aStart,
aContent: a.slice(aStart, aEnd),
oStart: regionStart,
oLength: regionEnd - regionStart,
oContent: o.slice(regionStart, regionEnd),
bStart,
bLength: bEnd - bStart,
bContent: b.slice(bStart, bEnd)
};
results.push(result);
}
currOffset = regionEnd;
}
advanceTo(o.length);
return results;
}
function diff3Merge(a, o, b, options) {
let defaults = {
excludeFalseConflicts: true,
stringSeparator: /\s+/
};
options = Object.assign(defaults, options);
if (typeof a === "string")
a = a.split(options.stringSeparator);
if (typeof o === "string")
o = o.split(options.stringSeparator);
if (typeof b === "string")
b = b.split(options.stringSeparator);
let results = [];
const regions = diff3MergeRegions(a, o, b);
let okBuffer = [];
function flushOk() {
if (okBuffer.length) {
results.push({ ok: okBuffer });
}
okBuffer = [];
}
function isFalseConflict(a2, b2) {
if (a2.length !== b2.length)
return false;
for (let i = 0;i < a2.length; i++) {
if (a2[i] !== b2[i])
return false;
}
return true;
}
regions.forEach((region) => {
if (region.stable) {
okBuffer.push(...region.bufferContent);
} else {
if (options.excludeFalseConflicts && isFalseConflict(region.aContent, region.bContent)) {
okBuffer.push(...region.aContent);
} else {
flushOk();
results.push({
conflict: {
a: region.aContent,
aIndex: region.aStart,
o: region.oContent,
oIndex: region.oStart,
b: region.bContent,
bIndex: region.bStart
}
});
}
}
});
flushOk();
return results;
}
function mergeDiff3(a, o, b, options) {
const defaults = {
excludeFalseConflicts: true,
stringSeparator: /\s+/,
label: {}
};
options = Object.assign(defaults, options);
const aSection = "<<<<<<<" + (options.label.a ? ` ${options.label.a}` : "");
const oSection = "|||||||" + (options.label.o ? ` ${options.label.o}` : "");
const xSection = "=======";
const bSection = ">>>>>>>" + (options.label.b ? ` ${options.label.b}` : "");
const regions = diff3Merge(a, o, b, options);
let conflict = false;
let result = [];
regions.forEach((region) => {
if (region.ok) {
result = result.concat(region.ok);
} else if (region.conflict) {
conflict = true;
result = result.concat([aSection], region.conflict.a, [oSection], region.conflict.o, [xSection], region.conflict.b, [bSection]);
}
});
return {
conflict,
result
};
}
function merge(a, o, b, options) {
const defaults = {
excludeFalseConflicts: true,
stringSeparator: /\s+/,
label: {}
};
options = Object.assign(defaults, options);
const aSection = "<<<<<<<" + (options.label.a ? ` ${options.label.a}` : "");
const xSection = "=======";
const bSection = ">>>>>>>" + (options.label.b ? ` ${options.label.b}` : "");
const regions = diff3Merge(a, o, b, options);
let conflict = false;
let result = [];
regions.forEach((region) => {
if (region.ok) {
result = result.concat(region.ok);
} else if (region.conflict) {
conflict = true;
result = result.concat([aSection], region.conflict.a, [xSection], region.conflict.b, [bSection]);
}
});
return {
conflict,
result
};
}
function mergeDigIn(a, o, b, options) {
const defaults = {
excludeFalseConflicts: true,
stringSeparator: /\s+/,
label: {}
};
options = Object.assign(defaults, options);
const aSection = "<<<<<<<" + (options.label.a ? ` ${options.label.a}` : "");
const xSection = "=======";
const bSection = ">>>>>>>" + (options.label.b ? ` ${options.label.b}` : "");
const regions = diff3Merge(a, o, b, options);
let conflict = false;
let result = [];
regions.forEach((region) => {
if (region.ok) {
result = result.concat(region.ok);
} else {
const c = diffComm(region.conflict.a, region.conflict.b);
for (let j = 0;j < c.length; j++) {
let inner = c[j];
if (inner.common) {
result = result.concat(inner.common);
} else {
conflict = true;
result = result.concat([aSection], inner.buffer1, [xSection], inner.buffer2, [bSection]);
}
}
}
});
return {
conflict,
result
};
}
function patch(buffer, patch2) {
let result = [];
let currOffset = 0;
function advanceTo(targetOffset) {
while (currOffset < targetOffset) {
result.push(buffer[currOffset]);
currOffset++;
}
}
for (let chunkIndex = 0;chunkIndex < patch2.length; chunkIndex++) {
let chunk = patch2[chunkIndex];
advanceTo(chunk.buffer1.offset);
for (let itemIndex = 0;itemIndex < chunk.buffer2.chunk.length; itemIndex++) {
result.push(chunk.buffer2.chunk[itemIndex]);
}
currOffset += chunk.buffer1.length;
}
advanceTo(buffer.length);
return result;
}
function stripPatch(patch2) {
return patch2.map((chunk) => ({
buffer1: { offset: chunk.buffer1.offset, length: chunk.buffer1.length },
buffer2: { chunk: chunk.buffer2.chunk }
}));
}
function invertPatch(patch2) {
return patch2.map((chunk) => ({
buffer1: chunk.buffer2,
buffer2: chunk.buffer1
}));
}
//# debugId=D476F1A6F1EBC8F364756E2164756E21
//# sourceMappingURL=diff3.cjs.map
{
"version": 3,
"sources": ["../src/diff3.mjs"],
"sourcesContent": [
"export {\n LCS,\n diffComm,\n diffIndices,\n diffPatch,\n diff3MergeRegions,\n diff3Merge,\n mergeDiff3,\n merge,\n mergeDigIn,\n patch,\n stripPatch,\n invertPatch\n};\n\n\n// Text diff algorithm following Hunt and McIlroy 1976.\n// J. W. Hunt and M. D. McIlroy, An algorithm for differential buffer\n// comparison, Bell Telephone Laboratories CSTR #41 (1976)\n// http://www.cs.dartmouth.edu/~doug/\n// https://en.wikipedia.org/wiki/Longest_common_subsequence_problem\n//\n// Expects two arrays, finds longest common sequence\nfunction LCS(buffer1, buffer2) {\n let equivalenceClasses = {};\n for (let j = 0; j < buffer2.length; j++) {\n const item = buffer2[j];\n if (equivalenceClasses[item]) {\n equivalenceClasses[item].push(j);\n } else {\n equivalenceClasses[item] = [j];\n }\n }\n\n const NULLRESULT = { buffer1index: -1, buffer2index: -1, chain: null };\n let candidates = [NULLRESULT];\n\n for (let i = 0; i < buffer1.length; i++) {\n const item = buffer1[i];\n const buffer2indices = equivalenceClasses[item] || [];\n let r = 0;\n let c = candidates[0];\n\n for (let jx = 0; jx < buffer2indices.length; jx++) {\n const j = buffer2indices[jx];\n\n let s;\n for (s = r; s < candidates.length; s++) {\n if ((candidates[s].buffer2index < j) && ((s === candidates.length - 1) || (candidates[s + 1].buffer2index > j))) {\n break;\n }\n }\n\n if (s < candidates.length) {\n const newCandidate = { buffer1index: i, buffer2index: j, chain: candidates[s] };\n if (r === candidates.length) {\n candidates.push(c);\n } else {\n candidates[r] = c;\n }\n r = s + 1;\n c = newCandidate;\n if (r === candidates.length) {\n break; // no point in examining further (j)s\n }\n }\n }\n\n candidates[r] = c;\n }\n\n // At this point, we know the LCS: it's in the reverse of the\n // linked-list through .chain of candidates[candidates.length - 1].\n\n return candidates[candidates.length - 1];\n}\n\n\n// We apply the LCS to build a 'comm'-style picture of the\n// differences between buffer1 and buffer2.\nfunction diffComm(buffer1, buffer2) {\n const lcs = LCS(buffer1, buffer2);\n let result = [];\n let tail1 = buffer1.length;\n let tail2 = buffer2.length;\n let common = {common: []};\n\n function processCommon() {\n if (common.common.length) {\n common.common.reverse();\n result.push(common);\n common = {common: []};\n }\n }\n\n for (let candidate = lcs; candidate !== null; candidate = candidate.chain) {\n let different = {buffer1: [], buffer2: []};\n\n while (--tail1 > candidate.buffer1index) {\n different.buffer1.push(buffer1[tail1]);\n }\n\n while (--tail2 > candidate.buffer2index) {\n different.buffer2.push(buffer2[tail2]);\n }\n\n if (different.buffer1.length || different.buffer2.length) {\n processCommon();\n different.buffer1.reverse();\n different.buffer2.reverse();\n result.push(different);\n }\n\n if (tail1 >= 0) {\n common.common.push(buffer1[tail1]);\n }\n }\n\n processCommon();\n\n result.reverse();\n return result;\n}\n\n\n// We apply the LCS to give a simple representation of the\n// offsets and lengths of mismatched chunks in the input\n// buffers. This is used by diff3MergeRegions.\nfunction diffIndices(buffer1, buffer2) {\n const lcs = LCS(buffer1, buffer2);\n let result = [];\n let tail1 = buffer1.length;\n let tail2 = buffer2.length;\n\n for (let candidate = lcs; candidate !== null; candidate = candidate.chain) {\n const mismatchLength1 = tail1 - candidate.buffer1index - 1;\n const mismatchLength2 = tail2 - candidate.buffer2index - 1;\n tail1 = candidate.buffer1index;\n tail2 = candidate.buffer2index;\n\n if (mismatchLength1 || mismatchLength2) {\n result.push({\n buffer1: [tail1 + 1, mismatchLength1],\n buffer1Content: buffer1.slice(tail1 + 1, tail1 + 1 + mismatchLength1),\n buffer2: [tail2 + 1, mismatchLength2],\n buffer2Content: buffer2.slice(tail2 + 1, tail2 + 1 + mismatchLength2)\n });\n }\n }\n\n result.reverse();\n return result;\n}\n\n\n// We apply the LCS to build a JSON representation of a\n// diff(1)-style patch.\nfunction diffPatch(buffer1, buffer2) {\n const lcs = LCS(buffer1, buffer2);\n let result = [];\n let tail1 = buffer1.length;\n let tail2 = buffer2.length;\n\n function chunkDescription(buffer, offset, length) {\n let chunk = [];\n for (let i = 0; i < length; i++) {\n chunk.push(buffer[offset + i]);\n }\n return {\n offset: offset,\n length: length,\n chunk: chunk\n };\n }\n\n for (let candidate = lcs; candidate !== null; candidate = candidate.chain) {\n const mismatchLength1 = tail1 - candidate.buffer1index - 1;\n const mismatchLength2 = tail2 - candidate.buffer2index - 1;\n tail1 = candidate.buffer1index;\n tail2 = candidate.buffer2index;\n\n if (mismatchLength1 || mismatchLength2) {\n result.push({\n buffer1: chunkDescription(buffer1, candidate.buffer1index + 1, mismatchLength1),\n buffer2: chunkDescription(buffer2, candidate.buffer2index + 1, mismatchLength2)\n });\n }\n }\n\n result.reverse();\n return result;\n}\n\n\n// Given three buffers, A, O, and B, where both A and B are\n// independently derived from O, returns a fairly complicated\n// internal representation of merge decisions it's taken. The\n// interested reader may wish to consult\n//\n// Sanjeev Khanna, Keshav Kunal, and Benjamin C. Pierce.\n// 'A Formal Investigation of ' In Arvind and Prasad,\n// editors, Foundations of Software Technology and Theoretical\n// Computer Science (FSTTCS), December 2007.\n//\n// (http://www.cis.upenn.edu/~bcpierce/papers/diff3-short.pdf)\n//\nfunction diff3MergeRegions(a, o, b) {\n\n // \"hunks\" are array subsets where `a` or `b` are different from `o`\n // https://www.gnu.org/software/diffutils/manual/html_node/diff3-Hunks.html\n let hunks = [];\n function addHunk(h, ab) {\n hunks.push({\n ab: ab,\n oStart: h.buffer1[0],\n oLength: h.buffer1[1], // length of o to remove\n abStart: h.buffer2[0],\n abLength: h.buffer2[1] // length of a/b to insert\n // abContent: (ab === 'a' ? a : b).slice(h.buffer2[0], h.buffer2[0] + h.buffer2[1])\n });\n }\n\n diffIndices(o, a).forEach(item => addHunk(item, 'a'));\n diffIndices(o, b).forEach(item => addHunk(item, 'b'));\n hunks.sort((x,y) => x.oStart - y.oStart);\n\n let results = [];\n let currOffset = 0;\n\n function advanceTo(endOffset) {\n if (endOffset > currOffset) {\n results.push({\n stable: true,\n buffer: 'o',\n bufferStart: currOffset,\n bufferLength: endOffset - currOffset,\n bufferContent: o.slice(currOffset, endOffset)\n });\n currOffset = endOffset;\n }\n }\n\n while (hunks.length) {\n let hunk = hunks.shift();\n let regionStart = hunk.oStart;\n let regionEnd = hunk.oStart + hunk.oLength;\n let regionHunks = [hunk];\n advanceTo(regionStart);\n\n // Try to pull next overlapping hunk into this region\n while (hunks.length) {\n const nextHunk = hunks[0];\n const nextHunkStart = nextHunk.oStart;\n if (nextHunkStart > regionEnd) break; // no overlap\n\n regionEnd = Math.max(regionEnd, nextHunkStart + nextHunk.oLength);\n regionHunks.push(hunks.shift());\n }\n\n if (regionHunks.length === 1) {\n // Only one hunk touches this region, meaning that there is no conflict here.\n // Either `a` or `b` is inserting into a region of `o` unchanged by the other.\n if (hunk.abLength > 0) {\n const buffer = (hunk.ab === 'a' ? a : b);\n results.push({\n stable: true,\n buffer: hunk.ab,\n bufferStart: hunk.abStart,\n bufferLength: hunk.abLength,\n bufferContent: buffer.slice(hunk.abStart, hunk.abStart + hunk.abLength)\n });\n }\n } else {\n // A true a/b conflict. Determine the bounds involved from `a`, `o`, and `b`.\n // Effectively merge all the `a` hunks into one giant hunk, then do the\n // same for the `b` hunks; then, correct for skew in the regions of `o`\n // that each side changed, and report appropriate spans for the three sides.\n let bounds = {\n a: [a.length, -1, o.length, -1],\n b: [b.length, -1, o.length, -1]\n };\n while (regionHunks.length) {\n hunk = regionHunks.shift();\n const oStart = hunk.oStart;\n const oEnd = oStart + hunk.oLength;\n const abStart = hunk.abStart;\n const abEnd = abStart + hunk.abLength;\n let b = bounds[hunk.ab];\n b[0] = Math.min(abStart, b[0]);\n b[1] = Math.max(abEnd, b[1]);\n b[2] = Math.min(oStart, b[2]);\n b[3] = Math.max(oEnd, b[3]);\n }\n\n const aStart = bounds.a[0] + (regionStart - bounds.a[2]);\n const aEnd = bounds.a[1] + (regionEnd - bounds.a[3]);\n const bStart = bounds.b[0] + (regionStart - bounds.b[2]);\n const bEnd = bounds.b[1] + (regionEnd - bounds.b[3]);\n\n let result = {\n stable: false,\n aStart: aStart,\n aLength: aEnd - aStart,\n aContent: a.slice(aStart, aEnd),\n oStart: regionStart,\n oLength: regionEnd - regionStart,\n oContent: o.slice(regionStart, regionEnd),\n bStart: bStart,\n bLength: bEnd - bStart,\n bContent: b.slice(bStart, bEnd)\n };\n results.push(result);\n }\n currOffset = regionEnd;\n }\n\n advanceTo(o.length);\n\n return results;\n}\n\n\n// Applies the output of diff3MergeRegions to actually\n// construct the merged buffer; the returned result alternates\n// between 'ok' and 'conflict' blocks.\n// A \"false conflict\" is where `a` and `b` both change the same from `o`\nfunction diff3Merge(a, o, b, options) {\n let defaults = {\n excludeFalseConflicts: true,\n stringSeparator: /\\s+/\n };\n options = Object.assign(defaults, options);\n\n if (typeof a === 'string') a = a.split(options.stringSeparator);\n if (typeof o === 'string') o = o.split(options.stringSeparator);\n if (typeof b === 'string') b = b.split(options.stringSeparator);\n\n let results = [];\n const regions = diff3MergeRegions(a, o, b);\n\n let okBuffer = [];\n function flushOk() {\n if (okBuffer.length) {\n results.push({ ok: okBuffer });\n }\n okBuffer = [];\n }\n\n function isFalseConflict(a, b) {\n if (a.length !== b.length) return false;\n for (let i = 0; i < a.length; i++) {\n if (a[i] !== b[i]) return false;\n }\n return true;\n }\n\n regions.forEach(region => {\n if (region.stable) {\n okBuffer.push(...region.bufferContent);\n } else {\n if (options.excludeFalseConflicts && isFalseConflict(region.aContent, region.bContent)) {\n okBuffer.push(...region.aContent);\n } else {\n flushOk();\n results.push({\n conflict: {\n a: region.aContent,\n aIndex: region.aStart,\n o: region.oContent,\n oIndex: region.oStart,\n b: region.bContent,\n bIndex: region.bStart\n }\n });\n }\n }\n });\n\n flushOk();\n return results;\n}\n\n\nfunction mergeDiff3(a, o, b, options) {\n const defaults = {\n excludeFalseConflicts: true,\n stringSeparator: /\\s+/,\n label: {}\n };\n options = Object.assign(defaults, options);\n\n const aSection = '<<<<<<<' + (options.label.a ? ` ${options.label.a}` : '');\n const oSection = '|||||||' + (options.label.o ? ` ${options.label.o}` : '');\n const xSection = '=======';\n const bSection = '>>>>>>>' + (options.label.b ? ` ${options.label.b}` : '');\n\n const regions = diff3Merge(a, o, b, options);\n let conflict = false;\n let result = [];\n\n regions.forEach(region => {\n if (region.ok) {\n result = result.concat(region.ok);\n } else if (region.conflict) {\n conflict = true;\n result = result.concat(\n [aSection],\n region.conflict.a,\n [oSection],\n region.conflict.o,\n [xSection],\n region.conflict.b,\n [bSection]\n );\n }\n });\n\n return {\n conflict: conflict,\n result: result\n };\n}\n\n\nfunction merge(a, o, b, options) {\n const defaults = {\n excludeFalseConflicts: true,\n stringSeparator: /\\s+/,\n label: {}\n };\n options = Object.assign(defaults, options);\n\n const aSection = '<<<<<<<' + (options.label.a ? ` ${options.label.a}` : '');\n const xSection = '=======';\n const bSection = '>>>>>>>' + (options.label.b ? ` ${options.label.b}` : '');\n\n const regions = diff3Merge(a, o, b, options);\n let conflict = false;\n let result = [];\n\n regions.forEach(region => {\n if (region.ok) {\n result = result.concat(region.ok);\n } else if (region.conflict) {\n conflict = true;\n result = result.concat(\n [aSection],\n region.conflict.a,\n [xSection],\n region.conflict.b,\n [bSection]\n );\n }\n });\n\n return {\n conflict: conflict,\n result: result\n };\n}\n\n\nfunction mergeDigIn(a, o, b, options) {\n const defaults = {\n excludeFalseConflicts: true,\n stringSeparator: /\\s+/,\n label: {}\n };\n options = Object.assign(defaults, options);\n\n const aSection = '<<<<<<<' + (options.label.a ? ` ${options.label.a}` : '');\n const xSection = '=======';\n const bSection = '>>>>>>>' + (options.label.b ? ` ${options.label.b}` : '');\n\n const regions = diff3Merge(a, o, b, options);\n let conflict = false;\n let result = [];\n\n regions.forEach(region => {\n if (region.ok) {\n result = result.concat(region.ok);\n } else {\n const c = diffComm(region.conflict.a, region.conflict.b);\n for (let j = 0; j < c.length; j++) {\n let inner = c[j];\n if (inner.common) {\n result = result.concat(inner.common);\n } else {\n conflict = true;\n result = result.concat(\n [aSection],\n inner.buffer1,\n [xSection],\n inner.buffer2,\n [bSection]\n );\n }\n }\n }\n });\n\n return {\n conflict: conflict,\n result: result\n };\n}\n\n\n// Applies a patch to a buffer.\n// Given buffer1 and buffer2, `patch(buffer1, diffPatch(buffer1, buffer2))` should give buffer2.\nfunction patch(buffer, patch) {\n let result = [];\n let currOffset = 0;\n\n function advanceTo(targetOffset) {\n while (currOffset < targetOffset) {\n result.push(buffer[currOffset]);\n currOffset++;\n }\n }\n\n for (let chunkIndex = 0; chunkIndex < patch.length; chunkIndex++) {\n let chunk = patch[chunkIndex];\n advanceTo(chunk.buffer1.offset);\n for (let itemIndex = 0; itemIndex < chunk.buffer2.chunk.length; itemIndex++) {\n result.push(chunk.buffer2.chunk[itemIndex]);\n }\n currOffset += chunk.buffer1.length;\n }\n\n advanceTo(buffer.length);\n return result;\n}\n\n\n// Takes the output of diffPatch(), and removes extra information from it.\n// It can still be used by patch(), below, but can no longer be inverted.\nfunction stripPatch(patch) {\n return patch.map(chunk => ({\n buffer1: { offset: chunk.buffer1.offset, length: chunk.buffer1.length },\n buffer2: { chunk: chunk.buffer2.chunk }\n }));\n}\n\n\n// Takes the output of diffPatch(), and inverts the sense of it, so that it\n// can be applied to buffer2 to give buffer1 rather than the other way around.\nfunction invertPatch(patch) {\n return patch.map(chunk => ({\n buffer1: chunk.buffer2,\n buffer2: chunk.buffer1\n }));\n}\n"
],
"mappings": "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",
"debugId": "D476F1A6F1EBC8F364756E2164756E21",
"names": []
}
(() => {
var __defProp = Object.defineProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, {
get: all[name],
enumerable: true,
configurable: true,
set: (newValue) => all[name] = () => newValue
});
};
// src/diff3.mjs
var exports_diff3 = {};
__export(exports_diff3, {
stripPatch: () => stripPatch,
patch: () => patch,
mergeDigIn: () => mergeDigIn,
mergeDiff3: () => mergeDiff3,
merge: () => merge,
invertPatch: () => invertPatch,
diffPatch: () => diffPatch,
diffIndices: () => diffIndices,
diffComm: () => diffComm,
diff3MergeRegions: () => diff3MergeRegions,
diff3Merge: () => diff3Merge,
LCS: () => LCS
});
function LCS(buffer1, buffer2) {
let equivalenceClasses = {};
for (let j = 0;j < buffer2.length; j++) {
const item = buffer2[j];
if (equivalenceClasses[item]) {
equivalenceClasses[item].push(j);
} else {
equivalenceClasses[item] = [j];
}
}
const NULLRESULT = { buffer1index: -1, buffer2index: -1, chain: null };
let candidates = [NULLRESULT];
for (let i = 0;i < buffer1.length; i++) {
const item = buffer1[i];
const buffer2indices = equivalenceClasses[item] || [];
let r = 0;
let c = candidates[0];
for (let jx = 0;jx < buffer2indices.length; jx++) {
const j = buffer2indices[jx];
let s;
for (s = r;s < candidates.length; s++) {
if (candidates[s].buffer2index < j && (s === candidates.length - 1 || candidates[s + 1].buffer2index > j)) {
break;
}
}
if (s < candidates.length) {
const newCandidate = { buffer1index: i, buffer2index: j, chain: candidates[s] };
if (r === candidates.length) {
candidates.push(c);
} else {
candidates[r] = c;
}
r = s + 1;
c = newCandidate;
if (r === candidates.length) {
break;
}
}
}
candidates[r] = c;
}
return candidates[candidates.length - 1];
}
function diffComm(buffer1, buffer2) {
const lcs = LCS(buffer1, buffer2);
let result = [];
let tail1 = buffer1.length;
let tail2 = buffer2.length;
let common = { common: [] };
function processCommon() {
if (common.common.length) {
common.common.reverse();
result.push(common);
common = { common: [] };
}
}
for (let candidate = lcs;candidate !== null; candidate = candidate.chain) {
let different = { buffer1: [], buffer2: [] };
while (--tail1 > candidate.buffer1index) {
different.buffer1.push(buffer1[tail1]);
}
while (--tail2 > candidate.buffer2index) {
different.buffer2.push(buffer2[tail2]);
}
if (different.buffer1.length || different.buffer2.length) {
processCommon();
different.buffer1.reverse();
different.buffer2.reverse();
result.push(different);
}
if (tail1 >= 0) {
common.common.push(buffer1[tail1]);
}
}
processCommon();
result.reverse();
return result;
}
function diffIndices(buffer1, buffer2) {
const lcs = LCS(buffer1, buffer2);
let result = [];
let tail1 = buffer1.length;
let tail2 = buffer2.length;
for (let candidate = lcs;candidate !== null; candidate = candidate.chain) {
const mismatchLength1 = tail1 - candidate.buffer1index - 1;
const mismatchLength2 = tail2 - candidate.buffer2index - 1;
tail1 = candidate.buffer1index;
tail2 = candidate.buffer2index;
if (mismatchLength1 || mismatchLength2) {
result.push({
buffer1: [tail1 + 1, mismatchLength1],
buffer1Content: buffer1.slice(tail1 + 1, tail1 + 1 + mismatchLength1),
buffer2: [tail2 + 1, mismatchLength2],
buffer2Content: buffer2.slice(tail2 + 1, tail2 + 1 + mismatchLength2)
});
}
}
result.reverse();
return result;
}
function diffPatch(buffer1, buffer2) {
const lcs = LCS(buffer1, buffer2);
let result = [];
let tail1 = buffer1.length;
let tail2 = buffer2.length;
function chunkDescription(buffer, offset, length) {
let chunk = [];
for (let i = 0;i < length; i++) {
chunk.push(buffer[offset + i]);
}
return {
offset,
length,
chunk
};
}
for (let candidate = lcs;candidate !== null; candidate = candidate.chain) {
const mismatchLength1 = tail1 - candidate.buffer1index - 1;
const mismatchLength2 = tail2 - candidate.buffer2index - 1;
tail1 = candidate.buffer1index;
tail2 = candidate.buffer2index;
if (mismatchLength1 || mismatchLength2) {
result.push({
buffer1: chunkDescription(buffer1, candidate.buffer1index + 1, mismatchLength1),
buffer2: chunkDescription(buffer2, candidate.buffer2index + 1, mismatchLength2)
});
}
}
result.reverse();
return result;
}
function diff3MergeRegions(a, o, b) {
let hunks = [];
function addHunk(h, ab) {
hunks.push({
ab,
oStart: h.buffer1[0],
oLength: h.buffer1[1],
abStart: h.buffer2[0],
abLength: h.buffer2[1]
});
}
diffIndices(o, a).forEach((item) => addHunk(item, "a"));
diffIndices(o, b).forEach((item) => addHunk(item, "b"));
hunks.sort((x, y) => x.oStart - y.oStart);
let results = [];
let currOffset = 0;
function advanceTo(endOffset) {
if (endOffset > currOffset) {
results.push({
stable: true,
buffer: "o",
bufferStart: currOffset,
bufferLength: endOffset - currOffset,
bufferContent: o.slice(currOffset, endOffset)
});
currOffset = endOffset;
}
}
while (hunks.length) {
let hunk = hunks.shift();
let regionStart = hunk.oStart;
let regionEnd = hunk.oStart + hunk.oLength;
let regionHunks = [hunk];
advanceTo(regionStart);
while (hunks.length) {
const nextHunk = hunks[0];
const nextHunkStart = nextHunk.oStart;
if (nextHunkStart > regionEnd)
break;
regionEnd = Math.max(regionEnd, nextHunkStart + nextHunk.oLength);
regionHunks.push(hunks.shift());
}
if (regionHunks.length === 1) {
if (hunk.abLength > 0) {
const buffer = hunk.ab === "a" ? a : b;
results.push({
stable: true,
buffer: hunk.ab,
bufferStart: hunk.abStart,
bufferLength: hunk.abLength,
bufferContent: buffer.slice(hunk.abStart, hunk.abStart + hunk.abLength)
});
}
} else {
let bounds = {
a: [a.length, -1, o.length, -1],
b: [b.length, -1, o.length, -1]
};
while (regionHunks.length) {
hunk = regionHunks.shift();
const oStart = hunk.oStart;
const oEnd = oStart + hunk.oLength;
const abStart = hunk.abStart;
const abEnd = abStart + hunk.abLength;
let b2 = bounds[hunk.ab];
b2[0] = Math.min(abStart, b2[0]);
b2[1] = Math.max(abEnd, b2[1]);
b2[2] = Math.min(oStart, b2[2]);
b2[3] = Math.max(oEnd, b2[3]);
}
const aStart = bounds.a[0] + (regionStart - bounds.a[2]);
const aEnd = bounds.a[1] + (regionEnd - bounds.a[3]);
const bStart = bounds.b[0] + (regionStart - bounds.b[2]);
const bEnd = bounds.b[1] + (regionEnd - bounds.b[3]);
let result = {
stable: false,
aStart,
aLength: aEnd - aStart,
aContent: a.slice(aStart, aEnd),
oStart: regionStart,
oLength: regionEnd - regionStart,
oContent: o.slice(regionStart, regionEnd),
bStart,
bLength: bEnd - bStart,
bContent: b.slice(bStart, bEnd)
};
results.push(result);
}
currOffset = regionEnd;
}
advanceTo(o.length);
return results;
}
function diff3Merge(a, o, b, options) {
let defaults = {
excludeFalseConflicts: true,
stringSeparator: /\s+/
};
options = Object.assign(defaults, options);
if (typeof a === "string")
a = a.split(options.stringSeparator);
if (typeof o === "string")
o = o.split(options.stringSeparator);
if (typeof b === "string")
b = b.split(options.stringSeparator);
let results = [];
const regions = diff3MergeRegions(a, o, b);
let okBuffer = [];
function flushOk() {
if (okBuffer.length) {
results.push({ ok: okBuffer });
}
okBuffer = [];
}
function isFalseConflict(a2, b2) {
if (a2.length !== b2.length)
return false;
for (let i = 0;i < a2.length; i++) {
if (a2[i] !== b2[i])
return false;
}
return true;
}
regions.forEach((region) => {
if (region.stable) {
okBuffer.push(...region.bufferContent);
} else {
if (options.excludeFalseConflicts && isFalseConflict(region.aContent, region.bContent)) {
okBuffer.push(...region.aContent);
} else {
flushOk();
results.push({
conflict: {
a: region.aContent,
aIndex: region.aStart,
o: region.oContent,
oIndex: region.oStart,
b: region.bContent,
bIndex: region.bStart
}
});
}
}
});
flushOk();
return results;
}
function mergeDiff3(a, o, b, options) {
const defaults = {
excludeFalseConflicts: true,
stringSeparator: /\s+/,
label: {}
};
options = Object.assign(defaults, options);
const aSection = "<<<<<<<" + (options.label.a ? ` ${options.label.a}` : "");
const oSection = "|||||||" + (options.label.o ? ` ${options.label.o}` : "");
const xSection = "=======";
const bSection = ">>>>>>>" + (options.label.b ? ` ${options.label.b}` : "");
const regions = diff3Merge(a, o, b, options);
let conflict = false;
let result = [];
regions.forEach((region) => {
if (region.ok) {
result = result.concat(region.ok);
} else if (region.conflict) {
conflict = true;
result = result.concat([aSection], region.conflict.a, [oSection], region.conflict.o, [xSection], region.conflict.b, [bSection]);
}
});
return {
conflict,
result
};
}
function merge(a, o, b, options) {
const defaults = {
excludeFalseConflicts: true,
stringSeparator: /\s+/,
label: {}
};
options = Object.assign(defaults, options);
const aSection = "<<<<<<<" + (options.label.a ? ` ${options.label.a}` : "");
const xSection = "=======";
const bSection = ">>>>>>>" + (options.label.b ? ` ${options.label.b}` : "");
const regions = diff3Merge(a, o, b, options);
let conflict = false;
let result = [];
regions.forEach((region) => {
if (region.ok) {
result = result.concat(region.ok);
} else if (region.conflict) {
conflict = true;
result = result.concat([aSection], region.conflict.a, [xSection], region.conflict.b, [bSection]);
}
});
return {
conflict,
result
};
}
function mergeDigIn(a, o, b, options) {
const defaults = {
excludeFalseConflicts: true,
stringSeparator: /\s+/,
label: {}
};
options = Object.assign(defaults, options);
const aSection = "<<<<<<<" + (options.label.a ? ` ${options.label.a}` : "");
const xSection = "=======";
const bSection = ">>>>>>>" + (options.label.b ? ` ${options.label.b}` : "");
const regions = diff3Merge(a, o, b, options);
let conflict = false;
let result = [];
regions.forEach((region) => {
if (region.ok) {
result = result.concat(region.ok);
} else {
const c = diffComm(region.conflict.a, region.conflict.b);
for (let j = 0;j < c.length; j++) {
let inner = c[j];
if (inner.common) {
result = result.concat(inner.common);
} else {
conflict = true;
result = result.concat([aSection], inner.buffer1, [xSection], inner.buffer2, [bSection]);
}
}
}
});
return {
conflict,
result
};
}
function patch(buffer, patch2) {
let result = [];
let currOffset = 0;
function advanceTo(targetOffset) {
while (currOffset < targetOffset) {
result.push(buffer[currOffset]);
currOffset++;
}
}
for (let chunkIndex = 0;chunkIndex < patch2.length; chunkIndex++) {
let chunk = patch2[chunkIndex];
advanceTo(chunk.buffer1.offset);
for (let itemIndex = 0;itemIndex < chunk.buffer2.chunk.length; itemIndex++) {
result.push(chunk.buffer2.chunk[itemIndex]);
}
currOffset += chunk.buffer1.length;
}
advanceTo(buffer.length);
return result;
}
function stripPatch(patch2) {
return patch2.map((chunk) => ({
buffer1: { offset: chunk.buffer1.offset, length: chunk.buffer1.length },
buffer2: { chunk: chunk.buffer2.chunk }
}));
}
function invertPatch(patch2) {
return patch2.map((chunk) => ({
buffer1: chunk.buffer2,
buffer2: chunk.buffer1
}));
}
// src/index.ts
globalThis.Diff3 = exports_diff3;
})();
//# debugId=5D96D19B25AE829964756E2164756E21
//# sourceMappingURL=diff3.iife.js.map
{
"version": 3,
"sources": ["../src/diff3.mjs", "../src/index.ts"],
"sourcesContent": [
"export {\n LCS,\n diffComm,\n diffIndices,\n diffPatch,\n diff3MergeRegions,\n diff3Merge,\n mergeDiff3,\n merge,\n mergeDigIn,\n patch,\n stripPatch,\n invertPatch\n};\n\n\n// Text diff algorithm following Hunt and McIlroy 1976.\n// J. W. Hunt and M. D. McIlroy, An algorithm for differential buffer\n// comparison, Bell Telephone Laboratories CSTR #41 (1976)\n// http://www.cs.dartmouth.edu/~doug/\n// https://en.wikipedia.org/wiki/Longest_common_subsequence_problem\n//\n// Expects two arrays, finds longest common sequence\nfunction LCS(buffer1, buffer2) {\n let equivalenceClasses = {};\n for (let j = 0; j < buffer2.length; j++) {\n const item = buffer2[j];\n if (equivalenceClasses[item]) {\n equivalenceClasses[item].push(j);\n } else {\n equivalenceClasses[item] = [j];\n }\n }\n\n const NULLRESULT = { buffer1index: -1, buffer2index: -1, chain: null };\n let candidates = [NULLRESULT];\n\n for (let i = 0; i < buffer1.length; i++) {\n const item = buffer1[i];\n const buffer2indices = equivalenceClasses[item] || [];\n let r = 0;\n let c = candidates[0];\n\n for (let jx = 0; jx < buffer2indices.length; jx++) {\n const j = buffer2indices[jx];\n\n let s;\n for (s = r; s < candidates.length; s++) {\n if ((candidates[s].buffer2index < j) && ((s === candidates.length - 1) || (candidates[s + 1].buffer2index > j))) {\n break;\n }\n }\n\n if (s < candidates.length) {\n const newCandidate = { buffer1index: i, buffer2index: j, chain: candidates[s] };\n if (r === candidates.length) {\n candidates.push(c);\n } else {\n candidates[r] = c;\n }\n r = s + 1;\n c = newCandidate;\n if (r === candidates.length) {\n break; // no point in examining further (j)s\n }\n }\n }\n\n candidates[r] = c;\n }\n\n // At this point, we know the LCS: it's in the reverse of the\n // linked-list through .chain of candidates[candidates.length - 1].\n\n return candidates[candidates.length - 1];\n}\n\n\n// We apply the LCS to build a 'comm'-style picture of the\n// differences between buffer1 and buffer2.\nfunction diffComm(buffer1, buffer2) {\n const lcs = LCS(buffer1, buffer2);\n let result = [];\n let tail1 = buffer1.length;\n let tail2 = buffer2.length;\n let common = {common: []};\n\n function processCommon() {\n if (common.common.length) {\n common.common.reverse();\n result.push(common);\n common = {common: []};\n }\n }\n\n for (let candidate = lcs; candidate !== null; candidate = candidate.chain) {\n let different = {buffer1: [], buffer2: []};\n\n while (--tail1 > candidate.buffer1index) {\n different.buffer1.push(buffer1[tail1]);\n }\n\n while (--tail2 > candidate.buffer2index) {\n different.buffer2.push(buffer2[tail2]);\n }\n\n if (different.buffer1.length || different.buffer2.length) {\n processCommon();\n different.buffer1.reverse();\n different.buffer2.reverse();\n result.push(different);\n }\n\n if (tail1 >= 0) {\n common.common.push(buffer1[tail1]);\n }\n }\n\n processCommon();\n\n result.reverse();\n return result;\n}\n\n\n// We apply the LCS to give a simple representation of the\n// offsets and lengths of mismatched chunks in the input\n// buffers. This is used by diff3MergeRegions.\nfunction diffIndices(buffer1, buffer2) {\n const lcs = LCS(buffer1, buffer2);\n let result = [];\n let tail1 = buffer1.length;\n let tail2 = buffer2.length;\n\n for (let candidate = lcs; candidate !== null; candidate = candidate.chain) {\n const mismatchLength1 = tail1 - candidate.buffer1index - 1;\n const mismatchLength2 = tail2 - candidate.buffer2index - 1;\n tail1 = candidate.buffer1index;\n tail2 = candidate.buffer2index;\n\n if (mismatchLength1 || mismatchLength2) {\n result.push({\n buffer1: [tail1 + 1, mismatchLength1],\n buffer1Content: buffer1.slice(tail1 + 1, tail1 + 1 + mismatchLength1),\n buffer2: [tail2 + 1, mismatchLength2],\n buffer2Content: buffer2.slice(tail2 + 1, tail2 + 1 + mismatchLength2)\n });\n }\n }\n\n result.reverse();\n return result;\n}\n\n\n// We apply the LCS to build a JSON representation of a\n// diff(1)-style patch.\nfunction diffPatch(buffer1, buffer2) {\n const lcs = LCS(buffer1, buffer2);\n let result = [];\n let tail1 = buffer1.length;\n let tail2 = buffer2.length;\n\n function chunkDescription(buffer, offset, length) {\n let chunk = [];\n for (let i = 0; i < length; i++) {\n chunk.push(buffer[offset + i]);\n }\n return {\n offset: offset,\n length: length,\n chunk: chunk\n };\n }\n\n for (let candidate = lcs; candidate !== null; candidate = candidate.chain) {\n const mismatchLength1 = tail1 - candidate.buffer1index - 1;\n const mismatchLength2 = tail2 - candidate.buffer2index - 1;\n tail1 = candidate.buffer1index;\n tail2 = candidate.buffer2index;\n\n if (mismatchLength1 || mismatchLength2) {\n result.push({\n buffer1: chunkDescription(buffer1, candidate.buffer1index + 1, mismatchLength1),\n buffer2: chunkDescription(buffer2, candidate.buffer2index + 1, mismatchLength2)\n });\n }\n }\n\n result.reverse();\n return result;\n}\n\n\n// Given three buffers, A, O, and B, where both A and B are\n// independently derived from O, returns a fairly complicated\n// internal representation of merge decisions it's taken. The\n// interested reader may wish to consult\n//\n// Sanjeev Khanna, Keshav Kunal, and Benjamin C. Pierce.\n// 'A Formal Investigation of ' In Arvind and Prasad,\n// editors, Foundations of Software Technology and Theoretical\n// Computer Science (FSTTCS), December 2007.\n//\n// (http://www.cis.upenn.edu/~bcpierce/papers/diff3-short.pdf)\n//\nfunction diff3MergeRegions(a, o, b) {\n\n // \"hunks\" are array subsets where `a` or `b` are different from `o`\n // https://www.gnu.org/software/diffutils/manual/html_node/diff3-Hunks.html\n let hunks = [];\n function addHunk(h, ab) {\n hunks.push({\n ab: ab,\n oStart: h.buffer1[0],\n oLength: h.buffer1[1], // length of o to remove\n abStart: h.buffer2[0],\n abLength: h.buffer2[1] // length of a/b to insert\n // abContent: (ab === 'a' ? a : b).slice(h.buffer2[0], h.buffer2[0] + h.buffer2[1])\n });\n }\n\n diffIndices(o, a).forEach(item => addHunk(item, 'a'));\n diffIndices(o, b).forEach(item => addHunk(item, 'b'));\n hunks.sort((x,y) => x.oStart - y.oStart);\n\n let results = [];\n let currOffset = 0;\n\n function advanceTo(endOffset) {\n if (endOffset > currOffset) {\n results.push({\n stable: true,\n buffer: 'o',\n bufferStart: currOffset,\n bufferLength: endOffset - currOffset,\n bufferContent: o.slice(currOffset, endOffset)\n });\n currOffset = endOffset;\n }\n }\n\n while (hunks.length) {\n let hunk = hunks.shift();\n let regionStart = hunk.oStart;\n let regionEnd = hunk.oStart + hunk.oLength;\n let regionHunks = [hunk];\n advanceTo(regionStart);\n\n // Try to pull next overlapping hunk into this region\n while (hunks.length) {\n const nextHunk = hunks[0];\n const nextHunkStart = nextHunk.oStart;\n if (nextHunkStart > regionEnd) break; // no overlap\n\n regionEnd = Math.max(regionEnd, nextHunkStart + nextHunk.oLength);\n regionHunks.push(hunks.shift());\n }\n\n if (regionHunks.length === 1) {\n // Only one hunk touches this region, meaning that there is no conflict here.\n // Either `a` or `b` is inserting into a region of `o` unchanged by the other.\n if (hunk.abLength > 0) {\n const buffer = (hunk.ab === 'a' ? a : b);\n results.push({\n stable: true,\n buffer: hunk.ab,\n bufferStart: hunk.abStart,\n bufferLength: hunk.abLength,\n bufferContent: buffer.slice(hunk.abStart, hunk.abStart + hunk.abLength)\n });\n }\n } else {\n // A true a/b conflict. Determine the bounds involved from `a`, `o`, and `b`.\n // Effectively merge all the `a` hunks into one giant hunk, then do the\n // same for the `b` hunks; then, correct for skew in the regions of `o`\n // that each side changed, and report appropriate spans for the three sides.\n let bounds = {\n a: [a.length, -1, o.length, -1],\n b: [b.length, -1, o.length, -1]\n };\n while (regionHunks.length) {\n hunk = regionHunks.shift();\n const oStart = hunk.oStart;\n const oEnd = oStart + hunk.oLength;\n const abStart = hunk.abStart;\n const abEnd = abStart + hunk.abLength;\n let b = bounds[hunk.ab];\n b[0] = Math.min(abStart, b[0]);\n b[1] = Math.max(abEnd, b[1]);\n b[2] = Math.min(oStart, b[2]);\n b[3] = Math.max(oEnd, b[3]);\n }\n\n const aStart = bounds.a[0] + (regionStart - bounds.a[2]);\n const aEnd = bounds.a[1] + (regionEnd - bounds.a[3]);\n const bStart = bounds.b[0] + (regionStart - bounds.b[2]);\n const bEnd = bounds.b[1] + (regionEnd - bounds.b[3]);\n\n let result = {\n stable: false,\n aStart: aStart,\n aLength: aEnd - aStart,\n aContent: a.slice(aStart, aEnd),\n oStart: regionStart,\n oLength: regionEnd - regionStart,\n oContent: o.slice(regionStart, regionEnd),\n bStart: bStart,\n bLength: bEnd - bStart,\n bContent: b.slice(bStart, bEnd)\n };\n results.push(result);\n }\n currOffset = regionEnd;\n }\n\n advanceTo(o.length);\n\n return results;\n}\n\n\n// Applies the output of diff3MergeRegions to actually\n// construct the merged buffer; the returned result alternates\n// between 'ok' and 'conflict' blocks.\n// A \"false conflict\" is where `a` and `b` both change the same from `o`\nfunction diff3Merge(a, o, b, options) {\n let defaults = {\n excludeFalseConflicts: true,\n stringSeparator: /\\s+/\n };\n options = Object.assign(defaults, options);\n\n if (typeof a === 'string') a = a.split(options.stringSeparator);\n if (typeof o === 'string') o = o.split(options.stringSeparator);\n if (typeof b === 'string') b = b.split(options.stringSeparator);\n\n let results = [];\n const regions = diff3MergeRegions(a, o, b);\n\n let okBuffer = [];\n function flushOk() {\n if (okBuffer.length) {\n results.push({ ok: okBuffer });\n }\n okBuffer = [];\n }\n\n function isFalseConflict(a, b) {\n if (a.length !== b.length) return false;\n for (let i = 0; i < a.length; i++) {\n if (a[i] !== b[i]) return false;\n }\n return true;\n }\n\n regions.forEach(region => {\n if (region.stable) {\n okBuffer.push(...region.bufferContent);\n } else {\n if (options.excludeFalseConflicts && isFalseConflict(region.aContent, region.bContent)) {\n okBuffer.push(...region.aContent);\n } else {\n flushOk();\n results.push({\n conflict: {\n a: region.aContent,\n aIndex: region.aStart,\n o: region.oContent,\n oIndex: region.oStart,\n b: region.bContent,\n bIndex: region.bStart\n }\n });\n }\n }\n });\n\n flushOk();\n return results;\n}\n\n\nfunction mergeDiff3(a, o, b, options) {\n const defaults = {\n excludeFalseConflicts: true,\n stringSeparator: /\\s+/,\n label: {}\n };\n options = Object.assign(defaults, options);\n\n const aSection = '<<<<<<<' + (options.label.a ? ` ${options.label.a}` : '');\n const oSection = '|||||||' + (options.label.o ? ` ${options.label.o}` : '');\n const xSection = '=======';\n const bSection = '>>>>>>>' + (options.label.b ? ` ${options.label.b}` : '');\n\n const regions = diff3Merge(a, o, b, options);\n let conflict = false;\n let result = [];\n\n regions.forEach(region => {\n if (region.ok) {\n result = result.concat(region.ok);\n } else if (region.conflict) {\n conflict = true;\n result = result.concat(\n [aSection],\n region.conflict.a,\n [oSection],\n region.conflict.o,\n [xSection],\n region.conflict.b,\n [bSection]\n );\n }\n });\n\n return {\n conflict: conflict,\n result: result\n };\n}\n\n\nfunction merge(a, o, b, options) {\n const defaults = {\n excludeFalseConflicts: true,\n stringSeparator: /\\s+/,\n label: {}\n };\n options = Object.assign(defaults, options);\n\n const aSection = '<<<<<<<' + (options.label.a ? ` ${options.label.a}` : '');\n const xSection = '=======';\n const bSection = '>>>>>>>' + (options.label.b ? ` ${options.label.b}` : '');\n\n const regions = diff3Merge(a, o, b, options);\n let conflict = false;\n let result = [];\n\n regions.forEach(region => {\n if (region.ok) {\n result = result.concat(region.ok);\n } else if (region.conflict) {\n conflict = true;\n result = result.concat(\n [aSection],\n region.conflict.a,\n [xSection],\n region.conflict.b,\n [bSection]\n );\n }\n });\n\n return {\n conflict: conflict,\n result: result\n };\n}\n\n\nfunction mergeDigIn(a, o, b, options) {\n const defaults = {\n excludeFalseConflicts: true,\n stringSeparator: /\\s+/,\n label: {}\n };\n options = Object.assign(defaults, options);\n\n const aSection = '<<<<<<<' + (options.label.a ? ` ${options.label.a}` : '');\n const xSection = '=======';\n const bSection = '>>>>>>>' + (options.label.b ? ` ${options.label.b}` : '');\n\n const regions = diff3Merge(a, o, b, options);\n let conflict = false;\n let result = [];\n\n regions.forEach(region => {\n if (region.ok) {\n result = result.concat(region.ok);\n } else {\n const c = diffComm(region.conflict.a, region.conflict.b);\n for (let j = 0; j < c.length; j++) {\n let inner = c[j];\n if (inner.common) {\n result = result.concat(inner.common);\n } else {\n conflict = true;\n result = result.concat(\n [aSection],\n inner.buffer1,\n [xSection],\n inner.buffer2,\n [bSection]\n );\n }\n }\n }\n });\n\n return {\n conflict: conflict,\n result: result\n };\n}\n\n\n// Applies a patch to a buffer.\n// Given buffer1 and buffer2, `patch(buffer1, diffPatch(buffer1, buffer2))` should give buffer2.\nfunction patch(buffer, patch) {\n let result = [];\n let currOffset = 0;\n\n function advanceTo(targetOffset) {\n while (currOffset < targetOffset) {\n result.push(buffer[currOffset]);\n currOffset++;\n }\n }\n\n for (let chunkIndex = 0; chunkIndex < patch.length; chunkIndex++) {\n let chunk = patch[chunkIndex];\n advanceTo(chunk.buffer1.offset);\n for (let itemIndex = 0; itemIndex < chunk.buffer2.chunk.length; itemIndex++) {\n result.push(chunk.buffer2.chunk[itemIndex]);\n }\n currOffset += chunk.buffer1.length;\n }\n\n advanceTo(buffer.length);\n return result;\n}\n\n\n// Takes the output of diffPatch(), and removes extra information from it.\n// It can still be used by patch(), below, but can no longer be inverted.\nfunction stripPatch(patch) {\n return patch.map(chunk => ({\n buffer1: { offset: chunk.buffer1.offset, length: chunk.buffer1.length },\n buffer2: { chunk: chunk.buffer2.chunk }\n }));\n}\n\n\n// Takes the output of diffPatch(), and inverts the sense of it, so that it\n// can be applied to buffer2 to give buffer1 rather than the other way around.\nfunction invertPatch(patch) {\n return patch.map(chunk => ({\n buffer1: chunk.buffer2,\n buffer2: chunk.buffer1\n }));\n}\n",
"import * as Diff3 from './diff3.mjs';\nglobalThis.Diff3 = Diff3;\n"
],
"mappings": "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",
"debugId": "5D96D19B25AE829964756E2164756E21",
"names": []
}
// src/diff3.mjs
function LCS(buffer1, buffer2) {
let equivalenceClasses = {};
for (let j = 0;j < buffer2.length; j++) {
const item = buffer2[j];
if (equivalenceClasses[item]) {
equivalenceClasses[item].push(j);
} else {
equivalenceClasses[item] = [j];
}
}
const NULLRESULT = { buffer1index: -1, buffer2index: -1, chain: null };
let candidates = [NULLRESULT];
for (let i = 0;i < buffer1.length; i++) {
const item = buffer1[i];
const buffer2indices = equivalenceClasses[item] || [];
let r = 0;
let c = candidates[0];
for (let jx = 0;jx < buffer2indices.length; jx++) {
const j = buffer2indices[jx];
let s;
for (s = r;s < candidates.length; s++) {
if (candidates[s].buffer2index < j && (s === candidates.length - 1 || candidates[s + 1].buffer2index > j)) {
break;
}
}
if (s < candidates.length) {
const newCandidate = { buffer1index: i, buffer2index: j, chain: candidates[s] };
if (r === candidates.length) {
candidates.push(c);
} else {
candidates[r] = c;
}
r = s + 1;
c = newCandidate;
if (r === candidates.length) {
break;
}
}
}
candidates[r] = c;
}
return candidates[candidates.length - 1];
}
function diffComm(buffer1, buffer2) {
const lcs = LCS(buffer1, buffer2);
let result = [];
let tail1 = buffer1.length;
let tail2 = buffer2.length;
let common = { common: [] };
function processCommon() {
if (common.common.length) {
common.common.reverse();
result.push(common);
common = { common: [] };
}
}
for (let candidate = lcs;candidate !== null; candidate = candidate.chain) {
let different = { buffer1: [], buffer2: [] };
while (--tail1 > candidate.buffer1index) {
different.buffer1.push(buffer1[tail1]);
}
while (--tail2 > candidate.buffer2index) {
different.buffer2.push(buffer2[tail2]);
}
if (different.buffer1.length || different.buffer2.length) {
processCommon();
different.buffer1.reverse();
different.buffer2.reverse();
result.push(different);
}
if (tail1 >= 0) {
common.common.push(buffer1[tail1]);
}
}
processCommon();
result.reverse();
return result;
}
function diffIndices(buffer1, buffer2) {
const lcs = LCS(buffer1, buffer2);
let result = [];
let tail1 = buffer1.length;
let tail2 = buffer2.length;
for (let candidate = lcs;candidate !== null; candidate = candidate.chain) {
const mismatchLength1 = tail1 - candidate.buffer1index - 1;
const mismatchLength2 = tail2 - candidate.buffer2index - 1;
tail1 = candidate.buffer1index;
tail2 = candidate.buffer2index;
if (mismatchLength1 || mismatchLength2) {
result.push({
buffer1: [tail1 + 1, mismatchLength1],
buffer1Content: buffer1.slice(tail1 + 1, tail1 + 1 + mismatchLength1),
buffer2: [tail2 + 1, mismatchLength2],
buffer2Content: buffer2.slice(tail2 + 1, tail2 + 1 + mismatchLength2)
});
}
}
result.reverse();
return result;
}
function diffPatch(buffer1, buffer2) {
const lcs = LCS(buffer1, buffer2);
let result = [];
let tail1 = buffer1.length;
let tail2 = buffer2.length;
function chunkDescription(buffer, offset, length) {
let chunk = [];
for (let i = 0;i < length; i++) {
chunk.push(buffer[offset + i]);
}
return {
offset,
length,
chunk
};
}
for (let candidate = lcs;candidate !== null; candidate = candidate.chain) {
const mismatchLength1 = tail1 - candidate.buffer1index - 1;
const mismatchLength2 = tail2 - candidate.buffer2index - 1;
tail1 = candidate.buffer1index;
tail2 = candidate.buffer2index;
if (mismatchLength1 || mismatchLength2) {
result.push({
buffer1: chunkDescription(buffer1, candidate.buffer1index + 1, mismatchLength1),
buffer2: chunkDescription(buffer2, candidate.buffer2index + 1, mismatchLength2)
});
}
}
result.reverse();
return result;
}
function diff3MergeRegions(a, o, b) {
let hunks = [];
function addHunk(h, ab) {
hunks.push({
ab,
oStart: h.buffer1[0],
oLength: h.buffer1[1],
abStart: h.buffer2[0],
abLength: h.buffer2[1]
});
}
diffIndices(o, a).forEach((item) => addHunk(item, "a"));
diffIndices(o, b).forEach((item) => addHunk(item, "b"));
hunks.sort((x, y) => x.oStart - y.oStart);
let results = [];
let currOffset = 0;
function advanceTo(endOffset) {
if (endOffset > currOffset) {
results.push({
stable: true,
buffer: "o",
bufferStart: currOffset,
bufferLength: endOffset - currOffset,
bufferContent: o.slice(currOffset, endOffset)
});
currOffset = endOffset;
}
}
while (hunks.length) {
let hunk = hunks.shift();
let regionStart = hunk.oStart;
let regionEnd = hunk.oStart + hunk.oLength;
let regionHunks = [hunk];
advanceTo(regionStart);
while (hunks.length) {
const nextHunk = hunks[0];
const nextHunkStart = nextHunk.oStart;
if (nextHunkStart > regionEnd)
break;
regionEnd = Math.max(regionEnd, nextHunkStart + nextHunk.oLength);
regionHunks.push(hunks.shift());
}
if (regionHunks.length === 1) {
if (hunk.abLength > 0) {
const buffer = hunk.ab === "a" ? a : b;
results.push({
stable: true,
buffer: hunk.ab,
bufferStart: hunk.abStart,
bufferLength: hunk.abLength,
bufferContent: buffer.slice(hunk.abStart, hunk.abStart + hunk.abLength)
});
}
} else {
let bounds = {
a: [a.length, -1, o.length, -1],
b: [b.length, -1, o.length, -1]
};
while (regionHunks.length) {
hunk = regionHunks.shift();
const oStart = hunk.oStart;
const oEnd = oStart + hunk.oLength;
const abStart = hunk.abStart;
const abEnd = abStart + hunk.abLength;
let b2 = bounds[hunk.ab];
b2[0] = Math.min(abStart, b2[0]);
b2[1] = Math.max(abEnd, b2[1]);
b2[2] = Math.min(oStart, b2[2]);
b2[3] = Math.max(oEnd, b2[3]);
}
const aStart = bounds.a[0] + (regionStart - bounds.a[2]);
const aEnd = bounds.a[1] + (regionEnd - bounds.a[3]);
const bStart = bounds.b[0] + (regionStart - bounds.b[2]);
const bEnd = bounds.b[1] + (regionEnd - bounds.b[3]);
let result = {
stable: false,
aStart,
aLength: aEnd - aStart,
aContent: a.slice(aStart, aEnd),
oStart: regionStart,
oLength: regionEnd - regionStart,
oContent: o.slice(regionStart, regionEnd),
bStart,
bLength: bEnd - bStart,
bContent: b.slice(bStart, bEnd)
};
results.push(result);
}
currOffset = regionEnd;
}
advanceTo(o.length);
return results;
}
function diff3Merge(a, o, b, options) {
let defaults = {
excludeFalseConflicts: true,
stringSeparator: /\s+/
};
options = Object.assign(defaults, options);
if (typeof a === "string")
a = a.split(options.stringSeparator);
if (typeof o === "string")
o = o.split(options.stringSeparator);
if (typeof b === "string")
b = b.split(options.stringSeparator);
let results = [];
const regions = diff3MergeRegions(a, o, b);
let okBuffer = [];
function flushOk() {
if (okBuffer.length) {
results.push({ ok: okBuffer });
}
okBuffer = [];
}
function isFalseConflict(a2, b2) {
if (a2.length !== b2.length)
return false;
for (let i = 0;i < a2.length; i++) {
if (a2[i] !== b2[i])
return false;
}
return true;
}
regions.forEach((region) => {
if (region.stable) {
okBuffer.push(...region.bufferContent);
} else {
if (options.excludeFalseConflicts && isFalseConflict(region.aContent, region.bContent)) {
okBuffer.push(...region.aContent);
} else {
flushOk();
results.push({
conflict: {
a: region.aContent,
aIndex: region.aStart,
o: region.oContent,
oIndex: region.oStart,
b: region.bContent,
bIndex: region.bStart
}
});
}
}
});
flushOk();
return results;
}
function mergeDiff3(a, o, b, options) {
const defaults = {
excludeFalseConflicts: true,
stringSeparator: /\s+/,
label: {}
};
options = Object.assign(defaults, options);
const aSection = "<<<<<<<" + (options.label.a ? ` ${options.label.a}` : "");
const oSection = "|||||||" + (options.label.o ? ` ${options.label.o}` : "");
const xSection = "=======";
const bSection = ">>>>>>>" + (options.label.b ? ` ${options.label.b}` : "");
const regions = diff3Merge(a, o, b, options);
let conflict = false;
let result = [];
regions.forEach((region) => {
if (region.ok) {
result = result.concat(region.ok);
} else if (region.conflict) {
conflict = true;
result = result.concat([aSection], region.conflict.a, [oSection], region.conflict.o, [xSection], region.conflict.b, [bSection]);
}
});
return {
conflict,
result
};
}
function merge(a, o, b, options) {
const defaults = {
excludeFalseConflicts: true,
stringSeparator: /\s+/,
label: {}
};
options = Object.assign(defaults, options);
const aSection = "<<<<<<<" + (options.label.a ? ` ${options.label.a}` : "");
const xSection = "=======";
const bSection = ">>>>>>>" + (options.label.b ? ` ${options.label.b}` : "");
const regions = diff3Merge(a, o, b, options);
let conflict = false;
let result = [];
regions.forEach((region) => {
if (region.ok) {
result = result.concat(region.ok);
} else if (region.conflict) {
conflict = true;
result = result.concat([aSection], region.conflict.a, [xSection], region.conflict.b, [bSection]);
}
});
return {
conflict,
result
};
}
function mergeDigIn(a, o, b, options) {
const defaults = {
excludeFalseConflicts: true,
stringSeparator: /\s+/,
label: {}
};
options = Object.assign(defaults, options);
const aSection = "<<<<<<<" + (options.label.a ? ` ${options.label.a}` : "");
const xSection = "=======";
const bSection = ">>>>>>>" + (options.label.b ? ` ${options.label.b}` : "");
const regions = diff3Merge(a, o, b, options);
let conflict = false;
let result = [];
regions.forEach((region) => {
if (region.ok) {
result = result.concat(region.ok);
} else {
const c = diffComm(region.conflict.a, region.conflict.b);
for (let j = 0;j < c.length; j++) {
let inner = c[j];
if (inner.common) {
result = result.concat(inner.common);
} else {
conflict = true;
result = result.concat([aSection], inner.buffer1, [xSection], inner.buffer2, [bSection]);
}
}
}
});
return {
conflict,
result
};
}
function patch(buffer, patch2) {
let result = [];
let currOffset = 0;
function advanceTo(targetOffset) {
while (currOffset < targetOffset) {
result.push(buffer[currOffset]);
currOffset++;
}
}
for (let chunkIndex = 0;chunkIndex < patch2.length; chunkIndex++) {
let chunk = patch2[chunkIndex];
advanceTo(chunk.buffer1.offset);
for (let itemIndex = 0;itemIndex < chunk.buffer2.chunk.length; itemIndex++) {
result.push(chunk.buffer2.chunk[itemIndex]);
}
currOffset += chunk.buffer1.length;
}
advanceTo(buffer.length);
return result;
}
function stripPatch(patch2) {
return patch2.map((chunk) => ({
buffer1: { offset: chunk.buffer1.offset, length: chunk.buffer1.length },
buffer2: { chunk: chunk.buffer2.chunk }
}));
}
function invertPatch(patch2) {
return patch2.map((chunk) => ({
buffer1: chunk.buffer2,
buffer2: chunk.buffer1
}));
}
export {
stripPatch,
patch,
mergeDigIn,
mergeDiff3,
merge,
invertPatch,
diffPatch,
diffIndices,
diffComm,
diff3MergeRegions,
diff3Merge,
LCS
};
//# debugId=1E2500EFBA7ACEE264756E2164756E21
//# sourceMappingURL=diff3.mjs.map
{
"version": 3,
"sources": ["../src/diff3.mjs"],
"sourcesContent": [
"export {\n LCS,\n diffComm,\n diffIndices,\n diffPatch,\n diff3MergeRegions,\n diff3Merge,\n mergeDiff3,\n merge,\n mergeDigIn,\n patch,\n stripPatch,\n invertPatch\n};\n\n\n// Text diff algorithm following Hunt and McIlroy 1976.\n// J. W. Hunt and M. D. McIlroy, An algorithm for differential buffer\n// comparison, Bell Telephone Laboratories CSTR #41 (1976)\n// http://www.cs.dartmouth.edu/~doug/\n// https://en.wikipedia.org/wiki/Longest_common_subsequence_problem\n//\n// Expects two arrays, finds longest common sequence\nfunction LCS(buffer1, buffer2) {\n let equivalenceClasses = {};\n for (let j = 0; j < buffer2.length; j++) {\n const item = buffer2[j];\n if (equivalenceClasses[item]) {\n equivalenceClasses[item].push(j);\n } else {\n equivalenceClasses[item] = [j];\n }\n }\n\n const NULLRESULT = { buffer1index: -1, buffer2index: -1, chain: null };\n let candidates = [NULLRESULT];\n\n for (let i = 0; i < buffer1.length; i++) {\n const item = buffer1[i];\n const buffer2indices = equivalenceClasses[item] || [];\n let r = 0;\n let c = candidates[0];\n\n for (let jx = 0; jx < buffer2indices.length; jx++) {\n const j = buffer2indices[jx];\n\n let s;\n for (s = r; s < candidates.length; s++) {\n if ((candidates[s].buffer2index < j) && ((s === candidates.length - 1) || (candidates[s + 1].buffer2index > j))) {\n break;\n }\n }\n\n if (s < candidates.length) {\n const newCandidate = { buffer1index: i, buffer2index: j, chain: candidates[s] };\n if (r === candidates.length) {\n candidates.push(c);\n } else {\n candidates[r] = c;\n }\n r = s + 1;\n c = newCandidate;\n if (r === candidates.length) {\n break; // no point in examining further (j)s\n }\n }\n }\n\n candidates[r] = c;\n }\n\n // At this point, we know the LCS: it's in the reverse of the\n // linked-list through .chain of candidates[candidates.length - 1].\n\n return candidates[candidates.length - 1];\n}\n\n\n// We apply the LCS to build a 'comm'-style picture of the\n// differences between buffer1 and buffer2.\nfunction diffComm(buffer1, buffer2) {\n const lcs = LCS(buffer1, buffer2);\n let result = [];\n let tail1 = buffer1.length;\n let tail2 = buffer2.length;\n let common = {common: []};\n\n function processCommon() {\n if (common.common.length) {\n common.common.reverse();\n result.push(common);\n common = {common: []};\n }\n }\n\n for (let candidate = lcs; candidate !== null; candidate = candidate.chain) {\n let different = {buffer1: [], buffer2: []};\n\n while (--tail1 > candidate.buffer1index) {\n different.buffer1.push(buffer1[tail1]);\n }\n\n while (--tail2 > candidate.buffer2index) {\n different.buffer2.push(buffer2[tail2]);\n }\n\n if (different.buffer1.length || different.buffer2.length) {\n processCommon();\n different.buffer1.reverse();\n different.buffer2.reverse();\n result.push(different);\n }\n\n if (tail1 >= 0) {\n common.common.push(buffer1[tail1]);\n }\n }\n\n processCommon();\n\n result.reverse();\n return result;\n}\n\n\n// We apply the LCS to give a simple representation of the\n// offsets and lengths of mismatched chunks in the input\n// buffers. This is used by diff3MergeRegions.\nfunction diffIndices(buffer1, buffer2) {\n const lcs = LCS(buffer1, buffer2);\n let result = [];\n let tail1 = buffer1.length;\n let tail2 = buffer2.length;\n\n for (let candidate = lcs; candidate !== null; candidate = candidate.chain) {\n const mismatchLength1 = tail1 - candidate.buffer1index - 1;\n const mismatchLength2 = tail2 - candidate.buffer2index - 1;\n tail1 = candidate.buffer1index;\n tail2 = candidate.buffer2index;\n\n if (mismatchLength1 || mismatchLength2) {\n result.push({\n buffer1: [tail1 + 1, mismatchLength1],\n buffer1Content: buffer1.slice(tail1 + 1, tail1 + 1 + mismatchLength1),\n buffer2: [tail2 + 1, mismatchLength2],\n buffer2Content: buffer2.slice(tail2 + 1, tail2 + 1 + mismatchLength2)\n });\n }\n }\n\n result.reverse();\n return result;\n}\n\n\n// We apply the LCS to build a JSON representation of a\n// diff(1)-style patch.\nfunction diffPatch(buffer1, buffer2) {\n const lcs = LCS(buffer1, buffer2);\n let result = [];\n let tail1 = buffer1.length;\n let tail2 = buffer2.length;\n\n function chunkDescription(buffer, offset, length) {\n let chunk = [];\n for (let i = 0; i < length; i++) {\n chunk.push(buffer[offset + i]);\n }\n return {\n offset: offset,\n length: length,\n chunk: chunk\n };\n }\n\n for (let candidate = lcs; candidate !== null; candidate = candidate.chain) {\n const mismatchLength1 = tail1 - candidate.buffer1index - 1;\n const mismatchLength2 = tail2 - candidate.buffer2index - 1;\n tail1 = candidate.buffer1index;\n tail2 = candidate.buffer2index;\n\n if (mismatchLength1 || mismatchLength2) {\n result.push({\n buffer1: chunkDescription(buffer1, candidate.buffer1index + 1, mismatchLength1),\n buffer2: chunkDescription(buffer2, candidate.buffer2index + 1, mismatchLength2)\n });\n }\n }\n\n result.reverse();\n return result;\n}\n\n\n// Given three buffers, A, O, and B, where both A and B are\n// independently derived from O, returns a fairly complicated\n// internal representation of merge decisions it's taken. The\n// interested reader may wish to consult\n//\n// Sanjeev Khanna, Keshav Kunal, and Benjamin C. Pierce.\n// 'A Formal Investigation of ' In Arvind and Prasad,\n// editors, Foundations of Software Technology and Theoretical\n// Computer Science (FSTTCS), December 2007.\n//\n// (http://www.cis.upenn.edu/~bcpierce/papers/diff3-short.pdf)\n//\nfunction diff3MergeRegions(a, o, b) {\n\n // \"hunks\" are array subsets where `a` or `b` are different from `o`\n // https://www.gnu.org/software/diffutils/manual/html_node/diff3-Hunks.html\n let hunks = [];\n function addHunk(h, ab) {\n hunks.push({\n ab: ab,\n oStart: h.buffer1[0],\n oLength: h.buffer1[1], // length of o to remove\n abStart: h.buffer2[0],\n abLength: h.buffer2[1] // length of a/b to insert\n // abContent: (ab === 'a' ? a : b).slice(h.buffer2[0], h.buffer2[0] + h.buffer2[1])\n });\n }\n\n diffIndices(o, a).forEach(item => addHunk(item, 'a'));\n diffIndices(o, b).forEach(item => addHunk(item, 'b'));\n hunks.sort((x,y) => x.oStart - y.oStart);\n\n let results = [];\n let currOffset = 0;\n\n function advanceTo(endOffset) {\n if (endOffset > currOffset) {\n results.push({\n stable: true,\n buffer: 'o',\n bufferStart: currOffset,\n bufferLength: endOffset - currOffset,\n bufferContent: o.slice(currOffset, endOffset)\n });\n currOffset = endOffset;\n }\n }\n\n while (hunks.length) {\n let hunk = hunks.shift();\n let regionStart = hunk.oStart;\n let regionEnd = hunk.oStart + hunk.oLength;\n let regionHunks = [hunk];\n advanceTo(regionStart);\n\n // Try to pull next overlapping hunk into this region\n while (hunks.length) {\n const nextHunk = hunks[0];\n const nextHunkStart = nextHunk.oStart;\n if (nextHunkStart > regionEnd) break; // no overlap\n\n regionEnd = Math.max(regionEnd, nextHunkStart + nextHunk.oLength);\n regionHunks.push(hunks.shift());\n }\n\n if (regionHunks.length === 1) {\n // Only one hunk touches this region, meaning that there is no conflict here.\n // Either `a` or `b` is inserting into a region of `o` unchanged by the other.\n if (hunk.abLength > 0) {\n const buffer = (hunk.ab === 'a' ? a : b);\n results.push({\n stable: true,\n buffer: hunk.ab,\n bufferStart: hunk.abStart,\n bufferLength: hunk.abLength,\n bufferContent: buffer.slice(hunk.abStart, hunk.abStart + hunk.abLength)\n });\n }\n } else {\n // A true a/b conflict. Determine the bounds involved from `a`, `o`, and `b`.\n // Effectively merge all the `a` hunks into one giant hunk, then do the\n // same for the `b` hunks; then, correct for skew in the regions of `o`\n // that each side changed, and report appropriate spans for the three sides.\n let bounds = {\n a: [a.length, -1, o.length, -1],\n b: [b.length, -1, o.length, -1]\n };\n while (regionHunks.length) {\n hunk = regionHunks.shift();\n const oStart = hunk.oStart;\n const oEnd = oStart + hunk.oLength;\n const abStart = hunk.abStart;\n const abEnd = abStart + hunk.abLength;\n let b = bounds[hunk.ab];\n b[0] = Math.min(abStart, b[0]);\n b[1] = Math.max(abEnd, b[1]);\n b[2] = Math.min(oStart, b[2]);\n b[3] = Math.max(oEnd, b[3]);\n }\n\n const aStart = bounds.a[0] + (regionStart - bounds.a[2]);\n const aEnd = bounds.a[1] + (regionEnd - bounds.a[3]);\n const bStart = bounds.b[0] + (regionStart - bounds.b[2]);\n const bEnd = bounds.b[1] + (regionEnd - bounds.b[3]);\n\n let result = {\n stable: false,\n aStart: aStart,\n aLength: aEnd - aStart,\n aContent: a.slice(aStart, aEnd),\n oStart: regionStart,\n oLength: regionEnd - regionStart,\n oContent: o.slice(regionStart, regionEnd),\n bStart: bStart,\n bLength: bEnd - bStart,\n bContent: b.slice(bStart, bEnd)\n };\n results.push(result);\n }\n currOffset = regionEnd;\n }\n\n advanceTo(o.length);\n\n return results;\n}\n\n\n// Applies the output of diff3MergeRegions to actually\n// construct the merged buffer; the returned result alternates\n// between 'ok' and 'conflict' blocks.\n// A \"false conflict\" is where `a` and `b` both change the same from `o`\nfunction diff3Merge(a, o, b, options) {\n let defaults = {\n excludeFalseConflicts: true,\n stringSeparator: /\\s+/\n };\n options = Object.assign(defaults, options);\n\n if (typeof a === 'string') a = a.split(options.stringSeparator);\n if (typeof o === 'string') o = o.split(options.stringSeparator);\n if (typeof b === 'string') b = b.split(options.stringSeparator);\n\n let results = [];\n const regions = diff3MergeRegions(a, o, b);\n\n let okBuffer = [];\n function flushOk() {\n if (okBuffer.length) {\n results.push({ ok: okBuffer });\n }\n okBuffer = [];\n }\n\n function isFalseConflict(a, b) {\n if (a.length !== b.length) return false;\n for (let i = 0; i < a.length; i++) {\n if (a[i] !== b[i]) return false;\n }\n return true;\n }\n\n regions.forEach(region => {\n if (region.stable) {\n okBuffer.push(...region.bufferContent);\n } else {\n if (options.excludeFalseConflicts && isFalseConflict(region.aContent, region.bContent)) {\n okBuffer.push(...region.aContent);\n } else {\n flushOk();\n results.push({\n conflict: {\n a: region.aContent,\n aIndex: region.aStart,\n o: region.oContent,\n oIndex: region.oStart,\n b: region.bContent,\n bIndex: region.bStart\n }\n });\n }\n }\n });\n\n flushOk();\n return results;\n}\n\n\nfunction mergeDiff3(a, o, b, options) {\n const defaults = {\n excludeFalseConflicts: true,\n stringSeparator: /\\s+/,\n label: {}\n };\n options = Object.assign(defaults, options);\n\n const aSection = '<<<<<<<' + (options.label.a ? ` ${options.label.a}` : '');\n const oSection = '|||||||' + (options.label.o ? ` ${options.label.o}` : '');\n const xSection = '=======';\n const bSection = '>>>>>>>' + (options.label.b ? ` ${options.label.b}` : '');\n\n const regions = diff3Merge(a, o, b, options);\n let conflict = false;\n let result = [];\n\n regions.forEach(region => {\n if (region.ok) {\n result = result.concat(region.ok);\n } else if (region.conflict) {\n conflict = true;\n result = result.concat(\n [aSection],\n region.conflict.a,\n [oSection],\n region.conflict.o,\n [xSection],\n region.conflict.b,\n [bSection]\n );\n }\n });\n\n return {\n conflict: conflict,\n result: result\n };\n}\n\n\nfunction merge(a, o, b, options) {\n const defaults = {\n excludeFalseConflicts: true,\n stringSeparator: /\\s+/,\n label: {}\n };\n options = Object.assign(defaults, options);\n\n const aSection = '<<<<<<<' + (options.label.a ? ` ${options.label.a}` : '');\n const xSection = '=======';\n const bSection = '>>>>>>>' + (options.label.b ? ` ${options.label.b}` : '');\n\n const regions = diff3Merge(a, o, b, options);\n let conflict = false;\n let result = [];\n\n regions.forEach(region => {\n if (region.ok) {\n result = result.concat(region.ok);\n } else if (region.conflict) {\n conflict = true;\n result = result.concat(\n [aSection],\n region.conflict.a,\n [xSection],\n region.conflict.b,\n [bSection]\n );\n }\n });\n\n return {\n conflict: conflict,\n result: result\n };\n}\n\n\nfunction mergeDigIn(a, o, b, options) {\n const defaults = {\n excludeFalseConflicts: true,\n stringSeparator: /\\s+/,\n label: {}\n };\n options = Object.assign(defaults, options);\n\n const aSection = '<<<<<<<' + (options.label.a ? ` ${options.label.a}` : '');\n const xSection = '=======';\n const bSection = '>>>>>>>' + (options.label.b ? ` ${options.label.b}` : '');\n\n const regions = diff3Merge(a, o, b, options);\n let conflict = false;\n let result = [];\n\n regions.forEach(region => {\n if (region.ok) {\n result = result.concat(region.ok);\n } else {\n const c = diffComm(region.conflict.a, region.conflict.b);\n for (let j = 0; j < c.length; j++) {\n let inner = c[j];\n if (inner.common) {\n result = result.concat(inner.common);\n } else {\n conflict = true;\n result = result.concat(\n [aSection],\n inner.buffer1,\n [xSection],\n inner.buffer2,\n [bSection]\n );\n }\n }\n }\n });\n\n return {\n conflict: conflict,\n result: result\n };\n}\n\n\n// Applies a patch to a buffer.\n// Given buffer1 and buffer2, `patch(buffer1, diffPatch(buffer1, buffer2))` should give buffer2.\nfunction patch(buffer, patch) {\n let result = [];\n let currOffset = 0;\n\n function advanceTo(targetOffset) {\n while (currOffset < targetOffset) {\n result.push(buffer[currOffset]);\n currOffset++;\n }\n }\n\n for (let chunkIndex = 0; chunkIndex < patch.length; chunkIndex++) {\n let chunk = patch[chunkIndex];\n advanceTo(chunk.buffer1.offset);\n for (let itemIndex = 0; itemIndex < chunk.buffer2.chunk.length; itemIndex++) {\n result.push(chunk.buffer2.chunk[itemIndex]);\n }\n currOffset += chunk.buffer1.length;\n }\n\n advanceTo(buffer.length);\n return result;\n}\n\n\n// Takes the output of diffPatch(), and removes extra information from it.\n// It can still be used by patch(), below, but can no longer be inverted.\nfunction stripPatch(patch) {\n return patch.map(chunk => ({\n buffer1: { offset: chunk.buffer1.offset, length: chunk.buffer1.length },\n buffer2: { chunk: chunk.buffer2.chunk }\n }));\n}\n\n\n// Takes the output of diffPatch(), and inverts the sense of it, so that it\n// can be applied to buffer2 to give buffer1 rather than the other way around.\nfunction invertPatch(patch) {\n return patch.map(chunk => ({\n buffer1: chunk.buffer2,\n buffer2: chunk.buffer1\n }));\n}\n"
],
"mappings": "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",
"debugId": "1E2500EFBA7ACEE264756E2164756E21",
"names": []
}
export interface ILCSResult {
buffer1index: number;
buffer2index: number;
chain: null | ILCSResult;
}
/**
* Expects two arrays, finds longest common sequence
* @param {T[]} buffer1
* @param {T[]} buffer2
* @returns {ILCSResult}
* @constructor
*/
export function LCS<T>(buffer1: T[], buffer2: T[]): ILCSResult;
export interface ICommResult<T> {
buffer1: T[];
buffer2: T[];
}
/**
* We apply the LCS to build a 'comm'-style picture of the
* differences between buffer1 and buffer2.
* @param {T[]} buffer1
* @param {T[]} buffer2
* @returns {Array<ICommResult<T>>}
*/
export function diffComm<T>(buffer1: T[], buffer2: T[]): ICommResult<T>[];
export interface IDiffIndicesResult<T> {
buffer1: [number, number];
buffer1Content: T[];
buffer2: [number, number];
buffer2Content: T[];
}
/**
* We apply the LCS to give a simple representation of the
* offsets and lengths of mismatched chunks in the input
* buffers. This is used by diff3MergeRegions.
* @param {T[]} buffer1
* @param {T[]} buffer2
* @returns {IDiffIndicesResult<T>[]}
*/
export function diffIndices<T>(
buffer1: T[],
buffer2: T[]
): IDiffIndicesResult<T>[];
export interface IChunk<T> {
offset: number;
length: number;
chunk: T[];
}
export interface IPatchRes<T> {
buffer1: IChunk<T>;
buffer2: IChunk<T>;
}
/**
* We apply the LCS to build a JSON representation of a
* diff(1)-style patch.
* @param {T[]} buffer1
* @param {T[]} buffer2
* @returns {IPatchRes<T>[]}
*/
export function diffPatch<T>(buffer1: T[], buffer2: T[]): IPatchRes<T>[];
export function patch<T>(buffer: T[], patch: IPatchRes<T>[]): T[];
export interface IStableRegion<T> {
stable: true;
buffer: 'a' | 'o' | 'b';
bufferStart: number;
bufferLength: number;
bufferContent: T[];
}
export interface IUnstableRegion<T> {
stable: false;
aStart: number;
aLength: number;
aContent: T[];
bStart: number;
bLength: number;
bContent: T[];
oStart: number;
oLength: number;
oContent: T[];
}
export type IRegion<T> = IStableRegion<T> | IUnstableRegion<T>;
/**
* Given three buffers, A, O, and B, where both A and B are
* independently derived from O, returns a fairly complicated
* internal representation of merge decisions it's taken. The
* interested reader may wish to consult
*
* Sanjeev Khanna, Keshav Kunal, and Benjamin C. Pierce.
* 'A Formal Investigation of ' In Arvind and Prasad,
* editors, Foundations of Software Technology and Theoretical
* Computer Science (FSTTCS), December 2007.
*
* (http://www.cis.upenn.edu/~bcpierce/papers/diff3-short.pdf)
*
* @param {T[]} a
* @param {T[]} o
* @param {T[]} b
* @returns {IRegion<T>[]}
*/
export function diff3MergeRegions<T>(a: T[], o: T[], b: T[]): IRegion<T>[];
export interface MergeRegion<T> {
ok?: T[];
conflict?: {
a: T[];
aIndex: number;
b: T[];
bIndex: number;
o: T[];
oIndex: number;
};
}
export interface MergeResult {
conflict: boolean;
result: string[];
}
export interface IMergeOptions {
excludeFalseConflicts?: boolean;
stringSeparator?: string | RegExp;
}
/**
* Applies the output of diff3MergeRegions to actually
* construct the merged buffer; the returned result alternates
* between 'ok' and 'conflict' blocks.
* A "false conflict" is where `a` and `b` both change the same from `o`
*
* @param {string | T[]} a
* @param {string | T[]} o
* @param {string | T[]} b
* @param {{excludeFalseConflicts: boolean; stringSeparator: RegExp}} options
* @returns {MergeRegion<T>[]}
*/
export function diff3Merge<T>(
a: string | T[],
o: string | T[],
b: string | T[],
options?: IMergeOptions
): MergeRegion<T>[];
export function merge<T>(
a: string | T[],
o: string | T[],
b: string | T[],
options?: IMergeOptions
): MergeResult;
export function mergeDiff3<T>(
a: string | T[],
o: string | T[],
b: string | T[],
options?: IMergeOptions & {
label?: {
a?: string;
o?: string;
b?: string;
}
}
): MergeResult;
export function mergeDigIn<T>(
a: string | T[],
o: string | T[],
b: string | T[],
options?: IMergeOptions
): MergeResult;
export {
LCS,
diffComm,
diffIndices,
diffPatch,
diff3MergeRegions,
diff3Merge,
mergeDiff3,
merge,
mergeDigIn,
patch,
stripPatch,
invertPatch
};
// Text diff algorithm following Hunt and McIlroy 1976.
// J. W. Hunt and M. D. McIlroy, An algorithm for differential buffer
// comparison, Bell Telephone Laboratories CSTR #41 (1976)
// http://www.cs.dartmouth.edu/~doug/
// https://en.wikipedia.org/wiki/Longest_common_subsequence_problem
//
// Expects two arrays, finds longest common sequence
function LCS(buffer1, buffer2) {
let equivalenceClasses = {};
for (let j = 0; j < buffer2.length; j++) {
const item = buffer2[j];
if (equivalenceClasses[item]) {
equivalenceClasses[item].push(j);
} else {
equivalenceClasses[item] = [j];
}
}
const NULLRESULT = { buffer1index: -1, buffer2index: -1, chain: null };
let candidates = [NULLRESULT];
for (let i = 0; i < buffer1.length; i++) {
const item = buffer1[i];
const buffer2indices = equivalenceClasses[item] || [];
let r = 0;
let c = candidates[0];
for (let jx = 0; jx < buffer2indices.length; jx++) {
const j = buffer2indices[jx];
let s;
for (s = r; s < candidates.length; s++) {
if ((candidates[s].buffer2index < j) && ((s === candidates.length - 1) || (candidates[s + 1].buffer2index > j))) {
break;
}
}
if (s < candidates.length) {
const newCandidate = { buffer1index: i, buffer2index: j, chain: candidates[s] };
if (r === candidates.length) {
candidates.push(c);
} else {
candidates[r] = c;
}
r = s + 1;
c = newCandidate;
if (r === candidates.length) {
break; // no point in examining further (j)s
}
}
}
candidates[r] = c;
}
// At this point, we know the LCS: it's in the reverse of the
// linked-list through .chain of candidates[candidates.length - 1].
return candidates[candidates.length - 1];
}
// We apply the LCS to build a 'comm'-style picture of the
// differences between buffer1 and buffer2.
function diffComm(buffer1, buffer2) {
const lcs = LCS(buffer1, buffer2);
let result = [];
let tail1 = buffer1.length;
let tail2 = buffer2.length;
let common = {common: []};
function processCommon() {
if (common.common.length) {
common.common.reverse();
result.push(common);
common = {common: []};
}
}
for (let candidate = lcs; candidate !== null; candidate = candidate.chain) {
let different = {buffer1: [], buffer2: []};
while (--tail1 > candidate.buffer1index) {
different.buffer1.push(buffer1[tail1]);
}
while (--tail2 > candidate.buffer2index) {
different.buffer2.push(buffer2[tail2]);
}
if (different.buffer1.length || different.buffer2.length) {
processCommon();
different.buffer1.reverse();
different.buffer2.reverse();
result.push(different);
}
if (tail1 >= 0) {
common.common.push(buffer1[tail1]);
}
}
processCommon();
result.reverse();
return result;
}
// We apply the LCS to give a simple representation of the
// offsets and lengths of mismatched chunks in the input
// buffers. This is used by diff3MergeRegions.
function diffIndices(buffer1, buffer2) {
const lcs = LCS(buffer1, buffer2);
let result = [];
let tail1 = buffer1.length;
let tail2 = buffer2.length;
for (let candidate = lcs; candidate !== null; candidate = candidate.chain) {
const mismatchLength1 = tail1 - candidate.buffer1index - 1;
const mismatchLength2 = tail2 - candidate.buffer2index - 1;
tail1 = candidate.buffer1index;
tail2 = candidate.buffer2index;
if (mismatchLength1 || mismatchLength2) {
result.push({
buffer1: [tail1 + 1, mismatchLength1],
buffer1Content: buffer1.slice(tail1 + 1, tail1 + 1 + mismatchLength1),
buffer2: [tail2 + 1, mismatchLength2],
buffer2Content: buffer2.slice(tail2 + 1, tail2 + 1 + mismatchLength2)
});
}
}
result.reverse();
return result;
}
// We apply the LCS to build a JSON representation of a
// diff(1)-style patch.
function diffPatch(buffer1, buffer2) {
const lcs = LCS(buffer1, buffer2);
let result = [];
let tail1 = buffer1.length;
let tail2 = buffer2.length;
function chunkDescription(buffer, offset, length) {
let chunk = [];
for (let i = 0; i < length; i++) {
chunk.push(buffer[offset + i]);
}
return {
offset: offset,
length: length,
chunk: chunk
};
}
for (let candidate = lcs; candidate !== null; candidate = candidate.chain) {
const mismatchLength1 = tail1 - candidate.buffer1index - 1;
const mismatchLength2 = tail2 - candidate.buffer2index - 1;
tail1 = candidate.buffer1index;
tail2 = candidate.buffer2index;
if (mismatchLength1 || mismatchLength2) {
result.push({
buffer1: chunkDescription(buffer1, candidate.buffer1index + 1, mismatchLength1),
buffer2: chunkDescription(buffer2, candidate.buffer2index + 1, mismatchLength2)
});
}
}
result.reverse();
return result;
}
// Given three buffers, A, O, and B, where both A and B are
// independently derived from O, returns a fairly complicated
// internal representation of merge decisions it's taken. The
// interested reader may wish to consult
//
// Sanjeev Khanna, Keshav Kunal, and Benjamin C. Pierce.
// 'A Formal Investigation of ' In Arvind and Prasad,
// editors, Foundations of Software Technology and Theoretical
// Computer Science (FSTTCS), December 2007.
//
// (http://www.cis.upenn.edu/~bcpierce/papers/diff3-short.pdf)
//
function diff3MergeRegions(a, o, b) {
// "hunks" are array subsets where `a` or `b` are different from `o`
// https://www.gnu.org/software/diffutils/manual/html_node/diff3-Hunks.html
let hunks = [];
function addHunk(h, ab) {
hunks.push({
ab: ab,
oStart: h.buffer1[0],
oLength: h.buffer1[1], // length of o to remove
abStart: h.buffer2[0],
abLength: h.buffer2[1] // length of a/b to insert
// abContent: (ab === 'a' ? a : b).slice(h.buffer2[0], h.buffer2[0] + h.buffer2[1])
});
}
diffIndices(o, a).forEach(item => addHunk(item, 'a'));
diffIndices(o, b).forEach(item => addHunk(item, 'b'));
hunks.sort((x,y) => x.oStart - y.oStart);
let results = [];
let currOffset = 0;
function advanceTo(endOffset) {
if (endOffset > currOffset) {
results.push({
stable: true,
buffer: 'o',
bufferStart: currOffset,
bufferLength: endOffset - currOffset,
bufferContent: o.slice(currOffset, endOffset)
});
currOffset = endOffset;
}
}
while (hunks.length) {
let hunk = hunks.shift();
let regionStart = hunk.oStart;
let regionEnd = hunk.oStart + hunk.oLength;
let regionHunks = [hunk];
advanceTo(regionStart);
// Try to pull next overlapping hunk into this region
while (hunks.length) {
const nextHunk = hunks[0];
const nextHunkStart = nextHunk.oStart;
if (nextHunkStart > regionEnd) break; // no overlap
regionEnd = Math.max(regionEnd, nextHunkStart + nextHunk.oLength);
regionHunks.push(hunks.shift());
}
if (regionHunks.length === 1) {
// Only one hunk touches this region, meaning that there is no conflict here.
// Either `a` or `b` is inserting into a region of `o` unchanged by the other.
if (hunk.abLength > 0) {
const buffer = (hunk.ab === 'a' ? a : b);
results.push({
stable: true,
buffer: hunk.ab,
bufferStart: hunk.abStart,
bufferLength: hunk.abLength,
bufferContent: buffer.slice(hunk.abStart, hunk.abStart + hunk.abLength)
});
}
} else {
// A true a/b conflict. Determine the bounds involved from `a`, `o`, and `b`.
// Effectively merge all the `a` hunks into one giant hunk, then do the
// same for the `b` hunks; then, correct for skew in the regions of `o`
// that each side changed, and report appropriate spans for the three sides.
let bounds = {
a: [a.length, -1, o.length, -1],
b: [b.length, -1, o.length, -1]
};
while (regionHunks.length) {
hunk = regionHunks.shift();
const oStart = hunk.oStart;
const oEnd = oStart + hunk.oLength;
const abStart = hunk.abStart;
const abEnd = abStart + hunk.abLength;
let b = bounds[hunk.ab];
b[0] = Math.min(abStart, b[0]);
b[1] = Math.max(abEnd, b[1]);
b[2] = Math.min(oStart, b[2]);
b[3] = Math.max(oEnd, b[3]);
}
const aStart = bounds.a[0] + (regionStart - bounds.a[2]);
const aEnd = bounds.a[1] + (regionEnd - bounds.a[3]);
const bStart = bounds.b[0] + (regionStart - bounds.b[2]);
const bEnd = bounds.b[1] + (regionEnd - bounds.b[3]);
let result = {
stable: false,
aStart: aStart,
aLength: aEnd - aStart,
aContent: a.slice(aStart, aEnd),
oStart: regionStart,
oLength: regionEnd - regionStart,
oContent: o.slice(regionStart, regionEnd),
bStart: bStart,
bLength: bEnd - bStart,
bContent: b.slice(bStart, bEnd)
};
results.push(result);
}
currOffset = regionEnd;
}
advanceTo(o.length);
return results;
}
// Applies the output of diff3MergeRegions to actually
// construct the merged buffer; the returned result alternates
// between 'ok' and 'conflict' blocks.
// A "false conflict" is where `a` and `b` both change the same from `o`
function diff3Merge(a, o, b, options) {
let defaults = {
excludeFalseConflicts: true,
stringSeparator: /\s+/
};
options = Object.assign(defaults, options);
if (typeof a === 'string') a = a.split(options.stringSeparator);
if (typeof o === 'string') o = o.split(options.stringSeparator);
if (typeof b === 'string') b = b.split(options.stringSeparator);
let results = [];
const regions = diff3MergeRegions(a, o, b);
let okBuffer = [];
function flushOk() {
if (okBuffer.length) {
results.push({ ok: okBuffer });
}
okBuffer = [];
}
function isFalseConflict(a, b) {
if (a.length !== b.length) return false;
for (let i = 0; i < a.length; i++) {
if (a[i] !== b[i]) return false;
}
return true;
}
regions.forEach(region => {
if (region.stable) {
okBuffer.push(...region.bufferContent);
} else {
if (options.excludeFalseConflicts && isFalseConflict(region.aContent, region.bContent)) {
okBuffer.push(...region.aContent);
} else {
flushOk();
results.push({
conflict: {
a: region.aContent,
aIndex: region.aStart,
o: region.oContent,
oIndex: region.oStart,
b: region.bContent,
bIndex: region.bStart
}
});
}
}
});
flushOk();
return results;
}
function mergeDiff3(a, o, b, options) {
const defaults = {
excludeFalseConflicts: true,
stringSeparator: /\s+/,
label: {}
};
options = Object.assign(defaults, options);
const aSection = '<<<<<<<' + (options.label.a ? ` ${options.label.a}` : '');
const oSection = '|||||||' + (options.label.o ? ` ${options.label.o}` : '');
const xSection = '=======';
const bSection = '>>>>>>>' + (options.label.b ? ` ${options.label.b}` : '');
const regions = diff3Merge(a, o, b, options);
let conflict = false;
let result = [];
regions.forEach(region => {
if (region.ok) {
result = result.concat(region.ok);
} else if (region.conflict) {
conflict = true;
result = result.concat(
[aSection],
region.conflict.a,
[oSection],
region.conflict.o,
[xSection],
region.conflict.b,
[bSection]
);
}
});
return {
conflict: conflict,
result: result
};
}
function merge(a, o, b, options) {
const defaults = {
excludeFalseConflicts: true,
stringSeparator: /\s+/,
label: {}
};
options = Object.assign(defaults, options);
const aSection = '<<<<<<<' + (options.label.a ? ` ${options.label.a}` : '');
const xSection = '=======';
const bSection = '>>>>>>>' + (options.label.b ? ` ${options.label.b}` : '');
const regions = diff3Merge(a, o, b, options);
let conflict = false;
let result = [];
regions.forEach(region => {
if (region.ok) {
result = result.concat(region.ok);
} else if (region.conflict) {
conflict = true;
result = result.concat(
[aSection],
region.conflict.a,
[xSection],
region.conflict.b,
[bSection]
);
}
});
return {
conflict: conflict,
result: result
};
}
function mergeDigIn(a, o, b, options) {
const defaults = {
excludeFalseConflicts: true,
stringSeparator: /\s+/,
label: {}
};
options = Object.assign(defaults, options);
const aSection = '<<<<<<<' + (options.label.a ? ` ${options.label.a}` : '');
const xSection = '=======';
const bSection = '>>>>>>>' + (options.label.b ? ` ${options.label.b}` : '');
const regions = diff3Merge(a, o, b, options);
let conflict = false;
let result = [];
regions.forEach(region => {
if (region.ok) {
result = result.concat(region.ok);
} else {
const c = diffComm(region.conflict.a, region.conflict.b);
for (let j = 0; j < c.length; j++) {
let inner = c[j];
if (inner.common) {
result = result.concat(inner.common);
} else {
conflict = true;
result = result.concat(
[aSection],
inner.buffer1,
[xSection],
inner.buffer2,
[bSection]
);
}
}
}
});
return {
conflict: conflict,
result: result
};
}
// Applies a patch to a buffer.
// Given buffer1 and buffer2, `patch(buffer1, diffPatch(buffer1, buffer2))` should give buffer2.
function patch(buffer, patch) {
let result = [];
let currOffset = 0;
function advanceTo(targetOffset) {
while (currOffset < targetOffset) {
result.push(buffer[currOffset]);
currOffset++;
}
}
for (let chunkIndex = 0; chunkIndex < patch.length; chunkIndex++) {
let chunk = patch[chunkIndex];
advanceTo(chunk.buffer1.offset);
for (let itemIndex = 0; itemIndex < chunk.buffer2.chunk.length; itemIndex++) {
result.push(chunk.buffer2.chunk[itemIndex]);
}
currOffset += chunk.buffer1.length;
}
advanceTo(buffer.length);
return result;
}
// Takes the output of diffPatch(), and removes extra information from it.
// It can still be used by patch(), below, but can no longer be inverted.
function stripPatch(patch) {
return patch.map(chunk => ({
buffer1: { offset: chunk.buffer1.offset, length: chunk.buffer1.length },
buffer2: { chunk: chunk.buffer2.chunk }
}));
}
// Takes the output of diffPatch(), and inverts the sense of it, so that it
// can be applied to buffer2 to give buffer1 rather than the other way around.
function invertPatch(patch) {
return patch.map(chunk => ({
buffer1: chunk.buffer2,
buffer2: chunk.buffer1
}));
}
import * as Diff3 from './diff3.mjs';
globalThis.Diff3 = Diff3;
+1
-1

@@ -11,3 +11,3 @@ ### The MIT License (MIT)

Copyright (c) 2006, 2008 LShift Ltd. &lt;query@lshift.net&gt;<br/>
Copyright (c) 2019 Bryan Housel &lt;bhousel@gmail.com&gt;<br/>
Copyright (c) 2019-2025 Bryan Housel &lt;bhousel@gmail.com&gt;<br/>

@@ -14,0 +14,0 @@ Permission is hereby granted, free of charge, to any person

{
"name": "node-diff3",
"version": "3.1.2",
"version": "3.2.0",
"license": "MIT",
"repository": "github:bhousel/node-diff3",
"description": "A node.js module for text diffing and three-way-merge.",
"description": "A JavaScript module for text diffing and three-way-merge.",
"contributors": [

@@ -17,41 +17,26 @@ "Bryan Housel <bhousel@gmail.com> (https://github.com/bhousel)"

"merge",
"nodejs",
"patch"
],
"files": [
"index.mjs",
"index.d.ts",
"dist/"
"dist/",
"src/"
],
"type": "module",
"source": "./index.mjs",
"types": "./index.d.ts",
"main": "./dist/index.cjs",
"module": "./index.mjs",
"exports": {
".": {
"import": {
"types": "./index.d.ts",
"default": "./index.mjs"
},
"require": "./dist/index.cjs"
}
"types": "./src/diff3.d.ts",
"import": "./dist/diff3.mjs",
"require": "./dist/diff3.cjs",
"browser": "./dist/diff3.iife.js"
},
"scripts": {
"all": "run-s clean test",
"clean": "shx rm -rf dist",
"build": "run-p build:**",
"build:browser": "esbuild ./index.mjs --platform=browser --format=iife --global-name=Diff3 --bundle --sourcemap --outfile=./dist/index.iife.js",
"build:cjs": "esbuild ./index.mjs --platform=node --format=cjs --sourcemap --outfile=./dist/index.cjs",
"lint": "eslint index.mjs test/*.js",
"tap": "c8 tap --reporter terse --no-cov test/*.js",
"test": "run-s build lint tap"
"all": "run-s clean lint build test",
"clean": "bun ./scripts/clean.ts",
"build": "bun ./scripts/build.ts",
"test": "bun test --dots --coverage ./test/*.js",
"lint": "eslint ./src/diff3.mjs ./test/*.js"
},
"devDependencies": {
"c8": "^7.11.3",
"esbuild": "^0.14.42",
"eslint": "^8.17.0",
"npm-run-all": "^4.1.5",
"shx": "^0.3.4",
"tap": "^16.2.0"
"@types/bun": "^1.3.0",
"eslint": "^9.38.0",
"npm-run-all2": "^8.0.4"
},

@@ -63,4 +48,5 @@ "sideEffects": false,

"engines": {
"node": ">14"
"bun": ">=1.3.0",
"node": ">=18"
}
}

@@ -42,3 +42,3 @@ [![build](https://github.com/bhousel/node-diff3/workflows/build/badge.svg)](https://github.com/bhousel/node-diff3/actions?query=workflow%3A%22build%22)

<head>
<script src="https://cdn.jsdelivr.net/npm/node-diff3@3.1/dist/index.iife.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/node-diff3@latest/dist/diff3.iife.min.js"></script>
</head>

@@ -58,2 +58,8 @@

## Contributing
See the [CONTRIBUTING.md](CONTRIBUTING.md) file for more info.
&nbsp;
## API Reference

@@ -60,0 +66,0 @@

var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
var node_diff3_exports = {};
__export(node_diff3_exports, {
LCS: () => LCS,
diff3Merge: () => diff3Merge,
diff3MergeRegions: () => diff3MergeRegions,
diffComm: () => diffComm,
diffIndices: () => diffIndices,
diffPatch: () => diffPatch,
invertPatch: () => invertPatch,
merge: () => merge,
mergeDiff3: () => mergeDiff3,
mergeDigIn: () => mergeDigIn,
patch: () => patch,
stripPatch: () => stripPatch
});
module.exports = __toCommonJS(node_diff3_exports);
function LCS(buffer1, buffer2) {
let equivalenceClasses = {};
for (let j = 0; j < buffer2.length; j++) {
const item = buffer2[j];
if (equivalenceClasses[item]) {
equivalenceClasses[item].push(j);
} else {
equivalenceClasses[item] = [j];
}
}
const NULLRESULT = { buffer1index: -1, buffer2index: -1, chain: null };
let candidates = [NULLRESULT];
for (let i = 0; i < buffer1.length; i++) {
const item = buffer1[i];
const buffer2indices = equivalenceClasses[item] || [];
let r = 0;
let c = candidates[0];
for (let jx = 0; jx < buffer2indices.length; jx++) {
const j = buffer2indices[jx];
let s;
for (s = r; s < candidates.length; s++) {
if (candidates[s].buffer2index < j && (s === candidates.length - 1 || candidates[s + 1].buffer2index > j)) {
break;
}
}
if (s < candidates.length) {
const newCandidate = { buffer1index: i, buffer2index: j, chain: candidates[s] };
if (r === candidates.length) {
candidates.push(c);
} else {
candidates[r] = c;
}
r = s + 1;
c = newCandidate;
if (r === candidates.length) {
break;
}
}
}
candidates[r] = c;
}
return candidates[candidates.length - 1];
}
function diffComm(buffer1, buffer2) {
const lcs = LCS(buffer1, buffer2);
let result = [];
let tail1 = buffer1.length;
let tail2 = buffer2.length;
let common = { common: [] };
function processCommon() {
if (common.common.length) {
common.common.reverse();
result.push(common);
common = { common: [] };
}
}
for (let candidate = lcs; candidate !== null; candidate = candidate.chain) {
let different = { buffer1: [], buffer2: [] };
while (--tail1 > candidate.buffer1index) {
different.buffer1.push(buffer1[tail1]);
}
while (--tail2 > candidate.buffer2index) {
different.buffer2.push(buffer2[tail2]);
}
if (different.buffer1.length || different.buffer2.length) {
processCommon();
different.buffer1.reverse();
different.buffer2.reverse();
result.push(different);
}
if (tail1 >= 0) {
common.common.push(buffer1[tail1]);
}
}
processCommon();
result.reverse();
return result;
}
function diffIndices(buffer1, buffer2) {
const lcs = LCS(buffer1, buffer2);
let result = [];
let tail1 = buffer1.length;
let tail2 = buffer2.length;
for (let candidate = lcs; candidate !== null; candidate = candidate.chain) {
const mismatchLength1 = tail1 - candidate.buffer1index - 1;
const mismatchLength2 = tail2 - candidate.buffer2index - 1;
tail1 = candidate.buffer1index;
tail2 = candidate.buffer2index;
if (mismatchLength1 || mismatchLength2) {
result.push({
buffer1: [tail1 + 1, mismatchLength1],
buffer1Content: buffer1.slice(tail1 + 1, tail1 + 1 + mismatchLength1),
buffer2: [tail2 + 1, mismatchLength2],
buffer2Content: buffer2.slice(tail2 + 1, tail2 + 1 + mismatchLength2)
});
}
}
result.reverse();
return result;
}
function diffPatch(buffer1, buffer2) {
const lcs = LCS(buffer1, buffer2);
let result = [];
let tail1 = buffer1.length;
let tail2 = buffer2.length;
function chunkDescription(buffer, offset, length) {
let chunk = [];
for (let i = 0; i < length; i++) {
chunk.push(buffer[offset + i]);
}
return {
offset,
length,
chunk
};
}
for (let candidate = lcs; candidate !== null; candidate = candidate.chain) {
const mismatchLength1 = tail1 - candidate.buffer1index - 1;
const mismatchLength2 = tail2 - candidate.buffer2index - 1;
tail1 = candidate.buffer1index;
tail2 = candidate.buffer2index;
if (mismatchLength1 || mismatchLength2) {
result.push({
buffer1: chunkDescription(buffer1, candidate.buffer1index + 1, mismatchLength1),
buffer2: chunkDescription(buffer2, candidate.buffer2index + 1, mismatchLength2)
});
}
}
result.reverse();
return result;
}
function diff3MergeRegions(a, o, b) {
let hunks = [];
function addHunk(h, ab) {
hunks.push({
ab,
oStart: h.buffer1[0],
oLength: h.buffer1[1],
abStart: h.buffer2[0],
abLength: h.buffer2[1]
});
}
diffIndices(o, a).forEach((item) => addHunk(item, "a"));
diffIndices(o, b).forEach((item) => addHunk(item, "b"));
hunks.sort((x, y) => x.oStart - y.oStart);
let results = [];
let currOffset = 0;
function advanceTo(endOffset) {
if (endOffset > currOffset) {
results.push({
stable: true,
buffer: "o",
bufferStart: currOffset,
bufferLength: endOffset - currOffset,
bufferContent: o.slice(currOffset, endOffset)
});
currOffset = endOffset;
}
}
while (hunks.length) {
let hunk = hunks.shift();
let regionStart = hunk.oStart;
let regionEnd = hunk.oStart + hunk.oLength;
let regionHunks = [hunk];
advanceTo(regionStart);
while (hunks.length) {
const nextHunk = hunks[0];
const nextHunkStart = nextHunk.oStart;
if (nextHunkStart > regionEnd)
break;
regionEnd = Math.max(regionEnd, nextHunkStart + nextHunk.oLength);
regionHunks.push(hunks.shift());
}
if (regionHunks.length === 1) {
if (hunk.abLength > 0) {
const buffer = hunk.ab === "a" ? a : b;
results.push({
stable: true,
buffer: hunk.ab,
bufferStart: hunk.abStart,
bufferLength: hunk.abLength,
bufferContent: buffer.slice(hunk.abStart, hunk.abStart + hunk.abLength)
});
}
} else {
let bounds = {
a: [a.length, -1, o.length, -1],
b: [b.length, -1, o.length, -1]
};
while (regionHunks.length) {
hunk = regionHunks.shift();
const oStart = hunk.oStart;
const oEnd = oStart + hunk.oLength;
const abStart = hunk.abStart;
const abEnd = abStart + hunk.abLength;
let b2 = bounds[hunk.ab];
b2[0] = Math.min(abStart, b2[0]);
b2[1] = Math.max(abEnd, b2[1]);
b2[2] = Math.min(oStart, b2[2]);
b2[3] = Math.max(oEnd, b2[3]);
}
const aStart = bounds.a[0] + (regionStart - bounds.a[2]);
const aEnd = bounds.a[1] + (regionEnd - bounds.a[3]);
const bStart = bounds.b[0] + (regionStart - bounds.b[2]);
const bEnd = bounds.b[1] + (regionEnd - bounds.b[3]);
let result = {
stable: false,
aStart,
aLength: aEnd - aStart,
aContent: a.slice(aStart, aEnd),
oStart: regionStart,
oLength: regionEnd - regionStart,
oContent: o.slice(regionStart, regionEnd),
bStart,
bLength: bEnd - bStart,
bContent: b.slice(bStart, bEnd)
};
results.push(result);
}
currOffset = regionEnd;
}
advanceTo(o.length);
return results;
}
function diff3Merge(a, o, b, options) {
let defaults = {
excludeFalseConflicts: true,
stringSeparator: /\s+/
};
options = Object.assign(defaults, options);
if (typeof a === "string")
a = a.split(options.stringSeparator);
if (typeof o === "string")
o = o.split(options.stringSeparator);
if (typeof b === "string")
b = b.split(options.stringSeparator);
let results = [];
const regions = diff3MergeRegions(a, o, b);
let okBuffer = [];
function flushOk() {
if (okBuffer.length) {
results.push({ ok: okBuffer });
}
okBuffer = [];
}
function isFalseConflict(a2, b2) {
if (a2.length !== b2.length)
return false;
for (let i = 0; i < a2.length; i++) {
if (a2[i] !== b2[i])
return false;
}
return true;
}
regions.forEach((region) => {
if (region.stable) {
okBuffer.push(...region.bufferContent);
} else {
if (options.excludeFalseConflicts && isFalseConflict(region.aContent, region.bContent)) {
okBuffer.push(...region.aContent);
} else {
flushOk();
results.push({
conflict: {
a: region.aContent,
aIndex: region.aStart,
o: region.oContent,
oIndex: region.oStart,
b: region.bContent,
bIndex: region.bStart
}
});
}
}
});
flushOk();
return results;
}
function mergeDiff3(a, o, b, options) {
const defaults = {
excludeFalseConflicts: true,
stringSeparator: /\s+/,
label: {}
};
options = Object.assign(defaults, options);
const aSection = "<<<<<<<" + (options.label.a ? ` ${options.label.a}` : "");
const oSection = "|||||||" + (options.label.o ? ` ${options.label.o}` : "");
const xSection = "=======";
const bSection = ">>>>>>>" + (options.label.b ? ` ${options.label.b}` : "");
const regions = diff3Merge(a, o, b, options);
let conflict = false;
let result = [];
regions.forEach((region) => {
if (region.ok) {
result = result.concat(region.ok);
} else if (region.conflict) {
conflict = true;
result = result.concat([aSection], region.conflict.a, [oSection], region.conflict.o, [xSection], region.conflict.b, [bSection]);
}
});
return {
conflict,
result
};
}
function merge(a, o, b, options) {
const defaults = {
excludeFalseConflicts: true,
stringSeparator: /\s+/,
label: {}
};
options = Object.assign(defaults, options);
const aSection = "<<<<<<<" + (options.label.a ? ` ${options.label.a}` : "");
const xSection = "=======";
const bSection = ">>>>>>>" + (options.label.b ? ` ${options.label.b}` : "");
const regions = diff3Merge(a, o, b, options);
let conflict = false;
let result = [];
regions.forEach((region) => {
if (region.ok) {
result = result.concat(region.ok);
} else if (region.conflict) {
conflict = true;
result = result.concat([aSection], region.conflict.a, [xSection], region.conflict.b, [bSection]);
}
});
return {
conflict,
result
};
}
function mergeDigIn(a, o, b, options) {
const defaults = {
excludeFalseConflicts: true,
stringSeparator: /\s+/,
label: {}
};
options = Object.assign(defaults, options);
const aSection = "<<<<<<<" + (options.label.a ? ` ${options.label.a}` : "");
const xSection = "=======";
const bSection = ">>>>>>>" + (options.label.b ? ` ${options.label.b}` : "");
const regions = diff3Merge(a, o, b, options);
let conflict = false;
let result = [];
regions.forEach((region) => {
if (region.ok) {
result = result.concat(region.ok);
} else {
const c = diffComm(region.conflict.a, region.conflict.b);
for (let j = 0; j < c.length; j++) {
let inner = c[j];
if (inner.common) {
result = result.concat(inner.common);
} else {
conflict = true;
result = result.concat([aSection], inner.buffer1, [xSection], inner.buffer2, [bSection]);
}
}
}
});
return {
conflict,
result
};
}
function patch(buffer, patch2) {
let result = [];
let currOffset = 0;
function advanceTo(targetOffset) {
while (currOffset < targetOffset) {
result.push(buffer[currOffset]);
currOffset++;
}
}
for (let chunkIndex = 0; chunkIndex < patch2.length; chunkIndex++) {
let chunk = patch2[chunkIndex];
advanceTo(chunk.buffer1.offset);
for (let itemIndex = 0; itemIndex < chunk.buffer2.chunk.length; itemIndex++) {
result.push(chunk.buffer2.chunk[itemIndex]);
}
currOffset += chunk.buffer1.length;
}
advanceTo(buffer.length);
return result;
}
function stripPatch(patch2) {
return patch2.map((chunk) => ({
buffer1: { offset: chunk.buffer1.offset, length: chunk.buffer1.length },
buffer2: { chunk: chunk.buffer2.chunk }
}));
}
function invertPatch(patch2) {
return patch2.map((chunk) => ({
buffer1: chunk.buffer2,
buffer2: chunk.buffer1
}));
}
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
LCS,
diff3Merge,
diff3MergeRegions,
diffComm,
diffIndices,
diffPatch,
invertPatch,
merge,
mergeDiff3,
mergeDigIn,
patch,
stripPatch
});
//# sourceMappingURL=index.cjs.map
{
"version": 3,
"sources": ["../index.mjs"],
"sourcesContent": ["export {\n LCS,\n diffComm,\n diffIndices,\n diffPatch,\n diff3MergeRegions,\n diff3Merge,\n mergeDiff3,\n merge,\n mergeDigIn,\n patch,\n stripPatch,\n invertPatch\n};\n\n\n// Text diff algorithm following Hunt and McIlroy 1976.\n// J. W. Hunt and M. D. McIlroy, An algorithm for differential buffer\n// comparison, Bell Telephone Laboratories CSTR #41 (1976)\n// http://www.cs.dartmouth.edu/~doug/\n// https://en.wikipedia.org/wiki/Longest_common_subsequence_problem\n//\n// Expects two arrays, finds longest common sequence\nfunction LCS(buffer1, buffer2) {\n\n let equivalenceClasses = {};\n for (let j = 0; j < buffer2.length; j++) {\n const item = buffer2[j];\n if (equivalenceClasses[item]) {\n equivalenceClasses[item].push(j);\n } else {\n equivalenceClasses[item] = [j];\n }\n }\n\n const NULLRESULT = { buffer1index: -1, buffer2index: -1, chain: null };\n let candidates = [NULLRESULT];\n\n for (let i = 0; i < buffer1.length; i++) {\n const item = buffer1[i];\n const buffer2indices = equivalenceClasses[item] || [];\n let r = 0;\n let c = candidates[0];\n\n for (let jx = 0; jx < buffer2indices.length; jx++) {\n const j = buffer2indices[jx];\n\n let s;\n for (s = r; s < candidates.length; s++) {\n if ((candidates[s].buffer2index < j) && ((s === candidates.length - 1) || (candidates[s + 1].buffer2index > j))) {\n break;\n }\n }\n\n if (s < candidates.length) {\n const newCandidate = { buffer1index: i, buffer2index: j, chain: candidates[s] };\n if (r === candidates.length) {\n candidates.push(c);\n } else {\n candidates[r] = c;\n }\n r = s + 1;\n c = newCandidate;\n if (r === candidates.length) {\n break; // no point in examining further (j)s\n }\n }\n }\n\n candidates[r] = c;\n }\n\n // At this point, we know the LCS: it's in the reverse of the\n // linked-list through .chain of candidates[candidates.length - 1].\n\n return candidates[candidates.length - 1];\n}\n\n\n// We apply the LCS to build a 'comm'-style picture of the\n// differences between buffer1 and buffer2.\nfunction diffComm(buffer1, buffer2) {\n const lcs = LCS(buffer1, buffer2);\n let result = [];\n let tail1 = buffer1.length;\n let tail2 = buffer2.length;\n let common = {common: []};\n\n function processCommon() {\n if (common.common.length) {\n common.common.reverse();\n result.push(common);\n common = {common: []};\n }\n }\n\n for (let candidate = lcs; candidate !== null; candidate = candidate.chain) {\n let different = {buffer1: [], buffer2: []};\n\n while (--tail1 > candidate.buffer1index) {\n different.buffer1.push(buffer1[tail1]);\n }\n\n while (--tail2 > candidate.buffer2index) {\n different.buffer2.push(buffer2[tail2]);\n }\n\n if (different.buffer1.length || different.buffer2.length) {\n processCommon();\n different.buffer1.reverse();\n different.buffer2.reverse();\n result.push(different);\n }\n\n if (tail1 >= 0) {\n common.common.push(buffer1[tail1]);\n }\n }\n\n processCommon();\n\n result.reverse();\n return result;\n}\n\n\n// We apply the LCS to give a simple representation of the\n// offsets and lengths of mismatched chunks in the input\n// buffers. This is used by diff3MergeRegions.\nfunction diffIndices(buffer1, buffer2) {\n const lcs = LCS(buffer1, buffer2);\n let result = [];\n let tail1 = buffer1.length;\n let tail2 = buffer2.length;\n\n for (let candidate = lcs; candidate !== null; candidate = candidate.chain) {\n const mismatchLength1 = tail1 - candidate.buffer1index - 1;\n const mismatchLength2 = tail2 - candidate.buffer2index - 1;\n tail1 = candidate.buffer1index;\n tail2 = candidate.buffer2index;\n\n if (mismatchLength1 || mismatchLength2) {\n result.push({\n buffer1: [tail1 + 1, mismatchLength1],\n buffer1Content: buffer1.slice(tail1 + 1, tail1 + 1 + mismatchLength1),\n buffer2: [tail2 + 1, mismatchLength2],\n buffer2Content: buffer2.slice(tail2 + 1, tail2 + 1 + mismatchLength2)\n });\n }\n }\n\n result.reverse();\n return result;\n}\n\n\n// We apply the LCS to build a JSON representation of a\n// diff(1)-style patch.\nfunction diffPatch(buffer1, buffer2) {\n const lcs = LCS(buffer1, buffer2);\n let result = [];\n let tail1 = buffer1.length;\n let tail2 = buffer2.length;\n\n function chunkDescription(buffer, offset, length) {\n let chunk = [];\n for (let i = 0; i < length; i++) {\n chunk.push(buffer[offset + i]);\n }\n return {\n offset: offset,\n length: length,\n chunk: chunk\n };\n }\n\n for (let candidate = lcs; candidate !== null; candidate = candidate.chain) {\n const mismatchLength1 = tail1 - candidate.buffer1index - 1;\n const mismatchLength2 = tail2 - candidate.buffer2index - 1;\n tail1 = candidate.buffer1index;\n tail2 = candidate.buffer2index;\n\n if (mismatchLength1 || mismatchLength2) {\n result.push({\n buffer1: chunkDescription(buffer1, candidate.buffer1index + 1, mismatchLength1),\n buffer2: chunkDescription(buffer2, candidate.buffer2index + 1, mismatchLength2)\n });\n }\n }\n\n result.reverse();\n return result;\n}\n\n\n// Given three buffers, A, O, and B, where both A and B are\n// independently derived from O, returns a fairly complicated\n// internal representation of merge decisions it's taken. The\n// interested reader may wish to consult\n//\n// Sanjeev Khanna, Keshav Kunal, and Benjamin C. Pierce.\n// 'A Formal Investigation of ' In Arvind and Prasad,\n// editors, Foundations of Software Technology and Theoretical\n// Computer Science (FSTTCS), December 2007.\n//\n// (http://www.cis.upenn.edu/~bcpierce/papers/diff3-short.pdf)\n//\nfunction diff3MergeRegions(a, o, b) {\n\n // \"hunks\" are array subsets where `a` or `b` are different from `o`\n // https://www.gnu.org/software/diffutils/manual/html_node/diff3-Hunks.html\n let hunks = [];\n function addHunk(h, ab) {\n hunks.push({\n ab: ab,\n oStart: h.buffer1[0],\n oLength: h.buffer1[1], // length of o to remove\n abStart: h.buffer2[0],\n abLength: h.buffer2[1] // length of a/b to insert\n // abContent: (ab === 'a' ? a : b).slice(h.buffer2[0], h.buffer2[0] + h.buffer2[1])\n });\n }\n\n diffIndices(o, a).forEach(item => addHunk(item, 'a'));\n diffIndices(o, b).forEach(item => addHunk(item, 'b'));\n hunks.sort((x,y) => x.oStart - y.oStart);\n\n let results = [];\n let currOffset = 0;\n\n function advanceTo(endOffset) {\n if (endOffset > currOffset) {\n results.push({\n stable: true,\n buffer: 'o',\n bufferStart: currOffset,\n bufferLength: endOffset - currOffset,\n bufferContent: o.slice(currOffset, endOffset)\n });\n currOffset = endOffset;\n }\n }\n\n while (hunks.length) {\n let hunk = hunks.shift();\n let regionStart = hunk.oStart;\n let regionEnd = hunk.oStart + hunk.oLength;\n let regionHunks = [hunk];\n advanceTo(regionStart);\n\n // Try to pull next overlapping hunk into this region\n while (hunks.length) {\n const nextHunk = hunks[0];\n const nextHunkStart = nextHunk.oStart;\n if (nextHunkStart > regionEnd) break; // no overlap\n\n regionEnd = Math.max(regionEnd, nextHunkStart + nextHunk.oLength);\n regionHunks.push(hunks.shift());\n }\n\n if (regionHunks.length === 1) {\n // Only one hunk touches this region, meaning that there is no conflict here.\n // Either `a` or `b` is inserting into a region of `o` unchanged by the other.\n if (hunk.abLength > 0) {\n const buffer = (hunk.ab === 'a' ? a : b);\n results.push({\n stable: true,\n buffer: hunk.ab,\n bufferStart: hunk.abStart,\n bufferLength: hunk.abLength,\n bufferContent: buffer.slice(hunk.abStart, hunk.abStart + hunk.abLength)\n });\n }\n } else {\n // A true a/b conflict. Determine the bounds involved from `a`, `o`, and `b`.\n // Effectively merge all the `a` hunks into one giant hunk, then do the\n // same for the `b` hunks; then, correct for skew in the regions of `o`\n // that each side changed, and report appropriate spans for the three sides.\n let bounds = {\n a: [a.length, -1, o.length, -1],\n b: [b.length, -1, o.length, -1]\n };\n while (regionHunks.length) {\n hunk = regionHunks.shift();\n const oStart = hunk.oStart;\n const oEnd = oStart + hunk.oLength;\n const abStart = hunk.abStart;\n const abEnd = abStart + hunk.abLength;\n let b = bounds[hunk.ab];\n b[0] = Math.min(abStart, b[0]);\n b[1] = Math.max(abEnd, b[1]);\n b[2] = Math.min(oStart, b[2]);\n b[3] = Math.max(oEnd, b[3]);\n }\n\n const aStart = bounds.a[0] + (regionStart - bounds.a[2]);\n const aEnd = bounds.a[1] + (regionEnd - bounds.a[3]);\n const bStart = bounds.b[0] + (regionStart - bounds.b[2]);\n const bEnd = bounds.b[1] + (regionEnd - bounds.b[3]);\n\n let result = {\n stable: false,\n aStart: aStart,\n aLength: aEnd - aStart,\n aContent: a.slice(aStart, aEnd),\n oStart: regionStart,\n oLength: regionEnd - regionStart,\n oContent: o.slice(regionStart, regionEnd),\n bStart: bStart,\n bLength: bEnd - bStart,\n bContent: b.slice(bStart, bEnd)\n };\n results.push(result);\n }\n currOffset = regionEnd;\n }\n\n advanceTo(o.length);\n\n return results;\n}\n\n\n// Applies the output of diff3MergeRegions to actually\n// construct the merged buffer; the returned result alternates\n// between 'ok' and 'conflict' blocks.\n// A \"false conflict\" is where `a` and `b` both change the same from `o`\nfunction diff3Merge(a, o, b, options) {\n let defaults = {\n excludeFalseConflicts: true,\n stringSeparator: /\\s+/\n };\n options = Object.assign(defaults, options);\n\n if (typeof a === 'string') a = a.split(options.stringSeparator);\n if (typeof o === 'string') o = o.split(options.stringSeparator);\n if (typeof b === 'string') b = b.split(options.stringSeparator);\n\n let results = [];\n const regions = diff3MergeRegions(a, o, b);\n\n let okBuffer = [];\n function flushOk() {\n if (okBuffer.length) {\n results.push({ ok: okBuffer });\n }\n okBuffer = [];\n }\n\n function isFalseConflict(a, b) {\n if (a.length !== b.length) return false;\n for (let i = 0; i < a.length; i++) {\n if (a[i] !== b[i]) return false;\n }\n return true;\n }\n\n regions.forEach(region => {\n if (region.stable) {\n okBuffer.push(...region.bufferContent);\n } else {\n if (options.excludeFalseConflicts && isFalseConflict(region.aContent, region.bContent)) {\n okBuffer.push(...region.aContent);\n } else {\n flushOk();\n results.push({\n conflict: {\n a: region.aContent,\n aIndex: region.aStart,\n o: region.oContent,\n oIndex: region.oStart,\n b: region.bContent,\n bIndex: region.bStart\n }\n });\n }\n }\n });\n\n flushOk();\n return results;\n}\n\n\nfunction mergeDiff3(a, o, b, options) {\n const defaults = {\n excludeFalseConflicts: true,\n stringSeparator: /\\s+/,\n label: {}\n };\n options = Object.assign(defaults, options);\n\n const aSection = '<<<<<<<' + (options.label.a ? ` ${options.label.a}` : '');\n const oSection = '|||||||' + (options.label.o ? ` ${options.label.o}` : '');\n const xSection = '=======';\n const bSection = '>>>>>>>' + (options.label.b ? ` ${options.label.b}` : '');\n\n const regions = diff3Merge(a, o, b, options);\n let conflict = false;\n let result = [];\n\n regions.forEach(region => {\n if (region.ok) {\n result = result.concat(region.ok);\n } else if (region.conflict) {\n conflict = true;\n result = result.concat(\n [aSection],\n region.conflict.a,\n [oSection],\n region.conflict.o,\n [xSection],\n region.conflict.b,\n [bSection]\n );\n }\n });\n\n return {\n conflict: conflict,\n result: result\n };\n}\n\n\nfunction merge(a, o, b, options) {\n const defaults = {\n excludeFalseConflicts: true,\n stringSeparator: /\\s+/,\n label: {}\n };\n options = Object.assign(defaults, options);\n\n const aSection = '<<<<<<<' + (options.label.a ? ` ${options.label.a}` : '');\n const xSection = '=======';\n const bSection = '>>>>>>>' + (options.label.b ? ` ${options.label.b}` : '');\n\n const regions = diff3Merge(a, o, b, options);\n let conflict = false;\n let result = [];\n\n regions.forEach(region => {\n if (region.ok) {\n result = result.concat(region.ok);\n } else if (region.conflict) {\n conflict = true;\n result = result.concat(\n [aSection],\n region.conflict.a,\n [xSection],\n region.conflict.b,\n [bSection]\n );\n }\n });\n\n return {\n conflict: conflict,\n result: result\n };\n}\n\n\nfunction mergeDigIn(a, o, b, options) {\n const defaults = {\n excludeFalseConflicts: true,\n stringSeparator: /\\s+/,\n label: {}\n };\n options = Object.assign(defaults, options);\n\n const aSection = '<<<<<<<' + (options.label.a ? ` ${options.label.a}` : '');\n const xSection = '=======';\n const bSection = '>>>>>>>' + (options.label.b ? ` ${options.label.b}` : '');\n\n const regions = diff3Merge(a, o, b, options);\n let conflict = false;\n let result = [];\n\n regions.forEach(region => {\n if (region.ok) {\n result = result.concat(region.ok);\n } else {\n const c = diffComm(region.conflict.a, region.conflict.b);\n for (let j = 0; j < c.length; j++) {\n let inner = c[j];\n if (inner.common) {\n result = result.concat(inner.common);\n } else {\n conflict = true;\n result = result.concat(\n [aSection],\n inner.buffer1,\n [xSection],\n inner.buffer2,\n [bSection]\n );\n }\n }\n }\n });\n\n return {\n conflict: conflict,\n result: result\n };\n}\n\n\n// Applies a patch to a buffer.\n// Given buffer1 and buffer2, `patch(buffer1, diffPatch(buffer1, buffer2))` should give buffer2.\nfunction patch(buffer, patch) {\n let result = [];\n let currOffset = 0;\n\n function advanceTo(targetOffset) {\n while (currOffset < targetOffset) {\n result.push(buffer[currOffset]);\n currOffset++;\n }\n }\n\n for (let chunkIndex = 0; chunkIndex < patch.length; chunkIndex++) {\n let chunk = patch[chunkIndex];\n advanceTo(chunk.buffer1.offset);\n for (let itemIndex = 0; itemIndex < chunk.buffer2.chunk.length; itemIndex++) {\n result.push(chunk.buffer2.chunk[itemIndex]);\n }\n currOffset += chunk.buffer1.length;\n }\n\n advanceTo(buffer.length);\n return result;\n}\n\n\n// Takes the output of diffPatch(), and removes extra information from it.\n// It can still be used by patch(), below, but can no longer be inverted.\nfunction stripPatch(patch) {\n return patch.map(chunk => ({\n buffer1: { offset: chunk.buffer1.offset, length: chunk.buffer1.length },\n buffer2: { chunk: chunk.buffer2.chunk }\n }));\n}\n\n\n// Takes the output of diffPatch(), and inverts the sense of it, so that it\n// can be applied to buffer2 to give buffer1 rather than the other way around.\nfunction invertPatch(patch) {\n return patch.map(chunk => ({\n buffer1: chunk.buffer2,\n buffer2: chunk.buffer1\n }));\n}\n"],
"mappings": "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",
"names": []
}
var Diff3 = (() => {
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
// index.mjs
var node_diff3_exports = {};
__export(node_diff3_exports, {
LCS: () => LCS,
diff3Merge: () => diff3Merge,
diff3MergeRegions: () => diff3MergeRegions,
diffComm: () => diffComm,
diffIndices: () => diffIndices,
diffPatch: () => diffPatch,
invertPatch: () => invertPatch,
merge: () => merge,
mergeDiff3: () => mergeDiff3,
mergeDigIn: () => mergeDigIn,
patch: () => patch,
stripPatch: () => stripPatch
});
function LCS(buffer1, buffer2) {
let equivalenceClasses = {};
for (let j = 0; j < buffer2.length; j++) {
const item = buffer2[j];
if (equivalenceClasses[item]) {
equivalenceClasses[item].push(j);
} else {
equivalenceClasses[item] = [j];
}
}
const NULLRESULT = { buffer1index: -1, buffer2index: -1, chain: null };
let candidates = [NULLRESULT];
for (let i = 0; i < buffer1.length; i++) {
const item = buffer1[i];
const buffer2indices = equivalenceClasses[item] || [];
let r = 0;
let c = candidates[0];
for (let jx = 0; jx < buffer2indices.length; jx++) {
const j = buffer2indices[jx];
let s;
for (s = r; s < candidates.length; s++) {
if (candidates[s].buffer2index < j && (s === candidates.length - 1 || candidates[s + 1].buffer2index > j)) {
break;
}
}
if (s < candidates.length) {
const newCandidate = { buffer1index: i, buffer2index: j, chain: candidates[s] };
if (r === candidates.length) {
candidates.push(c);
} else {
candidates[r] = c;
}
r = s + 1;
c = newCandidate;
if (r === candidates.length) {
break;
}
}
}
candidates[r] = c;
}
return candidates[candidates.length - 1];
}
function diffComm(buffer1, buffer2) {
const lcs = LCS(buffer1, buffer2);
let result = [];
let tail1 = buffer1.length;
let tail2 = buffer2.length;
let common = { common: [] };
function processCommon() {
if (common.common.length) {
common.common.reverse();
result.push(common);
common = { common: [] };
}
}
for (let candidate = lcs; candidate !== null; candidate = candidate.chain) {
let different = { buffer1: [], buffer2: [] };
while (--tail1 > candidate.buffer1index) {
different.buffer1.push(buffer1[tail1]);
}
while (--tail2 > candidate.buffer2index) {
different.buffer2.push(buffer2[tail2]);
}
if (different.buffer1.length || different.buffer2.length) {
processCommon();
different.buffer1.reverse();
different.buffer2.reverse();
result.push(different);
}
if (tail1 >= 0) {
common.common.push(buffer1[tail1]);
}
}
processCommon();
result.reverse();
return result;
}
function diffIndices(buffer1, buffer2) {
const lcs = LCS(buffer1, buffer2);
let result = [];
let tail1 = buffer1.length;
let tail2 = buffer2.length;
for (let candidate = lcs; candidate !== null; candidate = candidate.chain) {
const mismatchLength1 = tail1 - candidate.buffer1index - 1;
const mismatchLength2 = tail2 - candidate.buffer2index - 1;
tail1 = candidate.buffer1index;
tail2 = candidate.buffer2index;
if (mismatchLength1 || mismatchLength2) {
result.push({
buffer1: [tail1 + 1, mismatchLength1],
buffer1Content: buffer1.slice(tail1 + 1, tail1 + 1 + mismatchLength1),
buffer2: [tail2 + 1, mismatchLength2],
buffer2Content: buffer2.slice(tail2 + 1, tail2 + 1 + mismatchLength2)
});
}
}
result.reverse();
return result;
}
function diffPatch(buffer1, buffer2) {
const lcs = LCS(buffer1, buffer2);
let result = [];
let tail1 = buffer1.length;
let tail2 = buffer2.length;
function chunkDescription(buffer, offset, length) {
let chunk = [];
for (let i = 0; i < length; i++) {
chunk.push(buffer[offset + i]);
}
return {
offset,
length,
chunk
};
}
for (let candidate = lcs; candidate !== null; candidate = candidate.chain) {
const mismatchLength1 = tail1 - candidate.buffer1index - 1;
const mismatchLength2 = tail2 - candidate.buffer2index - 1;
tail1 = candidate.buffer1index;
tail2 = candidate.buffer2index;
if (mismatchLength1 || mismatchLength2) {
result.push({
buffer1: chunkDescription(buffer1, candidate.buffer1index + 1, mismatchLength1),
buffer2: chunkDescription(buffer2, candidate.buffer2index + 1, mismatchLength2)
});
}
}
result.reverse();
return result;
}
function diff3MergeRegions(a, o, b) {
let hunks = [];
function addHunk(h, ab) {
hunks.push({
ab,
oStart: h.buffer1[0],
oLength: h.buffer1[1],
abStart: h.buffer2[0],
abLength: h.buffer2[1]
});
}
diffIndices(o, a).forEach((item) => addHunk(item, "a"));
diffIndices(o, b).forEach((item) => addHunk(item, "b"));
hunks.sort((x, y) => x.oStart - y.oStart);
let results = [];
let currOffset = 0;
function advanceTo(endOffset) {
if (endOffset > currOffset) {
results.push({
stable: true,
buffer: "o",
bufferStart: currOffset,
bufferLength: endOffset - currOffset,
bufferContent: o.slice(currOffset, endOffset)
});
currOffset = endOffset;
}
}
while (hunks.length) {
let hunk = hunks.shift();
let regionStart = hunk.oStart;
let regionEnd = hunk.oStart + hunk.oLength;
let regionHunks = [hunk];
advanceTo(regionStart);
while (hunks.length) {
const nextHunk = hunks[0];
const nextHunkStart = nextHunk.oStart;
if (nextHunkStart > regionEnd)
break;
regionEnd = Math.max(regionEnd, nextHunkStart + nextHunk.oLength);
regionHunks.push(hunks.shift());
}
if (regionHunks.length === 1) {
if (hunk.abLength > 0) {
const buffer = hunk.ab === "a" ? a : b;
results.push({
stable: true,
buffer: hunk.ab,
bufferStart: hunk.abStart,
bufferLength: hunk.abLength,
bufferContent: buffer.slice(hunk.abStart, hunk.abStart + hunk.abLength)
});
}
} else {
let bounds = {
a: [a.length, -1, o.length, -1],
b: [b.length, -1, o.length, -1]
};
while (regionHunks.length) {
hunk = regionHunks.shift();
const oStart = hunk.oStart;
const oEnd = oStart + hunk.oLength;
const abStart = hunk.abStart;
const abEnd = abStart + hunk.abLength;
let b2 = bounds[hunk.ab];
b2[0] = Math.min(abStart, b2[0]);
b2[1] = Math.max(abEnd, b2[1]);
b2[2] = Math.min(oStart, b2[2]);
b2[3] = Math.max(oEnd, b2[3]);
}
const aStart = bounds.a[0] + (regionStart - bounds.a[2]);
const aEnd = bounds.a[1] + (regionEnd - bounds.a[3]);
const bStart = bounds.b[0] + (regionStart - bounds.b[2]);
const bEnd = bounds.b[1] + (regionEnd - bounds.b[3]);
let result = {
stable: false,
aStart,
aLength: aEnd - aStart,
aContent: a.slice(aStart, aEnd),
oStart: regionStart,
oLength: regionEnd - regionStart,
oContent: o.slice(regionStart, regionEnd),
bStart,
bLength: bEnd - bStart,
bContent: b.slice(bStart, bEnd)
};
results.push(result);
}
currOffset = regionEnd;
}
advanceTo(o.length);
return results;
}
function diff3Merge(a, o, b, options) {
let defaults = {
excludeFalseConflicts: true,
stringSeparator: /\s+/
};
options = Object.assign(defaults, options);
if (typeof a === "string")
a = a.split(options.stringSeparator);
if (typeof o === "string")
o = o.split(options.stringSeparator);
if (typeof b === "string")
b = b.split(options.stringSeparator);
let results = [];
const regions = diff3MergeRegions(a, o, b);
let okBuffer = [];
function flushOk() {
if (okBuffer.length) {
results.push({ ok: okBuffer });
}
okBuffer = [];
}
function isFalseConflict(a2, b2) {
if (a2.length !== b2.length)
return false;
for (let i = 0; i < a2.length; i++) {
if (a2[i] !== b2[i])
return false;
}
return true;
}
regions.forEach((region) => {
if (region.stable) {
okBuffer.push(...region.bufferContent);
} else {
if (options.excludeFalseConflicts && isFalseConflict(region.aContent, region.bContent)) {
okBuffer.push(...region.aContent);
} else {
flushOk();
results.push({
conflict: {
a: region.aContent,
aIndex: region.aStart,
o: region.oContent,
oIndex: region.oStart,
b: region.bContent,
bIndex: region.bStart
}
});
}
}
});
flushOk();
return results;
}
function mergeDiff3(a, o, b, options) {
const defaults = {
excludeFalseConflicts: true,
stringSeparator: /\s+/,
label: {}
};
options = Object.assign(defaults, options);
const aSection = "<<<<<<<" + (options.label.a ? ` ${options.label.a}` : "");
const oSection = "|||||||" + (options.label.o ? ` ${options.label.o}` : "");
const xSection = "=======";
const bSection = ">>>>>>>" + (options.label.b ? ` ${options.label.b}` : "");
const regions = diff3Merge(a, o, b, options);
let conflict = false;
let result = [];
regions.forEach((region) => {
if (region.ok) {
result = result.concat(region.ok);
} else if (region.conflict) {
conflict = true;
result = result.concat([aSection], region.conflict.a, [oSection], region.conflict.o, [xSection], region.conflict.b, [bSection]);
}
});
return {
conflict,
result
};
}
function merge(a, o, b, options) {
const defaults = {
excludeFalseConflicts: true,
stringSeparator: /\s+/,
label: {}
};
options = Object.assign(defaults, options);
const aSection = "<<<<<<<" + (options.label.a ? ` ${options.label.a}` : "");
const xSection = "=======";
const bSection = ">>>>>>>" + (options.label.b ? ` ${options.label.b}` : "");
const regions = diff3Merge(a, o, b, options);
let conflict = false;
let result = [];
regions.forEach((region) => {
if (region.ok) {
result = result.concat(region.ok);
} else if (region.conflict) {
conflict = true;
result = result.concat([aSection], region.conflict.a, [xSection], region.conflict.b, [bSection]);
}
});
return {
conflict,
result
};
}
function mergeDigIn(a, o, b, options) {
const defaults = {
excludeFalseConflicts: true,
stringSeparator: /\s+/,
label: {}
};
options = Object.assign(defaults, options);
const aSection = "<<<<<<<" + (options.label.a ? ` ${options.label.a}` : "");
const xSection = "=======";
const bSection = ">>>>>>>" + (options.label.b ? ` ${options.label.b}` : "");
const regions = diff3Merge(a, o, b, options);
let conflict = false;
let result = [];
regions.forEach((region) => {
if (region.ok) {
result = result.concat(region.ok);
} else {
const c = diffComm(region.conflict.a, region.conflict.b);
for (let j = 0; j < c.length; j++) {
let inner = c[j];
if (inner.common) {
result = result.concat(inner.common);
} else {
conflict = true;
result = result.concat([aSection], inner.buffer1, [xSection], inner.buffer2, [bSection]);
}
}
}
});
return {
conflict,
result
};
}
function patch(buffer, patch2) {
let result = [];
let currOffset = 0;
function advanceTo(targetOffset) {
while (currOffset < targetOffset) {
result.push(buffer[currOffset]);
currOffset++;
}
}
for (let chunkIndex = 0; chunkIndex < patch2.length; chunkIndex++) {
let chunk = patch2[chunkIndex];
advanceTo(chunk.buffer1.offset);
for (let itemIndex = 0; itemIndex < chunk.buffer2.chunk.length; itemIndex++) {
result.push(chunk.buffer2.chunk[itemIndex]);
}
currOffset += chunk.buffer1.length;
}
advanceTo(buffer.length);
return result;
}
function stripPatch(patch2) {
return patch2.map((chunk) => ({
buffer1: { offset: chunk.buffer1.offset, length: chunk.buffer1.length },
buffer2: { chunk: chunk.buffer2.chunk }
}));
}
function invertPatch(patch2) {
return patch2.map((chunk) => ({
buffer1: chunk.buffer2,
buffer2: chunk.buffer1
}));
}
return __toCommonJS(node_diff3_exports);
})();
//# sourceMappingURL=index.iife.js.map
{
"version": 3,
"sources": ["../index.mjs"],
"sourcesContent": ["export {\n LCS,\n diffComm,\n diffIndices,\n diffPatch,\n diff3MergeRegions,\n diff3Merge,\n mergeDiff3,\n merge,\n mergeDigIn,\n patch,\n stripPatch,\n invertPatch\n};\n\n\n// Text diff algorithm following Hunt and McIlroy 1976.\n// J. W. Hunt and M. D. McIlroy, An algorithm for differential buffer\n// comparison, Bell Telephone Laboratories CSTR #41 (1976)\n// http://www.cs.dartmouth.edu/~doug/\n// https://en.wikipedia.org/wiki/Longest_common_subsequence_problem\n//\n// Expects two arrays, finds longest common sequence\nfunction LCS(buffer1, buffer2) {\n\n let equivalenceClasses = {};\n for (let j = 0; j < buffer2.length; j++) {\n const item = buffer2[j];\n if (equivalenceClasses[item]) {\n equivalenceClasses[item].push(j);\n } else {\n equivalenceClasses[item] = [j];\n }\n }\n\n const NULLRESULT = { buffer1index: -1, buffer2index: -1, chain: null };\n let candidates = [NULLRESULT];\n\n for (let i = 0; i < buffer1.length; i++) {\n const item = buffer1[i];\n const buffer2indices = equivalenceClasses[item] || [];\n let r = 0;\n let c = candidates[0];\n\n for (let jx = 0; jx < buffer2indices.length; jx++) {\n const j = buffer2indices[jx];\n\n let s;\n for (s = r; s < candidates.length; s++) {\n if ((candidates[s].buffer2index < j) && ((s === candidates.length - 1) || (candidates[s + 1].buffer2index > j))) {\n break;\n }\n }\n\n if (s < candidates.length) {\n const newCandidate = { buffer1index: i, buffer2index: j, chain: candidates[s] };\n if (r === candidates.length) {\n candidates.push(c);\n } else {\n candidates[r] = c;\n }\n r = s + 1;\n c = newCandidate;\n if (r === candidates.length) {\n break; // no point in examining further (j)s\n }\n }\n }\n\n candidates[r] = c;\n }\n\n // At this point, we know the LCS: it's in the reverse of the\n // linked-list through .chain of candidates[candidates.length - 1].\n\n return candidates[candidates.length - 1];\n}\n\n\n// We apply the LCS to build a 'comm'-style picture of the\n// differences between buffer1 and buffer2.\nfunction diffComm(buffer1, buffer2) {\n const lcs = LCS(buffer1, buffer2);\n let result = [];\n let tail1 = buffer1.length;\n let tail2 = buffer2.length;\n let common = {common: []};\n\n function processCommon() {\n if (common.common.length) {\n common.common.reverse();\n result.push(common);\n common = {common: []};\n }\n }\n\n for (let candidate = lcs; candidate !== null; candidate = candidate.chain) {\n let different = {buffer1: [], buffer2: []};\n\n while (--tail1 > candidate.buffer1index) {\n different.buffer1.push(buffer1[tail1]);\n }\n\n while (--tail2 > candidate.buffer2index) {\n different.buffer2.push(buffer2[tail2]);\n }\n\n if (different.buffer1.length || different.buffer2.length) {\n processCommon();\n different.buffer1.reverse();\n different.buffer2.reverse();\n result.push(different);\n }\n\n if (tail1 >= 0) {\n common.common.push(buffer1[tail1]);\n }\n }\n\n processCommon();\n\n result.reverse();\n return result;\n}\n\n\n// We apply the LCS to give a simple representation of the\n// offsets and lengths of mismatched chunks in the input\n// buffers. This is used by diff3MergeRegions.\nfunction diffIndices(buffer1, buffer2) {\n const lcs = LCS(buffer1, buffer2);\n let result = [];\n let tail1 = buffer1.length;\n let tail2 = buffer2.length;\n\n for (let candidate = lcs; candidate !== null; candidate = candidate.chain) {\n const mismatchLength1 = tail1 - candidate.buffer1index - 1;\n const mismatchLength2 = tail2 - candidate.buffer2index - 1;\n tail1 = candidate.buffer1index;\n tail2 = candidate.buffer2index;\n\n if (mismatchLength1 || mismatchLength2) {\n result.push({\n buffer1: [tail1 + 1, mismatchLength1],\n buffer1Content: buffer1.slice(tail1 + 1, tail1 + 1 + mismatchLength1),\n buffer2: [tail2 + 1, mismatchLength2],\n buffer2Content: buffer2.slice(tail2 + 1, tail2 + 1 + mismatchLength2)\n });\n }\n }\n\n result.reverse();\n return result;\n}\n\n\n// We apply the LCS to build a JSON representation of a\n// diff(1)-style patch.\nfunction diffPatch(buffer1, buffer2) {\n const lcs = LCS(buffer1, buffer2);\n let result = [];\n let tail1 = buffer1.length;\n let tail2 = buffer2.length;\n\n function chunkDescription(buffer, offset, length) {\n let chunk = [];\n for (let i = 0; i < length; i++) {\n chunk.push(buffer[offset + i]);\n }\n return {\n offset: offset,\n length: length,\n chunk: chunk\n };\n }\n\n for (let candidate = lcs; candidate !== null; candidate = candidate.chain) {\n const mismatchLength1 = tail1 - candidate.buffer1index - 1;\n const mismatchLength2 = tail2 - candidate.buffer2index - 1;\n tail1 = candidate.buffer1index;\n tail2 = candidate.buffer2index;\n\n if (mismatchLength1 || mismatchLength2) {\n result.push({\n buffer1: chunkDescription(buffer1, candidate.buffer1index + 1, mismatchLength1),\n buffer2: chunkDescription(buffer2, candidate.buffer2index + 1, mismatchLength2)\n });\n }\n }\n\n result.reverse();\n return result;\n}\n\n\n// Given three buffers, A, O, and B, where both A and B are\n// independently derived from O, returns a fairly complicated\n// internal representation of merge decisions it's taken. The\n// interested reader may wish to consult\n//\n// Sanjeev Khanna, Keshav Kunal, and Benjamin C. Pierce.\n// 'A Formal Investigation of ' In Arvind and Prasad,\n// editors, Foundations of Software Technology and Theoretical\n// Computer Science (FSTTCS), December 2007.\n//\n// (http://www.cis.upenn.edu/~bcpierce/papers/diff3-short.pdf)\n//\nfunction diff3MergeRegions(a, o, b) {\n\n // \"hunks\" are array subsets where `a` or `b` are different from `o`\n // https://www.gnu.org/software/diffutils/manual/html_node/diff3-Hunks.html\n let hunks = [];\n function addHunk(h, ab) {\n hunks.push({\n ab: ab,\n oStart: h.buffer1[0],\n oLength: h.buffer1[1], // length of o to remove\n abStart: h.buffer2[0],\n abLength: h.buffer2[1] // length of a/b to insert\n // abContent: (ab === 'a' ? a : b).slice(h.buffer2[0], h.buffer2[0] + h.buffer2[1])\n });\n }\n\n diffIndices(o, a).forEach(item => addHunk(item, 'a'));\n diffIndices(o, b).forEach(item => addHunk(item, 'b'));\n hunks.sort((x,y) => x.oStart - y.oStart);\n\n let results = [];\n let currOffset = 0;\n\n function advanceTo(endOffset) {\n if (endOffset > currOffset) {\n results.push({\n stable: true,\n buffer: 'o',\n bufferStart: currOffset,\n bufferLength: endOffset - currOffset,\n bufferContent: o.slice(currOffset, endOffset)\n });\n currOffset = endOffset;\n }\n }\n\n while (hunks.length) {\n let hunk = hunks.shift();\n let regionStart = hunk.oStart;\n let regionEnd = hunk.oStart + hunk.oLength;\n let regionHunks = [hunk];\n advanceTo(regionStart);\n\n // Try to pull next overlapping hunk into this region\n while (hunks.length) {\n const nextHunk = hunks[0];\n const nextHunkStart = nextHunk.oStart;\n if (nextHunkStart > regionEnd) break; // no overlap\n\n regionEnd = Math.max(regionEnd, nextHunkStart + nextHunk.oLength);\n regionHunks.push(hunks.shift());\n }\n\n if (regionHunks.length === 1) {\n // Only one hunk touches this region, meaning that there is no conflict here.\n // Either `a` or `b` is inserting into a region of `o` unchanged by the other.\n if (hunk.abLength > 0) {\n const buffer = (hunk.ab === 'a' ? a : b);\n results.push({\n stable: true,\n buffer: hunk.ab,\n bufferStart: hunk.abStart,\n bufferLength: hunk.abLength,\n bufferContent: buffer.slice(hunk.abStart, hunk.abStart + hunk.abLength)\n });\n }\n } else {\n // A true a/b conflict. Determine the bounds involved from `a`, `o`, and `b`.\n // Effectively merge all the `a` hunks into one giant hunk, then do the\n // same for the `b` hunks; then, correct for skew in the regions of `o`\n // that each side changed, and report appropriate spans for the three sides.\n let bounds = {\n a: [a.length, -1, o.length, -1],\n b: [b.length, -1, o.length, -1]\n };\n while (regionHunks.length) {\n hunk = regionHunks.shift();\n const oStart = hunk.oStart;\n const oEnd = oStart + hunk.oLength;\n const abStart = hunk.abStart;\n const abEnd = abStart + hunk.abLength;\n let b = bounds[hunk.ab];\n b[0] = Math.min(abStart, b[0]);\n b[1] = Math.max(abEnd, b[1]);\n b[2] = Math.min(oStart, b[2]);\n b[3] = Math.max(oEnd, b[3]);\n }\n\n const aStart = bounds.a[0] + (regionStart - bounds.a[2]);\n const aEnd = bounds.a[1] + (regionEnd - bounds.a[3]);\n const bStart = bounds.b[0] + (regionStart - bounds.b[2]);\n const bEnd = bounds.b[1] + (regionEnd - bounds.b[3]);\n\n let result = {\n stable: false,\n aStart: aStart,\n aLength: aEnd - aStart,\n aContent: a.slice(aStart, aEnd),\n oStart: regionStart,\n oLength: regionEnd - regionStart,\n oContent: o.slice(regionStart, regionEnd),\n bStart: bStart,\n bLength: bEnd - bStart,\n bContent: b.slice(bStart, bEnd)\n };\n results.push(result);\n }\n currOffset = regionEnd;\n }\n\n advanceTo(o.length);\n\n return results;\n}\n\n\n// Applies the output of diff3MergeRegions to actually\n// construct the merged buffer; the returned result alternates\n// between 'ok' and 'conflict' blocks.\n// A \"false conflict\" is where `a` and `b` both change the same from `o`\nfunction diff3Merge(a, o, b, options) {\n let defaults = {\n excludeFalseConflicts: true,\n stringSeparator: /\\s+/\n };\n options = Object.assign(defaults, options);\n\n if (typeof a === 'string') a = a.split(options.stringSeparator);\n if (typeof o === 'string') o = o.split(options.stringSeparator);\n if (typeof b === 'string') b = b.split(options.stringSeparator);\n\n let results = [];\n const regions = diff3MergeRegions(a, o, b);\n\n let okBuffer = [];\n function flushOk() {\n if (okBuffer.length) {\n results.push({ ok: okBuffer });\n }\n okBuffer = [];\n }\n\n function isFalseConflict(a, b) {\n if (a.length !== b.length) return false;\n for (let i = 0; i < a.length; i++) {\n if (a[i] !== b[i]) return false;\n }\n return true;\n }\n\n regions.forEach(region => {\n if (region.stable) {\n okBuffer.push(...region.bufferContent);\n } else {\n if (options.excludeFalseConflicts && isFalseConflict(region.aContent, region.bContent)) {\n okBuffer.push(...region.aContent);\n } else {\n flushOk();\n results.push({\n conflict: {\n a: region.aContent,\n aIndex: region.aStart,\n o: region.oContent,\n oIndex: region.oStart,\n b: region.bContent,\n bIndex: region.bStart\n }\n });\n }\n }\n });\n\n flushOk();\n return results;\n}\n\n\nfunction mergeDiff3(a, o, b, options) {\n const defaults = {\n excludeFalseConflicts: true,\n stringSeparator: /\\s+/,\n label: {}\n };\n options = Object.assign(defaults, options);\n\n const aSection = '<<<<<<<' + (options.label.a ? ` ${options.label.a}` : '');\n const oSection = '|||||||' + (options.label.o ? ` ${options.label.o}` : '');\n const xSection = '=======';\n const bSection = '>>>>>>>' + (options.label.b ? ` ${options.label.b}` : '');\n\n const regions = diff3Merge(a, o, b, options);\n let conflict = false;\n let result = [];\n\n regions.forEach(region => {\n if (region.ok) {\n result = result.concat(region.ok);\n } else if (region.conflict) {\n conflict = true;\n result = result.concat(\n [aSection],\n region.conflict.a,\n [oSection],\n region.conflict.o,\n [xSection],\n region.conflict.b,\n [bSection]\n );\n }\n });\n\n return {\n conflict: conflict,\n result: result\n };\n}\n\n\nfunction merge(a, o, b, options) {\n const defaults = {\n excludeFalseConflicts: true,\n stringSeparator: /\\s+/,\n label: {}\n };\n options = Object.assign(defaults, options);\n\n const aSection = '<<<<<<<' + (options.label.a ? ` ${options.label.a}` : '');\n const xSection = '=======';\n const bSection = '>>>>>>>' + (options.label.b ? ` ${options.label.b}` : '');\n\n const regions = diff3Merge(a, o, b, options);\n let conflict = false;\n let result = [];\n\n regions.forEach(region => {\n if (region.ok) {\n result = result.concat(region.ok);\n } else if (region.conflict) {\n conflict = true;\n result = result.concat(\n [aSection],\n region.conflict.a,\n [xSection],\n region.conflict.b,\n [bSection]\n );\n }\n });\n\n return {\n conflict: conflict,\n result: result\n };\n}\n\n\nfunction mergeDigIn(a, o, b, options) {\n const defaults = {\n excludeFalseConflicts: true,\n stringSeparator: /\\s+/,\n label: {}\n };\n options = Object.assign(defaults, options);\n\n const aSection = '<<<<<<<' + (options.label.a ? ` ${options.label.a}` : '');\n const xSection = '=======';\n const bSection = '>>>>>>>' + (options.label.b ? ` ${options.label.b}` : '');\n\n const regions = diff3Merge(a, o, b, options);\n let conflict = false;\n let result = [];\n\n regions.forEach(region => {\n if (region.ok) {\n result = result.concat(region.ok);\n } else {\n const c = diffComm(region.conflict.a, region.conflict.b);\n for (let j = 0; j < c.length; j++) {\n let inner = c[j];\n if (inner.common) {\n result = result.concat(inner.common);\n } else {\n conflict = true;\n result = result.concat(\n [aSection],\n inner.buffer1,\n [xSection],\n inner.buffer2,\n [bSection]\n );\n }\n }\n }\n });\n\n return {\n conflict: conflict,\n result: result\n };\n}\n\n\n// Applies a patch to a buffer.\n// Given buffer1 and buffer2, `patch(buffer1, diffPatch(buffer1, buffer2))` should give buffer2.\nfunction patch(buffer, patch) {\n let result = [];\n let currOffset = 0;\n\n function advanceTo(targetOffset) {\n while (currOffset < targetOffset) {\n result.push(buffer[currOffset]);\n currOffset++;\n }\n }\n\n for (let chunkIndex = 0; chunkIndex < patch.length; chunkIndex++) {\n let chunk = patch[chunkIndex];\n advanceTo(chunk.buffer1.offset);\n for (let itemIndex = 0; itemIndex < chunk.buffer2.chunk.length; itemIndex++) {\n result.push(chunk.buffer2.chunk[itemIndex]);\n }\n currOffset += chunk.buffer1.length;\n }\n\n advanceTo(buffer.length);\n return result;\n}\n\n\n// Takes the output of diffPatch(), and removes extra information from it.\n// It can still be used by patch(), below, but can no longer be inverted.\nfunction stripPatch(patch) {\n return patch.map(chunk => ({\n buffer1: { offset: chunk.buffer1.offset, length: chunk.buffer1.length },\n buffer2: { chunk: chunk.buffer2.chunk }\n }));\n}\n\n\n// Takes the output of diffPatch(), and inverts the sense of it, so that it\n// can be applied to buffer2 to give buffer1 rather than the other way around.\nfunction invertPatch(patch) {\n return patch.map(chunk => ({\n buffer1: chunk.buffer2,\n buffer2: chunk.buffer1\n }));\n}\n"],
"mappings": "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",
"names": []
}
export interface ILCSResult {
buffer1index: number;
buffer2index: number;
chain: null | ILCSResult;
}
/**
* Expects two arrays, finds longest common sequence
* @param {T[]} buffer1
* @param {T[]} buffer2
* @returns {ILCSResult}
* @constructor
*/
export function LCS<T>(buffer1: T[], buffer2: T[]): ILCSResult;
export interface ICommResult<T> {
buffer1: T[];
buffer2: T[];
}
/**
* We apply the LCS to build a 'comm'-style picture of the
* differences between buffer1 and buffer2.
* @param {T[]} buffer1
* @param {T[]} buffer2
* @returns {Array<ICommResult<T>>}
*/
export function diffComm<T>(buffer1: T[], buffer2: T[]): ICommResult<T>[];
export interface IDiffIndicesResult<T> {
buffer1: [number, number];
buffer1Content: T[];
buffer2: [number, number];
buffer2Content: T[];
}
/**
* We apply the LCS to give a simple representation of the
* offsets and lengths of mismatched chunks in the input
* buffers. This is used by diff3MergeRegions.
* @param {T[]} buffer1
* @param {T[]} buffer2
* @returns {IDiffIndicesResult<T>[]}
*/
export function diffIndices<T>(
buffer1: T[],
buffer2: T[]
): IDiffIndicesResult<T>[];
export interface IChunk<T> {
offset: number;
length: number;
chunk: T[];
}
export interface IPatchRes<T> {
buffer1: IChunk<T>;
buffer2: IChunk<T>;
}
/**
* We apply the LCS to build a JSON representation of a
* diff(1)-style patch.
* @param {T[]} buffer1
* @param {T[]} buffer2
* @returns {IPatchRes<T>[]}
*/
export function diffPatch<T>(buffer1: T[], buffer2: T[]): IPatchRes<T>[];
export function patch<T>(buffer: T[], patch: IPatchRes<T>[]): T[];
export interface IStableRegion<T> {
stable: true;
buffer: 'a' | 'o' | 'b';
bufferStart: number;
bufferLength: number;
bufferContent: T[];
}
export interface IUnstableRegion<T> {
stable: false;
aStart: number;
aLength: number;
aContent: T[];
bStart: number;
bLength: number;
bContent: T[];
oStart: number;
oLength: number;
oContent: T[];
}
export type IRegion<T> = IStableRegion<T> | IUnstableRegion<T>;
/**
* Given three buffers, A, O, and B, where both A and B are
* independently derived from O, returns a fairly complicated
* internal representation of merge decisions it's taken. The
* interested reader may wish to consult
*
* Sanjeev Khanna, Keshav Kunal, and Benjamin C. Pierce.
* 'A Formal Investigation of ' In Arvind and Prasad,
* editors, Foundations of Software Technology and Theoretical
* Computer Science (FSTTCS), December 2007.
*
* (http://www.cis.upenn.edu/~bcpierce/papers/diff3-short.pdf)
*
* @param {T[]} a
* @param {T[]} o
* @param {T[]} b
* @returns {IRegion<T>[]}
*/
export function diff3MergeRegions<T>(a: T[], o: T[], b: T[]): IRegion<T>[];
export interface MergeRegion<T> {
ok?: T[];
conflict?: {
a: T[];
aIndex: number;
b: T[];
bIndex: number;
o: T[];
oIndex: number;
};
}
export interface MergeResult {
conflict: boolean;
result: string[];
}
export interface IMergeOptions {
excludeFalseConflicts?: boolean;
stringSeparator?: string | RegExp;
}
/**
* Applies the output of diff3MergeRegions to actually
* construct the merged buffer; the returned result alternates
* between 'ok' and 'conflict' blocks.
* A "false conflict" is where `a` and `b` both change the same from `o`
*
* @param {string | T[]} a
* @param {string | T[]} o
* @param {string | T[]} b
* @param {{excludeFalseConflicts: boolean; stringSeparator: RegExp}} options
* @returns {MergeRegion<T>[]}
*/
export function diff3Merge<T>(
a: string | T[],
o: string | T[],
b: string | T[],
options?: IMergeOptions
): MergeRegion<T>[];
export function merge<T>(
a: string | T[],
o: string | T[],
b: string | T[],
options?: IMergeOptions
): MergeResult;
export function mergeDiff3<T>(
a: string | T[],
o: string | T[],
b: string | T[],
options?: IMergeOptions & {
label?: {
a?: string;
o?: string;
b?: string;
}
}
): MergeResult;
export function mergeDigIn<T>(
a: string | T[],
o: string | T[],
b: string | T[],
options?: IMergeOptions
): MergeResult;
export {
LCS,
diffComm,
diffIndices,
diffPatch,
diff3MergeRegions,
diff3Merge,
mergeDiff3,
merge,
mergeDigIn,
patch,
stripPatch,
invertPatch
};
// Text diff algorithm following Hunt and McIlroy 1976.
// J. W. Hunt and M. D. McIlroy, An algorithm for differential buffer
// comparison, Bell Telephone Laboratories CSTR #41 (1976)
// http://www.cs.dartmouth.edu/~doug/
// https://en.wikipedia.org/wiki/Longest_common_subsequence_problem
//
// Expects two arrays, finds longest common sequence
function LCS(buffer1, buffer2) {
let equivalenceClasses = {};
for (let j = 0; j < buffer2.length; j++) {
const item = buffer2[j];
if (equivalenceClasses[item]) {
equivalenceClasses[item].push(j);
} else {
equivalenceClasses[item] = [j];
}
}
const NULLRESULT = { buffer1index: -1, buffer2index: -1, chain: null };
let candidates = [NULLRESULT];
for (let i = 0; i < buffer1.length; i++) {
const item = buffer1[i];
const buffer2indices = equivalenceClasses[item] || [];
let r = 0;
let c = candidates[0];
for (let jx = 0; jx < buffer2indices.length; jx++) {
const j = buffer2indices[jx];
let s;
for (s = r; s < candidates.length; s++) {
if ((candidates[s].buffer2index < j) && ((s === candidates.length - 1) || (candidates[s + 1].buffer2index > j))) {
break;
}
}
if (s < candidates.length) {
const newCandidate = { buffer1index: i, buffer2index: j, chain: candidates[s] };
if (r === candidates.length) {
candidates.push(c);
} else {
candidates[r] = c;
}
r = s + 1;
c = newCandidate;
if (r === candidates.length) {
break; // no point in examining further (j)s
}
}
}
candidates[r] = c;
}
// At this point, we know the LCS: it's in the reverse of the
// linked-list through .chain of candidates[candidates.length - 1].
return candidates[candidates.length - 1];
}
// We apply the LCS to build a 'comm'-style picture of the
// differences between buffer1 and buffer2.
function diffComm(buffer1, buffer2) {
const lcs = LCS(buffer1, buffer2);
let result = [];
let tail1 = buffer1.length;
let tail2 = buffer2.length;
let common = {common: []};
function processCommon() {
if (common.common.length) {
common.common.reverse();
result.push(common);
common = {common: []};
}
}
for (let candidate = lcs; candidate !== null; candidate = candidate.chain) {
let different = {buffer1: [], buffer2: []};
while (--tail1 > candidate.buffer1index) {
different.buffer1.push(buffer1[tail1]);
}
while (--tail2 > candidate.buffer2index) {
different.buffer2.push(buffer2[tail2]);
}
if (different.buffer1.length || different.buffer2.length) {
processCommon();
different.buffer1.reverse();
different.buffer2.reverse();
result.push(different);
}
if (tail1 >= 0) {
common.common.push(buffer1[tail1]);
}
}
processCommon();
result.reverse();
return result;
}
// We apply the LCS to give a simple representation of the
// offsets and lengths of mismatched chunks in the input
// buffers. This is used by diff3MergeRegions.
function diffIndices(buffer1, buffer2) {
const lcs = LCS(buffer1, buffer2);
let result = [];
let tail1 = buffer1.length;
let tail2 = buffer2.length;
for (let candidate = lcs; candidate !== null; candidate = candidate.chain) {
const mismatchLength1 = tail1 - candidate.buffer1index - 1;
const mismatchLength2 = tail2 - candidate.buffer2index - 1;
tail1 = candidate.buffer1index;
tail2 = candidate.buffer2index;
if (mismatchLength1 || mismatchLength2) {
result.push({
buffer1: [tail1 + 1, mismatchLength1],
buffer1Content: buffer1.slice(tail1 + 1, tail1 + 1 + mismatchLength1),
buffer2: [tail2 + 1, mismatchLength2],
buffer2Content: buffer2.slice(tail2 + 1, tail2 + 1 + mismatchLength2)
});
}
}
result.reverse();
return result;
}
// We apply the LCS to build a JSON representation of a
// diff(1)-style patch.
function diffPatch(buffer1, buffer2) {
const lcs = LCS(buffer1, buffer2);
let result = [];
let tail1 = buffer1.length;
let tail2 = buffer2.length;
function chunkDescription(buffer, offset, length) {
let chunk = [];
for (let i = 0; i < length; i++) {
chunk.push(buffer[offset + i]);
}
return {
offset: offset,
length: length,
chunk: chunk
};
}
for (let candidate = lcs; candidate !== null; candidate = candidate.chain) {
const mismatchLength1 = tail1 - candidate.buffer1index - 1;
const mismatchLength2 = tail2 - candidate.buffer2index - 1;
tail1 = candidate.buffer1index;
tail2 = candidate.buffer2index;
if (mismatchLength1 || mismatchLength2) {
result.push({
buffer1: chunkDescription(buffer1, candidate.buffer1index + 1, mismatchLength1),
buffer2: chunkDescription(buffer2, candidate.buffer2index + 1, mismatchLength2)
});
}
}
result.reverse();
return result;
}
// Given three buffers, A, O, and B, where both A and B are
// independently derived from O, returns a fairly complicated
// internal representation of merge decisions it's taken. The
// interested reader may wish to consult
//
// Sanjeev Khanna, Keshav Kunal, and Benjamin C. Pierce.
// 'A Formal Investigation of ' In Arvind and Prasad,
// editors, Foundations of Software Technology and Theoretical
// Computer Science (FSTTCS), December 2007.
//
// (http://www.cis.upenn.edu/~bcpierce/papers/diff3-short.pdf)
//
function diff3MergeRegions(a, o, b) {
// "hunks" are array subsets where `a` or `b` are different from `o`
// https://www.gnu.org/software/diffutils/manual/html_node/diff3-Hunks.html
let hunks = [];
function addHunk(h, ab) {
hunks.push({
ab: ab,
oStart: h.buffer1[0],
oLength: h.buffer1[1], // length of o to remove
abStart: h.buffer2[0],
abLength: h.buffer2[1] // length of a/b to insert
// abContent: (ab === 'a' ? a : b).slice(h.buffer2[0], h.buffer2[0] + h.buffer2[1])
});
}
diffIndices(o, a).forEach(item => addHunk(item, 'a'));
diffIndices(o, b).forEach(item => addHunk(item, 'b'));
hunks.sort((x,y) => x.oStart - y.oStart);
let results = [];
let currOffset = 0;
function advanceTo(endOffset) {
if (endOffset > currOffset) {
results.push({
stable: true,
buffer: 'o',
bufferStart: currOffset,
bufferLength: endOffset - currOffset,
bufferContent: o.slice(currOffset, endOffset)
});
currOffset = endOffset;
}
}
while (hunks.length) {
let hunk = hunks.shift();
let regionStart = hunk.oStart;
let regionEnd = hunk.oStart + hunk.oLength;
let regionHunks = [hunk];
advanceTo(regionStart);
// Try to pull next overlapping hunk into this region
while (hunks.length) {
const nextHunk = hunks[0];
const nextHunkStart = nextHunk.oStart;
if (nextHunkStart > regionEnd) break; // no overlap
regionEnd = Math.max(regionEnd, nextHunkStart + nextHunk.oLength);
regionHunks.push(hunks.shift());
}
if (regionHunks.length === 1) {
// Only one hunk touches this region, meaning that there is no conflict here.
// Either `a` or `b` is inserting into a region of `o` unchanged by the other.
if (hunk.abLength > 0) {
const buffer = (hunk.ab === 'a' ? a : b);
results.push({
stable: true,
buffer: hunk.ab,
bufferStart: hunk.abStart,
bufferLength: hunk.abLength,
bufferContent: buffer.slice(hunk.abStart, hunk.abStart + hunk.abLength)
});
}
} else {
// A true a/b conflict. Determine the bounds involved from `a`, `o`, and `b`.
// Effectively merge all the `a` hunks into one giant hunk, then do the
// same for the `b` hunks; then, correct for skew in the regions of `o`
// that each side changed, and report appropriate spans for the three sides.
let bounds = {
a: [a.length, -1, o.length, -1],
b: [b.length, -1, o.length, -1]
};
while (regionHunks.length) {
hunk = regionHunks.shift();
const oStart = hunk.oStart;
const oEnd = oStart + hunk.oLength;
const abStart = hunk.abStart;
const abEnd = abStart + hunk.abLength;
let b = bounds[hunk.ab];
b[0] = Math.min(abStart, b[0]);
b[1] = Math.max(abEnd, b[1]);
b[2] = Math.min(oStart, b[2]);
b[3] = Math.max(oEnd, b[3]);
}
const aStart = bounds.a[0] + (regionStart - bounds.a[2]);
const aEnd = bounds.a[1] + (regionEnd - bounds.a[3]);
const bStart = bounds.b[0] + (regionStart - bounds.b[2]);
const bEnd = bounds.b[1] + (regionEnd - bounds.b[3]);
let result = {
stable: false,
aStart: aStart,
aLength: aEnd - aStart,
aContent: a.slice(aStart, aEnd),
oStart: regionStart,
oLength: regionEnd - regionStart,
oContent: o.slice(regionStart, regionEnd),
bStart: bStart,
bLength: bEnd - bStart,
bContent: b.slice(bStart, bEnd)
};
results.push(result);
}
currOffset = regionEnd;
}
advanceTo(o.length);
return results;
}
// Applies the output of diff3MergeRegions to actually
// construct the merged buffer; the returned result alternates
// between 'ok' and 'conflict' blocks.
// A "false conflict" is where `a` and `b` both change the same from `o`
function diff3Merge(a, o, b, options) {
let defaults = {
excludeFalseConflicts: true,
stringSeparator: /\s+/
};
options = Object.assign(defaults, options);
if (typeof a === 'string') a = a.split(options.stringSeparator);
if (typeof o === 'string') o = o.split(options.stringSeparator);
if (typeof b === 'string') b = b.split(options.stringSeparator);
let results = [];
const regions = diff3MergeRegions(a, o, b);
let okBuffer = [];
function flushOk() {
if (okBuffer.length) {
results.push({ ok: okBuffer });
}
okBuffer = [];
}
function isFalseConflict(a, b) {
if (a.length !== b.length) return false;
for (let i = 0; i < a.length; i++) {
if (a[i] !== b[i]) return false;
}
return true;
}
regions.forEach(region => {
if (region.stable) {
okBuffer.push(...region.bufferContent);
} else {
if (options.excludeFalseConflicts && isFalseConflict(region.aContent, region.bContent)) {
okBuffer.push(...region.aContent);
} else {
flushOk();
results.push({
conflict: {
a: region.aContent,
aIndex: region.aStart,
o: region.oContent,
oIndex: region.oStart,
b: region.bContent,
bIndex: region.bStart
}
});
}
}
});
flushOk();
return results;
}
function mergeDiff3(a, o, b, options) {
const defaults = {
excludeFalseConflicts: true,
stringSeparator: /\s+/,
label: {}
};
options = Object.assign(defaults, options);
const aSection = '<<<<<<<' + (options.label.a ? ` ${options.label.a}` : '');
const oSection = '|||||||' + (options.label.o ? ` ${options.label.o}` : '');
const xSection = '=======';
const bSection = '>>>>>>>' + (options.label.b ? ` ${options.label.b}` : '');
const regions = diff3Merge(a, o, b, options);
let conflict = false;
let result = [];
regions.forEach(region => {
if (region.ok) {
result = result.concat(region.ok);
} else if (region.conflict) {
conflict = true;
result = result.concat(
[aSection],
region.conflict.a,
[oSection],
region.conflict.o,
[xSection],
region.conflict.b,
[bSection]
);
}
});
return {
conflict: conflict,
result: result
};
}
function merge(a, o, b, options) {
const defaults = {
excludeFalseConflicts: true,
stringSeparator: /\s+/,
label: {}
};
options = Object.assign(defaults, options);
const aSection = '<<<<<<<' + (options.label.a ? ` ${options.label.a}` : '');
const xSection = '=======';
const bSection = '>>>>>>>' + (options.label.b ? ` ${options.label.b}` : '');
const regions = diff3Merge(a, o, b, options);
let conflict = false;
let result = [];
regions.forEach(region => {
if (region.ok) {
result = result.concat(region.ok);
} else if (region.conflict) {
conflict = true;
result = result.concat(
[aSection],
region.conflict.a,
[xSection],
region.conflict.b,
[bSection]
);
}
});
return {
conflict: conflict,
result: result
};
}
function mergeDigIn(a, o, b, options) {
const defaults = {
excludeFalseConflicts: true,
stringSeparator: /\s+/,
label: {}
};
options = Object.assign(defaults, options);
const aSection = '<<<<<<<' + (options.label.a ? ` ${options.label.a}` : '');
const xSection = '=======';
const bSection = '>>>>>>>' + (options.label.b ? ` ${options.label.b}` : '');
const regions = diff3Merge(a, o, b, options);
let conflict = false;
let result = [];
regions.forEach(region => {
if (region.ok) {
result = result.concat(region.ok);
} else {
const c = diffComm(region.conflict.a, region.conflict.b);
for (let j = 0; j < c.length; j++) {
let inner = c[j];
if (inner.common) {
result = result.concat(inner.common);
} else {
conflict = true;
result = result.concat(
[aSection],
inner.buffer1,
[xSection],
inner.buffer2,
[bSection]
);
}
}
}
});
return {
conflict: conflict,
result: result
};
}
// Applies a patch to a buffer.
// Given buffer1 and buffer2, `patch(buffer1, diffPatch(buffer1, buffer2))` should give buffer2.
function patch(buffer, patch) {
let result = [];
let currOffset = 0;
function advanceTo(targetOffset) {
while (currOffset < targetOffset) {
result.push(buffer[currOffset]);
currOffset++;
}
}
for (let chunkIndex = 0; chunkIndex < patch.length; chunkIndex++) {
let chunk = patch[chunkIndex];
advanceTo(chunk.buffer1.offset);
for (let itemIndex = 0; itemIndex < chunk.buffer2.chunk.length; itemIndex++) {
result.push(chunk.buffer2.chunk[itemIndex]);
}
currOffset += chunk.buffer1.length;
}
advanceTo(buffer.length);
return result;
}
// Takes the output of diffPatch(), and removes extra information from it.
// It can still be used by patch(), below, but can no longer be inverted.
function stripPatch(patch) {
return patch.map(chunk => ({
buffer1: { offset: chunk.buffer1.offset, length: chunk.buffer1.length },
buffer2: { chunk: chunk.buffer2.chunk }
}));
}
// Takes the output of diffPatch(), and inverts the sense of it, so that it
// can be applied to buffer2 to give buffer1 rather than the other way around.
function invertPatch(patch) {
return patch.map(chunk => ({
buffer1: chunk.buffer2,
buffer2: chunk.buffer1
}));
}