var SequenceMatcher, arrayDiff, colorize, descalarize, diff, diffScore, diffString, diffWithScore, extendedTypeOf, findMatchingObject, isScalar, isScalarized, objectDiff, scalarize,
__hasProp = {}.hasOwnProperty;
SequenceMatcher = require('difflib').SequenceMatcher;
extendedTypeOf = require('./util').extendedTypeOf;
colorize = require('./colorize').colorize;
isScalar = function(obj) {
return typeof obj !== 'object';
objectDiff = function(obj1, obj2) {
var change, key, keys1, keys2, result, score, subscore, value1, value2, _ref, _ref1;
keys1 = Object.keys(obj1);
keys2 = Object.keys(obj2);
if (!__hasProp.call(obj1, key)) continue;
if (!(!(key in obj2))) continue;
result["" + key + "__deleted"] = value1;
if (!__hasProp.call(obj2, key)) continue;
if (!(!(key in obj1))) continue;
result["" + key + "__added"] = value2;
if (!__hasProp.call(obj1, key)) continue;
if (!(key in obj2)) continue;
_ref = diffWithScore(value1, value2), subscore = _ref[0], change = _ref[1];
if (change) result[key] = change;
score += Math.min(20, Math.max(-10, subscore / 5));
if (Object.keys(result).length === 0) {
_ref1 = [100 * Object.keys(obj1).length, void 0], score = _ref1[0], result = _ref1[1];
score = Math.max(0, score);
findMatchingObject = function(item, fuzzyOriginals) {
var bestMatch, candidate, key, score;
for (key in fuzzyOriginals) {
if (!__hasProp.call(fuzzyOriginals, key)) continue;
candidate = fuzzyOriginals[key];
if (extendedTypeOf(item) === extendedTypeOf(candidate)) {
score = diffScore(item, candidate);
if (!bestMatch || score > bestMatch.score) {
scalarize = function(array, originals, fuzzyOriginals) {
var bestMatch, item, proxy, _i, _len, _results;
for (_i = 0, _len = array.length; _i < _len; _i++) {
} else if (fuzzyOriginals && (bestMatch = findMatchingObject(item, fuzzyOriginals)) && bestMatch.score > 40) {
originals[bestMatch.key] = item;
_results.push(bestMatch.key);
proxy = "__$!SCALAR" + originals.__next++;
isScalarized = function(item, originals) {
return (typeof item === 'string') && (item in originals);
descalarize = function(item, originals) {
if (isScalarized(item, originals)) {
arrayDiff = function(obj1, obj2, stats) {
var allEqual, change, i, i1, i2, item, item1, item2, j, j1, j2, op, opcodes, originals1, originals2, result, score, seq1, seq2, _i, _j, _k, _l, _len, _m, _n, _ref;
seq1 = scalarize(obj1, originals1);
__next: originals1.__next
seq2 = scalarize(obj2, originals2, originals1);
opcodes = new SequenceMatcher(null, seq1, seq2).getOpcodes();
for (_i = 0, _len = opcodes.length; _i < _len; _i++) {
_ref = opcodes[_i], op = _ref[0], i1 = _ref[1], i2 = _ref[2], j1 = _ref[3], j2 = _ref[4];
if (op !== 'equal') allEqual = false;
for (i = _j = i1; i1 <= i2 ? _j < i2 : _j > i2; i = i1 <= i2 ? ++_j : --_j) {
if (isScalarized(item, originals1)) {
if (!isScalarized(item, originals2)) {
throw new AssertionError("internal bug: isScalarized(item, originals1) != isScalarized(item, originals2) for item " + (JSON.stringify(item)));
item1 = descalarize(item, originals1);
item2 = descalarize(item, originals2);
change = diff(item1, item2);
result.push(['~', change]);
result.push([' ', item]);
for (i = _k = i1; i1 <= i2 ? _k < i2 : _k > i2; i = i1 <= i2 ? ++_k : --_k) {
result.push(['-', descalarize(seq1[i], originals1)]);
for (j = _l = j1; j1 <= j2 ? _l < j2 : _l > j2; j = j1 <= j2 ? ++_l : --_l) {
result.push(['+', descalarize(seq2[j], originals2)]);
for (i = _m = i1; i1 <= i2 ? _m < i2 : _m > i2; i = i1 <= i2 ? ++_m : --_m) {
result.push(['-', descalarize(seq1[i], originals1)]);
for (j = _n = j1; j1 <= j2 ? _n < j2 : _n > j2; j = j1 <= j2 ? ++_n : --_n) {
result.push(['+', descalarize(seq2[j], originals2)]);
if (allEqual || (opcodes.length === 0)) {
score = Math.max(0, score);
diffWithScore = function(obj1, obj2) {
type1 = extendedTypeOf(obj1);
type2 = extendedTypeOf(obj2);
return objectDiff(obj1, obj2);
return arrayDiff(obj1, obj2);
diff = function(obj1, obj2) {
_ref = diffWithScore(obj1, obj2), score = _ref[0], change = _ref[1];
diffScore = function(obj1, obj2) {
_ref = diffWithScore(obj1, obj2), score = _ref[0], change = _ref[1];
diffString = function(obj1, obj2, options) {
return colorize(diff(obj1, obj2), options);