:: UtilJS [script]

if(!Array.prototype.findIndex) {
	Array.prototype.findIndex = function(predicate) {
		if (this == null) {
			throw new TypeError('Array.prototype.find called on null or undefined');
		}
		if (typeof predicate !== 'function') {
			throw new TypeError('predicate must be a function');
		}
		var list = Object(this);
		var length = list.length >>> 0;
		var thisArg = arguments[1];
		var value;

		for (var i = 0; i < length; i++) {
			value = list[i];
			if (predicate.call(thisArg, value, i, list)) {
				return i;
			}
		}
		return -1;
	};
};

/*
A categorizer is used to "slice" a value range into distinct categories in an efficient manner.

--- Example ---
Original SugarCube code
<<if _Slave.muscles > 95>>
	Musc++
<<elseif _Slave.muscles > 30>>
	Musc+
<<elseif _Slave.muscles > 5>>
	Toned
<<elseif _Slave.muscles > -6>>
<<elseif _Slave.muscles > -31>>
	@@color:red;weak@@
<<elseif _Slave.muscles > -96>>
	@@color:red;weak+@@
<<else>>
	@@color:red;weak++@@
<</if>>

As a categorizer
<<if ndef $cats>><<set $cats = {}>><</if>>
<<if ndef $cats.muscleCat>>
	<!-- This only gets set once, skipping much of the code evaluation, and can be set outside of the code in an "init" passage for further optimization -->
	<<set $cats.muscleCat = new Categorizer([96, 'Musc++'], [31, 'Musc+'], [6, 'Toned'], [-5, ''], [-30, '@@color:red;weak@@'], [-95, '@@color:red;weak+@@'], [-Infinity, '@@color:red;weak++@@'])>>
<</if>>
<<print $cats.muscleCat.cat(_Slave.muscles)>>
*/
window.Categorizer = function() {
	this.cats = Array.prototype.slice.call(arguments)
		.filter(function(e, i, a) {
			return e instanceof Array && e.length == 2 && typeof e[0] === 'number' && !isNaN(e[0])
				&& a.findIndex(function(val) { return e[0] === val[0]; }) === i; /* uniqueness test */ })
		.sort(function(a, b) { return b[0] - a[0]; /* reverse sort */ });
};
window.Categorizer.prototype.cat = function(val, def) {
	if(typeof val !== 'number' || isNaN(val)) {
		return def;
	}
	var result = this.cats.find(function(e) { return val >= e[0]; });
	return result ? result[1] : def;
};

src/js/utilJS.tw