(function($) {
	function toIntegersAtLease(n) {
		return n < 10 ? '0' + n : n;
	}
	Date.prototype.toJSON = function(date) {
		return date.getUTCFullYear() + '-'
				+ toIntegersAtLease(date.getUTCMonth() + 1) + '-'
				+ toIntegersAtLease(date.getUTCDate());
	};
	var escapeable = /["\\\x00-\x1f\x7f-\x9f]/g;
	var meta = {
		'\b' : '\\b',
		'\t' : '\\t',
		'\n' : '\\n',
		'\f' : '\\f',
		'\r' : '\\r',
		'"' : '\\"',
		'\\' : '\\\\'
	}
	$.quoteString = function(string) {
		if (escapeable.test(string)) {
			return '"' + string.replace(escapeable, function(a) {
						var c = meta[a];
						if (typeof c === 'string') {
							return c;
						}
						c = a.charCodeAt();
						return '\\u00' + Math.floor(c / 16).toString(16)
								+ (c % 16).toString(16);
					}) + '"'
		}
		return '"' + string + '"';
	}
	$.toJSON = function(o, compact) {
		var type = typeof(o);
		if (type == "undefined")
			return "undefined";
		else if (type == "number" || type == "boolean")
			return o + "";
		else if (o === null)
			return "null";
		if (type == "string") {
			return $.quoteString(o);
		}
		if (type == "object" && typeof o.toJSON == "function")
			return o.toJSON(compact);
		if (type != "function" && typeof(o.length) == "number") {
			var ret = [];
			for (var i = 0; i < o.length; i++) {
				ret.push($.toJSON(o[i], compact));
			}
			if (compact)
				return "[" + ret.join(",") + "]";
			else
				return "[" + ret.join(", ") + "]";
		}
		if (type == "function") {
			throw new TypeError("Unable to convert object of type 'function' to json.");
		}
		ret = [];
		for (var k in o) {
			var name;
			var type = typeof(k);
			if (type == "number")
				name = '"' + k + '"';
			else if (type == "string")
				name = $.quoteString(k);
			else
				continue;
			val = $.toJSON(o[k], compact);
			if (typeof(val) != "string") {
				continue;
			}
			if (compact)
				ret.push(name + ":" + val);
			else
				ret.push(name + ": " + val);
		}
		return "{" + ret.join(", ") + "}";
	}
	$.compactJSON = function(o) {
		return $.toJSON(o, true);
	}
	$.evalJSON = function(src) {
		return eval("(" + src + ")");
	}
	$.secureEvalJSON = function(src) {
		var filtered = src;
		filtered = filtered.replace(/\\["\\\/bfnrtu]/g, '@');
		filtered = filtered
				.replace(
						/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,
						']');
		filtered = filtered.replace(/(?:^|:|,)(?:\s*\[)+/g, '');
		if (/^[\],:{}\s]*$/.test(filtered))
			return eval("(" + src + ")");
		else
			throw new SyntaxError("Error parsing JSON, source is not valid.");
	}
})(jQuery);
