<commit_before>(function() {
	'use strict';

	var T = window.Touche = {},
		abs = Math.abs,
		sqrt = Math.sqrt,
		pow = Math.pow,
		atan2 = Math.atan2,
		PI = Math.PI,
		sortExpando = 9,
		getSortKey = function() {
			return 5 * (++sortExpando);
		},
		doc = window.document,
		touch = ('ontouchstart' in window),
		events = {
			start: touch ? 'touchstart' : 'mousedown',
			move: touch ? 'touchmove' : 'mousemove',
			end: touch ? 'touchend' : 'mouseup'
		};

	T.utils = {
		logger: function(event, touchList) {
			if(!event.touches) return;
			touchList = touchList || 'touches';

			var str = "",
				i, len = event[touchList].length;

			str += "touches: " + len;

			for(i = 0; i < len; ++i) {
				str += " x:" + event.touches[i].pageX + " y:" + event.touches[i].pageY;
			}

			window.console.log(str);
		},
		isFunction: function(f) {
			return Object.prototype.toString.call(f) === '[object Function]';
		},
		isArray: function(a) {
			return Array.isArray(a);
		},
		isObject: function(o) {
			return Object.prototype.toString.call(o) === '[object Object]';
		},
		extend: function(src1, src2) {
			var key, val, i;

			if(!src2) {
				return src1;
			}

			for (key in src2) {
				val = src2[key];
				if (this.isArray(val)) {
					src1[key] = this.isArray(src1[key]) ? src1[key] : [];
					for (i = 0; i < val.length; i++) {
						this.extend(src1[key][i], val[i]);
					}
				} else if (this.isFunction(val)) {
					// we probably need something better here,
					// but it works for normal usecases
					/*jshint loopfunc: true*/
					(function() {
						var fn = val;
						src1[key] = function() {
							fn.apply(this, arguments);
						};
					})();
				} else if (this.isObject(val)) {
					this.extend((src1[key] = src1[key] || {}), val);
				} else {
					// assume we can reuse the value straight up
					src1[key] = src2[key];
				}
			}

			return src1;
		},
		getAngle: function(startPoint, currentPoint) {
			var x = startPoint.x - currentPoint.x,
				y = startPoint.y - currentPoint.y,
				theta = atan2(y, x),
				degrees = theta * 180 / PI;
			degrees = degrees < 0 ? 360 + degrees : degrees;
			return degrees;
		},
		getDeltaAngle: function(startPoint, currentPoint) {
			var x = currentPoint.x - startPoint.x,
				y = currentPoint.y - startPoint.y,
				theta = atan2(y, x),
				degrees = theta * 180 / PI;
			return degrees;
		},
		getDirection: function(degrees) {
			return((degrees >= 0 && degrees < 45) || (degrees >= 315)) ? 'right' : (degrees >= 45 && degrees < 135) ? 'down' : (degrees >= 135 && degrees < 225) ? 'left' : (degrees >= 225 && degrees < 315) ? 'up' : 'invalid';
		},
		getVelocity: function(startPoint, currentPoint, startTime, currentTime) {
			var dist = startPoint.distanceTo(currentPoint),<commit_msg>Fix bug in `utils#getDirection`<commit_after>(function() {
	'use strict';

	var T = window.Touche = {},
		abs = Math.abs,
		sqrt = Math.sqrt,
		pow = Math.pow,
		atan2 = Math.atan2,
		PI = Math.PI,
		sortExpando = 9,
		getSortKey = function() {
			return 5 * (++sortExpando);
		},
		doc = window.document,
		touch = ('ontouchstart' in window),
		events = {
			start: touch ? 'touchstart' : 'mousedown',
			move: touch ? 'touchmove' : 'mousemove',
			end: touch ? 'touchend' : 'mouseup'
		};

	T.utils = {
		logger: function(event, touchList) {
			if(!event.touches) return;
			touchList = touchList || 'touches';

			var str = "",
				i, len = event[touchList].length;

			str += "touches: " + len;

			for(i = 0; i < len; ++i) {
				str += " x:" + event.touches[i].pageX + " y:" + event.touches[i].pageY;
			}

			window.console.log(str);
		},
		isFunction: function(f) {
			return Object.prototype.toString.call(f) === '[object Function]';
		},
		isArray: function(a) {
			return Array.isArray(a);
		},
		isObject: function(o) {
			return Object.prototype.toString.call(o) === '[object Object]';
		},
		extend: function(src1, src2) {
			var key, val, i;

			if(!src2) {
				return src1;
			}

			for (key in src2) {
				val = src2[key];
				if (this.isArray(val)) {
					src1[key] = this.isArray(src1[key]) ? src1[key] : [];
					for (i = 0; i < val.length; i++) {
						this.extend(src1[key][i], val[i]);
					}
				} else if (this.isFunction(val)) {
					// we probably need something better here,
					// but it works for normal usecases
					/*jshint loopfunc: true*/
					(function() {
						var fn = val;
						src1[key] = function() {
							fn.apply(this, arguments);
						};
					})();
				} else if (this.isObject(val)) {
					this.extend((src1[key] = src1[key] || {}), val);
				} else {
					// assume we can reuse the value straight up
					src1[key] = src2[key];
				}
			}

			return src1;
		},
		getAngle: function(startPoint, currentPoint) {
			var x = startPoint.x - currentPoint.x,
				y = startPoint.y - currentPoint.y,
				theta = atan2(y, x),
				degrees = theta * 180 / PI;
			degrees = degrees < 0 ? 360 + degrees : degrees;
			return degrees;
		},
		getDeltaAngle: function(startPoint, currentPoint) {
			var x = currentPoint.x - startPoint.x,
				y = currentPoint.y - startPoint.y,
				theta = atan2(y, x),
				degrees = theta * 180 / PI;
			return degrees;
		},
		getDirection: function(degrees) {
			return((degrees >= 0 && degrees < 45) || (degrees >= 315 && degrees <= 360)) ? 'right' : (degrees >= 45 && degrees < 135) ? 'down' : (degrees >= 135 && degrees < 225) ? 'left' : (degrees >= 225 && degrees < 315) ? 'up' : 'invalid';
		},
		getVelocity: function(startPoint, currentPoint, startTime, currentTime) {
			var dist = startPoint.distanceTo(currentPoint),
{'fraction_non_alphanumeric': 0.17345100864553314, 'fraction_numerical': 0.021073487031700287, 'mean_word_length': 2.7878581173260573, 'pattern_counts': {'":': 0, '<': 18, '<?xml version=': 0, '>': 13, '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': '4687528', 'n_tokens_mistral': 2488, 'n_tokens_neox': 1998, 'n_words': 478}