<commit_before>
<html>
<script type='text/javascript' src='underscore.js'></script>
<script type='text/javascript'>

if (!_)
	throw {name:'RequiresException', message:'Requires underscore.js'};


// Perhaps the '.__' prefix can be changed to a random string, unique per
// page load.

Model = (function()
{
	// NOTE: These can be individual per Handle.  Why did I do it this way?
	var listeners = {};
	
	var special = {
		delete:{}
	};
	
	// NOTE: Playing around with another private var.
	var onEvent = function(handle,eventName,func,args)
	{
		listeners[handle.__id][eventName].push({func:func,args:args});
	};
	
	var offEvent = function(handle,eventName,func)
	{
		var events = listeners[handle.__id][eventName]
		var funcs = events.map(function(a){return a.func});
		
		var index = funcs.indexOf(func);
		
		console.log(index,funcs);
		
		if (index >= 0)
			listeners[handle.__id][eventName].splice(index,1);
		
		return index >= 0;
	};
	
	// NOTE: I want these Handle objects to remain *independent* of Model
	//   instances, though...  Will think through, later.
	function Handle(ob)
	{
		var self = this;
		var handle = this;
		
		// ob effectively holds a mirror copy of... everthing.  There's a reason I'm
		// using it, and testing has revealed that reason as valid.  But exactly what
		// is that reason...?  Was it the leaf node Handles?
		ob = (typeof ob === 'object' ?
				(Array.isArray(ob) ? ob.slice() : _.extend({},ob)): ob)
		
		Object.defineProperty(this,'__id',{
			enumerable:false,
			configurable:false,
			writable:false,
			value:_.uniqueId()
		});
		
		// Add listeners entry, with arrays of event callbacks.
		listeners[this.__id] = {change:[],delete:[],all:[]};
		
		Object.defineProperty(this,'$on',{
			enumerable:false,
			configurable:false,
			value:function(eventName,func,args)
			{ onEvent(self,eventName,func,args); }
		});
		
		Object.defineProperty(this,'$off',{
			enumerable:false,
			configurable:false,
			value:function(eventName,func)
			{
				return offEvent(self,eventName,func);
			}
		});
		
		Object.defineProperty(this,'$',{
			enumerable:false,
			configurable:false,
			get:function()
			{
				if (typeof ob !== 'object')
					return ob;
				
				var ret = (Array.isArray(ob) ? [] : {});
				for (var p in ob)
					ret[p] = ob[p].$;
				return ret;
			}
		});
		
		//console.log('Handle('+ob+')',self.__id);
		
		if (typeof ob === 'object')
		for (var p in ob)
		{
			//ob[p] = (typeof ob[p] === 'object' ? new Handle(ob[p]) : ob[p]);
			ob[p] = new Handle(ob[p]);
			ob[p].__parent = this;
			
			Object.defineProperty(this,p,{
				enumerable:true,
				configurable:false,
				get:(function(k){return function(){return ob[k]}})(p),
				set:(function(k){return function(val)
				{
					var oldHandle = ob[k];
					var newHandle;
					
					if (val == special.delete)
					{
						// NOTE: Deletion needs to go somewhere more accissible.
						
						listeners[oldHandle.__id].delete.map(function(action)
						{
							action.func(oldHandle.$);
						});
						
						listeners[oldHandle.__id].all.map(function(action)
						{
							action.func('delete',[oldHandle.$]);
						});
						
						// NOTE: WAAAAIT!
						//   This must recurse.  It needs to recurse.
						//   Or does it?  What if something else is using these?
						for (var x in oldHandle)
							if (oldHandle[x] instanceof Handle)
								oldHandle[x] = special.delete;
						
						// Remove events from listeners object.
						delete listeners[oldHandle.__id];
						delete ob[k];
						delete self[k];
						return;
					}
					
					newHandle = (val instanceof Handle ? val : new Handle(val));
					ob[k] = newHandle;
					
					if (typeof val !== 'object')
						newHandle.valueOf = function()
						{ console.log('val?',val); return val };
					
					// Modify listeners object.
					// - Copy oldHandle's listeners over to newHandle's.
					// - Remove oldHandle's listeners. 
					_.extend(listeners[newHandle.__id],listeners[oldHandle.__id]);
					delete listeners[oldHandle.__id];
					
					// Run change event listeners.
					listeners[ob[k].__id].change.map(function(action)
					{
						action.func(val,oldHandle.$,action.args);
					});
					
					// Run 'all' event listeners.<commit_msg>Added  function to Handle trees (but not root)<commit_after>
<html>
<script type='text/javascript' src='underscore.js'></script>
<script type='text/javascript'>

if (!_)
	throw {name:'RequiresException', message:'Requires underscore.js'};


// Perhaps the '.__' prefix can be changed to a random string, unique per
// page load.

Model = (function()
{
	// NOTE: These can be individual per Handle.  Why did I do it this way?
	var listeners = {};
	
	var special = {
		delete:{}
	};
	
	// NOTE: Playing around with another private var.
	var onEvent = function(handle,eventName,func,args)
	{
		listeners[handle.__id][eventName].push({func:func,args:args});
	};
	
	var offEvent = function(handle,eventName,func)
	{
		var events = listeners[handle.__id][eventName]
		var funcs = events.map(function(a){return a.func});
		
		var index = funcs.indexOf(func);
		
		console.log(index,funcs);
		
		if (index >= 0)
			listeners[handle.__id][eventName].splice(index,1);
		
		return index >= 0;
	};
	
	// NOTE: I want these Handle objects to remain *independent* of Model
	//   instances, though...  Will think through, later.
	function Handle(ob)
	{
		var self = this;
		var handle = this;
		
		// ob effectively holds a mirror copy of... everthing.  There's a reason I'm
		// using it, and testing has revealed that reason as valid.  But exactly what
		// is that reason...?  Was it the leaf node Handles?
		ob = (typeof ob === 'object' ?
				(Array.isArray(ob) ? ob.slice() : _.extend({},ob)): ob)
		
		Object.defineProperty(this,'__id',{
			enumerable:false,
			configurable:false,
			writable:false,
			value:_.uniqueId()
		});
		
		// Add listeners entry, with arrays of event callbacks.
		listeners[this.__id] = {change:[],delete:[],all:[]};
		
		Object.defineProperty(this,'$on',{
			enumerable:false,
			configurable:false,
			value:function(eventName,func,args)
			{ onEvent(self,eventName,func,args); }
		});
		
		Object.defineProperty(this,'$off',{
			enumerable:false,
			configurable:false,
			value:function(eventName,func)
			{
				return offEvent(self,eventName,func);
			}
		});
		
		Object.defineProperty(this,'$',{
			enumerable:false,
			configurable:false,
			get:function()
			{
				if (typeof ob !== 'object')
					return ob;
				
				var ret = (Array.isArray(ob) ? [] : {});
				for (var p in ob)
					ret[p] = ob[p].$;
				return ret;
			}
		});
		
		//console.log('Handle('+ob+')',self.__id);
		
		if (typeof ob === 'object')
		for (var p in ob)
		{
			//ob[p] = (typeof ob[p] === 'object' ? new Handle(ob[p]) : ob[p]);
			ob[p] = new Handle(ob[p]);
			ob[p].__parent = this;
			
			// NOTE: Put this here for private access to its parent while
			//   retaining its given property name.
			Object.defineProperty(ob[p],'$delete',{
				enumerable:false,
				configurable:false,
				value:(function(k){return function()
				{
					console.log('special.delete',self,k,special.delete);
					console.log('              ',self[k],special.delete);
					self[k] = special.delete;
				}})(p)
			});
			
			Object.defineProperty(this,p,{
				enumerable:true,
				configurable:true,
				get:(function(k){return function(){return ob[k]}})(p),
				set:(function(k){return function(val)
				{
					var oldHandle = ob[k];
					var newHandle;
					
						console.log('Ragvagbag');
						
					if (val == special.delete)
					{
						// NOTE: Deletion needs to go somewhere more accissible.
						
						listeners[oldHandle.__id].delete.map(function(action)
						{
							action.func(oldHandle.$);
						});
						
						listeners[oldHandle.__id].all.map(function(action)
						{
							action.func('delete',[oldHandle.$]);
						});
						
						// NOTE: WAAAAIT!
						//   This must recurse.  It needs to recurse.
						//   Or does it?  What if something else is using these?
						/*
						for (var x in oldHandle)
							if (oldHandle[x] instanceof Handle)
								oldHandle[x] = special.delete;
						//*/
						
						console.log('deleting!',oldHandle,k);
						// Remove events from listeners object.
						delete listeners[oldHandle.__id];
						delete ob[k];
						delete self[k];
						console.log('still there?',console.log(ob));
						console.log(Object.getOwnPropertyNames(ob));
						return;
					}
					
					newHandle = (val instanceof Handle ? val : new Handle(val));
					ob[k] = newHandle;
					
					if (typeof val !== 'object')
						newHandle.valueOf = function()
						{ console.log('val?',val); return val };
					
					// Modify listeners object.
					// - Copy oldHandle's listeners over to newHandle's.
					// - Remove oldHandle's listeners. 
					_.extend(listeners[newHandle.__id],listeners[oldHandle.__id]);
					delete listeners[oldHandle.__id];
					
					// Run change event listeners.
					listeners[ob[k].__id].change.map(function(action)
					{
						action.func(val,oldHandle.$,action.args);
					});
					
					// Run 'all' event listeners.
{'fraction_non_alphanumeric': 0.15241023388602173, 'fraction_numerical': 0.0006588338640606127, 'mean_word_length': 2.787110187110187, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 15, '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': '2426862', 'n_tokens_mistral': 3821, 'n_tokens_neox': 2885, 'n_words': 696}