//This prototype is provided by the Mozilla foundation and
//is distributed under the MIT license.
//http://www.ibiblio.org/pub/Linux/LICENSES/mit.license

if (!Array.prototype.indexOf)
{
	Array.prototype.indexOf = function(elt /*, from*/)
	{
		var len = this.length;

		var from = Number(arguments[1]) || 0;
		from = (from < 0)
		? Math.ceil(from)
		: Math.floor(from);
		if (from < 0)
			from += len;

		for (; from < len; from++)
		{
			if (from in this &&
				this[from] === elt)
				return from;
		}
		return -1;
	};
}

//This prototype is provided by the Mozilla foundation and
//is distributed under the MIT license.
//http://www.ibiblio.org/pub/Linux/LICENSES/mit.license

if (!Array.prototype.lastIndexOf)
{
	Array.prototype.lastIndexOf = function(elt /*, from*/)
	{
		var len = this.length;

		var from = Number(arguments[1]);
		if (isNaN(from))
		{
			from = len - 1;
		}
		else
		{
			from = (from < 0)
			? Math.ceil(from)
			: Math.floor(from);
			if (from < 0)
				from += len;
			else if (from >= len)
				from = len - 1;
		}

		for (; from > -1; from--)
		{
			if (from in this &&
				this[from] === elt)
				return from;
		}
		return -1;
	};
}

//This prototype is provided by the Mozilla foundation and
//is distributed under the MIT license.
//http://www.ibiblio.org/pub/Linux/LICENSES/mit.license
if (!Array.prototype.map)
{
	Array.prototype.map = function(fun /*, thisp*/)
	{
		var len = this.length;
		if (typeof fun != "function")
			throw new TypeError();

		var res = new Array(len);
		var thisp = arguments[1];
		for (var i = 0; i < len; i++)
		{
			if (i in this)
				res[i] = fun.call(thisp, this[i], i, this);
		}

		return res;
	};
}

//This prototype is provided by the Mozilla foundation and
//is distributed under the MIT license.
//http://www.ibiblio.org/pub/Linux/LICENSES/mit.license

if (!Array.prototype.some)
{
	Array.prototype.some = function(fun /*, thisp*/)
	{
		var len = this.length;
		if (typeof fun != "function")
			throw new TypeError();

		var thisp = arguments[1];
		for (var i = 0; i < len; i++)
		{
			if (i in this &&
				fun.call(thisp, this[i], i, this))
				return true;
		}

		return false;
	};
}

//This prototype is provided by the Mozilla foundation and
//is distributed under the MIT license.
//http://www.ibiblio.org/pub/Linux/LICENSES/mit.license

if (!Array.prototype.every)
{
	Array.prototype.every = function(fun /*, thisp*/)
	{
		var len = this.length;
		if (typeof fun != "function")
			throw new TypeError();

		var thisp = arguments[1];
		for (var i = 0; i < len; i++)
		{
			if (i in this &&
				!fun.call(thisp, this[i], i, this))
				return false;
		}

		return true;
	};
}

//This prototype is provided by the Mozilla foundation and
//is distributed under the MIT license.
//http://www.ibiblio.org/pub/Linux/LICENSES/mit.license

if (!Array.prototype.filter)
{
	Array.prototype.filter = function(fun /*, thisp*/)
	{
		var len = this.length;
		if (typeof fun != "function")
			throw new TypeError();

		var res = new Array();
		var thisp = arguments[1];
		for (var i = 0; i < len; i++)
		{
			if (i in this)
			{
				var val = this[i]; // in case fun mutates this
				if (fun.call(thisp, val, i, this))
					res.push(val);
			}
		}

		return res;
	};
}

//This prototype is provided by the Mozilla foundation and
//is distributed under the MIT license.
//http://www.ibiblio.org/pub/Linux/LICENSES/mit.license

if (!Array.prototype.forEach)
{
	Array.prototype.forEach = function(fun /*, thisp*/)
	{
		var len = this.length;
		if (typeof fun != "function")
			throw new TypeError();

		var thisp = arguments[1];
		for (var i = 0; i < len; i++)
		{
			if (i in this)
				fun.call(thisp, this[i], i, this);
		}
	};
}

if (!Array.prototype.sortNum)
{
	Array.prototype.sortNum = function() {
		return this.sort( function (a,b) {
			return a-b;
		} );
	}
}

if (!Array.prototype.find)
{
	Array.prototype.find = function(searchStr) {
		var returnArray = false;
		for (i=0; i<this.length; i++) {
			if (typeof(searchStr) == 'function') {
				if (searchStr.test(this[i])) {
					if (!returnArray) {
						returnArray = []
					}
					returnArray.push(i);
				}
			} else {
				if (this[i]===searchStr) {
					if (!returnArray) {
						returnArray = []
					}
					returnArray.push(i);
				}
			}
		}
		return returnArray;
	}
}

if (!Array.prototype.shuffle)
{
	Array.prototype.shuffle = function (){
		for(var rnd, tmp, i=this.length; i; rnd=parseInt(Math.random()*i), tmp=this[--i], this[i]=this[rnd], this[rnd]=tmp);
	};
}

if (!Array.prototype.compare)
{
	Array.prototype.compare = function(testArr) {
		if (this.length != testArr.length) return false;
		for (var i = 0; i < testArr.length; i++) {
			if (this[i].compare) {
				if (!this[i].compare(testArr[i])) return false;
			}
			if (this[i] !== testArr[i]) return false;
		}
		return true;
	}
}

if (!Array.prototype.remove)
{
	/**
   * Add array.remove() convenience method to remove element from array.
   *
   * @param {Object} elem Element to remove.
   */
	Array.prototype.remove = function(elem) {
		var index = this.indexOf(elem);
		if (index !== -1) {
			this.splice(index, 1);
		}
	};
}