<commit_before>if(SUPPORT_EXPERIMENTAL) {

	var NODETYPE_COMMENT = 8;


	function findElementComments( element , comments) {
		if( !comments ) {
			comments = {};
		}

		var children;

		if( !element || !(children = element.childNodes) ) {
			return comments;
		} 

		if( element.nodeType == NODETYPE_COMMENT ){
			comments[element.data] = element.nextSibling;
		}

		for(var i = -1, l = children.length ; ++i < l; ) {
			findElementComments(children[i], comments);
		}

		return comments;
	}

    function tpl( render ){
    	
    	this.render = render;

    	this.update = function( element, variable, value ){
    		
    		if( USE_WITH === false ) {
    			variable = INPUT_VAR + "." + variable;
    		}

    		// jquery element can be passed
    		element = element.jquery ? element[0] : element;

    		var vars = findElementComments( element );

    		if( vars[variable] ) {
    			if( DEBUG ) {
    				vars[variable].data = Wzhik.v(value);
    			} else {
    				vars[variable].data = Wzhik.v(value);
    			}
    		}
    	}

    	this.observe = function( data, element ){
    		var self = this;
    		Object.observe(data, function(changes){
			    changes.forEach(function(change) {
			    	console.log(change.type, change.name, change.oldValue);
			        self.update( preview, change.name, data[change.name] );
			    });
			});
    	}
    }


    // Redefine
    function Wzhik(templateString, templateID){

		if(templateString.charAt(0) === "#"){
			templateID = templateString;
			if( DEBUG ) {
				var element = document.getElementById(templateString.substr(1));
				if( !element ) {
					console.error("The is no element with ID ", templateString);
				}

				templateString = element.innerHTML;

			} else {
				templateString = document.getElementById(templateString.substr(1)).innerHTML;
			}
		}

		!templateID && (templateID = ("t" + UID++));

		if(_cacheCompiledByTpl[templateString])
			return _cacheCompiledByTpl[templateString];

		if( DEBUG ) {
			console.group( "tpl: " + templateID );
		}

		var compiled = compileTemplateString(templateString, templateID);

		if( DEBUG ) {
			console.groupEnd("tpl: " + templateID);
		}

		var fn = new tpl(new Function(INPUT_VAR, compiled));

		_cacheCompiledByTpl[templateString] = fn;

		if(templateID && !_cacheCompiled[templateID]){
			// _cacheCompiled[templateID] = fn;
			_cacheCompiled[templateID] = compiled;
		}

		return fn;
    }	
	
}<commit_msg>experimental : node diff<commit_after>

//= "_vdom3.js"

function cloneObject(obj) {
    if(obj == null || typeof(obj) != 'object')
        return obj;

    var temp = obj.constructor(); // changed

    for(var key in obj) {
        if(obj.hasOwnProperty(key)) {
            temp[key] = cloneObject(obj[key]);
        }
    }
    return temp;
}


Template.prototype = {

    update : function( newData ) {

        // var self = this;
        // if(!this.olddata) {
        //     this.olddata = cloneObject(newData);
        // }
        // var dataDiffs = accumulateDiff(this.olddata, newData);
        // console.log( this.olddata, newData , dataDiffs );
        // dataDiffs && dataDiffs.length && Wzhik.each(dataDiffs, function(diff){
        //     diffApplyChange(self.olddata, {}, diff);
        // });

        var element = this.element;

        var tmp = element.cloneNode( false );
        tmp.innerHTML = this.render( newData );
        
        var tmpJSON = nodeToObj(tmp);
        var diffs = accumulateDiff( this.vdom, tmpJSON );

        if( !diffs || !diffs.length ) {
            return false;
        }

        // @todo 
        // Make groupping diffs by kind.
        // E.g. append documentfragment

        for( var diff, k = diffs.length; k--;){
            diff = diffs[k];
            // 
            // Apply change to virtual DOM object
            this.updateVDOM(diff);
            // 
            // Apply change to real DOM object
            applyNodeChange(element, diff, tmpJSON);
        }

    },

    'attach' : function( selector ){
    	this.element = $(selector || this.id)[0];
        return this;
    },

    'renderTo' : function( data ) {
    	this.element.innerHTML = this.render(data);
        this.updateVDOM();
    },

    diffs : [],

    updateVDOM : function( diff ){
        var self = this;
        if (diff ) {
            self.diffs.push( diff );
        }
        clearTimeout(this.t);
        self.t = setTimeout(function(){
            if( diff ) {
                var tmp;
                while( tmp = self.diffs.pop() ) {
                    diffApplyChange(self.vdom, {}, tmp);
                }
            } else {
                self.vdom = nodeToObj(self.element);   
            }
        }, 0);
    }
}
{'fraction_non_alphanumeric': 0.1353479463715684, 'fraction_numerical': 0.001915301127899553, 'mean_word_length': 2.020565552699229, 'pattern_counts': {'":': 0, '<': 4, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7114461', 'n_tokens_mistral': 1608, 'n_tokens_neox': 1458, 'n_words': 298}