text: 
  (function () {
      // Simple calculation based on Levenshtein distance.
      function calculateEditDistanceMatrix(oldArray, newArray, maxAllowedDistance) {
          var distances = [];
          for (var i = 0; i <= newArray.length; i++)
              distances[i] = [];
  
          // Top row - transform old array into empty array via deletions
          for (var i = 0, j = Math.min(oldArray.length, maxAllowedDistance); i <= j; i++)
              distances[0][i] = i;
  
          // Left row - transform empty array into new array via additions
          for (var i = 1, j = Math.min(newArray.length, maxAllowedDistance); i <= j; i++) {
              distances[i][0] = i;
          }
  
          // Fill out the body of the array
          var oldIndex, oldIndexMax = oldArray.length, newIndex, newIndexMax = newArray.length;
          var distanceViaAddition, distanceViaDeletion;
          for (oldIndex = 1; oldIndex <= oldIndexMax; oldIndex++) {
              var newIndexMinForRow = Math.max(1, oldIndex - maxAllowedDistance);
              var newIndexMaxForRow = Math.min(newIndexMax, oldIndex + maxAllowedDistance);
              for (newIndex = newIndexMinForRow; newIndex <= newIndexMaxForRow; newIndex++) {
                  if (oldArray[oldIndex - 1] === newArray[newIndex - 1])
                      distances[newIndex][oldIndex] = distances[newIndex - 1][oldIndex - 1];
                  else {
                      var northDistance = distances[newIndex - 1][oldIndex] === undefined ? Number.MAX_VALUE : distances[newIndex - 1][oldIndex] + 1;
                      var westDistance = distances[newIndex][oldIndex - 1] === undefined ? Number.MAX_VALUE : distances[newIndex][oldIndex - 1] + 1;
                      distances[newIndex][oldIndex] = Math.min(northDistance, westDistance);
                  }
              }
          }
  
          return distances;
      }
  
      function findEditScriptFromEditDistanceMatrix(editDistanceMatrix, oldArray, newArray) {
          var oldIndex = oldArray.length;
          var newIndex = newArray.length;
          var editScript = [];
          var maxDistance = editDistanceMatrix[newIndex][oldIndex];
          if (maxDistance === undefined)
              return null; // maxAllowedDistance must be too small
          while ((oldIndex > 0) || (newIndex > 0)) {
              var me = editDistanceMatrix[newIndex][oldIndex];
              var distanceViaAdd = (newIndex > 0) ? editDistanceMatrix[newIndex - 1][oldIndex] : maxDistance + 1;
              var distanceViaDelete = (oldIndex > 0) ? editDistanceMatrix[newIndex][oldIndex - 1] : maxDistance + 1;
              var distanceViaRetain = (newIndex > 0) && (oldIndex > 0) ? editDistanceMatrix[newIndex - 1][oldIndex - 1] : maxDistance + 1;
              if ((distanceViaAdd === undefined) || (distanceViaAdd < me - 1)) distanceViaAdd = maxDistance + 1;
              if ((distanceViaDelete === undefined) || (distanceViaDelete < me - 1)) distanceViaDelete = maxDistance + 1;
              if (distanceViaRetain < me - 1) distanceViaRetain = maxDistance + 1;
  
              if ((distanceViaAdd <= distanceViaDelete) && (distanceViaAdd < distanceViaRetain)) {
                  editScript.push({ status: "added", value: newArray[newIndex - 1] });
                  newIndex--;
              } else if ((distanceViaDelete < distanceViaAdd) && (distanceViaDelete < distanceViaRetain)) {
                  editScript.push({ status: "deleted", value: oldArray[oldIndex - 1] });
                  oldIndex--;
              } else {
                  editScript.push({ status: "retained", value: oldArray[oldIndex - 1] });
                  newIndex--;
                  oldIndex--;
              }
          }
          return editScript.reverse();
      }
  
      ko.utils.compareArrays = function (oldArray, newArray, maxEditsToConsider) {
          if (maxEditsToConsider === undefined) {
              return ko.utils.compareArrays(oldArray, newArray, 1)                 // First consider likely case where there is at most one edit (very fast)
                  || ko.utils.compareArrays(oldArray, newArray, 10)                // If that fails, account for a fair number of changes while still being fast
                  || ko.utils.compareArrays(oldArray, newArray, Number.MAX_VALUE); // Ultimately give the right answer, even though it may take a long time
          } else {
              oldArray = oldArray || [];
              newArray = newArray || [];
              var editDistanceMatrix = calculateEditDistanceMatrix(oldArray, newArray, maxEditsToConsider);
              return findEditScriptFromEditDistanceMatrix(editDistanceMatrix, oldArray, newArray);
          }
      };    
  })();
  
  ko.exportSymbol('ko.utils.compareArrays', ko.utils.compareArrays);
  