Tomato.js

/***
 * Source: http://www.tomatousb.org/
 */

var cookie = {
	// The value 2147483647000 is ((2^31)-1)*1000, which is the number of
	// milliseconds (minus 1 second) which correlates with the year 2038 counter
	// rollover. This effectively makes the cookie never expire.
	set: function(key, value, days) {
		document.cookie = 'tomato_' + encodeURIComponent(key) + '=' + encodeURIComponent(value) + '; expires=' +
			new Date(2147483647000).toUTCString() + '; path=/';
	},
	get: function(key) {
		var r = ('; ' + document.cookie + ';').match('; tomato_' + encodeURIComponent(key) + '=(.*?);');
		return r ? decodeURIComponent(r[1]) : null;
	},
	unset: function(key) {
		document.cookie = 'tomato_' + encodeURIComponent(key) + '=; expires=' +
			(new Date(1)).toUTCString() + '; path=/';
	}
};

function escapeHTML(s) {
	function esc(c) {
		return '&#' + c.charCodeAt(0) + ';';
	}
	return s.replace(/[&"'<>\r\n]/g, esc);
}

function escapeCGI(s) {
	return escape(s).replace(/\+/g, '%2B'); // escape() doesn't handle +
}

function escapeD(s) {
	function esc(c) {
		return '%' + c.charCodeAt(0).hex(2);
	}
	return s.replace(/[<>|%]/g, esc);
}

function ellipsis(s, max) {
	return (s.length <= max) ? s : s.substr(0, max - 3) + '...';
}

function MIN(a, b) {
	return (a < b) ? a : b;
}

function MAX(a, b) {
	return (a > b) ? a : b;
}

function fixInt(n, min, max, def) {
	if(n === null) {
		return def;
	}
	n *= 1;
	if(isNaN(n)) {
		return def;
	}
	if(n < min) {
		return min;
	}
	if(n > max) {
		return max;
	}
	return n;
}

function comma(n) {
	n = '' + n;
	var p = n;
	while((n = n.replace(/(\d+)(\d{3})/g, '$1,$2')) != p) {
		p = n;
	}
	return n;
}

function doScaleSize(n, sm) {
	if(isNaN(n *= 1)) {
		return '-';
	}
	if(n <= 9999) {
		return '' + n;
	}
	var s = -1;
	do {
		n /= 1024;
		++s;
	} while((n > 9999) && (s < 2));
	return comma(n.toFixed(2)) + (sm ? '<small> ' : ' ') + (['KB', 'MB', 'GB'])[s] + (sm ? '</small>' : '');
}

function scaleSize(n) {
	return doScaleSize(n, 1);
}

function timeString(mins) {
	var h = Math.floor(mins / 60);
	if((new Date(2000, 0, 1, 23, 0, 0, 0)).toLocaleString().indexOf('23') != -1) {
		return h + ':' + (mins % 60).pad(2);
	}
	return ((h == 0) ? 12 : ((h > 12) ? h - 12 : h)) + ':' + (mins % 60).pad(2) + ((h >= 12) ? ' PM' : ' AM');
}