export const DiffWrapper={charDiff:function(text1,text2,cleanup){const differ=new diff_match_patch();const diff=differ.diff_main(text1,text2);if(cleanup){differ.diff_cleanupSemantic(diff);}
return diff;},lineDiff:function(lines1,lines2){const idMap=new Common.CharacterIdMap();const text1=lines1.map(line=>idMap.toChar(line)).join('');const text2=lines2.map(line=>idMap.toChar(line)).join('');const diff=DiffWrapper.charDiff(text1,text2);const lineDiff=[];for(let i=0;i<diff.length;i++){const lines=[];for(let j=0;j<diff[i][1].length;j++){lines.push(idMap.fromChar(diff[i][1][j]));}
lineDiff.push({0:diff[i][0],1:lines});}
return lineDiff;},convertToEditDiff:function(diff){const normalized=[];let added=0;let removed=0;for(let i=0;i<diff.length;++i){const token=diff[i];if(token[0]===Operation.Equal){flush();normalized.push([Operation.Equal,token[1].length]);}else if(token[0]===Operation.Delete){removed+=token[1].length;}else{added+=token[1].length;}}
flush();return normalized;function flush(){if(added&&removed){const min=Math.min(added,removed);normalized.push([Operation.Edit,min]);added-=min;removed-=min;}
if(added||removed){const balance=added-removed;const type=balance<0?Operation.Delete:Operation.Insert;normalized.push([type,Math.abs(balance)]);added=0;removed=0;}}}};export const Operation={Equal:0,Insert:1,Delete:-1,Edit:2};self.Diff=self.Diff||{};Diff=Diff||{};Diff.Diff=DiffWrapper;Diff.Diff.Operation=Operation;Diff.Diff.DiffArray;