/*
 * Core - JavaScript Utilities
 *
 * Licensed under the new BSD License.
 * Copyright 2008, Bram Stein
 * All rights reserved.
 */
Object.extend=function(D){var C=1,B,A=arguments.length;for(;C<A;C+=1){for(B in arguments[C]){if(arguments[C].hasOwnProperty(B)&&(!D[B]||D.propertyIsEnumerable(B))){D[B]=arguments[C][B]}}}return D};Object.extend(Object,{isAtom:function(A){return((typeof A!=="object"||A===null)&&typeof A!=="function")||Object.isBoolean(A)},isBoolean:function(A){return A!==null&&typeof A==="boolean"},isArray:function(A){return typeof A==="object"&&typeof A.length==="number"&&typeof A.splice==="function"&&!A.propertyIsEnumerable("length")},isObject:function(A){return typeof A==="object"&&!Object.isArray(A)},isFunction:function(A){return typeof A==="function"},filter:function(D,A,F){var B,C={},E;F=F||D;for(B in D){if(D.hasOwnProperty(B)){E=D[B];if(A.call(F,E,B,D)){C[B]=E}}}return C},map:function(D,A,E){var B,C={};E=E||D;for(B in D){if(D.hasOwnProperty(B)){C[B]=A.call(E,D[B],B,D)}}return C},forEach:function(C,A,D){var B;D=D||C;for(B in C){if(C.hasOwnProperty(B)){A.call(D,C[B],B,C)}}},every:function(C,A,D){var B;D=D||C;for(B in C){if(C.hasOwnProperty(B)&&!A.call(D,C[B],B,C)){return false}}return true},some:function(C,A,D){var B;D=D||C;for(B in C){if(C.hasOwnProperty(B)&&A.call(D,C[B],B,C)){return true}}return false},isEmpty:function(A){return Object.every(A,function(C,B){return !A.hasOwnProperty(B)})},beget:function(B){function A(){}A.prototype=B;return new A()},equals:function(C,A){var B=0;return Object.every(C,function(E,D){B+=1;return A.hasOwnProperty(D)&&((Object.isObject(E)&&Object.equals(E,A[D]))||E.equals(A[D]))})&&B===Object.reduce(A,function(D){return(D+=1)},0)},reduce:function(E,A,C){var D,B;if(Object.isEmpty(E)&&C===undefined){throw new TypeError()}if(C===undefined){for(D in E){if(E.hasOwnProperty(D)){C=E[D];B=D;break}}}for(D in E){if(E.hasOwnProperty(D)&&D!==B){C=A.call(null,C,E[D],D,E)}}return C}});Object.extend(Array.prototype,{append:function(){var B=0,A=arguments.length;for(;B<A;B+=1){this.push.apply(this,arguments[B])}return this},top:function(){return this[this.length-1]},equals:function(A){return A&&this.length===A.length&&this.every(function(C,B){return(Object.isObject(C)&&Object.equals(C,A[B]))||C.equals(A[B])})},contains:function(A){return this.indexOf(A)!==-1},filter:function(B,F){var C=0,D=[],E,A=this.length;F=F||this;for(;C<A;C+=1){if(C in this){E=this[C];if(B.call(F,E,C,this)){D.push(E)}}}return D},map:function(B,E){var C=0,D=[],A=this.length;E=E||this;for(;C<A;C+=1){if(C in this){D[C]=B.call(E,this[C],C,this)}}return D},forEach:function(B,D){var C=0,A=this.length;D=D||this;for(;C<A;C+=1){if(C in this){B.call(D,this[C],C,this)}}},every:function(B,D){var C=0,A=this.length;D=D||this;for(;C<A;C+=1){if(C in this&&!B.call(D,this[C],C,this)){return false}}return true},some:function(B,D){var C=0,A=this.length;D=D||this;for(;C<A;C+=1){if(C in this&&B.call(D,this[C],C,this)){return true}}return false},indexOf:function(B,C){var A=this.length;C=Number(C)||0;C=(C<0)?Math.ceil(C):Math.floor(C);C=(C<0)?C+A:C;for(;C<A;C+=1){if(C in this&&this[C]===B){return C}}return -1},lastIndexOf:function(B,C){var A=this.length;C=Number(C)||(A-1);C=(C<0)?Math.ceil(C):Math.floor(C);C=(C<0)?C+A:C;C=(C>=A)?A:C;for(;C>-1;C-=1){if(C in this&&this[C]===B){return C}}return -1},reduce:function(B,C){var D=0,A=this.length;if(A===0&&C===undefined){throw new TypeError()}if(C===undefined){do{if(D in this){C=this[D];D+=1;break}D+=1;if(D>=A){throw new TypeError()}}while(true)}for(;D<A;D+=1){if(D in this){C=B.call(null,C,this[D],D,this)}}return C},reduceRight:function(B,C){var A=this.length,D=A-1;if(A===0&&C===undefined){throw new TypeError()}if(C===undefined){do{if(D in this){C=this[D];D-=1;break}D-=1;if(D<0){throw new TypeError()}}while(true)}for(;D>=0;D-=1){if(D in this){C=B.call(null,C,this[D],D,this)}}return C}});[Boolean,String,Date,Number,Function,RegExp].forEach(function(A){Object.extend(A.prototype,{equals:function(B){return this==B}})});["reduce","reduceRight","equals","contains","append","top","filter","map","forEach","some","every","indexOf","lastIndexOf","join","sort","reverse","push","pop","shift","unshift","splice","concat","slice"].forEach(function(A){if(!(A in Array)&&A in Array.prototype){Array[A]=function(B){return this.prototype[A].apply(B,Array.prototype.slice.call(arguments,1))}}});Object.extend(Function.prototype,{bind:function(A){var B=this;return function(){return B.apply(A,arguments)}},curry:function(){var B=this,A=Array.slice(arguments);return function(){return B.apply(this,A.concat(Array.slice(arguments)))}}});