	// If not built-in.
if (!Array.prototype.indexOf) {
	Array.prototype.indexOf = function(x) {
		for (var i=0; i<this.length; i++) {
			if (this[i] == x) {
				return i;
			}
		}
		return -1;
	};
}
if (!Array.prototype.lastIndexOf) {
	Array.prototype.lastIndexOf = function(x) {
		for (var i=this.length-1; i>0; i++) {
			if (this[i] == x) {
				return i;
			}
		}
		return -1;
	};
}
if (!Array.prototype.map) {
	Array.prototype.map = function(f) {
		var o = new Array(this.length);
		for (var i=0; i<this.length; i++) {
			o[i] = f(this[i], i, this);
		}
		return o;
	};
}
if (!Array.prototype.filter) {
	Array.prototype.filter = function(f) {
		var o = [];
		for (var i=0; i<this.length; i++) {
			if (f(this[i], i, this)) {
				o.push(this[i]);
			}
		}
		return o;
	};
}
if (!Array.prototype.forEach) {
	Array.prototype.forEach = function(f) {
		for (var i=0; i<this.length; i++) {
			if (typeof(this[i]) !== 'undefined') {
				f(this[i], i, this);
			}
		}
	};
}
if (!Array.prototype.every) {
	Array.prototype.every = function(f) {
		for (var i=0; i<this.length; i++) {
			if (!f(this[i], i, this)) {
				return false;
			}
		}
		return true;
	};
}
if (!Array.prototype.some) {
	Array.prototype.some = function(f) {
		for (var i=0; i<this.length; i++) {
			if (f(this[i], i, this)) {
				return true;
			}
		}
		return false;
	};
}
if (!Array.prototype.reduce) {
	Array.prototype.reduce = function(f) {
		if (this.length == 1) {
			return this[0];
		} else {
			return f(this[0], this.slice(1).reduce(f));
		}
	};
}
if (!Array.prototype.reduceRight) {
	Array.prototype.reduceRight = function(f) {
		if (this.length == 1) {
			return this[0];
		} else {
			return f(this.slice(0, this.length-1).reduceRight(f),
					this[this.length-1]);
		}
	};
}

	// Custom.
if (!Array.prototype.rotate) {
	Array.prototype.rotate = function(n) {
		if (n === 0)
			return this.copy();
		
		if (typeof(n) == 'undefined') {
			n = 1;
		} else {
			n %= this.length;
		}
		return this.slice(this.length-n, this.length).
				concat(this.slice(0, this.length-n));
	};
}
if (!Array.prototype.copy) {
	Array.prototype.copy = function() {
		return this.slice(0);
	};
}
if (!Array.prototype.multiply) {
	Array.prototype.multiply = function(n) {
		if (typeof(n) == 'undefined') n = 1;
		var o = [];
		
		for (var i=0; i<n; i++) {
			o.push(this.copy());
		}
		return o;
	};
}
if (!Array.prototype.square) {
	Array.prototype.square = function() {
		return this.multiply(this.length);
	};
}
if (!Array.prototype.mapDeep) {
	Array.prototype.mapDeep = function(cb) {
		var o = [];
		for (var i=0; i<this.length; i++) {
			if (typeof(this[i]) == 'object' && this[i] != null &&
					this[i] instanceof Array) {
				o.push(this[i].mapDeep(cb));
			} else {
				o.push(cb(this[i], i, this));
			}
		}
		return o;
	};
}
if (!Array.prototype.zip) {
	Array.prototype.zip = function(other, cb) {
		if (typeof(cb) == 'undefined') {
			cb = function(a, b) {return [a, b]};
		}
		
		if (typeof(other) != 'object' || other == null || !(other
				instanceof Array) || this.length != other.length) {
			throw new TypeError();
		} else {
			var o = new Array(this.length);
			for (var i=0; i<this.length; i++) {
				o[i] = cb(this[i], other[i], i, this, other);
			}
			return o;
		}
	};
}
if (!Array.prototype.inner) {
	Array.prototype.inner = function(other, cb, cb2) {
		if (typeof(cb) == 'undefined') {
			cb = function(a, b) {return a*b};
		}
		if (typeof(cb2) == 'undefined') {
			cb2 = function(a, b) {return a+b};
		}
		
		return this.zip(other, cb).reduce(cb2);
	};
}
if (!Array.prototype.outer) {
	Array.prototype.outer = function(other, cb) {
		if (typeof(other) != 'object' || other == null ||
				!(other instanceof Array)) {
			throw new TypeError();
		} else {
			var o = new Array(this.length);
			for (var i=0; i<this.length; i++) {
				o[i] = new Array(other.length);
				for (var j=0; j<other.length; j++) {
					o[i][j] = cb(this[i], other[j], i, j, this, other);
				}
			}
			return o;
		}
	};
}
if (!Array.prototype.wrap) {
	Array.prototype.wrap = function(n) {
		if (typeof(n) == 'undefined') n = 1;
		var c = this.copy(), o = [];
		while (c.length > 0) {
			var t = [];
			for (var i=0; i<n && c.length>0; i++)
				t.push(c.shift());
			o.push(t);
		}
		return o;
	};
}
if (!Array.prototype.permute) {
	Array.prototype.permute = function() {
		var ks = [], vs = [];
		for (var i=0; i<this.length; i++) {
			if (ks.indexOf(this[i]) >= 0) {
				vs[ks.indexOf(this[i])]++;
			} else {
				ks.push(this[i]);
				vs.push(1);
			}
		}
		
		function internalPermute(keys, vals) {
			if (keys.length == 1) {
				var o = [];
				for (var i=0; i<vals[0]; i++) {
					o.push(keys[0]);
				}
				return [o];
			} else {
				var o = [];
				for (var i=0; i<keys.length; i++) {
					var vali = vals.copy();
					var keyi = keys.copy();
					if (vals[i] == 1) {
						vali.splice(i, 1);
						keyi.splice(i, 1);
					} else {
						vali[i]--;
					}
					var perms = internalPermute(keyi, vali);
					o = o.concat(perms.map(function(a) {
						return [keys[i]].concat(a);
					}));
				}
				return o;
			}
		};
		
		return internalPermute(ks, vs);
	};
}
if (!Array.prototype.padBefore) {
	Array.prototype.padBefore = function(pad, n) {
		var o = [];
		for (var i=0; i<this.length; i++) {
			if (typeof(this[i]) != 'object' || this[i] == null ||
					!(this[i] instanceof Array)) {
				throw new TypeError();
			} else {
				var p = Array.range(n - this[i].length).map(function() {
					return pad;
				});
				o.push(p.concat(this[i]));
			}
		}
		return o;
	}
}
if (!Array.prototype.interchange) {
	Array.prototype.interchange = function(v, n) {
		var i = 0;
		return this.copy().map(function(a) {
			if (a == v) {
				return n[i++];
			} else {
				return a;
			}
		});
	};
}
if (!Array.prototype.interchangeDeep) {
	Array.prototype.interchangeDeep = function(v, n) {
		var i = 0;
		return this.copy().mapDeep(function(a) {
			if (a == v) {
				return n[i++];
			} else {
				return a;
			}
		});
	};
}
if (!Array.prototype.count) {
	Array.prototype.count = function(e) {
		return this.filter(function(a) {return a==e}).length;
	};
}
if (!Array.prototype.asSet) {
	Array.prototype.asSet = function() {
		var o = [];
		for (var i=0; i<this.length; i++) {
			if (o.realIndexOf(this[i]) == -1)
				o.push(this[i]);
		}
		return o;
	};
}
if (!Array.prototype.union) {
	Array.prototype.union = function(other) {
		return this.concat(other).asSet();
	};
}
if (!Array.prototype.intersect) {
	Array.prototype.intersect = function(other) {
		var o = [];
		for (var i=0; i<this.length; i++) {
			if (other.indexOf(this[i]) != -1)
				o.push(this[i]);
		}
		return o;
	};
}
if (!Array.prototype.sans) {
	Array.prototype.sans = function(arr) {
		return this.filter(function(a) {
			return arr.realIndexOf(a) == -1;
		});
	};
}
if (!Array.prototype.similarTo) {
	Array.prototype.similarTo = function(other) {
		if (this.length != other.length) {
			return false;
		} else {
			for (var i=0; i<this.length; i++) {
				if (typeof(this[i]) == 'object' && this[i] != null &&
						this[i] instanceof Array) {
					if (!this[i].similarTo(other[i]))
						return false;
				} else {
					if (this[i] != other[i])
						return false;
				}
			}
			return true;
		}
	};
}
if (!Array.prototype.realIndexOf) {
	Array.prototype.realIndexOf = function(el) {
		if (typeof(el) == 'object' && el != null && el instanceof Array) {
			for (var i=0; i<this.length; i++) {
				if (this[i].similarTo(el))
					return i;
			}
			return -1;
		} else {
			return this.indexOf(el);
		}
	};
}
if (!Array.prototype.flatten) {
	Array.prototype.flatten = function() {
		return this.reduce(function(a, b) {return a.concat(b)});
	};
}
if (!Array.prototype.stitch) {
	Array.prototype.stitch = function(other) {
		var o = this.copy();
		for (var i=0; i<other.length; i++) {
			if (this.length <= i)
				break;
			
			o[i] = o[i].concat(other[i]);
		}
		return o;
	};
}
if (!Array.prototype.stitchFold) {
	Array.prototype.stitchFold = function() {
		return this.reduce(function(a, b) {return a.stitch(b)});
	};
}
if (!Array.prototype.nIndexOf) {
	Array.prototype.nIndexOf = function(other) {
		if (other.length > this.length) {
			return [-1];
		} else {
			if (typeof(this[0]) != 'object' && this[0] != null &&
					!(this[0] instanceof Array)) {
				var n = 0;
				for (var i=0; i<this.length; i++) {
					if (this[i] == other[n]) {
						n++;
						if (n == other.length) {
							return [i-n+1];
						}
					} else {
						n = 0;
					}
				}
				return [-1];
			} else {
				var t;
		outer:	for (var i=0; i<this.length; i++) {
					if ((t = this[i].nIndexOf(other[0]))[0] >= 0) {
							// See if done.
						for (var j=1; j<other.length; j++) {
							if (!this[i+j].slice(t[0], t[0] + other[j].length).
									similarTo(other[j])) {
								continue outer;
							}
							return [i].concat(t);
						}
					}
				}
				return [-1];
			}
		}
	}
}

if (!Array.range) {
	Array.range = function(a, b) {
		if (!b) {
			b = a;
			a = 1;
		}
		
		var out = [];
		for (var i=a; i<=b; i++) {
			out.push(i);
		}
		return out;
	};
}
if (!Array.indices) {
	Array.indices = function() {
		var o = [];
		for (var i=0; i<arguments.length; i++) {
			for (var j=0; j<arguments[i]; j++) {
				o.push(i);
			}
		}
		return o;
	};
}
if (!Array.radixNumbers) {
	Array.radixNumbers = function(r, n) {
		var o = [];
		for (var i=0; i<n; i++) {
			o.push((i).toString(r).split('').map(function(a) {
				return parseInt(a);
			}));
		}
		return o;
	};
}

if (!Function.prototype.iterate) {
	Function.prototype.iterate = function(x, n) {
		if (n == 0) {
			return [];
		} else if (n < 0) {
			throw new TypeError();
		} else {
			var o = [x];
			for (var i=1; i<n; i++) {
				o.push(this(o[i-1]));
			}
			return o;
		}
	};
}

if (!Math.add) {
	Math.add = function(a, b) {return a+b};
}
if (!Math.multiply) {
	Math.multiply = function(a, b) {return a*b};
}
if (!Math.subtract) {
	Math.subtract = function(a, b) {return a-b};
}
if (!Math.divide) {
	Math.divide = function(a, b) {return a/b};
}
if (!Math.square) {
	Math.square = function(a) {return a*a};
}
if (!Math.getMultiplier) {
	Math.getMultiplier = function(a) {
		return function(b) {return a*b}
	};
}
if (!Math.pow) {
	Math.pow = function(a, b) {return Math.pow(a, b)};
}