<commit_before>////////////////////////////////////////////////////////////////////////////////
// Tag Control Base (Abstract)
////////////////////////////////////////////////////////////////////////////////
var controls = function (controls, $, services) {
	// tag collection
	controls.tags = function (names) {
		var separator = /\s*[^A-Za-z0-9:\s]+\s*/;
		
		return {
			// splits string along non-word parts
			split: function () {
				return names.split(separator);
			},
			// removes separators from string
			sanitize: function () {
				return names.replace(separator, '');
			}
		};
	};
	
	// - row: media data record
	// - handler: callback redrawing parent
	controls.tagbase = function (row) {
		var	base = controls.editable(),
				self = Object.create(base),
				i;

		// initializing tag lookup
		(function () {
			var siblings = row.tags;
			self.lookup = {};
			for (i = 0; i < siblings.length; i++) {
				self.lookup[siblings[i]] = true;
			}
		}());
		
		// gets key from a lookup table
		function keys(lookup) {
			var result = [],
					name;
			for (name in lookup) {
				result.push(name);
			}
			return result;
		}
		
		// changes tag to one or more tags
		// - before: value before change, either a string or null (insertion)
		// - after: value after change, comma separated string or null (deletion)
		self.changetag = function (before, after, row) {
			// deleting old tag if there was one
			if (before) {
				delete this.lookup[before];
			}
			// adding new value(s) to buffer
			var names, i;
			if (after) {
				names = controls.tags(after).split();
				for (i = 0; i < names.length; i++) {
					this.lookup[names[i]] = true;
				}
			}
			// finalizing changes
			row.tags = keys(this.lookup);
			this.parent.redraw();
		};
		
		return self;
	};
	
	return controls;
}(controls || {},
	jQuery,
	services);
<commit_msg>new tag kinds are instantly refreshed<commit_after>////////////////////////////////////////////////////////////////////////////////
// Tag Control Base (Abstract)
////////////////////////////////////////////////////////////////////////////////
var controls = function (controls, $, services, data) {
	// tag collection
	controls.tags = function (names) {
		var separator = /\s*[^A-Za-z0-9:\s]+\s*/;
		
		return {
			// splits string along non-word parts
			split: function () {
				return names.split(separator);
			},
			// removes separators from string
			sanitize: function () {
				return names.replace(separator, '');
			}
		};
	};
	
	// - row: media data record
	// - handler: callback redrawing parent
	controls.tagbase = function (row) {
		var	base = controls.editable(),
				self = Object.create(base),
				i;

		// initializing tag lookup
		(function () {
			var siblings = row.tags;
			self.lookup = {};
			for (i = 0; i < siblings.length; i++) {
				self.lookup[siblings[i]] = true;
			}
		}());
		
		// gets key from a lookup table
		function keys(lookup) {
			var result = [],
					name;
			for (name in lookup) {
				result.push(name);
			}
			return result;
		}
		
		// changes tag to one or more tags
		// - before: value before change, either a string or null (insertion)
		// - after: value after change, comma separated string or null (deletion)
		self.changetag = function (before, after, row) {
			var self = this,
					names, i;

			// deleting old tag if there was one
			if (before) {
				delete self.lookup[before];
			}
			// adding new value(s) to buffer
			if (after) {
				names = controls.tags(after).split();
				for (i = 0; i < names.length; i++) {
					self.lookup[names[i]] = true;
				}
			}
			// finalizing changes
			row.tags = keys(this.lookup);
			
			// refreshing kinds
			data.kinds.init(function () {
				self.parent.redraw();
				controls.kinds.redraw();
			});
		};
		
		return self;
	};
	
	return controls;
}(controls || {},
	jQuery,
	services,
	data);

{'fraction_non_alphanumeric': 0.21760581667099455, 'fraction_numerical': 0.002077382498052454, 'mean_word_length': 1.9049773755656108, 'pattern_counts': {'":': 0, '<': 7, '<?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': '5800487', 'n_tokens_mistral': 1419, 'n_tokens_neox': 1139, 'n_words': 337}