whole_func_string: function partiallyDiffText(a,b){
  	if(b.length >= a.length){
  		for(var i=0;i<a.length;++i){
  			if(a[i] !== b[i]) break
  		}
  		var fi = i
  		
  		if(fi === a.length){
  			return {type: 'add', index: fi, value: b.substr(fi)}
  		}else{
  
  			var ea = a.substr(fi)
  			var eb = b.substr(fi)
  		
  			for(var i=0;i<ea.length;++i){
  				if(ea[ea.length-i-1] !== eb[eb.length-i-1]){
  					break
  				}
  			}
  
  			var tailLength = i
  			
  			if(b.length-tailLength-fi > b.length-a.length){//if the changed region is larger than the difference in length	
  				var manyToRemove = (b.length-tailLength-fi)-(b.length-a.length)
  				return {type: 'remove', index: fi, many: manyToRemove}
  			}else{
  				return {type: 'add', index: fi, value: b.substring(fi,b.length-tailLength)}
  			}
  		}
  	}else{
  		var c = partiallyDiffText(b,a)
  		if(c.type === 'remove'){
  			return {type: 'add', index: c.index, value: b.substr(c.index,c.many)}
  		}else{
  			return {type: 'remove', index: c.index, many: c.value.length}
  		}
  	}
  }
func_code_string: function partiallyDiffText(a,b){
  	if(b.length >= a.length){
  		for(var i=0;i<a.length;++i){
  			if(a[i] !== b[i]) break
  		}
  		var fi = i
  		
  		if(fi === a.length){
  			return {type: 'add', index: fi, value: b.substr(fi)}
  		}else{
  
  			var ea = a.substr(fi)
  			var eb = b.substr(fi)
  		
  			for(var i=0;i<ea.length;++i){
  				if(ea[ea.length-i-1] !== eb[eb.length-i-1]){
  					break
  				}
  			}
  
  			var tailLength = i
  			
  			if(b.length-tailLength-fi > b.length-a.length){//if the changed region is larger than the difference in length	
  				var manyToRemove = (b.length-tailLength-fi)-(b.length-a.length)
  				return {type: 'remove', index: fi, many: manyToRemove}
  			}else{
  				return {type: 'add', index: fi, value: b.substring(fi,b.length-tailLength)}
  			}
  		}
  	}else{
  		var c = partiallyDiffText(b,a)
  		if(c.type === 'remove'){
  			return {type: 'add', index: c.index, value: b.substr(c.index,c.many)}
  		}else{
  			return {type: 'remove', index: c.index, many: c.value.length}
  		}
  	}
  }
func_documentation_string: produces a *partial* update - call and apply repeatedly until a===b to get all the changes