eval(function(p,a,c,k,e,d){e=function(c){return(c<a?'':e(parseInt(c/a)))+((c=c%a)>35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--){d[e(c)]=k[c]||e(c)}k=[function(e){return d[e]}];e=function(){return'\\w+'};c=1};while(c--){if(k[c]){p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c])}}return p}('G 1e={90:\'1.6.0.3\',1X:{44:!!(1F.7Z&&4u.4j.3H(\'4o\')===-1),4o:4u.4j.3H(\'4o\')>-1,4x:4u.4j.3H(\'dn/\')>-1,7x:4u.4j.3H(\'7x\')>-1&&4u.4j.3H(\'aW\')===-1,bJ:!!4u.4j.1f(/dq.*df.*aY/)},3L:{7v:!!1b.2V,cH:!!1b.cE,6t:!!1F.6u,7o:1b.42(\'1P\')[\'5j\']&&1b.42(\'1P\')[\'5j\']!==1b.42(\'1y\')[\'5j\']},7h:\'<5v[^>]*>([\\\\S\\\\s]*?)<\\/5v>\',bj:/^\\/\\*-dA-([\\s\\S]*)\\*\\/\\s*$/,3h:q(){},K:q(x){o x}};E(1e.1X.bJ)1e.3L.7o=1p;G 2l={2u:q(){G 2Y=1k,3j=$A(1q);E(M.2D(3j[0]))2Y=3j.5w();q 1M(){C.2L.3q(C,1q)}M.17(1M,2l.1c);1M.95=2Y;1M.bD=[];E(2Y){G 9z=q(){};9z.1j=2Y.1j;1M.1j=1t 9z;2Y.bD.1h(1M)}18(G i=0;i<3j.O;i++)1M.6r(3j[i]);E(!1M.1j.2L)1M.1j.2L=1e.3h;1M.1j.eo=1M;o 1M}};2l.1c={6r:q(25){G 3N=C.95&&C.95.1j;G 3j=M.4q(25);E(!M.4q({2I:1v}).O)3j.1h("2I","88");18(G i=0,O=3j.O;i<O;i++){G 1z=3j[i],I=25[1z];E(3N&&M.2D(I)&&I.c4().3M()=="$49"){G 1B=I;I=(q(m){o q(){o 3N[m].3q(C,1q)}})(1z).4N(1B);I.88=1B.88.2F(1B);I.2I=1B.2I.2F(1B)}C.1j[1z]=I}o C}};G 4U={};M.17=q(63,25){18(G 1z 1Q 25)63[1z]=25[1z];o 63};M.17(M,{2G:q(W){24{E(M.2H(W))o\'4D\';E(W===1k)o\'1k\';o W.2G?W.2G():22(W)}2a(e){E(e bY dB)o\'...\';4J e}},3w:q(W){G 1s=3g W;5k(1s){2j\'4D\':2j\'q\':2j\'dz\':o;2j\'dL\':o W.2I()}E(W===1k)o\'1k\';E(W.3w)o W.3w();E(M.4v(W))o;G U=[];18(G 1z 1Q W){G I=M.3w(W[1z]);E(!M.2H(I))U.1h(1z.3w()+\': \'+I)}o\'{\'+U.2B(\', \')+\'}\'},4K:q(W){o $H(W).4K()},4i:q(W){o W&&W.4i?W.4i():22.5Z(W)},4q:q(W){G 4q=[];18(G 1z 1Q W)4q.1h(1z);o 4q},1W:q(W){G 1W=[];18(G 1z 1Q W)1W.1h(W[1z]);o 1W},2E:q(W){o M.17({},W)},4v:q(W){o!!(W&&W.3B==1)},4E:q(W){o W!=1k&&3g W=="W"&&\'dF\'1Q W&&\'2B\'1Q W},8z:q(W){o W bY 3X},2D:q(W){o 3g W=="q"},3k:q(W){o 3g W=="3o"},55:q(W){o 3g W=="3W"},2H:q(W){o 3g W=="4D"}});M.17(dE.1j,{c4:q(){G 3E=C.2I().1f(/^[\\s\\(]*q[^(]*\\(([^\\)]*)\\)/)[1].1U(/\\s+/g,\'\').4n(\',\');o 3E.O==1&&!3E[0]?[]:3E},2F:q(){E(1q.O<2&&M.2H(1q[0]))o C;G 3n=C,1V=$A(1q),W=1V.5w();o q(){o 3n.3q(W,1V.1R($A(1q)))}},dJ:q(){G 3n=C,1V=$A(1q),W=1V.5w();o q(1a){o 3n.3q(W,[1a||1F.1a].1R(1V))}},9G:q(){E(!1q.O)o C;G 3n=C,1V=$A(1q);o q(){o 3n.3q(C,1V.1R($A(1q)))}},8w:q(){G 3n=C,1V=$A(1q),c3=1V.5w()*bS;o 1F.dK(q(){o 3n.3q(3n,1V)},c3)},4S:q(){G 1V=[0.dS].1R($A(1q));o C.8w.3q(C,1V)},4N:q(1L){G 3n=C;o q(){o 1L.3q(C,[3n.2F(C)].1R($A(1q)))}},4C:q(){E(C.8U)o C.8U;G 3n=C;o C.8U=q(){o 3n.3q(1k,[C].1R($A(1q)))}}});dT.1j.3w=q(){o\'"\'+C.dU()+\'-\'+(C.dQ()+1).4P(2)+\'-\'+C.dP().4P(2)+\'T\'+C.dy().4P(2)+\':\'+C.du().4P(2)+\':\'+C.dh().4P(2)+\'Z"\'};G cV={cU:q(){G 86;18(G i=0,O=1q.O;i<O;i++){G bU=1q[i];24{86=bU();2i}2a(e){}}o 86}};4b.1j.1f=4b.1j.2P;4b.aj=q(61){o 22(61).1U(/([.*+?^=!:${}()|[\\]\\/\\\\])/g,\'\\\\$1\')};G b8=2l.2u({2L:q(3b,4a){C.3b=3b;C.4a=4a;C.7g=1p;C.74()},74:q(){C.3Z=bM(C.6D.2F(C),C.4a*bS)},8i:q(){C.3b(C)},9w:q(){E(!C.3Z)o;bQ(C.3Z);C.3Z=1k},6D:q(){E(!C.7g){24{C.7g=1v;C.8i()}di{C.7g=1p}}}});M.17(22,{5Z:q(I){o I==1k?\'\':22(I)},bi:{\'\\b\':\'\\\\b\',\'\\t\':\'\\\\t\',\'\\n\':\'\\\\n\',\'\\f\':\'\\\\f\',\'\\r\':\'\\\\r\',\'\\\\\':\'\\\\\\\\\'}});M.17(22.1j,{3p:q(26,3y){G 1r=\'\',25=C,1f;3y=1q.5C.8W(3y);1N(25.O>0){E(1f=25.1f(26)){1r+=25.3u(0,1f.1n);1r+=22.5Z(3y(1f));25=25.3u(1f.1n+1f[0].O)}1i{1r+=25,25=\'\'}}o 1r},bf:q(26,3y,3s){3y=C.3p.8W(3y);3s=M.2H(3s)?1:3s;o C.3p(26,q(1f){E(--3s<0)o 1f[0];o 3y(1f)})},bH:q(26,1g){C.3p(26,1g);o 22(C)},dv:q(O,5P){O=O||30;5P=M.2H(5P)?\'...\':5P;o C.O>O?C.3u(0,O-5P.O)+5P:22(C)},4g:q(){o C.1U(/^\\s+/,\'\').1U(/\\s+$/,\'\')},8I:q(){o C.1U(/<\\/?[^>]+>/gi,\'\')},47:q(){o C.1U(1t 4b(1e.7h,\'cp\'),\'\')},c8:q(){G ch=1t 4b(1e.7h,\'cp\');G c9=1t 4b(1e.7h,\'eI\');o(C.1f(ch)||[]).2Q(q(ca){o(ca.1f(c9)||[\'\',\'\'])[1]})},58:q(){o C.c8().2Q(q(5v){o 7d(5v)})},6Y:q(){G 5y=1q.5C;5y.4d.7B=C;o 5y.1P.59},bm:q(){G 1P=1t J(\'1P\');1P.59=C.8I();o 1P.3l[0]?(1P.3l.O>1?$A(1P.3l).3C(\'\',q(2T,L){o 2T+L.4p}):1P.3l[0].4p):\'\'},7T:q(cc){G 1f=C.4g().1f(/([^?#]*)(#.*)?$/);E(!1f)o{};o 1f[1].4n(cc||\'&\').3C({},q(3D,1J){E((1J=1J.4n(\'=\'))[0]){G 1w=9O(1J.5w());G I=1J.O>1?1J.2B(\'=\'):1J[0];E(I!=4D)I=9O(I);E(1w 1Q 3D){E(!M.4E(3D[1w]))3D[1w]=[3D[1w]];3D[1w].1h(I)}1i 3D[1w]=I}o 3D})},3z:q(){o C.4n(\'\')},8J:q(){o C.3u(0,C.O-1)+22.em(C.bh(C.O-1)+1)},7E:q(3s){o 3s<1?\'\':1t 2r(3s+1).2B(C)},9g:q(){G 4z=C.4n(\'-\'),99=4z.O;E(99==1)o 4z[0];G 9h=C.7j(0)==\'-\'?4z[0].7j(0).2o()+4z[0].5K(1):4z[0];18(G i=1;i<99;i++)9h+=4z[i].7j(0).2o()+4z[i].5K(1);o 9h},6v:q(){o C.7j(0).2o()+C.5K(1).2e()},eF:q(){o C.3p(/::/,\'/\').3p(/([A-Z]+)([A-Z][a-z])/,\'#{1}6x#{2}\').3p(/([a-z\\d])([A-Z])/,\'#{1}6x#{2}\').3p(/-/,\'6x\').2e()},eG:q(){o C.3p(/6x/,\'-\')},2G:q(bg){G 8H=C.3p(/[\\eH-\\eB\\\\]/,q(1f){G 8B=22.bi[1f[0]];o 8B?8B:\'\\\\ej\'+1f[0].bh().4P(2,16)});E(bg)o\'"\'+8H.1U(/"/g,\'\\\\"\')+\'"\';o"\'"+8H.1U(/\'/g,\'\\\\\\\'\')+"\'"},3w:q(){o C.2G(1v)},8a:q(2h){o C.bf(2h||1e.bj,\'#{1}\')},bn:q(){G 61=C;E(61.53())o 1p;61=C.1U(/\\\\./g,\'@\').1U(/"[^"\\\\\\n\\r]*"/g,\'\');o(/^[,:{}\\[\\]0-9.\\-+e2-u \\n\\r\\t]*$/).2P(61)},5S:q(bk){G 3m=C.8a();24{E(!bk||3m.bn())o 7d(\'(\'+3m+\')\')}2a(e){}4J 1t dX(\'dY dZ aq 3o: \'+C.2G())},1I:q(26){o C.3H(26)>-1},9B:q(26){o C.3H(26)===0},9A:q(26){G d=C.O-26.O;o d>=0&&C.8f(26)===d},5R:q(){o C==\'\'},53:q(){o/^\\s*$/.2P(C)},aL:q(W,26){o 1t 3d(C,26).2V(W)}});E(1e.1X.4x||1e.1X.44)M.17(22.1j,{6Y:q(){o C.1U(/&/g,\'&bl;\').1U(/</g,\'&be;\').1U(/>/g,\'&gt;\')},bm:q(){o C.8I().1U(/&bl;/g,\'&\').1U(/&be;/g,\'<\').1U(/&gt;/g,\'>\')}});22.1j.3p.8W=q(3y){E(M.2D(3y))o 3y;G 6b=1t 3d(3y);o q(1f){o 6b.2V(1f)}};22.1j.e8=22.1j.7T;M.17(22.1j.6Y,{1P:1b.42(\'1P\'),4d:1b.aX(\'\')});22.1j.6Y.1P.69(22.1j.6Y.4d);G 3d=2l.2u({2L:q(6b,26){C.6b=6b.2I();C.26=26||3d.b5},2V:q(W){E(M.2D(W.8V))W=W.8V();o C.6b.3p(C.26,q(1f){E(W==1k)o\'\';G 5n=1f[1]||\'\';E(5n==\'\\\\\')o 1f[2];G 6W=W,6X=1f[3];G 26=/^([^.[]+|\\[((?:.*?[^\\\\])?)\\])(\\.|\\[|$)/;1f=26.b6(6X);E(1f==1k)o 5n;1N(1f!=1k){G bd=1f[1].9B(\'[\')?1f[2].3p(\'\\\\\\\\]\',\']\'):1f[1];6W=6W[bd];E(1k==6W||\'\'==1f[3])2i;6X=6X.5K(\'[\'==1f[3]?1f[1].O:1f[0].O);1f=26.b6(6X)}o 5n+22.5Z(6W)})}});3d.b5=/(^|.|\\r|\\n)(#\\{(.*?)\\})/;G $2i={};G 2J={1E:q(1g,1G){G 1n=0;24{C.4y(q(I){1g.2M(1G,I,1n++)})}2a(e){E(e!=$2i)4J e}o C},bo:q(3W,1g,1G){G 1n=-3W,8O=[],2z=C.3z();E(3W<1)o 2z;1N((1n+=3W)<2z.O)8O.1h(2z.3u(1n,1n+3W));o 8O.98(1g,1G)},9p:q(1g,1G){1g=1g||1e.K;G 1r=1v;C.1E(q(I,1n){1r=1r&&!!1g.2M(1G,I,1n);E(!1r)4J $2i});o 1r},bu:q(1g,1G){1g=1g||1e.K;G 1r=1p;C.1E(q(I,1n){E(1r=!!1g.2M(1G,I,1n))4J $2i});o 1r},98:q(1g,1G){1g=1g||1e.K;G U=[];C.1E(q(I,1n){U.1h(1g.2M(1G,I,1n))});o U},7a:q(1g,1G){G 1r;C.1E(q(I,1n){E(1g.2M(1G,I,1n)){1r=I;4J $2i}});o 1r},5M:q(1g,1G){G U=[];C.1E(q(I,1n){E(1g.2M(1G,I,1n))U.1h(I)});o U},ea:q(2h,1g,1G){1g=1g||1e.K;G U=[];E(M.3k(2h))2h=1t 4b(2h);C.1E(q(I,1n){E(2h.1f(I))U.1h(1g.2M(1G,I,1n))});o U},1I:q(W){E(M.2D(C.3H))E(C.3H(W)!=-1)o 1v;G 9N=1p;C.1E(q(I){E(I==W){9N=1v;4J $2i}});o 9N},ec:q(3W,72){72=M.2H(72)?1k:72;o C.bo(3W,q(3u){1N(3u.O<3W)3u.1h(72);o 3u})},3C:q(2T,1g,1G){C.1E(q(I,1n){2T=1g.2M(1G,2T,I,1n)});o 2T},9t:q(1B){G 1V=$A(1q).3u(1);o C.2Q(q(I){o I[1B].3q(I,1V)})},ee:q(1g,1G){1g=1g||1e.K;G 1r;C.1E(q(I,1n){I=1g.2M(1G,I,1n);E(1r==1k||I>=1r)1r=I});o 1r},ef:q(1g,1G){1g=1g||1e.K;G 1r;C.1E(q(I,1n){I=1g.2M(1G,I,1n);E(1r==1k||I<1r)1r=I});o 1r},e0:q(1g,1G){1g=1g||1e.K;G 9o=[],9r=[];C.1E(q(I,1n){(1g.2M(1G,I,1n)?9o:9r).1h(I)});o[9o,9r]},5x:q(1z){G U=[];C.1E(q(I){U.1h(I[1z])});o U},eD:q(1g,1G){G U=[];C.1E(q(I,1n){E(!1g.2M(1G,I,1n))U.1h(I)});o U},bF:q(1g,1G){o C.2Q(q(I,1n){o{I:I,6I:1g.2M(1G,I,1n)}}).eE(q(2w,5X){G a=2w.6I,b=5X.6I;o a<b?-1:a>b?1:0}).5x(\'I\')},3z:q(){o C.2Q()},eu:q(){G 1g=1e.K,1V=$A(1q);E(M.2D(1V.2v()))1g=1V.dW();G bA=[C].1R(1V).2Q($A);o C.2Q(q(I,1n){o 1g(bA.5x(1n))})},db:q(){o C.3z().O},2G:q(){o\'#<2J:\'+C.3z().2G()+\'>\'}};M.17(2J,{2Q:2J.98,9j:2J.7a,2A:2J.5M,2h:2J.5M,dt:2J.1I,de:2J.3z,dk:2J.9p,dj:2J.bu});q $A(2X){E(!2X)o[];E(2X.3z)o 2X.3z();G O=2X.O||0,U=1t 2r(O);1N(O--)U[O]=2X[O];o U}E(1e.1X.4x){$A=q(2X){E(!2X)o[];E(!(3g 2X===\'q\'&&3g 2X.O===\'3W\'&&3g 2X.4X===\'q\')&&2X.3z)o 2X.3z();G O=2X.O||0,U=1t 2r(O);1N(O--)U[O]=2X[O];o U}}2r.d1=$A;M.17(2r.1j,2J);E(!2r.1j.9S)2r.1j.9S=2r.1j.4w;M.17(2r.1j,{4y:q(1g){18(G i=0,O=C.O;i<O;i++)1g(C[i])},bE:q(){C.O=0;o C},3M:q(){o C[0]},2v:q(){o C[C.O-1]},dH:q(){o C.2A(q(I){o I!=1k})},d8:q(){o C.3C([],q(2z,I){o 2z.1R(M.4E(I)?I.d8():[I])})},6z:q(){G 1W=$A(1q);o C.2A(q(I){o!1W.1I(I)})},4w:q(b2){o(b2!==1p?C:C.3z()).9S()},dO:q(){o C.O>1?C:C[0]},d4:q(dc){o C.3C([],q(2z,I,1n){E(0==1n||(dc?2z.2v()!=I:!2z.1I(I)))2z.1h(I);o 2z})},dd:q(2z){o C.d4().5M(q(4X){o 2z.7a(q(I){o 4X===I})})},2E:q(){o[].1R(C)},db:q(){o C.O},2G:q(){o\'[\'+C.2Q(M.2G).2B(\', \')+\']\'},3w:q(){G U=[];C.1E(q(W){G I=M.3w(W);E(!M.2H(I))U.1h(I)});o\'[\'+U.2B(\', \')+\']\'}});E(M.2D(2r.1j.d5))2r.1j.4y=2r.1j.d5;E(!2r.1j.3H)2r.1j.3H=q(4X,i){i||(i=0);G O=C.O;E(i<0)i=O+i;18(;i<O;i++)E(C[i]===4X)o i;o-1};E(!2r.1j.8f)2r.1j.8f=q(4X,i){i=ei(i)?C.O:(i<0?C.O+i:i)+1;G n=C.3u(0,i).4w().3H(4X);o(n<0)?n:i-n-1};2r.1j.3z=2r.1j.2E;q $w(3o){E(!M.3k(3o))o[];3o=3o.4g();o 3o?3o.4n(/\\s+/):[]}E(1e.1X.4o){2r.1j.1R=q(){G 2z=[];18(G i=0,O=C.O;i<O;i++)2z.1h(C[i]);18(G i=0,O=1q.O;i<O;i++){E(M.4E(1q[i])){18(G j=0,cw=1q[i].O;j<cw;j++)2z.1h(1q[i][j])}1i{2z.1h(1q[i])}}o 2z}}M.17(54.1j,{e3:q(){o C.4P(2,16)},8J:q(){o C+1},7E:q(1g,1G){$R(0,C,1v).1E(1g,1G);o C},4P:q(O,cy){G 3o=C.2I(cy||10);o\'0\'.7E(O-3o.O)+3o},3w:q(){o eq(C)?C.2I():\'1k\'}});$w(\'er et dm dr\').1E(q(1B){54.1j[1B]=ds[1B].4C()});q $H(W){o 1t 3X(W)};G 3X=2l.2u(2J,(q(){q 8T(1w,I){E(M.2H(I))o 1w;o 1w+\'=\'+cZ(22.5Z(I))}o{2L:q(W){C.4l=M.8z(W)?W.6A():M.2E(W)},4y:q(1g){18(G 1w 1Q C.4l){G I=C.4l[1w],1J=[1w,I];1J.1w=1w;1J.I=I;1g(1J)}},6w:q(1w,I){o C.4l[1w]=I},9n:q(1w){E(C.4l[1w]!==M.1j[1w])o C.4l[1w]},dw:q(1w){G I=C.4l[1w];8K C.4l[1w];o I},6A:q(){o M.2E(C.4l)},4q:q(){o C.5x(\'1w\')},1W:q(){o C.5x(\'I\')},1n:q(I){G 1f=C.7a(q(1J){o 1J.I===I});o 1f&&1f.1w},dx:q(W){o C.2E().52(W)},52:q(W){o 1t 3X(W).3C(C,q(1r,1J){1r.6w(1J.1w,1J.I);o 1r})},4K:q(){o C.3C([],q(U,1J){G 1w=cZ(1J.1w),1W=1J.I;E(1W&&3g 1W==\'W\'){E(M.4E(1W))o U.1R(1W.2Q(8T.9G(1w)))}1i U.1h(8T(1w,1W));o U}).2B(\'&\')},2G:q(){o\'#<3X:{\'+C.2Q(q(1J){o 1J.2Q(M.2G).2B(\': \')}).2B(\', \')+\'}>\'},3w:q(){o M.3w(C.6A())},2E:q(){o 1t 3X(C)}}})());3X.1j.8V=3X.1j.6A;3X.d1=$H;G d0=2l.2u(2J,{2L:q(48,56,5T){C.48=48;C.56=56;C.5T=5T},4y:q(1g){G I=C.48;1N(C.1I(I)){1g(I);I=I.8J()}},1I:q(I){E(I<C.48)o 1p;E(C.5T)o I<C.56;o I<=C.56}});G $R=q(48,56,5T){o 1t d0(48,56,5T)};G 1O={cT:q(){o cV.cU(q(){o 1t aE()},q(){o 1t cP(\'dg.cO\')},q(){o 1t cP(\'dV.cO\')})||1p},8s:0};1O.65={6B:[],4y:q(1g){C.6B.4y(1g)},cN:q(4s){E(!C.1I(4s))C.6B.1h(4s)},dN:q(4s){C.6B=C.6B.6z(4s)},7y:q(3b,2R,20,3m){C.1E(q(4s){E(M.2D(4s[3b])){24{4s[3b].3q(4s,[2R,20,3m])}2a(e){}}})}};M.17(1O.65,2J);1O.65.cN({7q:q(){1O.8s++},3R:q(){1O.8s--}});1O.8u=2l.2u({2L:q(V){C.V={1B:\'6F\',7l:1v,6S:\'7O/x-dR-1y-dC\',89:\'dD-8\',3J:\'\',5S:1v,8h:1v};M.17(C.V,V||{});C.V.1B=C.V.1B.2e();E(M.3k(C.V.3J))C.V.3J=C.V.3J.7T();1i E(M.8z(C.V.3J))C.V.3J=C.V.3J.6A()}});1O.5g=2l.2u(1O.8u,{8d:1p,2L:q($49,2Z,V){$49(V);C.20=1O.cT();C.2R(2Z)},2R:q(2Z){C.2Z=2Z;C.1B=C.V.1B;G 3e=M.2E(C.V.3J);E(![\'9n\',\'6F\'].1I(C.1B)){3e[\'dG\']=C.1B;C.1B=\'6F\'}C.3J=3e;E(3e=M.4K(3e)){E(C.1B==\'9n\')C.2Z+=(C.2Z.1I(\'?\')?\'&\':\'?\')+3e;1i E(/dI|aY|aW/.2P(4u.4j))3e+=\'&6x=\'}24{G 2y=1t 1O.9v(C);E(C.V.7q)C.V.7q(2y);1O.65.7y(\'7q\',C,2y);C.20.el(C.1B.2o(),C.2Z,C.V.7l);E(C.V.7l)C.8j.2F(C).4S(1);C.20.7m=C.8M.2F(C);C.aF();C.2b=C.1B==\'6F\'?(C.V.ep||3e):1k;C.20.ew(C.2b);E(!C.V.7l&&C.20.aV)C.8M()}2a(e){C.5o(e)}},8M:q(){G 2S=C.20.2S;E(2S>1&&!((2S==4)&&C.8d))C.8j(C.20.2S)},aF:q(){G 4V={\'X-ez-ek\':\'aE\',\'X-1e-90\':1e.90,\'e5\':\'4d/e6, 4d/7Q, 7O/6h, 4d/6h, */*\'};E(C.1B==\'6F\'){4V[\'8n-1s\']=C.V.6S+(C.V.89?\'; e1=\'+C.V.89:\'\');E(C.20.aV&&(4u.4j.1f(/7x\\/(\\d{4})/)||[0,aT])[1]<aT)4V[\'eg\']=\'ed\'}E(3g C.V.b1==\'W\'){G 5Q=C.V.b1;E(M.2D(5Q.1h))18(G i=0,O=5Q.O;i<O;i+=2)4V[5Q[i]]=5Q[i+1];1i $H(5Q).1E(q(1J){4V[1J.1w]=1J.I})}18(G 1d 1Q 4V)C.20.eb(1d,4V[1d])},5c:q(){G 4L=C.6l();o!4L||(4L>=es&&4L<e9)},6l:q(){24{o C.20.4L||0}2a(e){o 0}},8j:q(2S){G 6L=1O.5g.ar[2S],2y=1t 1O.9v(C);E(6L==\'9C\'){24{C.8d=1v;(C.V[\'5G\'+2y.4L]||C.V[\'5G\'+(C.5c()?\'eh\':\'e7\')]||1e.3h)(2y,2y.7A)}2a(e){C.5o(e)}G 6S=2y.5N(\'8n-1s\');E(C.V.8h==\'al\'||(C.V.8h&&C.7u()&&6S&&6S.1f(/^\\s*(4d|7O)\\/(x-)?(ev|dM)5v(;.*)?\\s*$/i)))C.ad()}24{(C.V[\'5G\'+6L]||1e.3h)(2y,2y.7A);1O.65.7y(\'5G\'+6L,C,2y,2y.7A)}2a(e){C.5o(e)}E(6L==\'9C\'){C.20.7m=1e.3h}},7u:q(){G m=C.2Z.1f(/^\\s*ey?:\\/\\/[^\\/]*/);o!m||(m[0]==\'#{92}//#{9y}#{7C}\'.aL({92:83.92,9y:1b.9y,7C:83.7C?\':\'+83.7C:\'\'}))},5N:q(1d){24{o C.20.9K(1d)||1k}2a(e){o 1k}},ad:q(){24{o 7d((C.20.32||\'\').8a())}2a(e){C.5o(e)}},5o:q(8A){(C.V.ab||1e.3h)(C,8A);1O.65.7y(\'ab\',C,8A)}});1O.5g.ar=[\'e4\',\'eA\',\'eC\',\'ex\',\'9C\'];1O.9v=2l.2u({2L:q(2R){C.2R=2R;G 20=C.20=2R.20,2S=C.2S=20.2S;E((2S>2&&!1e.1X.44)||2S==4){C.4L=C.6l();C.9X=C.ax();C.32=22.5Z(20.32);C.7A=C.ae()}E(2S==4){G 6h=20.an;C.an=M.2H(6h)?1k:6h;C.dp=C.az()}},4L:0,9X:\'\',6l:1O.5g.1j.6l,ax:q(){24{o C.20.9X||\'\'}2a(e){o\'\'}},5N:1O.5g.1j.5N,dl:q(){24{o C.9T()}2a(e){o 1k}},9K:q(1d){o C.20.9K(1d)},9T:q(){o C.20.9T()},ae:q(){G 3m=C.5N(\'X-aq\');E(!3m)o 1k;3m=9O(aj(3m));24{o 3m.5S(C.2R.V.aI||!C.2R.7u())}2a(e){C.2R.5o(e)}},az:q(){G V=C.2R.V;E(!V.5S||(V.5S!=\'al\'&&!(C.5N(\'8n-1s\')||\'\').1I(\'7O/3m\'))||C.32.53())o 1k;24{o C.32.5S(V.aI||!C.2R.7u())}2a(e){C.2R.5o(e)}}});1O.b0=2l.2u(1O.5g,{2L:q($49,3F,2Z,V){C.3F={5c:(3F.5c||3F),8D:(3F.8D||(3F.5c?1k:3F))};V=M.2E(V);G 3R=V.3R;V.3R=(q(2y,3m){C.ao(2y.32);E(M.2D(3R))3R(2y,3m)}).2F(C);$49(2Z,V)},ao:q(32){G 60=C.3F[C.5c()?\'5c\':\'8D\'],V=C.V;E(!V.58)32=32.47();E(60=$(60)){E(V.5s){E(M.3k(V.5s)){G 5s={};5s[V.5s]=32;60.3G(5s)}1i V.5s(60,32)}1i 60.52(32)}}});1O.f8=2l.2u(1O.8u,{2L:q($49,3F,2Z,V){$49(V);C.3R=C.V.3R;C.4a=(C.V.4a||2);C.5h=(C.V.5h||1);C.8X={};C.3F=3F;C.2Z=2Z;C.48()},48:q(){C.V.3R=C.aa.2F(C);C.6D()},9w:q(){C.8X.V.3R=4D;hj(C.3Z);(C.3R||1e.3h).3q(C,1q)},aa:q(2y){E(C.V.5h){C.5h=(2y.32==C.ac?C.5h*C.V.5h:1);C.ac=2y.32}C.3Z=C.6D.2F(C).8w(C.5h*C.4a)},6D:q(){C.8X=1t 1O.b0(C.3F,C.2Z,C.V)}});q $(k){E(1q.O>1){18(G i=0,1Y=[],O=1q.O;i<O;i++)1Y.1h($(1q[i]));o 1Y}E(M.3k(k))k=1b.hN(k);o J.17(k)}E(1e.3L.7v){1b.8k=q(1u,7s){G U=[];G 8Q=1b.2V(1u,$(7s)||1b,1k,hE.hw,1k);18(G i=0,O=8Q.hA;i<O;i++)U.1h(J.17(8Q.hD(i)));o U}}E(!1F.76)G 76={};E(!76.aZ){M.17(76,{aZ:1,gE:2,cg:3,gD:4,gC:5,gB:6,gF:7,gJ:8,gA:9,gz:10,gr:11,gx:12})}(q(){G k=C.J;C.J=q(15,2t){2t=2t||{};15=15.2e();G 2W=J.2W;E(1e.1X.44&&2t.1d){15=\'<\'+15+\' 1d="\'+2t.1d+\'">\';8K 2t.1d;o J.71(1b.42(15),2t)}E(!2W[15])2W[15]=J.17(1b.42(15));o J.71(2W[15].gY(1p),2t)};M.17(C.J,k||{});E(k)C.J.1j=k.1j}).2M(1F);J.2W={};J.1c={9E:q(k){o $(k).Y.3t!=\'7G\'},bW:q(k){k=$(k);J[J.9E(k)?\'aJ\':\'ay\'](k);o k},aJ:q(k){k=$(k);k.Y.3t=\'7G\';o k},ay:q(k){k=$(k);k.Y.3t=\'\';o k},d3:q(k){k=$(k);k.1S.6C(k);o k},52:q(k,19){k=$(k);E(19&&19.3r)19=19.3r();E(M.4v(19))o k.52().3G(19);19=M.4i(19);k.59=19.47();19.58.2F(19).4S();o k},1U:q(k,19){k=$(k);E(19&&19.3r)19=19.3r();1i E(!M.4v(19)){19=M.4i(19);G 9b=k.h1.h5();9b.h3(k);19.58.2F(19).4S();19=9b.gO(19.47())}k.1S.8y(19,k);o k},3G:q(k,3U){k=$(k);E(M.3k(3U)||M.55(3U)||M.4v(3U)||(3U&&(3U.3r||3U.4i)))3U={5q:3U};G 19,3G,15,3l;18(G 1x 1Q 3U){19=3U[1x];1x=1x.2e();3G=J.6e[1x];E(19&&19.3r)19=19.3r();E(M.4v(19)){3G(k,19);3V}19=M.4i(19);15=((1x==\'5n\'||1x==\'7c\')?k.1S:k).15.2o();3l=J.84(15,19.47());E(1x==\'2m\'||1x==\'7c\')3l.4w();3l.1E(3G.9G(k));19.58.2F(19).4S()}o k},4N:q(k,1L,2t){k=$(k);E(M.4v(1L))$(1L).71(2t||{});1i E(M.3k(1L))1L=1t J(1L,2t);1i 1L=1t J(\'1P\',1L);E(k.1S)k.1S.8y(1L,k);1L.69(k);o 1L},2G:q(k){k=$(k);G 1r=\'<\'+k.15.2e();$H({\'1o\':\'1o\',\'1l\':\'6V\'}).1E(q(1J){G 1z=1J.3M(),1T=1J.2v();G I=(k[1z]||\'\').2I();E(I)1r+=\' \'+1T+\'=\'+I.2G(1v)});o 1r+\'>\'},7F:q(k,1z){k=$(k);G 1Y=[];1N(k=k[1z])E(k.3B==1)1Y.1h(J.17(k));o 1Y},5H:q(k){o $(k).7F(\'1S\')},a8:q(k){o $(k).2A("*")},at:q(k){k=$(k).67;1N(k&&k.3B!=1)k=k.4m;o $(k)},au:q(k){E(!(k=$(k).67))o[];1N(k&&k.3B!=1)k=k.4m;E(k)o[k].1R($(k).4Q());o[]},5J:q(k){o $(k).7F(\'ct\')},4Q:q(k){o $(k).7F(\'4m\')},gU:q(k){k=$(k);o k.5J().4w().1R(k.4Q())},1f:q(k,41){E(M.3k(41))41=1t 14(41);o 41.1f($(k))},ht:q(k,1u,1n){k=$(k);E(1q.O==1)o $(k.1S);G 5H=k.5H();o M.55(1u)?5H[1u]:14.68(5H,1u,1n)},gT:q(k,1u,1n){k=$(k);E(1q.O==1)o k.at();o M.55(1u)?k.a8()[1u]:J.2A(k,1u)[1n||0]},gN:q(k,1u,1n){k=$(k);E(1q.O==1)o $(14.28.6o(k));G 5J=k.5J();o M.55(1u)?5J[1u]:14.68(5J,1u,1n)},6K:q(k,1u,1n){k=$(k);E(1q.O==1)o $(14.28.6U(k));G 4Q=k.4Q();o M.55(1u)?4Q[1u]:14.68(4Q,1u,1n)},2A:q(){G 1V=$A(1q),k=$(1V.5w());o 14.7S(k,1V)},50:q(){G 1V=$A(1q),k=$(1V.5w());o 14.7S(k.1S,1V).6z(k)},8o:q(k){k=$(k);G 1o=k.57(\'1o\'),5y=1q.5C;E(1o)o 1o;do{1o=\'gv\'+5y.ah++}1N($(1o));k.71(\'1o\',1o);o 1o},57:q(k,1d){k=$(k);E(1e.1X.44){G t=J.3Q.7r;E(t.1W[1d])o t.1W[1d](k,1d);E(t.3E[1d])1d=t.3E[1d];E(1d.1I(\':\')){o(!k.2t||!k.2t[1d])?1k:k.2t[1d].I}}o k.9V(1d)},71:q(k,1d,I){k=$(k);G 2t={},t=J.3Q.6E;E(3g 1d==\'W\')2t=1d;1i 2t[1d]=M.2H(I)?1v:I;18(G 2d 1Q 2t){1d=t.3E[2d]||2d;I=2t[2d];E(t.1W[2d])1d=t.1W[2d](k,I);E(I===1p||I===1k)k.9x(1d);1i E(I===1v)k.aK(1d,1d);1i k.aK(1d,I)}o k},cD:q(k){o $(k).5A().3c},cC:q(k){o $(k).5A().2f},6p:q(k){o 1t J.7W(k)},7Y:q(k,1l){E(!(k=$(k)))o;G 7z=k.1l;o(7z.O>0&&(7z==1l||1t 4b("(^|\\\\s)"+1l+"(\\\\s|$)").2P(7z)))},ag:q(k,1l){E(!(k=$(k)))o;E(!k.7Y(1l))k.1l+=(k.1l?\' \':\'\')+1l;o k},ap:q(k,1l){E(!(k=$(k)))o;k.1l=k.1l.1U(1t 4b("(^|\\\\s+)"+1l+"(\\\\s+|$)"),\' \').4g();o k},gq:q(k,1l){E(!(k=$(k)))o;o k[k.7Y(1l)?\'ap\':\'ag\'](1l)},gG:q(k){k=$(k);G L=k.67;1N(L){G aD=L.4m;E(L.3B==3&&!/\\S/.2P(L.4p))k.6C(L);L=aD}o k},5R:q(k){o $(k).59.53()},77:q(k,3N){k=$(k),3N=$(3N);E(k.ai)o(k.ai(3N)&8)===8;E(3N.5m)o 3N.5m(k)&&3N!==k;1N(k=k.1S)E(k==3N)o 1v;o 1p},am:q(k){k=$(k);G 6d=k.4r();1F.am(6d[0],6d[1]);o k},2c:q(k,Y){k=$(k);Y=Y==\'9l\'?\'7p\':Y.9g();G I=k.Y[Y];E(!I||I==\'6f\'){G 8G=1b.hL.hd(k,1k);I=8G?8G[Y]:1k}E(Y==\'3S\')o I?4W(I):1.0;o I==\'6f\'?1k:I},hc:q(k){o $(k).2c(\'3S\')},5z:q(k,4O){k=$(k);G 8t=k.Y,1f;E(M.3k(4O)){k.Y.8e+=\';\'+4O;o 4O.1I(\'3S\')?k.6c(4O.1f(/3S:\\s*(\\d?\\.?\\d*)/)[1]):k}18(G 1z 1Q 4O)E(1z==\'3S\')k.6c(4O[1z]);1i 8t[(1z==\'9l\'||1z==\'7p\')?(M.2H(8t.9f)?\'7p\':\'9f\'):1z]=4O[1z];o k},6c:q(k,I){k=$(k);k.Y.3S=(I==1||I===\'\')?\'\':(I<0.78)?0:I;o k},5A:q(k){k=$(k);G 3t=k.2c(\'3t\');E(3t!=\'7G\'&&3t!=1k)o{2f:k.5L,3c:k.5U};G 43=k.Y;G aS=43.8x;G a6=43.1x;G a5=43.3t;43.8x=\'51\';43.1x=\'5W\';43.3t=\'hs\';G aN=k.a7;G aU=k.aA;43.3t=a5;43.1x=a6;43.8x=aS;o{2f:aN,3c:aU}},hJ:q(k){k=$(k);G 6d=J.2c(k,\'1x\');E(6d==\'5O\'||!6d){k.8P=1v;k.Y.1x=\'6j\';E(1e.1X.4o){k.Y.2m=0;k.Y.2w=0}}o k},hH:q(k){k=$(k);E(k.8P){k.8P=4D;k.Y.1x=k.Y.2m=k.Y.2w=k.Y.5q=k.Y.5X=\'\'}o k},hz:q(k){k=$(k);E(k.5a)o k;k.5a=J.2c(k,\'8g\')||\'6f\';E(k.5a!==\'51\')k.Y.8g=\'51\';o k},hC:q(k){k=$(k);E(!k.5a)o k;k.Y.8g=k.5a==\'6f\'?\'\':k.5a;k.5a=1k;o k},4r:q(k){G 2O=0,2K=0;do{2O+=k.5b||0;2K+=k.4Y||0;k=k.2N}1N(k);o J.4k(2K,2O)},6H:q(k){G 2O=0,2K=0;do{2O+=k.5b||0;2K+=k.4Y||0;k=k.2N;E(k){E(k.15.2o()==\'aC\')2i;G p=J.2c(k,\'1x\');E(p!==\'5O\')2i}}1N(k);o J.4k(2K,2O)},9M:q(k){k=$(k);E(k.2c(\'1x\')==\'5W\')o k;G 9P=k.6H();G 2m=9P[1];G 2w=9P[0];G 2f=k.a7;G 3c=k.aA;k.aG=2w-4W(k.Y.2w||0);k.aO=2m-4W(k.Y.2m||0);k.aw=k.Y.2f;k.aH=k.Y.3c;k.Y.1x=\'5W\';k.Y.2m=2m+\'3i\';k.Y.2w=2w+\'3i\';k.Y.2f=2f+\'3i\';k.Y.3c=3c+\'3i\';o k},9k:q(k){k=$(k);E(k.2c(\'1x\')==\'6j\')o k;k.Y.1x=\'6j\';G 2m=4W(k.Y.2m||0)-(k.aO||0);G 2w=4W(k.Y.2w||0)-(k.aG||0);k.Y.2m=2m+\'3i\';k.Y.2w=2w+\'3i\';k.Y.3c=k.aH;k.Y.2f=k.aw;o k},94:q(k){G 2O=0,2K=0;do{2O+=k.4h||0;2K+=k.4f||0;k=k.1S}1N(k);o J.4k(2K,2O)},62:q(k){E(k.2N)o $(k.2N);E(k==1b.2b)o $(k);1N((k=k.1S)&&k!=1b.2b)E(J.2c(k,\'1x\')!=\'5O\')o $(k);o $(1b.2b)},70:q(9I){G 2O=0,2K=0;G k=9I;do{2O+=k.5b||0;2K+=k.4Y||0;E(k.2N==1b.2b&&J.2c(k,\'1x\')==\'5W\')2i}1N(k=k.2N);k=9I;do{E(!1e.1X.4o||(k.15&&(k.15.2o()==\'aC\'))){2O-=k.4h||0;2K-=k.4f||0}}1N(k=k.1S);o J.4k(2K,2O)},cd:q(k,25){G V=M.17({aB:1v,aM:1v,af:1v,ak:1v,5b:0,4Y:0},1q[2]||{});25=$(25);G p=25.70();k=$(k);G 5Y=[0,0];G 2Y=1k;E(J.2c(k,\'1x\')==\'5W\'){2Y=k.62();5Y=2Y.70()}E(2Y==1b.2b){5Y[0]-=1b.2b.4Y;5Y[1]-=1b.2b.5b}E(V.aB)k.Y.2w=(p[0]-5Y[0]+V.4Y)+\'3i\';E(V.aM)k.Y.2m=(p[1]-5Y[1]+V.5b)+\'3i\';E(V.af)k.Y.2f=25.5L+\'3i\';E(V.ak)k.Y.3c=25.5U+\'3i\';o k}};J.1c.8o.ah=1;M.17(J.1c,{h6:J.1c.2A,gH:J.1c.au});J.3Q={6E:{3E:{1l:\'6V\',aR:\'18\'},1W:{}}};E(1e.1X.4o){J.1c.2c=J.1c.2c.4N(q(2U,k,Y){5k(Y){2j\'2w\':2j\'2m\':2j\'5X\':2j\'5q\':E(2U(k,\'1x\')===\'5O\')o 1k;2j\'3c\':2j\'2f\':E(!J.9E(k))o 1k;G 7R=av(2U(k,Y),10);E(7R!==k[\'3a\'+Y.6v()])o 7R+\'3i\';G 3j;E(Y===\'3c\'){3j=[\'81-2m-2f\',\'85-2m\',\'85-5q\',\'81-5q-2f\']}1i{3j=[\'81-2w-2f\',\'85-2w\',\'85-5X\',\'81-5X-2f\']}o 3j.3C(7R,q(2T,1z){G 97=2U(k,1z);o 97===1k?2T:2T-av(97,10)})+\'3i\';64:o 2U(k,Y)}});J.1c.57=J.1c.57.4N(q(2U,k,1T){E(1T===\'7N\')o k.7N;o 2U(k,1T)})}1i E(1e.1X.44){J.1c.62=J.1c.62.4N(q(2U,k){k=$(k);24{k.2N}2a(e){o $(1b.2b)}G 1x=k.2c(\'1x\');E(1x!==\'5O\')o 2U(k);k.5z({1x:\'6j\'});G I=2U(k);k.5z({1x:1x});o I});$w(\'6H 70\').1E(q(1B){J.1c[1B]=J.1c[1B].4N(q(2U,k){k=$(k);24{k.2N}2a(e){o J.4k(0,0)}G 1x=k.2c(\'1x\');E(1x!==\'5O\')o 2U(k);G 2N=k.62();E(2N&&2N.2c(\'1x\')===\'gQ\')2N.5z({9U:1});k.5z({1x:\'6j\'});G I=2U(k);k.5z({1x:1x});o I})});J.1c.4r=J.1c.4r.4N(q(2U,k){24{k.2N}2a(e){o J.4k(0,0)}o 2U(k)});J.1c.2c=q(k,Y){k=$(k);Y=(Y==\'9l\'||Y==\'7p\')?\'9f\':Y.9g();G I=k.Y[Y];E(!I&&k.5d)I=k.5d[Y];E(Y==\'3S\'){E(I=(k.2c(\'2h\')||\'\').1f(/a1\\(3S=(.*)\\)/))E(I[1])o 4W(I[1])/aQ;o 1.0}E(I==\'6f\'){E((Y==\'2f\'||Y==\'3c\')&&(k.2c(\'3t\')!=\'7G\'))o k[\'3a\'+Y.6v()]+\'3i\';o 1k}o I};J.1c.6c=q(k,I){q 9R(2h){o 2h.1U(/a1\\([^\\)]*\\)/gi,\'\')}k=$(k);G 5d=k.5d;E((5d&&!5d.gS)||(!5d&&k.Y.9U==\'cJ\'))k.Y.9U=1;G 2h=k.2c(\'2h\'),Y=k.Y;E(I==1||I===\'\'){(2h=9R(2h))?Y.2h=2h:Y.9x(\'2h\');o k}1i E(I<0.78)I=0;Y.2h=9R(2h)+\'a1(3S=\'+(I*aQ)+\')\';o k};J.3Q={7r:{3E:{\'6V\':\'1l\',\'18\':\'aR\'},1W:{7b:q(k,1T){o k.9V(1T,2)},aP:q(k,1T){G L=k.cS(1T);o L?L.I:""},2s:q(k,1T){1T=k.9V(1T);o 1T?1T.2I().3u(23,-2):1k},6R:q(k,1T){o $(k).3T(1T)?1T:1k},Y:q(k){o k.Y.8e.2e()},7N:q(k){o k.7N}}}};J.3Q.6E={3E:M.17({gR:\'gM\',gP:\'gW\'},J.3Q.7r.3E),1W:{3O:q(k,I){k.3O=!!I},Y:q(k,I){k.Y.8e=I?I:\'\'}}};J.3Q.8E={};$w(\'h4 h2 gX gZ h0 7K \'+\'gL gK gw gy gu\').1E(q(2d){J.3Q.6E.3E[2d.2e()]=2d;J.3Q.8E[2d.2e()]=2d});(q(v){M.17(v,{bC:v.7b,bO:v.7b,1s:v.7b,66:v.aP,3v:v.6R,3O:v.6R,gs:v.6R,go:v.6R,gp:v.2s,co:v.2s,gI:v.2s,h7:v.2s,hB:v.2s,hv:v.2s,hx:v.2s,hy:v.2s,hF:v.2s,hM:v.2s,hO:v.2s,hP:v.2s,hG:v.2s,hI:v.2s,hK:v.2s,hu:v.2s,he:v.2s,hf:v.2s})})(J.3Q.7r.1W)}1i E(1e.1X.7x&&/hg:1\\.8\\.0/.2P(4u.4j)){J.1c.6c=q(k,I){k=$(k);k.Y.3S=(I==1)?0.hh:(I===\'\')?\'\':(I<0.78)?0:I;o k}}1i E(1e.1X.4x){J.1c.6c=q(k,I){k=$(k);k.Y.3S=(I==1||I===\'\')?\'\':(I<0.78)?0:I;E(I==1)E(k.15.2o()==\'cW\'&&k.2f){k.2f++;k.2f--}1i 24{G n=1b.aX(\' \');k.69(n);k.6C(n)}2a(e){}o k};J.1c.4r=q(k){G 2O=0,2K=0;do{2O+=k.5b||0;2K+=k.4Y||0;E(k.2N==1b.2b)E(J.2c(k,\'1x\')==\'5W\')2i;k=k.2N}1N(k);o J.4k(2K,2O)}}E(1e.1X.44||1e.1X.4o){J.1c.52=q(k,19){k=$(k);E(19&&19.3r)19=19.3r();E(M.4v(19))o k.52().3G(19);19=M.4i(19);G 15=k.15.2o();E(15 1Q J.6e.4A){$A(k.3l).1E(q(L){k.6C(L)});J.84(15,19.47()).1E(q(L){k.69(L)})}1i k.59=19.47();19.58.2F(19).4S();o k}}E(\'a9\'1Q 1b.42(\'1P\')){J.1c.1U=q(k,19){k=$(k);E(19&&19.3r)19=19.3r();E(M.4v(19)){k.1S.8y(19,k);o k}19=M.4i(19);G 2Y=k.1S,15=2Y.15.2o();E(J.6e.4A[15]){G 4m=k.6K();G 8v=J.84(15,19.47());2Y.6C(k);E(4m)8v.1E(q(L){2Y.7M(L,4m)});1i 8v.1E(q(L){2Y.69(L)})}1i k.a9=19.47();19.58.2F(19).4S();o k}}J.4k=q(l,t){G 1r=[l,t];1r.2w=l;1r.2m=t;o 1r};J.84=q(15,7Q){G 1P=1t J(\'1P\'),t=J.6e.4A[15];E(t){1P.59=t[0]+7Q+t[1];t[2].7E(q(){1P=1P.67})}1i 1P.59=7Q;o $A(1P.3l)};J.6e={5n:q(k,L){k.1S.7M(L,k)},2m:q(k,L){k.7M(L,k.67)},5q:q(k,L){k.69(L)},7c:q(k,L){k.1S.7M(L,k.4m)},4A:{h8:[\'<4H>\',\'</4H>\',1],7t:[\'<4H><6a>\',\'</6a></4H>\',2],cA:[\'<4H><6a><7L>\',\'</7L></6a></4H>\',3],8r:[\'<4H><6a><7L><bG>\',\'</bG></7L></6a></4H>\',4],cR:[\'<2A>\',\'</2A>\',1]}};(q(){M.17(C.4A,{cM:C.4A.7t,cL:C.4A.7t,cB:C.4A.8r})}).2M(J.6e);J.1c.7n={3T:q(k,1T){1T=J.3Q.8E[1T]||1T;G L=$(k).cS(1T);o!!(L&&L.h9)}};J.1c.3x={};M.17(J,J.1c);E(!1e.3L.6t&&1b.42(\'1P\')[\'5j\']){1F.6u={};1F.6u.1j=1b.42(\'1P\')[\'5j\'];1e.3L.6t=1v}J.17=(q(){E(1e.3L.7o)o 1e.K;G 1c={},3x=J.1c.3x;G 17=M.17(q(k){E(!k||k.7V||k.3B!=1||k==1F)o k;G 2C=M.2E(1c),15=k.15.2o(),1z,I;E(3x[15])M.17(2C,3x[15]);18(1z 1Q 2C){I=2C[1z];E(M.2D(I)&&!(1z 1Q k))k[1z]=I.4C()}k.7V=1e.3h;o k},{7U:q(){E(!1e.3L.6t){M.17(1c,J.1c);M.17(1c,J.1c.7n)}}});17.7U();o 17})();J.3T=q(k,1T){E(k.3T)o k.3T(1T);o J.1c.7n.3T(k,1T)};J.6r=q(2C){G F=1e.3L,T=J.1c.3x;E(!2C){M.17(1C,1C.1c);M.17(1C.J,1C.J.1c);M.17(J.1c.3x,{"ha":M.2E(1C.1c),"hb":M.2E(1C.J.1c),"cR":M.2E(1C.J.1c),"cQ":M.2E(1C.J.1c)})}E(1q.O==2){G 15=2C;2C=1q[1]}E(!15)M.17(J.1c,2C||{});1i{E(M.4E(15))15.1E(17);1i 17(15)}q 17(15){15=15.2o();E(!J.1c.3x[15])J.1c.3x[15]={};M.17(J.1c.3x[15],2C)}q 7i(2C,63,7H){7H=7H||1p;18(G 1z 1Q 2C){G I=2C[1z];E(!M.2D(I))3V;E(!7H||!(1z 1Q 63))63[1z]=I.4C()}}q cv(15){G 1M;G 8Y={"hi":"hq","cQ":"hr","P":"hp","ho":"hk","hl":"hm","hn":"gV","gm":"fh","fi":"fj","fk":"5V","fg":"5V","ff":"5V","fb":"5V","fa":"5V","fc":"5V","Q":"fd","fe":"cY","fl":"cY","A":"fm","cW":"ft","fu":"fv","fw":"cX","fs":"cX","cM":"8Z","cL":"8Z","7t":"8Z","cA":"fr","cB":"cz","8r":"cz","fn":"fo","fp":"eJ"};E(8Y[15])1M=\'8S\'+8Y[15]+\'J\';E(1F[1M])o 1F[1M];1M=\'8S\'+15+\'J\';E(1F[1M])o 1F[1M];1M=\'8S\'+15.6v()+\'J\';E(1F[1M])o 1F[1M];1F[1M]={};1F[1M].1j=1b.42(15)[\'5j\'];o 1F[1M]}E(F.6t){7i(J.1c,6u.1j);7i(J.1c.7n,6u.1j,1v)}E(F.7o){18(G 8L 1Q J.1c.3x){G 1M=cv(8L);E(M.2H(1M))3V;7i(T[8L],1M.1j)}}M.17(J,J.1c);8K J.3x;E(J.17.7U)J.17.7U();J.2W={}};1b.fq={5A:q(){G 6P={},B=1e.1X;$w(\'2f 3c\').1E(q(d){G D=d.6v();E(B.4x&&!1b.2V){6P[d]=5y[\'f9\'+D]}1i E(B.4o&&4W(1F.gn.eR())<9.5){6P[d]=1b.2b[\'cx\'+D]}1i{6P[d]=1b.5u[\'cx\'+D]}});o 6P},cC:q(){o C.5A().2f},cD:q(){o C.5A().3c},eS:q(){o J.4k(1F.c5||1b.5u.4f||1b.2b.4f,1F.c2||1b.5u.4h||1b.2b.4h)}};G 14=2l.2u({2L:q(1u){C.1u=1u.4g();E(C.cI()){C.4R=\'d2\'}1i E(C.cK()){C.4R=\'2p\';C.cG()}1i{C.4R="cJ";C.cF()}},cK:q(){E(!1e.3L.7v)o 1p;G e=C.1u;E(1e.1X.4x&&(e.1I("-2x-1s")||e.1I(":5R")))o 1p;E((/(\\[[\\w-]*?:|:3O)/).2P(e))o 1p;o 1v},cI:q(){E(!1e.3L.cH)o 1p;E(!14.8b)14.8b=1t J(\'1P\');24{14.8b.cE(C.1u)}2a(e){o 1p}o 1v},cF:q(){G e=C.1u,4t=14.6J,h=14.28,c=14.6I,3A,p,m;E(14.5f[e]){C.3P=14.5f[e];o}C.3P=["C.3P = q(1m) {","G r = 1m, h = 14.28, c = 1p, n;"];1N(e&&3A!=e&&(/\\S/).2P(e)){3A=e;18(G i 1Q 4t){p=4t[i];E(m=e.1f(p)){C.3P.1h(M.2D(c[i])?c[i](m):1t 3d(c[i]).2V(m));e=e.1U(m[0],\'\');2i}}}C.3P.1h("o h.9F(n);\\n}");7d(C.3P.2B(\'\\n\'));14.5f[C.1u]=C.3P},cG:q(){G e=C.1u,4t=14.6J,x=14.2p,3A,m;E(14.5f[e]){C.2p=14.5f[e];o}C.3P=[\'.//*\'];1N(e&&3A!=e&&(/\\S/).2P(e)){3A=e;18(G i 1Q 4t){E(m=e.1f(4t[i])){C.3P.1h(M.2D(x[i])?x[i](m):1t 3d(x[i]).2V(m));e=e.1U(m[0],\'\');2i}}}C.2p=C.3P.2B(\'\');14.5f[C.1u]=C.2p},80:q(1m){1m=1m||1b;G e=C.1u,U;5k(C.4R){2j\'d2\':E(1m!==1b){G d9=1m.1o,1o=$(1m).8o();e="#"+1o+" "+e}U=$A(1m.eT(e)).2Q(J.17);1m.1o=d9;o U;2j\'2p\':o 1b.8k(C.2p,1m);64:o C.3P(1m)}},1f:q(k){C.8c=[];G e=C.1u,4t=14.6J,as=14.9Q;G 3A,p,m;1N(e&&3A!==e&&(/\\S/).2P(e)){3A=e;18(G i 1Q 4t){p=4t[i];E(m=e.1f(p)){E(as[i]){C.8c.1h([i,M.2E(m)]);e=e.1U(m[0],\'\')}1i{o C.80(1b).1I(k)}}}}G 1f=1v,1d,2q;18(G i=0,7D;7D=C.8c[i];i++){1d=7D[0],2q=7D[1];E(!14.9Q[1d](k,2q)){1f=1p;2i}}o 1f},2I:q(){o C.1u},2G:q(){o"#<14:"+C.1u.2G()+">"}});M.17(14,{5f:{},2p:{4T:"//*",1H:"/*",50:"/6N-4F::*[1]",6T:\'/6N-4F::*\',15:q(m){E(m[1]==\'*\')o\'\';o"[d7-1d()=\'"+m[1].2e()+"\' d6 d7-1d()=\'"+m[1].2o()+"\']"},1l:"[5m(1R(\' \', @6V, \' \'), \' #{1} \')]",1o:"[@1o=\'#{1}\']",5E:q(m){m[1]=m[1].2e();o 1t 3d("[@#{1}]").2V(m)},2d:q(m){m[1]=m[1].2e();m[3]=m[5]||m[6];o 1t 3d(14.2p.6i[m[2]]).2V(m)},6n:q(m){G h=14.2p.2k[m[1]];E(!h)o\'\';E(M.2D(h))o h(m);o 1t 3d(14.2p.2k[m[1]]).2V(m)},6i:{\'=\':"[@#{1}=\'#{3}\']",\'!=\':"[@#{1}!=\'#{3}\']",\'^=\':"[eU-eQ(@#{1}, \'#{3}\')]",\'$=\':"[5K(@#{1}, (3o-O(@#{1}) - 3o-O(\'#{3}\') + 1))=\'#{3}\']",\'*=\':"[5m(@#{1}, \'#{3}\')]",\'~=\':"[5m(1R(\' \', @#{1}, \' \'), \' #{3} \')]",\'|=\':"[5m(1R(\'-\', @#{1}, \'-\'), \'-#{3}-\')]"},2k:{\'3M-1H\':\'[4M(a4-4F::*)]\',\'2v-1H\':\'[4M(6N-4F::*)]\',\'6m-1H\':\'[4M(a4-4F::* d6 6N-4F::*)]\',\'5R\':"[3s(*) = 0 6G (3s(4d()) = 0)]",\'3O\':"[@3O]",\'3v\':"[(@3v) 6G (@1s!=\'51\')]",\'bz\':"[4M(@3v) 6G (@1s!=\'51\')]",\'4M\':q(m){G e=m[6],p=14.6J,x=14.2p,3A,v;G 9Z=[];1N(e&&3A!=e&&(/\\S/).2P(e)){3A=e;18(G i 1Q p){E(m=e.1f(p[i])){v=M.2D(x[i])?x[i](m):1t 3d(x[i]).2V(m);9Z.1h("("+v.5K(1,v.O-1)+")");e=e.1U(m[0],\'\');2i}}}o"[4M("+9Z.2B(" 6G ")+")]"},\'21-1H\':q(m){o 14.2p.2k.21("(3s(./a4-4F::*) + 1) ",m)},\'21-2v-1H\':q(m){o 14.2p.2k.21("(3s(./6N-4F::*) + 1) ",m)},\'21-2x-1s\':q(m){o 14.2p.2k.21("1x() ",m)},\'21-2v-2x-1s\':q(m){o 14.2p.2k.21("(2v() + 1 - 1x()) ",m)},\'3M-2x-1s\':q(m){m[6]="1";o 14.2p.2k[\'21-2x-1s\'](m)},\'2v-2x-1s\':q(m){m[6]="1";o 14.2p.2k[\'21-2v-2x-1s\'](m)},\'6m-2x-1s\':q(m){G p=14.2p.2k;o p[\'3M-2x-1s\'](m)+p[\'2v-2x-1s\'](m)},21:q(5F,m){G 3Y,1K=m[6],9W;E(1K==\'br\')1K=\'2n+0\';E(1K==\'bs\')1K=\'2n+1\';E(3Y=1K.1f(/^(\\d+)$/))o\'[\'+5F+"= "+3Y[1]+\']\';E(3Y=1K.1f(/^(-?\\d*)?n(([+-])(\\d+))?/)){E(3Y[1]=="-")3Y[1]=-1;G a=3Y[1]?54(3Y[1]):1;G b=3Y[2]?54(3Y[2]):0;9W="[((#{5F} - #{b}) eP #{a} = 0) 6G "+"((#{5F} - #{b}) 1P #{a} >= 0)]";o 1t 3d(9W).2V({5F:5F,a:a,b:b})}}}},6I:{15:\'n = h.15(n, r, "#{1}", c);      c = 1p;\',1l:\'n = h.1l(n, r, "#{1}", c);    c = 1p;\',1o:\'n = h.1o(n, r, "#{1}", c);           c = 1p;\',5E:\'n = h.5E(n, r, "#{1}", c); c = 1p;\',2d:q(m){m[3]=(m[5]||m[6]);o 1t 3d(\'n = h.2d(n, r, "#{1}", "#{3}", "#{2}", c); c = 1p;\').2V(m)},6n:q(m){E(m[6])m[6]=m[6].1U(/"/g,\'\\\\"\');o 1t 3d(\'n = h.6n(n, "#{1}", "#{6}", r, c); c = 1p;\').2V(m)},4T:\'c = "4T";\',1H:\'c = "1H";\',50:\'c = "50";\',6T:\'c = "6T";\'},6J:{6T:/^\\s*~\\s*/,1H:/^\\s*>\\s*/,50:/^\\s*\\+\\s*/,4T:/^\\s/,15:/^\\s*(\\*|[\\w\\-]+)(\\b|$)?/,1o:/^#([\\w\\-\\*]+)(\\b|$)/,1l:/^\\.([\\w\\-\\*]+)(\\b|$)/,6n:/^:((3M|2v|21|21-2v|6m)(-1H|-2x-1s)|5R|3O|(en|eL)eK|4M)(\\((.*?)\\))?(\\b|$|(?=\\s|[:+~>]))/,5E:/^\\[((?:[\\w]+:)?[\\w]+)\\]/,2d:/\\[((?:[\\w-]*:)?[\\w-]+)\\s*(?:([!^$*~|]?=)\\s*(([\'"])([^\\4]*?)\\4|([^\'"][^\\]]*?)))?\\]/},9Q:{15:q(k,2q){o 2q[1].2o()==k.15.2o()},1l:q(k,2q){o J.7Y(k,2q[1])},1o:q(k,2q){o k.1o===2q[1]},5E:q(k,2q){o J.3T(k,2q[1])},2d:q(k,2q){G 4p=J.57(k,2q[1]);o 4p&&14.6i[2q[2]](4p,2q[5]||2q[6])}},28:{1R:q(a,b){18(G i=0,L;L=b[i];i++)a.1h(L);o a},7X:q(N){G da=1e.3h;18(G i=0,L;L=N[i];i++)L.3K=da;o N},4Z:q(N){18(G i=0,L;L=N[i];i++)L.3K=4D;o N},1n:q(1S,4w,6k){1S.3K=1e.3h;E(4w){18(G N=1S.3l,i=N.O-1,j=1;i>=0;i--){G L=N[i];E(L.3B==1&&(!6k||L.3K))L.79=j++}}1i{18(G i=0,j=1,N=1S.3l;L=N[i];i++)E(L.3B==1&&(!6k||L.3K))L.79=j++}},9F:q(N){E(N.O==0)o N;G U=[],n;18(G i=0,l=N.O;i<l;i++)E(!(n=N[i]).3K){n.3K=1e.3h;U.1h(J.17(n))}o 14.28.4Z(U)},4T:q(N){G h=14.28;18(G i=0,U=[],L;L=N[i];i++)h.1R(U,L.4e(\'*\'));o U},1H:q(N){G h=14.28;18(G i=0,U=[],L;L=N[i];i++){18(G j=0,1H;1H=L.3l[j];j++)E(1H.3B==1&&1H.15!=\'!\')U.1h(1H)}o U},50:q(N){18(G i=0,U=[],L;L=N[i];i++){G 6K=C.6U(L);E(6K)U.1h(6K)}o U},6T:q(N){G h=14.28;18(G i=0,U=[],L;L=N[i];i++)h.1R(U,J.4Q(L));o U},6U:q(L){1N(L=L.4m)E(L.3B==1)o L;o 1k},6o:q(L){1N(L=L.ct)E(L.3B==1)o L;o 1k},15:q(N,1m,15,29){G bw=15.2o();G U=[],h=14.28;E(N){E(29){E(29=="4T"){18(G i=0,L;L=N[i];i++)h.1R(U,L.4e(15));o U}1i N=C[29](N);E(15=="*")o N}18(G i=0,L;L=N[i];i++)E(L.15.2o()===bw)U.1h(L);o U}1i o 1m.4e(15)},1o:q(N,1m,1o,29){G 3f=$(1o),h=14.28;E(!3f)o[];E(!N&&1m==1b)o[3f];E(N){E(29){E(29==\'1H\'){18(G i=0,L;L=N[i];i++)E(3f.1S==L)o[3f]}1i E(29==\'4T\'){18(G i=0,L;L=N[i];i++)E(J.77(3f,L))o[3f]}1i E(29==\'50\'){18(G i=0,L;L=N[i];i++)E(14.28.6o(3f)==L)o[3f]}1i N=h[29](N)}18(G i=0,L;L=N[i];i++)E(L==3f)o[3f];o[]}o(3f&&J.77(3f,1m))?[3f]:[]},1l:q(N,1m,1l,29){E(N&&29)N=C[29](N);o 14.28.bx(N,1m,1l)},bx:q(N,1m,1l){E(!N)N=14.28.4T([1m]);G by=\' \'+1l+\' \';18(G i=0,U=[],L,6g;L=N[i];i++){6g=L.1l;E(6g.O==0)3V;E(6g==1l||(\' \'+6g+\' \').1I(by))U.1h(L)}o U},5E:q(N,1m,2d,29){E(!N)N=1m.4e("*");E(N&&29)N=C[29](N);G U=[];18(G i=0,L;L=N[i];i++)E(J.3T(L,2d))U.1h(L);o U},2d:q(N,1m,2d,I,bv,29){E(!N)N=1m.4e("*");E(N&&29)N=C[29](N);G 2g=14.6i[bv],U=[];18(G i=0,L;L=N[i];i++){G 4p=J.57(L,2d);E(4p===1k)3V;E(2g(4p,I))U.1h(L)}o U},6n:q(N,1d,I,1m,29){E(N&&29)N=C[29](N);E(!N)N=1m.4e("*");o 14.2k[1d](N,I,1m)}},2k:{\'3M-1H\':q(N,I,1m){18(G i=0,U=[],L;L=N[i];i++){E(14.28.6o(L))3V;U.1h(L)}o U},\'2v-1H\':q(N,I,1m){18(G i=0,U=[],L;L=N[i];i++){E(14.28.6U(L))3V;U.1h(L)}o U},\'6m-1H\':q(N,I,1m){G h=14.28;18(G i=0,U=[],L;L=N[i];i++)E(!h.6o(L)&&!h.6U(L))U.1h(L);o U},\'21-1H\':q(N,1K,1m){o 14.2k.21(N,1K,1m)},\'21-2v-1H\':q(N,1K,1m){o 14.2k.21(N,1K,1m,1v)},\'21-2x-1s\':q(N,1K,1m){o 14.2k.21(N,1K,1m,1p,1v)},\'21-2v-2x-1s\':q(N,1K,1m){o 14.2k.21(N,1K,1m,1v,1v)},\'3M-2x-1s\':q(N,1K,1m){o 14.2k.21(N,"1",1m,1p,1v)},\'2v-2x-1s\':q(N,1K,1m){o 14.2k.21(N,"1",1m,1v,1v)},\'6m-2x-1s\':q(N,1K,1m){G p=14.2k;o p[\'2v-2x-1s\'](p[\'3M-2x-1s\'](N,1K,1m),1K,1m)},bt:q(a,b,bq){E(a==0)o b>0?[b]:[];o $R(1,bq).3C([],q(2T,i){E(0==(i-b)%a&&(i-b)/a>=0)2T.1h(i);o 2T})},21:q(N,1K,1m,4w,6k){E(N.O==0)o[];E(1K==\'br\')1K=\'2n+0\';E(1K==\'bs\')1K=\'2n+1\';G h=14.28,U=[],9a=[],m;h.7X(N);18(G i=0,L;L=N[i];i++){E(!L.1S.3K){h.1n(L.1S,4w,6k);9a.1h(L.1S)}}E(1K.1f(/^\\d+$/)){1K=54(1K);18(G i=0,L;L=N[i];i++)E(L.79==1K)U.1h(L)}1i E(m=1K.1f(/^(-?\\d*)?n(([+-])(\\d+))?/)){E(m[1]=="-")m[1]=-1;G a=m[1]?54(m[1]):1;G b=m[2]?54(m[2]):0;G 96=14.2k.bt(a,b,N.O);18(G i=0,L,l=96.O;L=N[i];i++){18(G j=0;j<l;j++)E(L.79==96[j])U.1h(L)}}h.4Z(N);h.4Z(9a);o U},\'5R\':q(N,I,1m){18(G i=0,U=[],L;L=N[i];i++){E(L.15==\'!\'||L.67)3V;U.1h(L)}o U},\'4M\':q(N,41,1m){G h=14.28,eM,m;G 9m=1t 14(41).80(1m);h.7X(9m);18(G i=0,U=[],L;L=N[i];i++)E(!L.3K)U.1h(L);h.4Z(9m);o U},\'bz\':q(N,I,1m){18(G i=0,U=[],L;L=N[i];i++)E(!L.3v&&(!L.1s||L.1s!==\'51\'))U.1h(L);o U},\'3v\':q(N,I,1m){18(G i=0,U=[],L;L=N[i];i++)E(L.3v)U.1h(L);o U},\'3O\':q(N,I,1m){18(G i=0,U=[],L;L=N[i];i++)E(L.3O)U.1h(L);o U}},6i:{\'=\':q(1Z,v){o 1Z==v},\'!=\':q(1Z,v){o 1Z!=v},\'^=\':q(1Z,v){o 1Z==v||1Z&&1Z.9B(v)},\'$=\':q(1Z,v){o 1Z==v||1Z&&1Z.9A(v)},\'*=\':q(1Z,v){o 1Z==v||1Z&&1Z.1I(v)},\'$=\':q(1Z,v){o 1Z.9A(v)},\'*=\':q(1Z,v){o 1Z.1I(v)},\'~=\':q(1Z,v){o(\' \'+1Z+\' \').1I(\' \'+v+\' \')},\'|=\':q(1Z,v){o(\'-\'+(1Z||"").2o()+\'-\').1I(\'-\'+(v||"").2o()+\'-\')}},4n:q(1u){G 4I=[];1u.bH(/(([\\w#:.~>+()\\s-]+|\\*|\\[.*?\\])+)\\s*(,|$)/,q(m){4I.1h(m[1].4g())});o 4I},bI:q(1Y,1u){G 2q=$$(1u),h=14.28;h.7X(2q);18(G i=0,U=[],k;k=1Y[i];i++)E(k.3K)U.1h(k);h.4Z(2q);o U},68:q(1Y,1u,1n){E(M.55(1u)){1n=1u;1u=1p}o 14.bI(1Y,1u||\'*\')[1n||0]},7S:q(k,4I){4I=14.4n(4I.2B(\',\'));G U=[],h=14.28;18(G i=0,l=4I.O,41;i<l;i++){41=1t 14(4I[i].4g());h.1R(U,41.80(k))}o(l>1)?h.9F(U):U}});E(1e.1X.44){M.17(14.28,{1R:q(a,b){18(G i=0,L;L=b[i];i++)E(L.15!=="!")a.1h(L);o a},4Z:q(N){18(G i=0,L;L=N[i];i++)L.9x(\'3K\');o N}})}q $$(){o 14.7S(1b,$A(1q))}G 1C={9i:q(1y){$(1y).9i();o 1y},cu:q(1Y,V){E(3g V!=\'W\')V={3D:!!V};1i E(M.2H(V.3D))V.3D=1v;G 1w,I,9q=1p,5e=V.5e;G 7B=1Y.3C({},q(1r,k){E(!k.3v&&k.1d){1w=k.1d;I=$(k).31();E(I!=1k&&k.1s!=\'eN\'&&(k.1s!=\'5e\'||(!9q&&5e!==1p&&(!5e||1w==5e)&&(9q=1v)))){E(1w 1Q 1r){E(!M.4E(1r[1w]))1r[1w]=[1r[1w]];1r[1w].1h(I)}1i 1r[1w]=I}}o 1r});o V.3D?7B:M.4K(7B)}};1C.1c={73:q(1y,V){o 1C.cu(1C.5B(1y),V)},5B:q(1y){o $A($(1y).4e(\'*\')).3C([],q(1Y,1H){E(1C.J.5I[1H.15.2e()])1Y.1h(J.17(1H));o 1Y})},eO:q(1y,7P,1d){1y=$(1y);G 7J=1y.4e(\'4c\');E(!7P&&!1d)o $A(7J).2Q(J.17);18(G i=0,9s=[],O=7J.O;i<O;i++){G 4c=7J[i];E((7P&&4c.1s!=7P)||(1d&&4c.1d!=1d))3V;9s.1h(J.17(4c))}o 9s},9d:q(1y){1y=$(1y);1C.5B(1y).9t(\'9d\');o 1y},9e:q(1y){1y=$(1y);1C.5B(1y).9t(\'9e\');o 1y},bB:q(1y){G 1Y=$(1y).5B().5M(q(k){o\'51\'!=k.1s&&!k.3v});G 9u=1Y.5M(q(k){o k.3T(\'7K\')&&k.7K>=0}).bF(q(k){o k.7K}).3M();o 9u?9u:1Y.9j(q(k){o[\'4c\',\'2A\',\'9Y\'].1I(k.15.2e())})},eV:q(1y){1y=$(1y);1y.bB().bp();o 1y},2R:q(1y,V){1y=$(1y),V=M.2E(V||{});G 3e=V.3J,66=1y.57(\'66\')||\'\';E(66.53())66=1F.83.bC;V.3J=1y.73(1v);E(3e){E(M.3k(3e))3e=3e.7T();M.17(V.3J,3e)}E(1y.3T(\'1B\')&&!V.1B)V.1B=1y.1B;o 1t 1O.5g(66,V)}};1C.J={9c:q(k){$(k).9c();o k},2A:q(k){$(k).2A();o k}};1C.J.1c={73:q(k){k=$(k);E(!k.3v&&k.1d){G I=k.31();E(I!=4D){G 1J={};1J[k.1d]=I;o M.4K(1J)}}o\'\'},31:q(k){k=$(k);G 1B=k.15.2e();o 1C.J.5I[1B](k)},eW:q(k,I){k=$(k);G 1B=k.15.2e();1C.J.5I[1B](k,I);o k},bE:q(k){$(k).I=\'\';o k},f4:q(k){o $(k).I!=\'\'},bp:q(k){k=$(k);24{k.9c();E(k.2A&&(k.15.2e()!=\'4c\'||![\'8R\',\'9i\',\'5e\'].1I(k.1s)))k.2A()}2a(e){}o k},9d:q(k){k=$(k);k.3v=1v;o k},9e:q(k){k=$(k);k.3v=1p;o k}};G f5=1C.J;G $F=1C.J.1c.31;1C.J.5I={4c:q(k,I){5k(k.1s.2e()){2j\'b4\':2j\'91\':o 1C.J.5I.b9(k,I);64:o 1C.J.5I.9Y(k,I)}},b9:q(k,I){E(M.2H(I))o k.3O?k.I:1k;1i k.3O=!!I},9Y:q(k,I){E(M.2H(I))o k.I;1i k.I=I},2A:q(k,I){E(M.2H(I))o C[k.1s==\'2A-f6\'?\'bb\':\'bc\'](k);1i{G 3I,7k,ba=!M.4E(I);18(G i=0,O=k.O;i<O;i++){3I=k.V[i];7k=C.82(3I);E(ba){E(7k==I){3I.9L=1v;o}}1i 3I.9L=I.1I(7k)}}},bb:q(k){G 1n=k.f7;o 1n>=0?C.82(k.V[1n]):1k},bc:q(k){G 1W,O=k.O;E(!O)o 1k;18(G i=0,1W=[];i<O;i++){G 3I=k.V[i];E(3I.9L)1W.1h(C.82(3I))}o 1W},82:q(3I){o J.17(3I).3T(\'I\')?3I.I:3I.4d}};4U.8m=2l.2u(b8,{2L:q($49,k,4a,3b){$49(3b,4a);C.k=$(k);C.4G=C.31()},8i:q(){G I=C.31();E(M.3k(C.4G)&&M.3k(I)?C.4G!=I:22(C.4G)!=22(I)){C.3b(C.k,I);C.4G=I}}});1C.J.b7=2l.2u(4U.8m,{31:q(){o 1C.J.31(C.k)}});1C.b7=2l.2u(4U.8m,{31:q(){o 1C.73(C.k)}});4U.75=2l.2u({2L:q(k,3b){C.k=$(k);C.3b=3b;C.4G=C.31();E(C.k.15.2e()==\'1y\')C.b3();1i C.74(C.k)},8N:q(){G I=C.31();E(C.4G!=I){C.3b(C.k,I);C.4G=I}},b3:q(){1C.5B(C.k).1E(C.74,C)},74:q(k){E(k.1s){5k(k.1s.2e()){2j\'b4\':2j\'91\':1D.4B(k,\'cf\',C.8N.2F(C));2i;64:1D.4B(k,\'f3\',C.8N.2F(C));2i}}}});1C.J.75=2l.2u(4U.75,{31:q(){o 1C.J.31(C.k)}});1C.75=2l.2u(4U.75,{31:q(){o 1C.73(C.k)}});E(!1F.1D)G 1D={};M.17(1D,{f2:8,eY:9,eX:13,eZ:27,f0:37,f1:38,fx:39,fy:40,g5:46,g6:36,g7:35,g8:33,g4:34,g3:45,2W:{},9D:q(1a){G k;5k(1a.1s){2j\'fZ\':k=1a.fY;2i;2j\'g0\':k=1a.3r;2i;64:o 1k}o J.17(k)}});1D.1c=(q(){G 5i;E(1e.1X.44){G bK={0:1,1:4,2:2};5i=q(1a,5t){o 1a.8R==bK[5t]}}1i E(1e.1X.4x){5i=q(1a,5t){5k(5t){2j 0:o 1a.7f==1&&!1a.ce;2j 1:o 1a.7f==1&&1a.ce;64:o 1p}}}1i{5i=q(1a,5t){o 1a.7f?(1a.7f===5t+1):(1a.8R===5t)}}o{g1:q(1a){o 5i(1a,0)},g2:q(1a){o 5i(1a,1)},g9:q(1a){o 5i(1a,2)},k:q(1a){1a=1D.17(1a);G L=1a.7w,1s=1a.1s,5r=1a.5r;E(5r&&5r.15){E(1s===\'bN\'||1s===\'cs\'||(1s===\'cf\'&&5r.15.2e()===\'4c\'&&5r.1s===\'91\'))L=5r}E(L){E(L.3B==76.cg)L=L.1S;o J.17(L)}1i o 1p},68:q(1a,1u){G k=1D.k(1a);E(!1u)o k;G 1Y=[k].1R(k.5H());o 14.68(1Y,1u,0)},5p:q(1a){G 6Z=1b.5u,2b=1b.2b||{4f:0,4h:0};o{x:1a.cq||(1a.ga+(6Z.4f||2b.4f)-(6Z.gh||0)),y:1a.cr||(1a.gj+(6Z.4h||2b.4h)-(6Z.gk||0))}},gl:q(1a){o 1D.5p(1a).x},gg:q(1a){o 1D.5p(1a).y},9w:q(1a){1D.17(1a);1a.ci();1a.cb();1a.gf=1v}}})();1D.17=(q(){G 2C=M.4q(1D.1c).3C({},q(m,1d){m[1d]=1D.1c[1d].4C();o m});E(1e.1X.44){M.17(2C,{cb:q(){C.gb=1v},ci:q(){C.86=1p},2G:q(){o"[W 1D]"}});o q(1a){E(!1a)o 1p;E(1a.7V)o 1a;1a.7V=1e.3h;G 5p=1D.5p(1a);M.17(1a,{7w:1a.gc,9D:1D.9D(1a),cq:5p.x,cr:5p.y});o M.17(1a,2C)}}1i{1D.1j=1D.1j||1b.6M("c7")[\'5j\'];M.17(1D.1j,2C);o 1e.K}})();M.17(1D,(q(){G 2W=1D.2W;q 9H(k){24{E(k.93)o k.93[0];1q.5C.1o=1q.5C.1o||1;o k.93=[++1q.5C.1o]}2a(cs){o 1p}}q a0(1A){E(1A&&1A.1I(\':\'))o"c6";o 1A}q 7I(1o){o 2W[1o]=2W[1o]||{}}q 87(1o,1A){G c=7I(1o);o c[1A]=c[1A]||[]}q ck(k,1A,2g){G 1o=9H(k);G c=87(1o,1A);E(c.5x("2g").1I(2g))o 1p;G 1L=q(1a){E(!1D||!1D.17||(1a.1A&&1a.1A!=1A))o 1p;1D.17(1a);2g.2M(k,1a)};1L.2g=2g;c.1h(1L);o 1L}q a3(1o,1A,2g){G c=87(1o,1A);o c.9j(q(1L){o 1L.2g==2g})}q cm(1o,1A,2g){G c=7I(1o);E(!c[1A])o 1p;c[1A]=c[1A].6z(a3(1o,1A,2g))}q cj(){18(G 1o 1Q 2W)18(G 1A 1Q 2W[1o])2W[1o][1A]=1k}E(1F.7Z){1F.7Z("co",cj)}E(1e.1X.4x){1F.6O(\'gd\',1e.3h,1p)}o{4B:q(k,1A,2g){k=$(k);G 1d=a0(1A);G 1L=ck(k,1A,2g);E(!1L)o k;E(k.6O){k.6O(1d,1L,1p)}1i{k.7Z("5G"+1d,1L)}o k},5l:q(k,1A,2g){k=$(k);G 1o=9H(k),1d=a0(1A);E(!2g&&1A){87(1o,1A).1E(q(1L){k.5l(1A,1L.2g)});o k}1i E(!1A){M.4q(7I(1o)).1E(q(1A){k.5l(1A)});o k}G 1L=a3(1o,1A,2g);E(!1L)o k;E(k.cl){k.cl(1d,1L,1p)}1i{k.ge("5G"+1d,1L)}cm(1o,1A,2g);o k},5D:q(k,1A,2T){k=$(k);E(k==1b&&1b.6M&&!k.bT)k=1b.5u;G 1a;E(1b.6M){1a=1b.6M("c7");1a.fX("c6",1v,1v)}1i{1a=1b.fW();1a.bR="fG"}1a.1A=1A;1a.2T=2T||{};E(1b.6M){k.bT(1a)}1i{k.fH(1a.bR,1a)}o 1D.17(1a)}}})());M.17(1D,1D.1c);J.6r({5D:1D.5D,4B:1D.4B,5l:1D.5l});M.17(1b,{5D:J.1c.5D.4C(),4B:J.1c.4B.4C(),5l:J.1c.5l.4C(),6Q:1p});(q(){G 3Z;q 6s(){E(1b.6Q)o;E(3Z)1F.bQ(3Z);1b.5D("fI:6Q");1b.6Q=1v}E(1b.6O){E(1e.1X.4x){3Z=1F.bM(q(){E(/6Q|bV/.2P(1b.2S))6s()},0);1D.4B(1F,"bN",6s)}1i{1b.6O("fJ",6s,1p)}}1i{1b.6E("<5v 1o=bP 4S bO=//:><\\/5v>");$("bP").7m=q(){E(C.2S=="bV"){C.7m=1k;6s()}}}})();3X.4K=M.4K;G fF={3t:J.bW};J.1c.fE=J.1c.77;G fA={fz:q(k,19){o J.3G(k,{5n:19})},fB:q(k,19){o J.3G(k,{2m:19})},fC:q(k,19){o J.3G(k,{5q:19})},fD:q(k,19){o J.3G(k,{7c:19})}};G $3V=1t fK(\'"4J $3V" fL fS, fT "o" fU\');G 9J={c1:1p,a2:q(){C.bZ=1F.c5||1b.5u.4f||1b.2b.4f||0;C.c0=1F.c2||1b.5u.4h||1b.2b.4h||0},fV:q(k,x,y){E(C.c1)o C.bX(k,x,y);C.6q=x;C.6y=y;C.3a=J.4r(k);o(y>=C.3a[1]&&y<C.3a[1]+k.5U&&x>=C.3a[0]&&x<C.3a[0]+k.5L)},bX:q(k,x,y){G 8C=J.94(k);C.6q=x+8C[0]-C.bZ;C.6y=y+8C[1]-C.c0;C.3a=J.4r(k);o(C.6y>=C.3a[1]&&C.6y<C.3a[1]+k.5U&&C.6q>=C.3a[0]&&C.6q<C.3a[0]+k.5L)},fR:q(4R,k){E(!4R)o 0;E(4R==\'fQ\')o((C.3a[1]+k.5U)-C.6y)/k.5U;E(4R==\'fM\')o((C.3a[0]+k.5L)-C.6q)/k.5L},4r:J.1c.4r,6H:J.1c.6H,9M:q(k){9J.a2();o J.9M(k)},9k:q(k){9J.a2();o J.9k(k)},fN:J.1c.94,2N:J.1c.62,fO:J.1c.70,2E:q(25,7w,V){V=V||{};o J.cd(7w,25,V)}};E(!1b.7e)1b.7e=q(bL){q 8l(1d){o 1d.53()?1k:"[5m(1R(\' \', @6V, \' \'), \' "+1d+" \')]"}bL.7e=1e.3L.7v?q(k,1l){1l=1l.2I().4g();G 8p=/\\s/.2P(1l)?$w(1l).2Q(8l).2B(\'\'):8l(1l);o 8p?1b.8k(\'.//*\'+8p,k):[]}:q(k,1l){1l=1l.2I().4g();G 1Y=[],6p=(/\\s/.2P(1l)?$w(1l):1k);E(!6p&&!1l)o 1Y;G N=$(k).4e(\'*\');1l=\' \'+1l+\' \';18(G i=0,1H,cn;1H=N[i];i++){E(1H.1l&&(cn=\' \'+1H.1l+\' \')&&(cn.1I(1l)||(6p&&6p.9p(q(1d){o!1d.2I().53()&&cn.1I(\' \'+1d+\' \')}))))1Y.1h(J.17(1H))}o 1Y};o q(1l,7s){o $(7s||1b.2b).7e(1l)}}(J.1c);J.7W=2l.2u();J.7W.1j={2L:q(k){C.k=$(k)},4y:q(1g){C.k.1l.4n(/\\s+/).2A(q(1d){o 1d.O>0}).4y(1g)},6w:q(1l){C.k.1l=1l},fP:q(8q){E(C.1I(8q))o;C.6w($A(C).1R(8q).2B(\' \'))},d3:q(8F){E(!C.1I(8F))o;C.6w($A(C).6z(8F).2B(\' \'))},2I:q(){o $A(C).2B(\' \')}};M.17(J.7W.1j,2J);J.6r();',62,1106,'||||||||||||||||||||element||||return||function||||||||||||this||if||var||value|Element||node|Object|nodes|length||||||results|options|object||style||||||Selector|tagName||extend|for|content|event|document|Methods|name|Prototype|match|iterator|push|else|prototype|null|className|root|index|id|false|arguments|result|type|new|expression|true|key|position|form|property|eventName|method|Form|Event|each|window|context|child|include|pair|formula|wrapper|klass|while|Ajax|div|in|concat|parentNode|attribute|replace|args|values|Browser|elements|nv|transport|nth|String||try|source|pattern||handlers|combinator|catch|body|getStyle|attr|toLowerCase|width|handler|filter|break|case|pseudos|Class|top||toUpperCase|xpath|matches|Array|_getEv|attributes|create|last|left|of|response|array|select|join|methods|isFunction|clone|bind|inspect|isUndefined|toString|Enumerable|valueL|initialize|call|offsetParent|valueT|test|map|request|readyState|memo|proceed|evaluate|cache|iterable|parent|url||getValue|responseText||||||||offset|callback|height|Template|params|targetNode|typeof|emptyFunction|px|properties|isString|childNodes|json|__method|string|gsub|apply|toElement|count|display|slice|disabled|toJSON|ByTag|replacement|toArray|le|nodeType|inject|hash|names|container|insert|indexOf|opt|parameters|_countedByPrototype|BrowserFeatures|first|ancestor|checked|matcher|_attributeTranslations|onComplete|opacity|hasAttribute|insertions|continue|number|Hash|mm|timer||selector|createElement|els|IE|||stripScripts|start|super|frequency|RegExp|input|text|getElementsByTagName|scrollLeft|strip|scrollTop|toHTML|userAgent|_returnOffset|_object|nextSibling|split|Opera|nodeValue|keys|cumulativeOffset|responder|ps|navigator|isElement|reverse|WebKit|_each|parts|tags|observe|methodize|undefined|isArray|sibling|lastValue|table|expressions|throw|toQueryString|status|not|wrap|styles|toPaddedString|nextSiblings|mode|defer|descendant|Abstract|headers|parseFloat|item|offsetLeft|unmark|adjacent|hidden|update|blank|Number|isNumber|end|readAttribute|evalScripts|innerHTML|_overflow|offsetTop|success|currentStyle|submit|_cache|Request|decay|isButton|__proto__|switch|stopObserving|contains|before|dispatchException|pointer|bottom|currentTarget|insertion|code|documentElement|script|shift|pluck|self|setStyle|getDimensions|getElements|callee|fire|attrPresence|fragment|on|ancestors|Serializers|previousSiblings|substring|offsetWidth|findAll|getHeader|static|truncation|extras|empty|evalJSON|exclusive|offsetHeight|Heading|absolute|right|delta|interpret|receiver|str|getOffsetParent|destination|default|Responders|action|firstChild|findElement|appendChild|tbody|template|setOpacity|pos|_insertionTranslations|auto|nodeClassName|xml|operators|relative|ofType|getStatus|only|pseudo|previousElementSibling|classNames|xcomp|addMethods|fireContentLoadedEvent|ElementExtensions|HTMLElement|capitalize|set|_|ycomp|without|toObject|responders|removeChild|onTimerEvent|write|post|and|positionedOffset|criteria|patterns|next|state|createEvent|following|addEventListener|dimensions|loaded|_flag|contentType|laterSibling|nextElementSibling|class|ctx|expr|escapeHTML|docElement|viewportOffset|writeAttribute|fillWith|serialize|registerCallback|EventObserver|Node|descendantOf|00001|nodeIndex|detect|_getAttr|after|eval|getElementsByClassName|which|currentlyExecuting|ScriptFragment|copy|charAt|currentValue|asynchronous|onreadystatechange|Simulated|SpecificElementExtensions|cssFloat|onCreate|read|parentElement|TBODY|isSameOrigin|XPath|target|Gecko|dispatch|elementClassName|headerJSON|data|port|token|times|recursivelyCollect|none|onlyIfAbsent|getCacheForID|inputs|tabIndex|tr|insertBefore|title|application|typeName|html|dim|findChildElements|toQueryParams|refresh|_extendedByPrototype|ClassNames|mark|hasClassName|attachEvent|findElements|border|optionValue|location|_getContentFromAnonymousElement|padding|returnValue|getWrappersForEventName|valueOf|encoding|unfilterJSON|_div|tokens|_complete|cssText|lastIndexOf|overflow|evalJS|execute|respondToReadyState|_getElementsByXPath|iter|TimedObserver|Content|identify|cond|classNameToAdd|TD|activeRequestCount|elementStyle|Base|fragments|delay|visibility|replaceChild|isHash|exception|character|offsetcache|failure|has|classNameToRemove|css|escapedString|stripTags|succ|delete|tag|onStateChange|onElementEvent|slices|_madePositioned|query|button|HTML|toQueryPair|_methodized|toTemplateReplacements|prepareReplacement|updater|trans|TableSection|Version|radio|protocol|_prototypeEventID|cumulativeScrollOffset|superclass|indices|val|collect|len|indexed|range|focus|disable|enable|styleFloat|camelize|camelized|reset|find|relativize|float|exclusions|get|trues|all|submitted|falses|matchingInputs|invoke|firstByIndex|Response|stop|removeAttribute|domain|subclass|endsWith|startsWith|Complete|relatedTarget|visible|unique|curry|getEventID|forElement|Position|getResponseHeader|selected|absolutize|found|decodeURIComponent|offsets|assertions|stripAlpha|_reverse|getAllResponseHeaders|zoom|getAttribute|predicate|statusText|textarea|exclusion|getDOMEventName|alpha|prepare|findWrapper|preceding|originalDisplay|originalPosition|clientWidth|descendants|outerHTML|updateComplete|onException|lastText|evalResponse|_getHeaderJSON|setWidth|addClassName|counter|compareDocumentPosition|escape|setHeight|force|scrollTo|responseXML|updateContent|removeClassName|JSON|Events||firstDescendant|immediateDescendants|parseInt|_originalWidth|getStatusText|show|_getResponseJSON|clientHeight|setLeft|BODY|nextNode|XMLHttpRequest|setRequestHeaders|_originalLeft|_originalHeight|sanitizeJSON|hide|setAttribute|interpolate|setTop|originalWidth|_originalTop|_getAttrNode|100|htmlFor|originalVisibility|2005|originalHeight|overrideMimeType|KHTML|createTextNode|Safari|ELEMENT_NODE|Updater|requestHeaders|inline|registerFormCallbacks|checkbox|Pattern|exec|Observer|PeriodicalExecuter|inputSelector|single|selectOne|selectMany|comp|lt|sub|useDoubleQuotes|charCodeAt|specialChar|JSONFilter|sanitize|amp|unescapeHTML|isJSON|eachSlice|activate|total|even|odd|getIndices|any|operator|uTagName|byClassName|needle|enabled|collections|findFirstElement|href|subclasses|clear|sortBy|td|scan|matchElements|MobileSafari|buttonMap|instanceMethods|setInterval|load|src|__onDOMContentLoaded|clearInterval|eventType|1000|dispatchEvent|lambda|complete|toggle|withinIncludingScrolloffsets|instanceof|deltaX|deltaY|includeScrollOffsets|pageYOffset|timeout|argumentNames|pageXOffset|dataavailable|HTMLEvents|extractScripts|matchOne|scriptTag|stopPropagation|separator|clonePosition|metaKey|click|TEXT_NODE|matchAll|preventDefault|destroyCache|createWrapper|removeEventListener|destroyWrapper||onunload|img|pageX|pageY|error|previousSibling|serializeElements|findDOMClass|arrayLength|client|radix|TableCell|TR|TH|getWidth|getHeight|querySelector|compileMatcher|compileXPathMatcher|SelectorsAPI|shouldUseSelectorsAPI|normal|shouldUseXPath|TFOOT|THEAD|register|XMLHTTP|ActiveXObject|TEXTAREA|SELECT|getAttributeNode|getTransport|these|Try|IMG|TableCol|Mod|encodeURIComponent|ObjectRange|from|selectorsAPI|remove|uniq|forEach|or|local|flatten|oldId|_true|size|sorted|intersect|entries|Mobile|Msxml2|getUTCSeconds|finally|some|every|getAllHeaders|ceil|AppleWebKit||responseJSON|Apple|floor|Math|member|getUTCMinutes|truncate|unset|merge|getUTCHours|unknown|secure|RangeError|urlencoded|UTF|Function|splice|_method|compact|Konqueror|bindAsEventListener|setTimeout|boolean|ecma|unregister|reduce|getUTCDate|getUTCMonth|www|01|Date|getUTCFullYear|Microsoft|pop|SyntaxError|Badly|formed|partition|charset|Eaeflnr|toColorPart|Uninitialized|Accept|javascript|Failure|parseQuery|300|grep|setRequestHeader|inGroupsOf|close|max|min|Connection|Success|isNaN|u00|With|open|fromCharCode||constructor|postBody|isFinite|abs|200|round|zip|java|send|Interactive|https|Requested|Loading|x1f|Loaded|reject|sort|underscore|dasherize|x00|im|IFrame|abled|dis|selectorType|file|getInputs|mod|with|version|getScrollOffsets|querySelectorAll|starts|focusFirstElement|setValue|KEY_RETURN|KEY_TAB|KEY_ESC|KEY_LEFT|KEY_UP|KEY_BACKSPACE|change|present|Field|one|selectedIndex|PeriodicalUpdater|inner|H5|H4|H6|Quote|INS|H3|H2|DList|DIR|Directory|H1|DEL|Anchor|FRAMESET|FrameSet|IFRAME|viewport|TableRow|COLGROUP|Image|CAPTION|TableCaption|COL|KEY_RIGHT|KEY_DOWN|Before|Insertion|Top|Bottom|After|childOf|Toggle|ondataavailable|fireEvent|dom|DOMContentLoaded|Error|is|horizontal|realOffset|page|add|vertical|overlap|deprecated|use|instead|within|createEventObject|initEvent|fromElement|mouseover|mouseout|isLeftClick|isMiddleClick|KEY_INSERT|KEY_PAGEDOWN|KEY_DELETE|KEY_HOME|KEY_END|KEY_PAGEUP|isRightClick|clientX|cancelBubble|srcElement|unload|detachEvent|stopped|pointerY|clientLeft||clientY|clientTop|pointerX|DL|opera|multiple|onload|toggleClassName|DOCUMENT_FRAGMENT_NODE|readonly||frameBorder|anonymous_element_|readOnly|NOTATION_NODE|longDesc|DOCUMENT_TYPE_NODE|DOCUMENT_NODE|ENTITY_NODE|ENTITY_REFERENCE_NODE|CDATA_SECTION_NODE|ATTRIBUTE_NODE|PROCESSING_INSTRUCTION_NODE|cleanWhitespace|childElements|onclick|COMMENT_NODE|maxLength|encType|cellPadding|previous|createContextualFragment|cellspacing|fixed|cellpadding|hasLayout|down|siblings|OList|cellSpacing|vAlign|cloneNode|dateTime|accessKey|ownerDocument|rowSpan|selectNode|colSpan|createRange|getElementsBySelector|ondblclick|TABLE|specified|FORM|INPUT|getOpacity|getComputedStyle|onselect|onchange|rv|999999|OPTGROUP|clearTimeout|FieldSet|UL|UList|OL|FIELDSET|Paragraph|OptGroup|TextArea|block|up|onreset|onmouseup|ORDERED_NODE_SNAPSHOT_TYPE|onmouseover|onmousemove|makeClipping|snapshotLength|onmousedown|undoClipping|snapshotItem|XPathResult|onmouseout|onkeydown|undoPositioned|onkeyup|makePositioned|onsubmit|defaultView|onfocus|getElementById|onblur|onkeypress'.split('|'),0,{}))

/*
* Really easy field validation with Prototype
* http://tetlaw.id.au/view/javascript/really-easy-field-validation
* Andrew Tetlaw
* Version 1.5.4.1 (2007-01-05)
*
* Copyright (c) 2007 Andrew Tetlaw
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use, copy,
* modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
*/
var Validator = Class.create();

Validator.prototype = {
    initialize : function(className, error, test, options) {
        if(typeof test == 'function'){
            this.options = $H(options);
            this._test = test;
        } else {
            this.options = $H(test);
            this._test = function(){return true};
        }
        this.error = error || 'Validation failed.';
        this.className = className;
    },
    test : function(v, elm) {
        return (this._test(v,elm) && this.options.all(function(p){
            return Validator.methods[p.key] ? Validator.methods[p.key](v,elm,p.value) : true;
        }));
    }
}
Validator.methods = {
    pattern : function(v,elm,opt) {return Validation.get('IsEmpty').test(v) || opt.test(v)},
    minLength : function(v,elm,opt) {return v.length >= opt},
    maxLength : function(v,elm,opt) {return v.length <= opt},
    min : function(v,elm,opt) {return v >= parseFloat(opt)},
    max : function(v,elm,opt) {return v <= parseFloat(opt)},
    notOneOf : function(v,elm,opt) {return $A(opt).all(function(value) {
        return v != value;
    })},
    oneOf : function(v,elm,opt) {return $A(opt).any(function(value) {
        return v == value;
    })},
    is : function(v,elm,opt) {return v == opt},
    isNot : function(v,elm,opt) {return v != opt},
    equalToField : function(v,elm,opt) {return v == $F(opt)},
    notEqualToField : function(v,elm,opt) {return v != $F(opt)},
    include : function(v,elm,opt) {return $A(opt).all(function(value) {
        return Validation.get(value).test(v,elm);
    })}
}

var Validation = Class.create();
Validation.defaultOptions = {
    onSubmit : true,
    stopOnFirst : false,
    immediate : false,
    focusOnError : true,
    useTitles : false,
    addClassNameToContainer: false,
    containerClassName: '.input-box',
    onFormValidate : function(result, form) {},
    onElementValidate : function(result, elm) {}
};

Validation.prototype = {
    initialize : function(form, options){
        this.form = $(form);
        if (!this.form) {
            return;
        }
        this.options = Object.extend({
            onSubmit : Validation.defaultOptions.onSubmit,
            stopOnFirst : Validation.defaultOptions.stopOnFirst,
            immediate : Validation.defaultOptions.immediate,
            focusOnError : Validation.defaultOptions.focusOnError,
            useTitles : Validation.defaultOptions.useTitles,
            onFormValidate : Validation.defaultOptions.onFormValidate,
            onElementValidate : Validation.defaultOptions.onElementValidate
        }, options || {});
        if(this.options.onSubmit) Event.observe(this.form,'submit',this.onSubmit.bind(this),false);
        if(this.options.immediate) {
            Form.getElements(this.form).each(function(input) { // Thanks Mike!
                if (input.tagName.toLowerCase() == 'select') {
                    Event.observe(input, 'blur', this.onChange.bindAsEventListener(this));
                }
                if (input.type.toLowerCase() == 'radio' || input.type.toLowerCase() == 'checkbox') {
                    Event.observe(input, 'click', this.onChange.bindAsEventListener(this));
                } else {
                    Event.observe(input, 'change', this.onChange.bindAsEventListener(this));
                }
            }, this);
        }
    },
    onChange : function (ev) {
        Validation.isOnChange = true;
        Validation.validate(Event.element(ev),{
                useTitle : this.options.useTitles,
                onElementValidate : this.options.onElementValidate
        });
        Validation.isOnChange = false;
    },
    onSubmit :  function(ev){
        if(!this.validate()) Event.stop(ev);
    },
    validate : function() {
        var result = false;
        var useTitles = this.options.useTitles;
        var callback = this.options.onElementValidate;
        try {
            if(this.options.stopOnFirst) {
                result = Form.getElements(this.form).all(function(elm) {
                    if (elm.hasClassName('local-validation') && !this.isElementInForm(elm, this.form)) {
                        return true;
                    }
                    return Validation.validate(elm,{useTitle : useTitles, onElementValidate : callback});
                }, this);
            } else {
                result = Form.getElements(this.form).collect(function(elm) {
                    if (elm.hasClassName('local-validation') && !this.isElementInForm(elm, this.form)) {
                        return true;
                    }
                    return Validation.validate(elm,{useTitle : useTitles, onElementValidate : callback});
                }, this).all();
            }
        } catch (e) {

        }
        if(!result && this.options.focusOnError) {
            try{
                Form.getElements(this.form).findAll(function(elm){return $(elm).hasClassName('validation-failed')}).first().focus()
            }
            catch(e){

            }
        }
        this.options.onFormValidate(result, this.form);
        return result;
    },
    reset : function() {
        Form.getElements(this.form).each(Validation.reset);
    },
    isElementInForm : function(elm, form) {
        var domForm = elm.up('form');
        if (domForm == form) {
            return true;
        }
        return false;
    }
}

Object.extend(Validation, {
    validate : function(elm, options){
        options = Object.extend({
            useTitle : false,
            onElementValidate : function(result, elm) {}
        }, options || {});
        elm = $(elm);

        var cn = $w(elm.className);
        return result = cn.all(function(value) {
            var test = Validation.test(value,elm,options.useTitle);
            options.onElementValidate(test, elm);
            return test;
        });
    },
    insertAdvice : function(elm, advice){
        var container = $(elm).up('.field-row');
        if(container){
            Element.insert(container, {after: advice});
        } else if (elm.up('td.value')) {
            elm.up('td.value').insert({bottom: advice});
        } else if (elm.advaiceContainer && $(elm.advaiceContainer)) {
            $(elm.advaiceContainer).update(advice);
        }
        else {
            switch (elm.type.toLowerCase()) {
                case 'checkbox':
                case 'radio':
                    var p = elm.parentNode;
                    if(p) {
                        Element.insert(p, {'bottom': advice});
                    } else {
                        Element.insert(elm, {'after': advice});
                    }
                    break;
                default:
                    Element.insert(elm, {'after': advice});
            }
        }
    },
    showAdvice : function(elm, advice, adviceName){
        if(!elm.advices){
            elm.advices = new Hash();
        }
        else{
            elm.advices.each(function(pair){
                this.hideAdvice(elm, pair.value);
            }.bind(this));
        }
        elm.advices.set(adviceName, advice);
        if(typeof Effect == 'undefined') {
            advice.style.display = 'block';
        } else {
            if(!advice._adviceAbsolutize) {
                new Effect.Appear(advice, {duration : 1 });
            } else {
                Position.absolutize(advice);
                advice.show();
                advice.setStyle({
                    'top':advice._adviceTop,
                    'left': advice._adviceLeft,
                    'width': advice._adviceWidth,
                    'z-index': 1000
                });
                advice.addClassName('advice-absolute');
            }
        }
    },
    hideAdvice : function(elm, advice){
        if(advice != null) advice.hide();
    },
    updateCallback : function(elm, status) {
        if (typeof elm.callbackFunction != 'undefined') {
            eval(elm.callbackFunction+'(\''+elm.id+'\',\''+status+'\')');
        }
    },
    ajaxError : function(elm, errorMsg) {
        var name = 'validate-ajax';
        var advice = Validation.getAdvice(name, elm);
        if (advice == null) {
            advice = this.createAdvice(name, elm, false, errorMsg);
        }
        this.showAdvice(elm, advice, 'validate-ajax');
        this.updateCallback(elm, 'failed');

        elm.addClassName('validation-failed');
        elm.addClassName('validate-ajax');
        if (Validation.defaultOptions.addClassNameToContainer && Validation.defaultOptions.containerClassName != '') {
            var container = elm.up(Validation.defaultOptions.containerClassName);
            if (container && this.allowContainerClassName(elm)) {
                container.removeClassName('validation-passed');
                container.addClassName('validation-error');
            }
        }
    },
    allowContainerClassName: function (elm) {
        if (elm.type == 'radio' || elm.type == 'checkbox') {
            return elm.hasClassName('change-container-classname');
        }

        return true;
    },
    test : function(name, elm, useTitle) {
        var v = Validation.get(name);
        var prop = '__advice'+name.camelize();
        try {
        if(Validation.isVisible(elm) && !v.test($F(elm), elm)) {
            //if(!elm[prop]) {
                var advice = Validation.getAdvice(name, elm);
                if (advice == null) {
                    advice = this.createAdvice(name, elm, useTitle);
                }
                this.showAdvice(elm, advice, name);
                this.updateCallback(elm, 'failed');
            //}
            elm[prop] = 1;
            if (!elm.advaiceContainer) {
                elm.removeClassName('validation-passed');
                elm.addClassName('validation-failed');
            }

           if (Validation.defaultOptions.addClassNameToContainer && Validation.defaultOptions.containerClassName != '') {
                var container = elm.up(Validation.defaultOptions.containerClassName);
                if (container && this.allowContainerClassName(elm)) {
                    container.removeClassName('validation-passed');
                    container.addClassName('validation-error');
                }
            }
            return false;
        } else {
            var advice = Validation.getAdvice(name, elm);
            this.hideAdvice(elm, advice);
            this.updateCallback(elm, 'passed');
            elm[prop] = '';
            elm.removeClassName('validation-failed');
            elm.addClassName('validation-passed');
            if (Validation.defaultOptions.addClassNameToContainer && Validation.defaultOptions.containerClassName != '') {
                var container = elm.up(Validation.defaultOptions.containerClassName);
                if (container && !container.down('.validation-failed') && this.allowContainerClassName(elm)) {
                    if (!Validation.get('IsEmpty').test(elm.value) || !this.isVisible(elm)) {
                        container.addClassName('validation-passed');
                    } else {
                        container.removeClassName('validation-passed');
                    }
                    container.removeClassName('validation-error');
                }
            }
            return true;
        }
        } catch(e) {
            throw(e)
        }
    },
    isVisible : function(elm) {
        while(elm.tagName != 'BODY') {
            if(!$(elm).visible()) return false;
            elm = elm.parentNode;
        }
        return true;
    },
    getAdvice : function(name, elm) {
        return $('advice-' + name + '-' + Validation.getElmID(elm)) || $('advice-' + Validation.getElmID(elm));
    },
    createAdvice : function(name, elm, useTitle, customError) {
        var v = Validation.get(name);
        var errorMsg = useTitle ? ((elm && elm.title) ? elm.title : v.error) : v.error;
        if (customError) {
            errorMsg = customError;
        }
        try {
            if (Translator){
                errorMsg = Translator.translate(errorMsg);
            }
        }
        catch(e){}

        advice = '<div class="validation-advice" id="advice-' + name + '-' + Validation.getElmID(elm) +'" style="display:none">' + errorMsg + '</div>'


        Validation.insertAdvice(elm, advice);
        advice = Validation.getAdvice(name, elm);
        if($(elm).hasClassName('absolute-advice')) {
            var dimensions = $(elm).getDimensions();
            var originalPosition = Position.cumulativeOffset(elm);

            advice._adviceTop = (originalPosition[1] + dimensions.height) + 'px';
            advice._adviceLeft = (originalPosition[0])  + 'px';
            advice._adviceWidth = (dimensions.width)  + 'px';
            advice._adviceAbsolutize = true;
        }
        return advice;
    },
    getElmID : function(elm) {
        return elm.id ? elm.id : elm.name;
    },
    reset : function(elm) {
        elm = $(elm);
        var cn = $w(elm.className);
        cn.each(function(value) {
            var prop = '__advice'+value.camelize();
            if(elm[prop]) {
                var advice = Validation.getAdvice(value, elm);
                if (advice) {
                    advice.hide();
                }
                elm[prop] = '';
            }
            elm.removeClassName('validation-failed');
            elm.removeClassName('validation-passed');
            if (Validation.defaultOptions.addClassNameToContainer && Validation.defaultOptions.containerClassName != '') {
                var container = elm.up(Validation.defaultOptions.containerClassName);
                if (container) {
                    container.removeClassName('validation-passed');
                    container.removeClassName('validation-error');
                }
            }
        });
    },
    add : function(className, error, test, options) {
        var nv = {};
        nv[className] = new Validator(className, error, test, options);
        Object.extend(Validation.methods, nv);
    },
    addAllThese : function(validators) {
        var nv = {};
        $A(validators).each(function(value) {
                nv[value[0]] = new Validator(value[0], value[1], value[2], (value.length > 3 ? value[3] : {}));
            });
        Object.extend(Validation.methods, nv);
    },
    get : function(name) {
        return  Validation.methods[name] ? Validation.methods[name] : Validation.methods['_LikeNoIDIEverSaw_'];
    },
    methods : {
        '_LikeNoIDIEverSaw_' : new Validator('_LikeNoIDIEverSaw_','',{})
    }
});

Validation.add('IsEmpty', '', function(v) {
    return  (v == '' || (v == null) || (v.length == 0) || /^\s+$/.test(v)); // || /^\s+$/.test(v));
});

Validation.addAllThese([
    ['validate-select', 'Please select an option.', function(v) {
                return ((v != "none") && (v != null) && (v.length != 0));
            }],
    ['required-entry', 'This is a required field.', function(v) {
                return !Validation.get('IsEmpty').test(v);
            }],
    ['validate-number', 'Please enter a valid number in this field.', function(v) {
                return Validation.get('IsEmpty').test(v) || (!isNaN(parseNumber(v)) && !/^\s+$/.test(parseNumber(v)));
            }],
    ['validate-digits', 'Please use numbers only in this field. please avoid spaces or other characters such as dots or commas.', function(v) {
                return Validation.get('IsEmpty').test(v) ||  !/[^\d]/.test(v);
            }],
    ['validate-alpha', 'Please use letters only (a-z or A-Z) in this field.', function (v) {
                return Validation.get('IsEmpty').test(v) ||  /^[a-zA-Z]+$/.test(v)
            }],
    ['validate-code', 'Please use only letters (a-z), numbers (0-9) or underscore(_) in this field, first character should be a letter.', function (v) {
                return Validation.get('IsEmpty').test(v) ||  /^[a-z]+[a-z0-9_]+$/.test(v)
            }],
    ['validate-alphanum', 'Please use only letters (a-z or A-Z) or numbers (0-9) only in this field. No spaces or other characters are allowed.', function(v) {
                return Validation.get('IsEmpty').test(v) ||  /^[a-zA-Z0-9]+$/.test(v) /*!/\W/.test(v)*/
            }],
    ['validate-street', 'Please use only letters (a-z or A-Z) or numbers (0-9) or spaces and # only in this field.', function(v) {
                return Validation.get('IsEmpty').test(v) ||  /^[ \w]{3,}([A-Za-z]\.)?([ \w]*\#\d+)?(\r\n| )[ \w]{3,}/.test(v)
            }],
    ['validate-phoneStrict', 'Please enter a valid phone number. For example (123) 456-7890 or 123-456-7890.', function(v) {
                return Validation.get('IsEmpty').test(v) || /^(\()?\d{3}(\))?(-|\s)?\d{3}(-|\s)\d{4}$/.test(v);
            }],
    ['validate-phoneLax', 'Please enter a valid phone number. For example (123) 456-7890 or 123-456-7890.', function(v) {
                return Validation.get('IsEmpty').test(v) || /^((\d[-. ]?)?((\(\d{3}\))|\d{3}))?[-. ]?\d{3}[-. ]?\d{4}$/.test(v);
            }],
    ['validate-fax', 'Please enter a valid fax number. For example (123) 456-7890 or 123-456-7890.', function(v) {
                return Validation.get('IsEmpty').test(v) || /^(\()?\d{3}(\))?(-|\s)?\d{3}(-|\s)\d{4}$/.test(v);
            }],
    ['validate-date', 'Please enter a valid date.', function(v) {
                var test = new Date(v);
                return Validation.get('IsEmpty').test(v) || !isNaN(test);
            }],
    ['validate-email', 'Please enter a valid email address. For example johndoe@domain.com.', function (v) {
                //return Validation.get('IsEmpty').test(v) || /\w{1,}[@][\w\-]{1,}([.]([\w\-]{1,})){1,3}$/.test(v)
                //return Validation.get('IsEmpty').test(v) || /^[\!\#$%\*/?|\^\{\}`~&\'\+\-=_a-z0-9][\!\#$%\*/?|\^\{\}`~&\'\+\-=_a-z0-9\.]{1,30}[\!\#$%\*/?|\^\{\}`~&\'\+\-=_a-z0-9]@([a-z0-9_-]{1,30}\.){1,5}[a-z]{2,4}$/i.test(v)
                return Validation.get('IsEmpty').test(v) || /^([a-z0-9,!\#\$%&'\*\+\/=\?\^_`\{\|\}~-]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z0-9,!\#\$%&'\*\+\/=\?\^_`\{\|\}~-]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*@([a-z0-9-]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z0-9-]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*\.(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]){2,})$/i.test(v)
            }],
    ['validate-emailSender', 'Please use only visible characters and spaces.', function (v) {
                return Validation.get('IsEmpty').test(v) ||  /^[\S ]+$/.test(v)
                    }],
    ['validate-password', 'Please enter 6 or more characters. Leading or trailing spaces will be ignored.', function(v) {
                var pass=v.strip(); /*strip leading and trailing spaces*/
                return !(pass.length>0 && pass.length < 6);
            }],
    ['validate-admin-password', 'Please enter 7 or more characters. Password should contain both numeric and alphabetic characters.', function(v) {
                var pass=v.strip();
                if (0 == pass.length) {
                    return true;
                }
                if (!(/[a-z]/i.test(v)) || !(/[0-9]/.test(v))) {
                    return false;
                }
                return !(pass.length < 7);
            }],
    ['validate-cpassword', 'Please make sure your passwords match.', function(v) {
                var conf = $('confirmation') ? $('confirmation') : $$('.validate-cpassword')[0];
                var pass = false;
                if ($('password')) {
                    pass = $('password');
                }
                var passwordElements = $$('.validate-password');
                for (var i = 0; i < passwordElements.size(); i++) {
                    var passwordElement = passwordElements[i];
                    if (passwordElement.up('form').id == conf.up('form').id) {
                        pass = passwordElement;
                    }
                }
                if ($$('.validate-admin-password').size()) {
                    pass = $$('.validate-admin-password')[0];
                }
                return (pass.value == conf.value);
            }],
    ['validate-url', 'Please enter a valid URL. http:// is required', function (v) {
                return Validation.get('IsEmpty').test(v) || /^(http|https|ftp):\/\/(([A-Z0-9][A-Z0-9_-]*)(\.[A-Z0-9][A-Z0-9_-]*)+)(:(\d+))?\/?/i.test(v)
            }],
    ['validate-clean-url', 'Please enter a valid URL. For example http://www.example.com or www.example.com', function (v) {
                return Validation.get('IsEmpty').test(v) || /^(http|https|ftp):\/\/(([A-Z0-9][A-Z0-9_-]*)(\.[A-Z0-9][A-Z0-9_-]*)+.(com|org|net|dk|at|us|tv|info|uk|co.uk|biz|se)$)(:(\d+))?\/?/i.test(v) || /^(www)((\.[A-Z0-9][A-Z0-9_-]*)+.(com|org|net|dk|at|us|tv|info|uk|co.uk|biz|se)$)(:(\d+))?\/?/i.test(v)
            }],
    ['validate-identifier', 'Please enter a valid URL Key. For example "example-page", "example-page.html" or "anotherlevel/example-page"', function (v) {
                return Validation.get('IsEmpty').test(v) || /^[A-Z0-9][A-Z0-9_\/-]+(\.[A-Z0-9_-]+)*$/i.test(v)
            }],
    ['validate-xml-identifier', 'Please enter a valid XML-identifier. For example something_1, block5, id-4', function (v) {
                return Validation.get('IsEmpty').test(v) || /^[A-Z][A-Z0-9_\/-]*$/i.test(v)
            }],
    ['validate-ssn', 'Please enter a valid social security number. For example 123-45-6789.', function(v) {
            return Validation.get('IsEmpty').test(v) || /^\d{3}-?\d{2}-?\d{4}$/.test(v);
            }],
    ['validate-zip', 'Please enter a valid zip code. For example 90602 or 90602-1234.', function(v) {
            return Validation.get('IsEmpty').test(v) || /(^\d{5}$)|(^\d{5}-\d{4}$)/.test(v);
            }],
    ['validate-zip-international', 'Please enter a valid zip code.', function(v) {
            //return Validation.get('IsEmpty').test(v) || /(^[A-z0-9]{2,10}([\s]{0,1}|[\-]{0,1})[A-z0-9]{2,10}$)/.test(v);
            return true;
            }],
    ['validate-date-au', 'Please use this date format: dd/mm/yyyy. For example 17/03/2006 for the 17th of March, 2006.', function(v) {
                if(Validation.get('IsEmpty').test(v)) return true;
                var regex = /^(\d{2})\/(\d{2})\/(\d{4})$/;
                if(!regex.test(v)) return false;
                var d = new Date(v.replace(regex, '$2/$1/$3'));
                return ( parseInt(RegExp.$2, 10) == (1+d.getMonth()) ) &&
                            (parseInt(RegExp.$1, 10) == d.getDate()) &&
                            (parseInt(RegExp.$3, 10) == d.getFullYear() );
            }],
    ['validate-currency-dollar', 'Please enter a valid $ amount. For example $100.00.', function(v) {
                // [$]1[##][,###]+[.##]
                // [$]1###+[.##]
                // [$]0.##
                // [$].##
                return Validation.get('IsEmpty').test(v) ||  /^\$?\-?([1-9]{1}[0-9]{0,2}(\,[0-9]{3})*(\.[0-9]{0,2})?|[1-9]{1}\d*(\.[0-9]{0,2})?|0(\.[0-9]{0,2})?|(\.[0-9]{1,2})?)$/.test(v)
            }],
    ['validate-one-required', 'Please select one of the above options.', function (v,elm) {
                var p = elm.parentNode;
                var options = p.getElementsByTagName('INPUT');
                return $A(options).any(function(elm) {
                    return $F(elm);
                });
            }],
    ['validate-one-required-by-name', 'Please select one of the options.', function (v,elm) {
                var inputs = $$('input[name="' + elm.name.replace(/([\\"])/g, '\\$1') + '"]');

                var error = 1;
                for(var i=0;i<inputs.length;i++) {
                    if((inputs[i].type == 'checkbox' || inputs[i].type == 'radio') && inputs[i].checked == true) {
                        error = 0;
                    }

                    if(Validation.isOnChange && (inputs[i].type == 'checkbox' || inputs[i].type == 'radio')) {
                        Validation.reset(inputs[i]);
                    }
                }

                if( error == 0 ) {
                    return true;
                } else {
                    return false;
                }
            }],
    ['validate-not-negative-number', 'Please enter a valid number in this field.', function(v) {
                v = parseNumber(v);
                return (!isNaN(v) && v>=0);
            }],
    ['validate-state', 'Please select State/Province.', function(v) {
                return (v!=0 || v == '');
            }],

    ['validate-new-password', 'Please enter 6 or more characters. Leading or trailing spaces will be ignored.', function(v) {
                if (!Validation.get('validate-password').test(v)) return false;
                if (Validation.get('IsEmpty').test(v) && v != '') return false;
                return true;
            }],
    ['validate-greater-than-zero', 'Please enter a number greater than 0 in this field.', function(v) {
                if(v.length)
                    return parseFloat(v) > 0;
                else
                    return true;
            }],
    ['validate-zero-or-greater', 'Please enter a number 0 or greater in this field.', function(v) {
                if(v.length)
                    return parseFloat(v) >= 0;
                else
                    return true;
            }],
    ['validate-cc-number', 'Please enter a valid credit card number.', function(v, elm) {
                // remove non-numerics
                var ccTypeContainer = $(elm.id.substr(0,elm.id.indexOf('_cc_number')) + '_cc_type');
                if (ccTypeContainer && typeof Validation.creditCartTypes.get(ccTypeContainer.value) != 'undefined'
                        && Validation.creditCartTypes.get(ccTypeContainer.value)[2] == false) {
                    if (!Validation.get('IsEmpty').test(v) && Validation.get('validate-digits').test(v)) {
                        return true;
                    } else {
                        return false;
                    }
                }
                return validateCreditCard(v);
            }],
    ['validate-cc-type', 'Credit card number doesn\'t match credit card type', function(v, elm) {
                // remove credit card number delimiters such as "-" and space
                elm.value = removeDelimiters(elm.value);
                v         = removeDelimiters(v);

                var ccTypeContainer = $(elm.id.substr(0,elm.id.indexOf('_cc_number')) + '_cc_type');
                if (!ccTypeContainer) {
                    return true;
                }
                var ccType = ccTypeContainer.value;

                if (typeof Validation.creditCartTypes.get(ccType) == 'undefined') {
                    return false;
                }

                // Other card type or switch or solo card
                if (Validation.creditCartTypes.get(ccType)[0]==false) {
                    return true;
                }

                // Matched credit card type
                var ccMatchedType = '';

                Validation.creditCartTypes.each(function (pair) {
                    if (pair.value[0] && v.match(pair.value[0])) {
                        ccMatchedType = pair.key;
                        throw $break;
                    }
                });

                if(ccMatchedType != ccType) {
                    return false;
                }

                if (ccTypeContainer.hasClassName('validation-failed') && Validation.isOnChange) {
                    Validation.validate(ccTypeContainer);
                }

                return true;
            }],
     ['validate-cc-type-select', 'Card type doesn\'t match credit card number', function(v, elm) {
                var ccNumberContainer = $(elm.id.substr(0,elm.id.indexOf('_cc_type')) + '_cc_number');
                if (Validation.isOnChange && Validation.get('IsEmpty').test(ccNumberContainer.value)) {
                    return true;
                }
                if (Validation.get('validate-cc-type').test(ccNumberContainer.value, ccNumberContainer)) {
                    Validation.validate(ccNumberContainer);
                }
                return Validation.get('validate-cc-type').test(ccNumberContainer.value, ccNumberContainer);
            }],
     ['validate-cc-exp', 'Incorrect credit card expiration date', function(v, elm) {
                var ccExpMonth   = v;
                var ccExpYear    = $(elm.id.substr(0,elm.id.indexOf('_expiration')) + '_expiration_yr').value;
                var currentTime  = new Date();
                var currentMonth = currentTime.getMonth() + 1;
                var currentYear  = currentTime.getFullYear();
                if (ccExpMonth < currentMonth && ccExpYear == currentYear) {
                    return false;
                }
                return true;
            }],
     ['validate-cc-cvn', 'Please enter a valid credit card verification number.', function(v, elm) {
                var ccTypeContainer = $(elm.id.substr(0,elm.id.indexOf('_cc_cid')) + '_cc_type');
                if (!ccTypeContainer) {
                    return true;
                }
                var ccType = ccTypeContainer.value;

                if (typeof Validation.creditCartTypes.get(ccType) == 'undefined') {
                    return false;
                }

                var re = Validation.creditCartTypes.get(ccType)[1];

                if (v.match(re)) {
                    return true;
                }

                return false;
            }],
     ['validate-ajax', '', function(v, elm) { return true; }],
     ['validate-data', 'Please use only letters (a-z or A-Z), numbers (0-9) or underscore(_) in this field, first character should be a letter.', function (v) {
                if(v != '' && v) {
                    return /^[A-Za-z]+[A-Za-z0-9_]+$/.test(v);
                }
                return true;
            }],
     ['validate-css-length', 'Please input a valid CSS-length. For example 100px or 77pt or 20em or .5ex or 50%', function (v) {
                if (v != '' && v) {
                    return /^[0-9\.]+(px|pt|em|ex|%)?$/.test(v) && (!(/\..*\./.test(v))) && !(/\.$/.test(v));
                }
                return true;
            }],
     ['validate-length', 'Maximum length exceeded.', function (v, elm) {
                var re = new RegExp(/^maximum-length-[0-9]+$/);
                var result = true;
                $w(elm.className).each(function(name, index) {
                        if (name.match(re) && result) {
                           var length = name.split('-')[2];
                           result = (v.length <= length);
                        }
                    });
                return result;
            }],
     ['validate-percents', 'Please enter a number lower than 100', {max:100}]

]);

function removeDelimiters (v) {
    v = v.replace(/\s/g, '');
    v = v.replace(/\-/g, '');
    return v;
}

function parseNumber(v)
{
    if (typeof v != 'string') {
        return parseFloat(v);
    }

    var isDot  = v.indexOf('.');
    var isComa = v.indexOf(',');

    if (isDot != -1 && isComa != -1) {
        if (isComa > isDot) {
            v = v.replace('.', '').replace(',', '.');
        }
        else {
            v = v.replace(',', '');
        }
    }
    else if (isComa != -1) {
        v = v.replace(',', '.');
    }

    return parseFloat(v);
}

/**
 * Hash with credit card types wich can be simply extended in payment modules
 * 0 - regexp for card number
 * 1 - regexp for cvn
 * 2 - check or not credit card number trough Luhn algorithm by
 *     function validateCreditCard wich you can find above in this file
 */
Validation.creditCartTypes = $H({
    'SS': [new RegExp('^((6759[0-9]{12})|(5018|5020|5038|6304|6759|6761|6763[0-9]{12,19})|(49[013][1356][0-9]{12})|(6333[0-9]{12})|(6334[0-4]\d{11})|(633110[0-9]{10})|(564182[0-9]{10}))([0-9]{2,3})?$'), new RegExp('^([0-9]{3}|[0-9]{4})?$'), true],
    'SO': [new RegExp('^(6334[5-9]([0-9]{11}|[0-9]{13,14}))|(6767([0-9]{12}|[0-9]{14,15}))$'), new RegExp('^([0-9]{3}|[0-9]{4})?$'), true],
    'SM': [new RegExp('(^(5[0678])[0-9]{11,18}$)|(^(6[^05])[0-9]{11,18}$)|(^(601)[^1][0-9]{9,16}$)|(^(6011)[0-9]{9,11}$)|(^(6011)[0-9]{13,16}$)|(^(65)[0-9]{11,13}$)|(^(65)[0-9]{15,18}$)|(^(49030)[2-9]([0-9]{10}$|[0-9]{12,13}$))|(^(49033)[5-9]([0-9]{10}$|[0-9]{12,13}$))|(^(49110)[1-2]([0-9]{10}$|[0-9]{12,13}$))|(^(49117)[4-9]([0-9]{10}$|[0-9]{12,13}$))|(^(49118)[0-2]([0-9]{10}$|[0-9]{12,13}$))|(^(4936)([0-9]{12}$|[0-9]{14,15}$))'), new RegExp('^([0-9]{3}|[0-9]{4})?$'), true],
    'VI': [new RegExp('^4[0-9]{12}([0-9]{3})?$'), new RegExp('^[0-9]{3}$'), true],
    'MC': [new RegExp('^5[1-5][0-9]{14}$'), new RegExp('^[0-9]{3}$'), true],
    'AE': [new RegExp('^3[47][0-9]{13}$'), new RegExp('^[0-9]{4}$'), true],
    'DI': [new RegExp('^6011[0-9]{12}$'), new RegExp('^[0-9]{3}$'), true],
    'JCB': [new RegExp('^(3[0-9]{15}|(2131|1800)[0-9]{11})$'), new RegExp('^[0-9]{4}$'), true],
    'OT': [false, new RegExp('^([0-9]{3}|[0-9]{4})?$'), false]
});

// script.aculo.us effects.js v1.8.2, Tue Nov 18 18:30:58 +0100 2008

// Copyright (c) 2005-2008 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
// Contributors:
//  Justin Palmer (http://encytemedia.com/)
//  Mark Pilgrim (http://diveintomark.org/)
//  Martin Bialasinki
//
// script.aculo.us is freely distributable under the terms of an MIT-style license.
// For details, see the script.aculo.us web site: http://script.aculo.us/

// converts rgb() and #xxx to #xxxxxx format,
// returns self (or first argument) if not convertable
String.prototype.parseColor = function() {
  var color = '#';
  if (this.slice(0,4) == 'rgb(') {
    var cols = this.slice(4,this.length-1).split(',');
    var i=0; do { color += parseInt(cols[i]).toColorPart() } while (++i<3);
  } else {
    if (this.slice(0,1) == '#') {
      if (this.length==4) for(var i=1;i<4;i++) color += (this.charAt(i) + this.charAt(i)).toLowerCase();
      if (this.length==7) color = this.toLowerCase();
    }
  }
  return (color.length==7 ? color : (arguments[0] || this));
};

/*--------------------------------------------------------------------------*/

Element.collectTextNodes = function(element) {
  return $A($(element).childNodes).collect( function(node) {
    return (node.nodeType==3 ? node.nodeValue :
      (node.hasChildNodes() ? Element.collectTextNodes(node) : ''));
  }).flatten().join('');
};

Element.collectTextNodesIgnoreClass = function(element, className) {
  return $A($(element).childNodes).collect( function(node) {
    return (node.nodeType==3 ? node.nodeValue :
      ((node.hasChildNodes() && !Element.hasClassName(node,className)) ?
        Element.collectTextNodesIgnoreClass(node, className) : ''));
  }).flatten().join('');
};

Element.setContentZoom = function(element, percent) {
  element = $(element);
  element.setStyle({fontSize: (percent/100) + 'em'});
  if (Prototype.Browser.WebKit) window.scrollBy(0,0);
  return element;
};

Element.getInlineOpacity = function(element){
  return $(element).style.opacity || '';
};

Element.forceRerendering = function(element) {
  try {
    element = $(element);
    var n = document.createTextNode(' ');
    element.appendChild(n);
    element.removeChild(n);
  } catch(e) { }
};

/*--------------------------------------------------------------------------*/

var Effect = {
  _elementDoesNotExistError: {
    name: 'ElementDoesNotExistError',
    message: 'The specified DOM element does not exist, but is required for this effect to operate'
  },
  Transitions: {
    linear: Prototype.K,
    sinoidal: function(pos) {
      return (-Math.cos(pos*Math.PI)/2) + .5;
    },
    reverse: function(pos) {
      return 1-pos;
    },
    flicker: function(pos) {
      var pos = ((-Math.cos(pos*Math.PI)/4) + .75) + Math.random()/4;
      return pos > 1 ? 1 : pos;
    },
    wobble: function(pos) {
      return (-Math.cos(pos*Math.PI*(9*pos))/2) + .5;
    },
    pulse: function(pos, pulses) {
      return (-Math.cos((pos*((pulses||5)-.5)*2)*Math.PI)/2) + .5;
    },
    spring: function(pos) {
      return 1 - (Math.cos(pos * 4.5 * Math.PI) * Math.exp(-pos * 6));
    },
    none: function(pos) {
      return 0;
    },
    full: function(pos) {
      return 1;
    }
  },
  DefaultOptions: {
    duration:   1.0,   // seconds
    fps:        100,   // 100= assume 66fps max.
    sync:       false, // true for combining
    from:       0.0,
    to:         1.0,
    delay:      0.0,
    queue:      'parallel'
  },
  tagifyText: function(element) {
    var tagifyStyle = 'position:relative';
    if (Prototype.Browser.IE) tagifyStyle += ';zoom:1';

    element = $(element);
    $A(element.childNodes).each( function(child) {
      if (child.nodeType==3) {
        child.nodeValue.toArray().each( function(character) {
          element.insertBefore(
            new Element('span', {style: tagifyStyle}).update(
              character == ' ' ? String.fromCharCode(160) : character),
              child);
        });
        Element.remove(child);
      }
    });
  },
  multiple: function(element, effect) {
    var elements;
    if (((typeof element == 'object') ||
        Object.isFunction(element)) &&
       (element.length))
      elements = element;
    else
      elements = $(element).childNodes;

    var options = Object.extend({
      speed: 0.1,
      delay: 0.0
    }, arguments[2] || { });
    var masterDelay = options.delay;

    $A(elements).each( function(element, index) {
      new effect(element, Object.extend(options, { delay: index * options.speed + masterDelay }));
    });
  },
  PAIRS: {
    'slide':  ['SlideDown','SlideUp'],
    'blind':  ['BlindDown','BlindUp'],
    'appear': ['Appear','Fade']
  },
  toggle: function(element, effect) {
    element = $(element);
    effect = (effect || 'appear').toLowerCase();
    var options = Object.extend({
      queue: { position:'end', scope:(element.id || 'global'), limit: 1 }
    }, arguments[2] || { });
    Effect[element.visible() ?
      Effect.PAIRS[effect][1] : Effect.PAIRS[effect][0]](element, options);
  }
};

Effect.DefaultOptions.transition = Effect.Transitions.sinoidal;

/* ------------- core effects ------------- */

Effect.ScopedQueue = Class.create(Enumerable, {
  initialize: function() {
    this.effects  = [];
    this.interval = null;
  },
  _each: function(iterator) {
    this.effects._each(iterator);
  },
  add: function(effect) {
    var timestamp = new Date().getTime();

    var position = Object.isString(effect.options.queue) ?
      effect.options.queue : effect.options.queue.position;

    switch(position) {
      case 'front':
        // move unstarted effects after this effect
        this.effects.findAll(function(e){ return e.state=='idle' }).each( function(e) {
            e.startOn  += effect.finishOn;
            e.finishOn += effect.finishOn;
          });
        break;
      case 'with-last':
        timestamp = this.effects.pluck('startOn').max() || timestamp;
        break;
      case 'end':
        // start effect after last queued effect has finished
        timestamp = this.effects.pluck('finishOn').max() || timestamp;
        break;
    }

    effect.startOn  += timestamp;
    effect.finishOn += timestamp;

    if (!effect.options.queue.limit || (this.effects.length < effect.options.queue.limit))
      this.effects.push(effect);

    if (!this.interval)
      this.interval = setInterval(this.loop.bind(this), 15);
  },
  remove: function(effect) {
    this.effects = this.effects.reject(function(e) { return e==effect });
    if (this.effects.length == 0) {
      clearInterval(this.interval);
      this.interval = null;
    }
  },
  loop: function() {
    var timePos = new Date().getTime();
    for(var i=0, len=this.effects.length;i<len;i++)
      this.effects[i] && this.effects[i].loop(timePos);
  }
});

Effect.Queues = {
  instances: $H(),
  get: function(queueName) {
    if (!Object.isString(queueName)) return queueName;

    return this.instances.get(queueName) ||
      this.instances.set(queueName, new Effect.ScopedQueue());
  }
};
Effect.Queue = Effect.Queues.get('global');

Effect.Base = Class.create({
  position: null,
  start: function(options) {
    function codeForEvent(options,eventName){
      return (
        (options[eventName+'Internal'] ? 'this.options.'+eventName+'Internal(this);' : '') +
        (options[eventName] ? 'this.options.'+eventName+'(this);' : '')
      );
    }
    if (options && options.transition === false) options.transition = Effect.Transitions.linear;
    this.options      = Object.extend(Object.extend({ },Effect.DefaultOptions), options || { });
    this.currentFrame = 0;
    this.state        = 'idle';
    this.startOn      = this.options.delay*1000;
    this.finishOn     = this.startOn+(this.options.duration*1000);
    this.fromToDelta  = this.options.to-this.options.from;
    this.totalTime    = this.finishOn-this.startOn;
    this.totalFrames  = this.options.fps*this.options.duration;

    this.render = (function() {
      function dispatch(effect, eventName) {
        if (effect.options[eventName + 'Internal'])
          effect.options[eventName + 'Internal'](effect);
        if (effect.options[eventName])
          effect.options[eventName](effect);
      }

      return function(pos) {
        if (this.state === "idle") {
          this.state = "running";
          dispatch(this, 'beforeSetup');
          if (this.setup) this.setup();
          dispatch(this, 'afterSetup');
        }
        if (this.state === "running") {
          pos = (this.options.transition(pos) * this.fromToDelta) + this.options.from;
          this.position = pos;
          dispatch(this, 'beforeUpdate');
          if (this.update) this.update(pos);
          dispatch(this, 'afterUpdate');
        }
      };
    })();

    this.event('beforeStart');
    if (!this.options.sync)
      Effect.Queues.get(Object.isString(this.options.queue) ?
        'global' : this.options.queue.scope).add(this);
  },
  loop: function(timePos) {
    if (timePos >= this.startOn) {
      if (timePos >= this.finishOn) {
        this.render(1.0);
        this.cancel();
        this.event('beforeFinish');
        if (this.finish) this.finish();
        this.event('afterFinish');
        return;
      }
      var pos   = (timePos - this.startOn) / this.totalTime,
          frame = (pos * this.totalFrames).round();
      if (frame > this.currentFrame) {
        this.render(pos);
        this.currentFrame = frame;
      }
    }
  },
  cancel: function() {
    if (!this.options.sync)
      Effect.Queues.get(Object.isString(this.options.queue) ?
        'global' : this.options.queue.scope).remove(this);
    this.state = 'finished';
  },
  event: function(eventName) {
    if (this.options[eventName + 'Internal']) this.options[eventName + 'Internal'](this);
    if (this.options[eventName]) this.options[eventName](this);
  },
  inspect: function() {
    var data = $H();
    for(property in this)
      if (!Object.isFunction(this[property])) data.set(property, this[property]);
    return '#<Effect:' + data.inspect() + ',options:' + $H(this.options).inspect() + '>';
  }
});

Effect.Parallel = Class.create(Effect.Base, {
  initialize: function(effects) {
    this.effects = effects || [];
    this.start(arguments[1]);
  },
  update: function(position) {
    this.effects.invoke('render', position);
  },
  finish: function(position) {
    this.effects.each( function(effect) {
      effect.render(1.0);
      effect.cancel();
      effect.event('beforeFinish');
      if (effect.finish) effect.finish(position);
      effect.event('afterFinish');
    });
  }
});

Effect.Tween = Class.create(Effect.Base, {
  initialize: function(object, from, to) {
    object = Object.isString(object) ? $(object) : object;
    var args = $A(arguments), method = args.last(),
      options = args.length == 5 ? args[3] : null;
    this.method = Object.isFunction(method) ? method.bind(object) :
      Object.isFunction(object[method]) ? object[method].bind(object) :
      function(value) { object[method] = value };
    this.start(Object.extend({ from: from, to: to }, options || { }));
  },
  update: function(position) {
    this.method(position);
  }
});

Effect.Event = Class.create(Effect.Base, {
  initialize: function() {
    this.start(Object.extend({ duration: 0 }, arguments[0] || { }));
  },
  update: Prototype.emptyFunction
});

Effect.Opacity = Class.create(Effect.Base, {
  initialize: function(element) {
    this.element = $(element);
    if (!this.element) throw(Effect._elementDoesNotExistError);
    // make this work on IE on elements without 'layout'
    if (Prototype.Browser.IE && (!this.element.currentStyle.hasLayout))
      this.element.setStyle({zoom: 1});
    var options = Object.extend({
      from: this.element.getOpacity() || 0.0,
      to:   1.0
    }, arguments[1] || { });
    this.start(options);
  },
  update: function(position) {
    this.element.setOpacity(position);
  }
});

Effect.Move = Class.create(Effect.Base, {
  initialize: function(element) {
    this.element = $(element);
    if (!this.element) throw(Effect._elementDoesNotExistError);
    var options = Object.extend({
      x:    0,
      y:    0,
      mode: 'relative'
    }, arguments[1] || { });
    this.start(options);
  },
  setup: function() {
    this.element.makePositioned();
    this.originalLeft = parseFloat(this.element.getStyle('left') || '0');
    this.originalTop  = parseFloat(this.element.getStyle('top')  || '0');
    if (this.options.mode == 'absolute') {
      this.options.x = this.options.x - this.originalLeft;
      this.options.y = this.options.y - this.originalTop;
    }
  },
  update: function(position) {
    this.element.setStyle({
      left: (this.options.x  * position + this.originalLeft).round() + 'px',
      top:  (this.options.y  * position + this.originalTop).round()  + 'px'
    });
  }
});

// for backwards compatibility
Effect.MoveBy = function(element, toTop, toLeft) {
  return new Effect.Move(element,
    Object.extend({ x: toLeft, y: toTop }, arguments[3] || { }));
};

Effect.Scale = Class.create(Effect.Base, {
  initialize: function(element, percent) {
    this.element = $(element);
    if (!this.element) throw(Effect._elementDoesNotExistError);
    var options = Object.extend({
      scaleX: true,
      scaleY: true,
      scaleContent: true,
      scaleFromCenter: false,
      scaleMode: 'box',        // 'box' or 'contents' or { } with provided values
      scaleFrom: 100.0,
      scaleTo:   percent
    }, arguments[2] || { });
    this.start(options);
  },
  setup: function() {
    this.restoreAfterFinish = this.options.restoreAfterFinish || false;
    this.elementPositioning = this.element.getStyle('position');

    this.originalStyle = { };
    ['top','left','width','height','fontSize'].each( function(k) {
      this.originalStyle[k] = this.element.style[k];
    }.bind(this));

    this.originalTop  = this.element.offsetTop;
    this.originalLeft = this.element.offsetLeft;

    var fontSize = this.element.getStyle('font-size') || '100%';
    ['em','px','%','pt'].each( function(fontSizeType) {
      if (fontSize.indexOf(fontSizeType)>0) {
        this.fontSize     = parseFloat(fontSize);
        this.fontSizeType = fontSizeType;
      }
    }.bind(this));

    this.factor = (this.options.scaleTo - this.options.scaleFrom)/100;

    this.dims = null;
    if (this.options.scaleMode=='box')
      this.dims = [this.element.offsetHeight, this.element.offsetWidth];
    if (/^content/.test(this.options.scaleMode))
      this.dims = [this.element.scrollHeight, this.element.scrollWidth];
    if (!this.dims)
      this.dims = [this.options.scaleMode.originalHeight,
                   this.options.scaleMode.originalWidth];
  },
  update: function(position) {
    var currentScale = (this.options.scaleFrom/100.0) + (this.factor * position);
    if (this.options.scaleContent && this.fontSize)
      this.element.setStyle({fontSize: this.fontSize * currentScale + this.fontSizeType });
    this.setDimensions(this.dims[0] * currentScale, this.dims[1] * currentScale);
  },
  finish: function(position) {
    if (this.restoreAfterFinish) this.element.setStyle(this.originalStyle);
  },
  setDimensions: function(height, width) {
    var d = { };
    if (this.options.scaleX) d.width = width.round() + 'px';
    if (this.options.scaleY) d.height = height.round() + 'px';
    if (this.options.scaleFromCenter) {
      var topd  = (height - this.dims[0])/2;
      var leftd = (width  - this.dims[1])/2;
      if (this.elementPositioning == 'absolute') {
        if (this.options.scaleY) d.top = this.originalTop-topd + 'px';
        if (this.options.scaleX) d.left = this.originalLeft-leftd + 'px';
      } else {
        if (this.options.scaleY) d.top = -topd + 'px';
        if (this.options.scaleX) d.left = -leftd + 'px';
      }
    }
    this.element.setStyle(d);
  }
});

Effect.Highlight = Class.create(Effect.Base, {
  initialize: function(element) {
    this.element = $(element);
    if (!this.element) throw(Effect._elementDoesNotExistError);
    var options = Object.extend({ startcolor: '#ffff99' }, arguments[1] || { });
    this.start(options);
  },
  setup: function() {
    // Prevent executing on elements not in the layout flow
    if (this.element.getStyle('display')=='none') { this.cancel(); return; }
    // Disable background image during the effect
    this.oldStyle = { };
    if (!this.options.keepBackgroundImage) {
      this.oldStyle.backgroundImage = this.element.getStyle('background-image');
      this.element.setStyle({backgroundImage: 'none'});
    }
    if (!this.options.endcolor)
      this.options.endcolor = this.element.getStyle('background-color').parseColor('#ffffff');
    if (!this.options.restorecolor)
      this.options.restorecolor = this.element.getStyle('background-color');
    // init color calculations
    this._base  = $R(0,2).map(function(i){ return parseInt(this.options.startcolor.slice(i*2+1,i*2+3),16) }.bind(this));
    this._delta = $R(0,2).map(function(i){ return parseInt(this.options.endcolor.slice(i*2+1,i*2+3),16)-this._base[i] }.bind(this));
  },
  update: function(position) {
    this.element.setStyle({backgroundColor: $R(0,2).inject('#',function(m,v,i){
      return m+((this._base[i]+(this._delta[i]*position)).round().toColorPart()); }.bind(this)) });
  },
  finish: function() {
    this.element.setStyle(Object.extend(this.oldStyle, {
      backgroundColor: this.options.restorecolor
    }));
  }
});

Effect.ScrollTo = function(element) {
  var options = arguments[1] || { },
  scrollOffsets = document.viewport.getScrollOffsets(),
  elementOffsets = $(element).cumulativeOffset();

  if (options.offset) elementOffsets[1] += options.offset;

  return new Effect.Tween(null,
    scrollOffsets.top,
    elementOffsets[1],
    options,
    function(p){ scrollTo(scrollOffsets.left, p.round()); }
  );
};

/* ------------- combination effects ------------- */

Effect.Fade = function(element) {
  element = $(element);
  var oldOpacity = element.getInlineOpacity();
  var options = Object.extend({
    from: element.getOpacity() || 1.0,
    to:   0.0,
    afterFinishInternal: function(effect) {
      if (effect.options.to!=0) return;
      effect.element.hide().setStyle({opacity: oldOpacity});
    }
  }, arguments[1] || { });
  return new Effect.Opacity(element,options);
};

Effect.Appear = function(element) {
  element = $(element);
  var options = Object.extend({
  from: (element.getStyle('display') == 'none' ? 0.0 : element.getOpacity() || 0.0),
  to:   1.0,
  // force Safari to render floated elements properly
  afterFinishInternal: function(effect) {
    effect.element.forceRerendering();
  },
  beforeSetup: function(effect) {
    effect.element.setOpacity(effect.options.from).show();
  }}, arguments[1] || { });
  return new Effect.Opacity(element,options);
};

Effect.Puff = function(element) {
  element = $(element);
  var oldStyle = {
    opacity: element.getInlineOpacity(),
    position: element.getStyle('position'),
    top:  element.style.top,
    left: element.style.left,
    width: element.style.width,
    height: element.style.height
  };
  return new Effect.Parallel(
   [ new Effect.Scale(element, 200,
      { sync: true, scaleFromCenter: true, scaleContent: true, restoreAfterFinish: true }),
     new Effect.Opacity(element, { sync: true, to: 0.0 } ) ],
     Object.extend({ duration: 1.0,
      beforeSetupInternal: function(effect) {
        Position.absolutize(effect.effects[0].element);
      },
      afterFinishInternal: function(effect) {
         effect.effects[0].element.hide().setStyle(oldStyle); }
     }, arguments[1] || { })
   );
};

Effect.BlindUp = function(element) {
  element = $(element);
  element.makeClipping();
  return new Effect.Scale(element, 0,
    Object.extend({ scaleContent: false,
      scaleX: false,
      restoreAfterFinish: true,
      afterFinishInternal: function(effect) {
        effect.element.hide().undoClipping();
      }
    }, arguments[1] || { })
  );
};

Effect.BlindDown = function(element) {
  element = $(element);
  var elementDimensions = element.getDimensions();
  return new Effect.Scale(element, 100, Object.extend({
    scaleContent: false,
    scaleX: false,
    scaleFrom: 0,
    scaleMode: {originalHeight: elementDimensions.height, originalWidth: elementDimensions.width},
    restoreAfterFinish: true,
    afterSetup: function(effect) {
      effect.element.makeClipping().setStyle({height: '0px'}).show();
    },
    afterFinishInternal: function(effect) {
      effect.element.undoClipping();
    }
  }, arguments[1] || { }));
};

Effect.SwitchOff = function(element) {
  element = $(element);
  var oldOpacity = element.getInlineOpacity();
  return new Effect.Appear(element, Object.extend({
    duration: 0.4,
    from: 0,
    transition: Effect.Transitions.flicker,
    afterFinishInternal: function(effect) {
      new Effect.Scale(effect.element, 1, {
        duration: 0.3, scaleFromCenter: true,
        scaleX: false, scaleContent: false, restoreAfterFinish: true,
        beforeSetup: function(effect) {
          effect.element.makePositioned().makeClipping();
        },
        afterFinishInternal: function(effect) {
          effect.element.hide().undoClipping().undoPositioned().setStyle({opacity: oldOpacity});
        }
      });
    }
  }, arguments[1] || { }));
};

Effect.DropOut = function(element) {
  element = $(element);
  var oldStyle = {
    top: element.getStyle('top'),
    left: element.getStyle('left'),
    opacity: element.getInlineOpacity() };
  return new Effect.Parallel(
    [ new Effect.Move(element, {x: 0, y: 100, sync: true }),
      new Effect.Opacity(element, { sync: true, to: 0.0 }) ],
    Object.extend(
      { duration: 0.5,
        beforeSetup: function(effect) {
          effect.effects[0].element.makePositioned();
        },
        afterFinishInternal: function(effect) {
          effect.effects[0].element.hide().undoPositioned().setStyle(oldStyle);
        }
      }, arguments[1] || { }));
};

Effect.Shake = function(element) {
  element = $(element);
  var options = Object.extend({
    distance: 20,
    duration: 0.5
  }, arguments[1] || {});
  var distance = parseFloat(options.distance);
  var split = parseFloat(options.duration) / 10.0;
  var oldStyle = {
    top: element.getStyle('top'),
    left: element.getStyle('left') };
    return new Effect.Move(element,
      { x:  distance, y: 0, duration: split, afterFinishInternal: function(effect) {
    new Effect.Move(effect.element,
      { x: -distance*2, y: 0, duration: split*2,  afterFinishInternal: function(effect) {
    new Effect.Move(effect.element,
      { x:  distance*2, y: 0, duration: split*2,  afterFinishInternal: function(effect) {
    new Effect.Move(effect.element,
      { x: -distance*2, y: 0, duration: split*2,  afterFinishInternal: function(effect) {
    new Effect.Move(effect.element,
      { x:  distance*2, y: 0, duration: split*2,  afterFinishInternal: function(effect) {
    new Effect.Move(effect.element,
      { x: -distance, y: 0, duration: split, afterFinishInternal: function(effect) {
        effect.element.undoPositioned().setStyle(oldStyle);
  }}); }}); }}); }}); }}); }});
};

Effect.SlideDown = function(element) {
  element = $(element).cleanWhitespace();
  // SlideDown need to have the content of the element wrapped in a container element with fixed height!
  var oldInnerBottom = element.down().getStyle('bottom');
  var elementDimensions = element.getDimensions();
  return new Effect.Scale(element, 100, Object.extend({
    scaleContent: false,
    scaleX: false,
    scaleFrom: window.opera ? 0 : 1,
    scaleMode: {originalHeight: elementDimensions.height, originalWidth: elementDimensions.width},
    restoreAfterFinish: true,
    afterSetup: function(effect) {
      effect.element.makePositioned();
      effect.element.down().makePositioned();
      if (window.opera) effect.element.setStyle({top: ''});
      effect.element.makeClipping().setStyle({height: '0px'}).show();
    },
    afterUpdateInternal: function(effect) {
      effect.element.down().setStyle({bottom:
        (effect.dims[0] - effect.element.clientHeight) + 'px' });
    },
    afterFinishInternal: function(effect) {
      effect.element.undoClipping().undoPositioned();
      effect.element.down().undoPositioned().setStyle({bottom: oldInnerBottom}); }
    }, arguments[1] || { })
  );
};

Effect.SlideUp = function(element) {
  element = $(element).cleanWhitespace();
  var oldInnerBottom = element.down().getStyle('bottom');
  var elementDimensions = element.getDimensions();
  return new Effect.Scale(element, window.opera ? 0 : 1,
   Object.extend({ scaleContent: false,
    scaleX: false,
    scaleMode: 'box',
    scaleFrom: 100,
    scaleMode: {originalHeight: elementDimensions.height, originalWidth: elementDimensions.width},
    restoreAfterFinish: true,
    afterSetup: function(effect) {
      effect.element.makePositioned();
      effect.element.down().makePositioned();
      if (window.opera) effect.element.setStyle({top: ''});
      effect.element.makeClipping().show();
    },
    afterUpdateInternal: function(effect) {
      effect.element.down().setStyle({bottom:
        (effect.dims[0] - effect.element.clientHeight) + 'px' });
    },
    afterFinishInternal: function(effect) {
      effect.element.hide().undoClipping().undoPositioned();
      effect.element.down().undoPositioned().setStyle({bottom: oldInnerBottom});
    }
   }, arguments[1] || { })
  );
};

// Bug in opera makes the TD containing this element expand for a instance after finish
Effect.Squish = function(element) {
  return new Effect.Scale(element, window.opera ? 1 : 0, {
    restoreAfterFinish: true,
    beforeSetup: function(effect) {
      effect.element.makeClipping();
    },
    afterFinishInternal: function(effect) {
      effect.element.hide().undoClipping();
    }
  });
};

Effect.Grow = function(element) {
  element = $(element);
  var options = Object.extend({
    direction: 'center',
    moveTransition: Effect.Transitions.sinoidal,
    scaleTransition: Effect.Transitions.sinoidal,
    opacityTransition: Effect.Transitions.full
  }, arguments[1] || { });
  var oldStyle = {
    top: element.style.top,
    left: element.style.left,
    height: element.style.height,
    width: element.style.width,
    opacity: element.getInlineOpacity() };

  var dims = element.getDimensions();
  var initialMoveX, initialMoveY;
  var moveX, moveY;

  switch (options.direction) {
    case 'top-left':
      initialMoveX = initialMoveY = moveX = moveY = 0;
      break;
    case 'top-right':
      initialMoveX = dims.width;
      initialMoveY = moveY = 0;
      moveX = -dims.width;
      break;
    case 'bottom-left':
      initialMoveX = moveX = 0;
      initialMoveY = dims.height;
      moveY = -dims.height;
      break;
    case 'bottom-right':
      initialMoveX = dims.width;
      initialMoveY = dims.height;
      moveX = -dims.width;
      moveY = -dims.height;
      break;
    case 'center':
      initialMoveX = dims.width / 2;
      initialMoveY = dims.height / 2;
      moveX = -dims.width / 2;
      moveY = -dims.height / 2;
      break;
  }

  return new Effect.Move(element, {
    x: initialMoveX,
    y: initialMoveY,
    duration: 0.01,
    beforeSetup: function(effect) {
      effect.element.hide().makeClipping().makePositioned();
    },
    afterFinishInternal: function(effect) {
      new Effect.Parallel(
        [ new Effect.Opacity(effect.element, { sync: true, to: 1.0, from: 0.0, transition: options.opacityTransition }),
          new Effect.Move(effect.element, { x: moveX, y: moveY, sync: true, transition: options.moveTransition }),
          new Effect.Scale(effect.element, 100, {
            scaleMode: { originalHeight: dims.height, originalWidth: dims.width },
            sync: true, scaleFrom: window.opera ? 1 : 0, transition: options.scaleTransition, restoreAfterFinish: true})
        ], Object.extend({
             beforeSetup: function(effect) {
               effect.effects[0].element.setStyle({height: '0px'}).show();
             },
             afterFinishInternal: function(effect) {
               effect.effects[0].element.undoClipping().undoPositioned().setStyle(oldStyle);
             }
           }, options)
      );
    }
  });
};

Effect.Shrink = function(element) {
  element = $(element);
  var options = Object.extend({
    direction: 'center',
    moveTransition: Effect.Transitions.sinoidal,
    scaleTransition: Effect.Transitions.sinoidal,
    opacityTransition: Effect.Transitions.none
  }, arguments[1] || { });
  var oldStyle = {
    top: element.style.top,
    left: element.style.left,
    height: element.style.height,
    width: element.style.width,
    opacity: element.getInlineOpacity() };

  var dims = element.getDimensions();
  var moveX, moveY;

  switch (options.direction) {
    case 'top-left':
      moveX = moveY = 0;
      break;
    case 'top-right':
      moveX = dims.width;
      moveY = 0;
      break;
    case 'bottom-left':
      moveX = 0;
      moveY = dims.height;
      break;
    case 'bottom-right':
      moveX = dims.width;
      moveY = dims.height;
      break;
    case 'center':
      moveX = dims.width / 2;
      moveY = dims.height / 2;
      break;
  }

  return new Effect.Parallel(
    [ new Effect.Opacity(element, { sync: true, to: 0.0, from: 1.0, transition: options.opacityTransition }),
      new Effect.Scale(element, window.opera ? 1 : 0, { sync: true, transition: options.scaleTransition, restoreAfterFinish: true}),
      new Effect.Move(element, { x: moveX, y: moveY, sync: true, transition: options.moveTransition })
    ], Object.extend({
         beforeStartInternal: function(effect) {
           effect.effects[0].element.makePositioned().makeClipping();
         },
         afterFinishInternal: function(effect) {
           effect.effects[0].element.hide().undoClipping().undoPositioned().setStyle(oldStyle); }
       }, options)
  );
};

Effect.Pulsate = function(element) {
  element = $(element);
  var options    = arguments[1] || { },
    oldOpacity = element.getInlineOpacity(),
    transition = options.transition || Effect.Transitions.linear,
    reverser   = function(pos){
      return 1 - transition((-Math.cos((pos*(options.pulses||5)*2)*Math.PI)/2) + .5);
    };

  return new Effect.Opacity(element,
    Object.extend(Object.extend({  duration: 2.0, from: 0,
      afterFinishInternal: function(effect) { effect.element.setStyle({opacity: oldOpacity}); }
    }, options), {transition: reverser}));
};

Effect.Fold = function(element) {
  element = $(element);
  var oldStyle = {
    top: element.style.top,
    left: element.style.left,
    width: element.style.width,
    height: element.style.height };
  element.makeClipping();
  return new Effect.Scale(element, 5, Object.extend({
    scaleContent: false,
    scaleX: false,
    afterFinishInternal: function(effect) {
    new Effect.Scale(element, 1, {
      scaleContent: false,
      scaleY: false,
      afterFinishInternal: function(effect) {
        effect.element.hide().undoClipping().setStyle(oldStyle);
      } });
  }}, arguments[1] || { }));
};

Effect.Morph = Class.create(Effect.Base, {
  initialize: function(element) {
    this.element = $(element);
    if (!this.element) throw(Effect._elementDoesNotExistError);
    var options = Object.extend({
      style: { }
    }, arguments[1] || { });

    if (!Object.isString(options.style)) this.style = $H(options.style);
    else {
      if (options.style.include(':'))
        this.style = options.style.parseStyle();
      else {
        this.element.addClassName(options.style);
        this.style = $H(this.element.getStyles());
        this.element.removeClassName(options.style);
        var css = this.element.getStyles();
        this.style = this.style.reject(function(style) {
          return style.value == css[style.key];
        });
        options.afterFinishInternal = function(effect) {
          effect.element.addClassName(effect.options.style);
          effect.transforms.each(function(transform) {
            effect.element.style[transform.style] = '';
          });
        };
      }
    }
    this.start(options);
  },

  setup: function(){
    function parseColor(color){
      if (!color || ['rgba(0, 0, 0, 0)','transparent'].include(color)) color = '#ffffff';
      color = color.parseColor();
      return $R(0,2).map(function(i){
        return parseInt( color.slice(i*2+1,i*2+3), 16 );
      });
    }
    this.transforms = this.style.map(function(pair){
      var property = pair[0], value = pair[1], unit = null;

      if (value.parseColor('#zzzzzz') != '#zzzzzz') {
        value = value.parseColor();
        unit  = 'color';
      } else if (property == 'opacity') {
        value = parseFloat(value);
        if (Prototype.Browser.IE && (!this.element.currentStyle.hasLayout))
          this.element.setStyle({zoom: 1});
      } else if (Element.CSS_LENGTH.test(value)) {
          var components = value.match(/^([\+\-]?[0-9\.]+)(.*)$/);
          value = parseFloat(components[1]);
          unit = (components.length == 3) ? components[2] : null;
      }

      var originalValue = this.element.getStyle(property);
      return {
        style: property.camelize(),
        originalValue: unit=='color' ? parseColor(originalValue) : parseFloat(originalValue || 0),
        targetValue: unit=='color' ? parseColor(value) : value,
        unit: unit
      };
    }.bind(this)).reject(function(transform){
      return (
        (transform.originalValue == transform.targetValue) ||
        (
          transform.unit != 'color' &&
          (isNaN(transform.originalValue) || isNaN(transform.targetValue))
        )
      );
    });
  },
  update: function(position) {
    var style = { }, transform, i = this.transforms.length;
    while(i--)
      style[(transform = this.transforms[i]).style] =
        transform.unit=='color' ? '#'+
          (Math.round(transform.originalValue[0]+
            (transform.targetValue[0]-transform.originalValue[0])*position)).toColorPart() +
          (Math.round(transform.originalValue[1]+
            (transform.targetValue[1]-transform.originalValue[1])*position)).toColorPart() +
          (Math.round(transform.originalValue[2]+
            (transform.targetValue[2]-transform.originalValue[2])*position)).toColorPart() :
        (transform.originalValue +
          (transform.targetValue - transform.originalValue) * position).toFixed(3) +
            (transform.unit === null ? '' : transform.unit);
    this.element.setStyle(style, true);
  }
});

Effect.Transform = Class.create({
  initialize: function(tracks){
    this.tracks  = [];
    this.options = arguments[1] || { };
    this.addTracks(tracks);
  },
  addTracks: function(tracks){
    tracks.each(function(track){
      track = $H(track);
      var data = track.values().first();
      this.tracks.push($H({
        ids:     track.keys().first(),
        effect:  Effect.Morph,
        options: { style: data }
      }));
    }.bind(this));
    return this;
  },
  play: function(){
    return new Effect.Parallel(
      this.tracks.map(function(track){
        var ids = track.get('ids'), effect = track.get('effect'), options = track.get('options');
        var elements = [$(ids) || $$(ids)].flatten();
        return elements.map(function(e){ return new effect(e, Object.extend({ sync:true }, options)) });
      }).flatten(),
      this.options
    );
  }
});

Element.CSS_PROPERTIES = $w(
  'backgroundColor backgroundPosition borderBottomColor borderBottomStyle ' +
  'borderBottomWidth borderLeftColor borderLeftStyle borderLeftWidth ' +
  'borderRightColor borderRightStyle borderRightWidth borderSpacing ' +
  'borderTopColor borderTopStyle borderTopWidth bottom clip color ' +
  'fontSize fontWeight height left letterSpacing lineHeight ' +
  'marginBottom marginLeft marginRight marginTop markerOffset maxHeight '+
  'maxWidth minHeight minWidth opacity outlineColor outlineOffset ' +
  'outlineWidth paddingBottom paddingLeft paddingRight paddingTop ' +
  'right textIndent top width wordSpacing zIndex');

Element.CSS_LENGTH = /^(([\+\-]?[0-9\.]+)(em|ex|px|in|cm|mm|pt|pc|\%))|0$/;

String.__parseStyleElement = document.createElement('div');
String.prototype.parseStyle = function(){
  var style, styleRules = $H();
  if (Prototype.Browser.WebKit)
    style = new Element('div',{style:this}).style;
  else {
    String.__parseStyleElement.innerHTML = '<div style="' + this + '"></div>';
    style = String.__parseStyleElement.childNodes[0].style;
  }

  Element.CSS_PROPERTIES.each(function(property){
    if (style[property]) styleRules.set(property, style[property]);
  });

  if (Prototype.Browser.IE && this.include('opacity'))
    styleRules.set('opacity', this.match(/opacity:\s*((?:0|1)?(?:\.\d*)?)/)[1]);

  return styleRules;
};

if (document.defaultView && document.defaultView.getComputedStyle) {
  Element.getStyles = function(element) {
    var css = document.defaultView.getComputedStyle($(element), null);
    return Element.CSS_PROPERTIES.inject({ }, function(styles, property) {
      styles[property] = css[property];
      return styles;
    });
  };
} else {
  Element.getStyles = function(element) {
    element = $(element);
    var css = element.currentStyle, styles;
    styles = Element.CSS_PROPERTIES.inject({ }, function(results, property) {
      results[property] = css[property];
      return results;
    });
    if (!styles.opacity) styles.opacity = element.getOpacity();
    return styles;
  };
}

Effect.Methods = {
  morph: function(element, style) {
    element = $(element);
    new Effect.Morph(element, Object.extend({ style: style }, arguments[2] || { }));
    return element;
  },
  visualEffect: function(element, effect, options) {
    element = $(element);
    var s = effect.dasherize().camelize(), klass = s.charAt(0).toUpperCase() + s.substring(1);
    new Effect[klass](element, options);
    return element;
  },
  highlight: function(element, options) {
    element = $(element);
    new Effect.Highlight(element, options);
    return element;
  }
};

$w('fade appear grow shrink fold blindUp blindDown slideUp slideDown '+
  'pulsate shake puff squish switchOff dropOut').each(
  function(effect) {
    Effect.Methods[effect] = function(element, options){
      element = $(element);
      Effect[effect.charAt(0).toUpperCase() + effect.substring(1)](element, options);
      return element;
    };
  }
);

$w('getInlineOpacity forceRerendering setContentZoom collectTextNodes collectTextNodesIgnoreClass getStyles').each(
  function(f) { Effect.Methods[f] = Element[f]; }
);

Element.addMethods(Effect.Methods);
// script.aculo.us controls.js v1.8.2, Tue Nov 18 18:30:58 +0100 2008

// Copyright (c) 2005-2008 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
//           (c) 2005-2008 Ivan Krstic (http://blogs.law.harvard.edu/ivan)
//           (c) 2005-2008 Jon Tirsen (http://www.tirsen.com)
// Contributors:
//  Richard Livsey
//  Rahul Bhargava
//  Rob Wills
//
// script.aculo.us is freely distributable under the terms of an MIT-style license.
// For details, see the script.aculo.us web site: http://script.aculo.us/

// Autocompleter.Base handles all the autocompletion functionality
// that's independent of the data source for autocompletion. This
// includes drawing the autocompletion menu, observing keyboard
// and mouse events, and similar.
//
// Specific autocompleters need to provide, at the very least,
// a getUpdatedChoices function that will be invoked every time
// the text inside the monitored textbox changes. This method
// should get the text for which to provide autocompletion by
// invoking this.getToken(), NOT by directly accessing
// this.element.value. This is to allow incremental tokenized
// autocompletion. Specific auto-completion logic (AJAX, etc)
// belongs in getUpdatedChoices.
//
// Tokenized incremental autocompletion is enabled automatically
// when an autocompleter is instantiated with the 'tokens' option
// in the options parameter, e.g.:
// new Ajax.Autocompleter('id','upd', '/url/', { tokens: ',' });
// will incrementally autocomplete with a comma as the token.
// Additionally, ',' in the above example can be replaced with
// a token array, e.g. { tokens: [',', '\n'] } which
// enables autocompletion on multiple tokens. This is most
// useful when one of the tokens is \n (a newline), as it
// allows smart autocompletion after linebreaks.

if(typeof Effect == 'undefined')
  throw("controls.js requires including script.aculo.us' effects.js library");

var Autocompleter = { };
Autocompleter.Base = Class.create({
  baseInitialize: function(element, update, options) {
    element          = $(element);
    this.element     = element;
    this.update      = $(update);
    this.hasFocus    = false;
    this.changed     = false;
    this.active      = false;
    this.index       = 0;
    this.entryCount  = 0;
    this.oldElementValue = this.element.value;

    if(this.setOptions)
      this.setOptions(options);
    else
      this.options = options || { };

    this.options.paramName    = this.options.paramName || this.element.name;
    this.options.tokens       = this.options.tokens || [];
    this.options.frequency    = this.options.frequency || 0.4;
    this.options.minChars     = this.options.minChars || 1;
    this.options.onShow       = this.options.onShow ||
      function(element, update){
        if(!update.style.position || update.style.position=='absolute') {
          update.style.position = 'absolute';
          Position.clone(element, update, {
            setHeight: false,
            offsetTop: element.offsetHeight
          });
        }
        Effect.Appear(update,{duration:0.15});
      };
    this.options.onHide = this.options.onHide ||
      function(element, update){ new Effect.Fade(update,{duration:0.15}) };

    if(typeof(this.options.tokens) == 'string')
      this.options.tokens = new Array(this.options.tokens);
    // Force carriage returns as token delimiters anyway
    if (!this.options.tokens.include('\n'))
      this.options.tokens.push('\n');

    this.observer = null;

    this.element.setAttribute('autocomplete','off');

    Element.hide(this.update);

    Event.observe(this.element, 'blur', this.onBlur.bindAsEventListener(this));
    Event.observe(this.element, 'keydown', this.onKeyPress.bindAsEventListener(this));
  },

  show: function() {
    if(Element.getStyle(this.update, 'display')=='none') this.options.onShow(this.element, this.update);
    if(!this.iefix &&
      (Prototype.Browser.IE) &&
      (Element.getStyle(this.update, 'position')=='absolute')) {
      new Insertion.After(this.update,
       '<iframe id="' + this.update.id + '_iefix" '+
       'style="display:none;position:absolute;filter:progid:DXImageTransform.Microsoft.Alpha(opacity=0);" ' +
       'src="javascript:false;" frameborder="0" scrolling="no"></iframe>');
      this.iefix = $(this.update.id+'_iefix');
    }
    if(this.iefix) setTimeout(this.fixIEOverlapping.bind(this), 50);
  },

  fixIEOverlapping: function() {
    Position.clone(this.update, this.iefix, {setTop:(!this.update.style.height)});
    this.iefix.style.zIndex = 1;
    this.update.style.zIndex = 2;
    Element.show(this.iefix);
  },

  hide: function() {
    this.stopIndicator();
    if(Element.getStyle(this.update, 'display')!='none') this.options.onHide(this.element, this.update);
    if(this.iefix) Element.hide(this.iefix);
  },

  startIndicator: function() {
    if(this.options.indicator) Element.show(this.options.indicator);
  },

  stopIndicator: function() {
    if(this.options.indicator) Element.hide(this.options.indicator);
  },

  onKeyPress: function(event) {
    if(this.active)
      switch(event.keyCode) {
       case Event.KEY_TAB:
       case Event.KEY_RETURN:
         this.selectEntry();
         Event.stop(event);
       case Event.KEY_ESC:
         this.hide();
         this.active = false;
         Event.stop(event);
         return;
       case Event.KEY_LEFT:
       case Event.KEY_RIGHT:
         return;
       case Event.KEY_UP:
         this.markPrevious();
         this.render();
         Event.stop(event);
         return;
       case Event.KEY_DOWN:
         this.markNext();
         this.render();
         Event.stop(event);
         return;
      }
     else
       if(event.keyCode==Event.KEY_TAB || event.keyCode==Event.KEY_RETURN ||
         (Prototype.Browser.WebKit > 0 && event.keyCode == 0)) return;

    this.changed = true;
    this.hasFocus = true;

    if(this.observer) clearTimeout(this.observer);
      this.observer =
        setTimeout(this.onObserverEvent.bind(this), this.options.frequency*1000);
  },

  activate: function() {
    this.changed = false;
    this.hasFocus = true;
    this.getUpdatedChoices();
  },

  onHover: function(event) {
    var element = Event.findElement(event, 'LI');
    if(this.index != element.autocompleteIndex)
    {
        this.index = element.autocompleteIndex;
        this.render();
    }
    Event.stop(event);
  },

  onClick: function(event) {
    var element = Event.findElement(event, 'LI');
    this.index = element.autocompleteIndex;
    this.selectEntry();
    this.hide();
  },

  onBlur: function(event) {
    // needed to make click events working
    setTimeout(this.hide.bind(this), 250);
    this.hasFocus = false;
    this.active = false;
  },

  render: function() {
    if(this.entryCount > 0) {
      for (var i = 0; i < this.entryCount; i++)
        this.index==i ?
          Element.addClassName(this.getEntry(i),"selected") :
          Element.removeClassName(this.getEntry(i),"selected");
      if(this.hasFocus) {
        this.show();
        this.active = true;
      }
    } else {
      this.active = false;
      this.hide();
    }
  },

  markPrevious: function() {
    if(this.index > 0) this.index--;
      else this.index = this.entryCount-1;
    //this.getEntry(this.index).scrollIntoView(true); useless
  },

  markNext: function() {
    if(this.index < this.entryCount-1) this.index++;
      else this.index = 0;
    this.getEntry(this.index).scrollIntoView(false);
  },

  getEntry: function(index) {
    return this.update.firstChild.childNodes[index];
  },

  getCurrentEntry: function() {
    return this.getEntry(this.index);
  },

  selectEntry: function() {
    this.active = false;
    this.updateElement(this.getCurrentEntry());
  },

  updateElement: function(selectedElement) {
    if (this.options.updateElement) {
      this.options.updateElement(selectedElement);
      return;
    }
    var value = '';
    if (this.options.select) {
      var nodes = $(selectedElement).select('.' + this.options.select) || [];
      if(nodes.length>0) value = Element.collectTextNodes(nodes[0], this.options.select);
    } else
      value = Element.collectTextNodesIgnoreClass(selectedElement, 'informal');

    var bounds = this.getTokenBounds();
    if (bounds[0] != -1) {
      var newValue = this.element.value.substr(0, bounds[0]);
      var whitespace = this.element.value.substr(bounds[0]).match(/^\s+/);
      if (whitespace)
        newValue += whitespace[0];
      this.element.value = newValue + value + this.element.value.substr(bounds[1]);
    } else {
      this.element.value = value;
    }
    this.oldElementValue = this.element.value;
    this.element.focus();

    if (this.options.afterUpdateElement)
      this.options.afterUpdateElement(this.element, selectedElement);
  },

  updateChoices: function(choices) {
    if(!this.changed && this.hasFocus) {
      this.update.innerHTML = choices;
      Element.cleanWhitespace(this.update);
      Element.cleanWhitespace(this.update.down());

      if(this.update.firstChild && this.update.down().childNodes) {
        this.entryCount =
          this.update.down().childNodes.length;
        for (var i = 0; i < this.entryCount; i++) {
          var entry = this.getEntry(i);
          entry.autocompleteIndex = i;
          this.addObservers(entry);
        }
      } else {
        this.entryCount = 0;
      }

      this.stopIndicator();
      this.index = 0;

      if(this.entryCount==1 && this.options.autoSelect) {
        this.selectEntry();
        this.hide();
      } else {
        this.render();
      }
    }
  },

  addObservers: function(element) {
    Event.observe(element, "mouseover", this.onHover.bindAsEventListener(this));
    Event.observe(element, "click", this.onClick.bindAsEventListener(this));
  },

  onObserverEvent: function() {
    this.changed = false;
    this.tokenBounds = null;
    if(this.getToken().length>=this.options.minChars) {
      this.getUpdatedChoices();
    } else {
      this.active = false;
      this.hide();
    }
    this.oldElementValue = this.element.value;
  },

  getToken: function() {
    var bounds = this.getTokenBounds();
    return this.element.value.substring(bounds[0], bounds[1]).strip();
  },

  getTokenBounds: function() {
    if (null != this.tokenBounds) return this.tokenBounds;
    var value = this.element.value;
    if (value.strip().empty()) return [-1, 0];
    var diff = arguments.callee.getFirstDifferencePos(value, this.oldElementValue);
    var offset = (diff == this.oldElementValue.length ? 1 : 0);
    var prevTokenPos = -1, nextTokenPos = value.length;
    var tp;
    for (var index = 0, l = this.options.tokens.length; index < l; ++index) {
      tp = value.lastIndexOf(this.options.tokens[index], diff + offset - 1);
      if (tp > prevTokenPos) prevTokenPos = tp;
      tp = value.indexOf(this.options.tokens[index], diff + offset);
      if (-1 != tp && tp < nextTokenPos) nextTokenPos = tp;
    }
    return (this.tokenBounds = [prevTokenPos + 1, nextTokenPos]);
  }
});

Autocompleter.Base.prototype.getTokenBounds.getFirstDifferencePos = function(newS, oldS) {
  var boundary = Math.min(newS.length, oldS.length);
  for (var index = 0; index < boundary; ++index)
    if (newS[index] != oldS[index])
      return index;
  return boundary;
};

Ajax.Autocompleter = Class.create(Autocompleter.Base, {
  initialize: function(element, update, url, options) {
    this.baseInitialize(element, update, options);
    this.options.asynchronous  = true;
    this.options.onComplete    = this.onComplete.bind(this);
    this.options.defaultParams = this.options.parameters || null;
    this.url                   = url;
  },

  getUpdatedChoices: function() {
    this.startIndicator();

    var entry = encodeURIComponent(this.options.paramName) + '=' +
      encodeURIComponent(this.getToken());

    this.options.parameters = this.options.callback ?
      this.options.callback(this.element, entry) : entry;

    if(this.options.defaultParams)
      this.options.parameters += '&' + this.options.defaultParams;

    new Ajax.Request(this.url, this.options);
  },

  onComplete: function(request) {
    this.updateChoices(request.responseText);
  }
});

// The local array autocompleter. Used when you'd prefer to
// inject an array of autocompletion options into the page, rather
// than sending out Ajax queries, which can be quite slow sometimes.
//
// The constructor takes four parameters. The first two are, as usual,
// the id of the monitored textbox, and id of the autocompletion menu.
// The third is the array you want to autocomplete from, and the fourth
// is the options block.
//
// Extra local autocompletion options:
// - choices - How many autocompletion choices to offer
//
// - partialSearch - If false, the autocompleter will match entered
//                    text only at the beginning of strings in the
//                    autocomplete array. Defaults to true, which will
//                    match text at the beginning of any *word* in the
//                    strings in the autocomplete array. If you want to
//                    search anywhere in the string, additionally set
//                    the option fullSearch to true (default: off).
//
// - fullSsearch - Search anywhere in autocomplete array strings.
//
// - partialChars - How many characters to enter before triggering
//                   a partial match (unlike minChars, which defines
//                   how many characters are required to do any match
//                   at all). Defaults to 2.
//
// - ignoreCase - Whether to ignore case when autocompleting.
//                 Defaults to true.
//
// It's possible to pass in a custom function as the 'selector'
// option, if you prefer to write your own autocompletion logic.
// In that case, the other options above will not apply unless
// you support them.

Autocompleter.Local = Class.create(Autocompleter.Base, {
  initialize: function(element, update, array, options) {
    this.baseInitialize(element, update, options);
    this.options.array = array;
  },

  getUpdatedChoices: function() {
    this.updateChoices(this.options.selector(this));
  },

  setOptions: function(options) {
    this.options = Object.extend({
      choices: 10,
      partialSearch: true,
      partialChars: 2,
      ignoreCase: true,
      fullSearch: false,
      selector: function(instance) {
        var ret       = []; // Beginning matches
        var partial   = []; // Inside matches
        var entry     = instance.getToken();
        var count     = 0;

        for (var i = 0; i < instance.options.array.length &&
          ret.length < instance.options.choices ; i++) {

          var elem = instance.options.array[i];
          var foundPos = instance.options.ignoreCase ?
            elem.toLowerCase().indexOf(entry.toLowerCase()) :
            elem.indexOf(entry);

          while (foundPos != -1) {
            if (foundPos == 0 && elem.length != entry.length) {
              ret.push("<li><strong>" + elem.substr(0, entry.length) + "</strong>" +
                elem.substr(entry.length) + "</li>");
              break;
            } else if (entry.length >= instance.options.partialChars &&
              instance.options.partialSearch && foundPos != -1) {
              if (instance.options.fullSearch || /\s/.test(elem.substr(foundPos-1,1))) {
                partial.push("<li>" + elem.substr(0, foundPos) + "<strong>" +
                  elem.substr(foundPos, entry.length) + "</strong>" + elem.substr(
                  foundPos + entry.length) + "</li>");
                break;
              }
            }

            foundPos = instance.options.ignoreCase ?
              elem.toLowerCase().indexOf(entry.toLowerCase(), foundPos + 1) :
              elem.indexOf(entry, foundPos + 1);

          }
        }
        if (partial.length)
          ret = ret.concat(partial.slice(0, instance.options.choices - ret.length));
        return "<ul>" + ret.join('') + "</ul>";
      }
    }, options || { });
  }
});

// AJAX in-place editor and collection editor
// Full rewrite by Christophe Porteneuve <tdd@tddsworld.com> (April 2007).

// Use this if you notice weird scrolling problems on some browsers,
// the DOM might be a bit confused when this gets called so do this
// waits 1 ms (with setTimeout) until it does the activation
Field.scrollFreeActivate = function(field) {
  setTimeout(function() {
    Field.activate(field);
  }, 1);
};

Ajax.InPlaceEditor = Class.create({
  initialize: function(element, url, options) {
    this.url = url;
    this.element = element = $(element);
    this.prepareOptions();
    this._controls = { };
    arguments.callee.dealWithDeprecatedOptions(options); // DEPRECATION LAYER!!!
    Object.extend(this.options, options || { });
    if (!this.options.formId && this.element.id) {
      this.options.formId = this.element.id + '-inplaceeditor';
      if ($(this.options.formId))
        this.options.formId = '';
    }
    if (this.options.externalControl)
      this.options.externalControl = $(this.options.externalControl);
    if (!this.options.externalControl)
      this.options.externalControlOnly = false;
    this._originalBackground = this.element.getStyle('background-color') || 'transparent';
    this.element.title = this.options.clickToEditText;
    this._boundCancelHandler = this.handleFormCancellation.bind(this);
    this._boundComplete = (this.options.onComplete || Prototype.emptyFunction).bind(this);
    this._boundFailureHandler = this.handleAJAXFailure.bind(this);
    this._boundSubmitHandler = this.handleFormSubmission.bind(this);
    this._boundWrapperHandler = this.wrapUp.bind(this);
    this.registerListeners();
  },
  checkForEscapeOrReturn: function(e) {
    if (!this._editing || e.ctrlKey || e.altKey || e.shiftKey) return;
    if (Event.KEY_ESC == e.keyCode)
      this.handleFormCancellation(e);
    else if (Event.KEY_RETURN == e.keyCode)
      this.handleFormSubmission(e);
  },
  createControl: function(mode, handler, extraClasses) {
    var control = this.options[mode + 'Control'];
    var text = this.options[mode + 'Text'];
    if ('button' == control) {
      var btn = document.createElement('input');
      btn.type = 'submit';
      btn.value = text;
      btn.className = 'editor_' + mode + '_button';
      if ('cancel' == mode)
        btn.onclick = this._boundCancelHandler;
      this._form.appendChild(btn);
      this._controls[mode] = btn;
    } else if ('link' == control) {
      var link = document.createElement('a');
      link.href = '#';
      link.appendChild(document.createTextNode(text));
      link.onclick = 'cancel' == mode ? this._boundCancelHandler : this._boundSubmitHandler;
      link.className = 'editor_' + mode + '_link';
      if (extraClasses)
        link.className += ' ' + extraClasses;
      this._form.appendChild(link);
      this._controls[mode] = link;
    }
  },
  createEditField: function() {
    var text = (this.options.loadTextURL ? this.options.loadingText : this.getText());
    var fld;
    if (1 >= this.options.rows && !/\r|\n/.test(this.getText())) {
      fld = document.createElement('input');
      fld.type = 'text';
      var size = this.options.size || this.options.cols || 0;
      if (0 < size) fld.size = size;
    } else {
      fld = document.createElement('textarea');
      fld.rows = (1 >= this.options.rows ? this.options.autoRows : this.options.rows);
      fld.cols = this.options.cols || 40;
    }
    fld.name = this.options.paramName;
    fld.value = text; // No HTML breaks conversion anymore
    fld.className = 'editor_field';
    if (this.options.submitOnBlur)
      fld.onblur = this._boundSubmitHandler;
    this._controls.editor = fld;
    if (this.options.loadTextURL)
      this.loadExternalText();
    this._form.appendChild(this._controls.editor);
  },
  createForm: function() {
    var ipe = this;
    function addText(mode, condition) {
      var text = ipe.options['text' + mode + 'Controls'];
      if (!text || condition === false) return;
      ipe._form.appendChild(document.createTextNode(text));
    };
    this._form = $(document.createElement('form'));
    this._form.id = this.options.formId;
    this._form.addClassName(this.options.formClassName);
    this._form.onsubmit = this._boundSubmitHandler;
    this.createEditField();
    if ('textarea' == this._controls.editor.tagName.toLowerCase())
      this._form.appendChild(document.createElement('br'));
    if (this.options.onFormCustomization)
      this.options.onFormCustomization(this, this._form);
    addText('Before', this.options.okControl || this.options.cancelControl);
    this.createControl('ok', this._boundSubmitHandler);
    addText('Between', this.options.okControl && this.options.cancelControl);
    this.createControl('cancel', this._boundCancelHandler, 'editor_cancel');
    addText('After', this.options.okControl || this.options.cancelControl);
  },
  destroy: function() {
    if (this._oldInnerHTML)
      this.element.innerHTML = this._oldInnerHTML;
    this.leaveEditMode();
    this.unregisterListeners();
  },
  enterEditMode: function(e) {
    if (this._saving || this._editing) return;
    this._editing = true;
    this.triggerCallback('onEnterEditMode');
    if (this.options.externalControl)
      this.options.externalControl.hide();
    this.element.hide();
    this.createForm();
    this.element.parentNode.insertBefore(this._form, this.element);
    if (!this.options.loadTextURL)
      this.postProcessEditField();
    if (e) Event.stop(e);
  },
  enterHover: function(e) {
    if (this.options.hoverClassName)
      this.element.addClassName(this.options.hoverClassName);
    if (this._saving) return;
    this.triggerCallback('onEnterHover');
  },
  getText: function() {
    return this.element.innerHTML.unescapeHTML();
  },
  handleAJAXFailure: function(transport) {
    this.triggerCallback('onFailure', transport);
    if (this._oldInnerHTML) {
      this.element.innerHTML = this._oldInnerHTML;
      this._oldInnerHTML = null;
    }
  },
  handleFormCancellation: function(e) {
    this.wrapUp();
    if (e) Event.stop(e);
  },
  handleFormSubmission: function(e) {
    var form = this._form;
    var value = $F(this._controls.editor);
    this.prepareSubmission();
    var params = this.options.callback(form, value) || '';
    if (Object.isString(params))
      params = params.toQueryParams();
    params.editorId = this.element.id;
    if (this.options.htmlResponse) {
      var options = Object.extend({ evalScripts: true }, this.options.ajaxOptions);
      Object.extend(options, {
        parameters: params,
        onComplete: this._boundWrapperHandler,
        onFailure: this._boundFailureHandler
      });
      new Ajax.Updater({ success: this.element }, this.url, options);
    } else {
      var options = Object.extend({ method: 'get' }, this.options.ajaxOptions);
      Object.extend(options, {
        parameters: params,
        onComplete: this._boundWrapperHandler,
        onFailure: this._boundFailureHandler
      });
      new Ajax.Request(this.url, options);
    }
    if (e) Event.stop(e);
  },
  leaveEditMode: function() {
    this.element.removeClassName(this.options.savingClassName);
    this.removeForm();
    this.leaveHover();
    this.element.style.backgroundColor = this._originalBackground;
    this.element.show();
    if (this.options.externalControl)
      this.options.externalControl.show();
    this._saving = false;
    this._editing = false;
    this._oldInnerHTML = null;
    this.triggerCallback('onLeaveEditMode');
  },
  leaveHover: function(e) {
    if (this.options.hoverClassName)
      this.element.removeClassName(this.options.hoverClassName);
    if (this._saving) return;
    this.triggerCallback('onLeaveHover');
  },
  loadExternalText: function() {
    this._form.addClassName(this.options.loadingClassName);
    this._controls.editor.disabled = true;
    var options = Object.extend({ method: 'get' }, this.options.ajaxOptions);
    Object.extend(options, {
      parameters: 'editorId=' + encodeURIComponent(this.element.id),
      onComplete: Prototype.emptyFunction,
      onSuccess: function(transport) {
        this._form.removeClassName(this.options.loadingClassName);
        var text = transport.responseText;
        if (this.options.stripLoadedTextTags)
          text = text.stripTags();
        this._controls.editor.value = text;
        this._controls.editor.disabled = false;
        this.postProcessEditField();
      }.bind(this),
      onFailure: this._boundFailureHandler
    });
    new Ajax.Request(this.options.loadTextURL, options);
  },
  postProcessEditField: function() {
    var fpc = this.options.fieldPostCreation;
    if (fpc)
      $(this._controls.editor)['focus' == fpc ? 'focus' : 'activate']();
  },
  prepareOptions: function() {
    this.options = Object.clone(Ajax.InPlaceEditor.DefaultOptions);
    Object.extend(this.options, Ajax.InPlaceEditor.DefaultCallbacks);
    [this._extraDefaultOptions].flatten().compact().each(function(defs) {
      Object.extend(this.options, defs);
    }.bind(this));
  },
  prepareSubmission: function() {
    this._saving = true;
    this.removeForm();
    this.leaveHover();
    this.showSaving();
  },
  registerListeners: function() {
    this._listeners = { };
    var listener;
    $H(Ajax.InPlaceEditor.Listeners).each(function(pair) {
      listener = this[pair.value].bind(this);
      this._listeners[pair.key] = listener;
      if (!this.options.externalControlOnly)
        this.element.observe(pair.key, listener);
      if (this.options.externalControl)
        this.options.externalControl.observe(pair.key, listener);
    }.bind(this));
  },
  removeForm: function() {
    if (!this._form) return;
    this._form.remove();
    this._form = null;
    this._controls = { };
  },
  showSaving: function() {
    this._oldInnerHTML = this.element.innerHTML;
    this.element.innerHTML = this.options.savingText;
    this.element.addClassName(this.options.savingClassName);
    this.element.style.backgroundColor = this._originalBackground;
    this.element.show();
  },
  triggerCallback: function(cbName, arg) {
    if ('function' == typeof this.options[cbName]) {
      this.options[cbName](this, arg);
    }
  },
  unregisterListeners: function() {
    $H(this._listeners).each(function(pair) {
      if (!this.options.externalControlOnly)
        this.element.stopObserving(pair.key, pair.value);
      if (this.options.externalControl)
        this.options.externalControl.stopObserving(pair.key, pair.value);
    }.bind(this));
  },
  wrapUp: function(transport) {
    this.leaveEditMode();
    // Can't use triggerCallback due to backward compatibility: requires
    // binding + direct element
    this._boundComplete(transport, this.element);
  }
});

Object.extend(Ajax.InPlaceEditor.prototype, {
  dispose: Ajax.InPlaceEditor.prototype.destroy
});

Ajax.InPlaceCollectionEditor = Class.create(Ajax.InPlaceEditor, {
  initialize: function($super, element, url, options) {
    this._extraDefaultOptions = Ajax.InPlaceCollectionEditor.DefaultOptions;
    $super(element, url, options);
  },

  createEditField: function() {
    var list = document.createElement('select');
    list.name = this.options.paramName;
    list.size = 1;
    this._controls.editor = list;
    this._collection = this.options.collection || [];
    if (this.options.loadCollectionURL)
      this.loadCollection();
    else
      this.checkForExternalText();
    this._form.appendChild(this._controls.editor);
  },

  loadCollection: function() {
    this._form.addClassName(this.options.loadingClassName);
    this.showLoadingText(this.options.loadingCollectionText);
    var options = Object.extend({ method: 'get' }, this.options.ajaxOptions);
    Object.extend(options, {
      parameters: 'editorId=' + encodeURIComponent(this.element.id),
      onComplete: Prototype.emptyFunction,
      onSuccess: function(transport) {
        var js = transport.responseText.strip();
        if (!/^\[.*\]$/.test(js)) // TODO: improve sanity check
          throw('Server returned an invalid collection representation.');
        this._collection = eval(js);
        this.checkForExternalText();
      }.bind(this),
      onFailure: this.onFailure
    });
    new Ajax.Request(this.options.loadCollectionURL, options);
  },

  showLoadingText: function(text) {
    this._controls.editor.disabled = true;
    var tempOption = this._controls.editor.firstChild;
    if (!tempOption) {
      tempOption = document.createElement('option');
      tempOption.value = '';
      this._controls.editor.appendChild(tempOption);
      tempOption.selected = true;
    }
    tempOption.update((text || '').stripScripts().stripTags());
  },

  checkForExternalText: function() {
    this._text = this.getText();
    if (this.options.loadTextURL)
      this.loadExternalText();
    else
      this.buildOptionList();
  },

  loadExternalText: function() {
    this.showLoadingText(this.options.loadingText);
    var options = Object.extend({ method: 'get' }, this.options.ajaxOptions);
    Object.extend(options, {
      parameters: 'editorId=' + encodeURIComponent(this.element.id),
      onComplete: Prototype.emptyFunction,
      onSuccess: function(transport) {
        this._text = transport.responseText.strip();
        this.buildOptionList();
      }.bind(this),
      onFailure: this.onFailure
    });
    new Ajax.Request(this.options.loadTextURL, options);
  },

  buildOptionList: function() {
    this._form.removeClassName(this.options.loadingClassName);
    this._collection = this._collection.map(function(entry) {
      return 2 === entry.length ? entry : [entry, entry].flatten();
    });
    var marker = ('value' in this.options) ? this.options.value : this._text;
    var textFound = this._collection.any(function(entry) {
      return entry[0] == marker;
    }.bind(this));
    this._controls.editor.update('');
    var option;
    this._collection.each(function(entry, index) {
      option = document.createElement('option');
      option.value = entry[0];
      option.selected = textFound ? entry[0] == marker : 0 == index;
      option.appendChild(document.createTextNode(entry[1]));
      this._controls.editor.appendChild(option);
    }.bind(this));
    this._controls.editor.disabled = false;
    Field.scrollFreeActivate(this._controls.editor);
  }
});

//**** DEPRECATION LAYER FOR InPlace[Collection]Editor! ****
//**** This only  exists for a while,  in order to  let ****
//**** users adapt to  the new API.  Read up on the new ****
//**** API and convert your code to it ASAP!            ****

Ajax.InPlaceEditor.prototype.initialize.dealWithDeprecatedOptions = function(options) {
  if (!options) return;
  function fallback(name, expr) {
    if (name in options || expr === undefined) return;
    options[name] = expr;
  };
  fallback('cancelControl', (options.cancelLink ? 'link' : (options.cancelButton ? 'button' :
    options.cancelLink == options.cancelButton == false ? false : undefined)));
  fallback('okControl', (options.okLink ? 'link' : (options.okButton ? 'button' :
    options.okLink == options.okButton == false ? false : undefined)));
  fallback('highlightColor', options.highlightcolor);
  fallback('highlightEndColor', options.highlightendcolor);
};

Object.extend(Ajax.InPlaceEditor, {
  DefaultOptions: {
    ajaxOptions: { },
    autoRows: 3,                                // Use when multi-line w/ rows == 1
    cancelControl: 'link',                      // 'link'|'button'|false
    cancelText: 'cancel',
    clickToEditText: 'Click to edit',
    externalControl: null,                      // id|elt
    externalControlOnly: false,
    fieldPostCreation: 'activate',              // 'activate'|'focus'|false
    formClassName: 'inplaceeditor-form',
    formId: null,                               // id|elt
    highlightColor: '#ffff99',
    highlightEndColor: '#ffffff',
    hoverClassName: '',
    htmlResponse: true,
    loadingClassName: 'inplaceeditor-loading',
    loadingText: 'Loading...',
    okControl: 'button',                        // 'link'|'button'|false
    okText: 'ok',
    paramName: 'value',
    rows: 1,                                    // If 1 and multi-line, uses autoRows
    savingClassName: 'inplaceeditor-saving',
    savingText: 'Saving...',
    size: 0,
    stripLoadedTextTags: false,
    submitOnBlur: false,
    textAfterControls: '',
    textBeforeControls: '',
    textBetweenControls: ''
  },
  DefaultCallbacks: {
    callback: function(form) {
      return Form.serialize(form);
    },
    onComplete: function(transport, element) {
      // For backward compatibility, this one is bound to the IPE, and passes
      // the element directly.  It was too often customized, so we don't break it.
      new Effect.Highlight(element, {
        startcolor: this.options.highlightColor, keepBackgroundImage: true });
    },
    onEnterEditMode: null,
    onEnterHover: function(ipe) {
      ipe.element.style.backgroundColor = ipe.options.highlightColor;
      if (ipe._effect)
        ipe._effect.cancel();
    },
    onFailure: function(transport, ipe) {
      alert('Error communication with the server: ' + transport.responseText.stripTags());
    },
    onFormCustomization: null, // Takes the IPE and its generated form, after editor, before controls.
    onLeaveEditMode: null,
    onLeaveHover: function(ipe) {
      ipe._effect = new Effect.Highlight(ipe.element, {
        startcolor: ipe.options.highlightColor, endcolor: ipe.options.highlightEndColor,
        restorecolor: ipe._originalBackground, keepBackgroundImage: true
      });
    }
  },
  Listeners: {
    click: 'enterEditMode',
    keydown: 'checkForEscapeOrReturn',
    mouseover: 'enterHover',
    mouseout: 'leaveHover'
  }
});

Ajax.InPlaceCollectionEditor.DefaultOptions = {
  loadingCollectionText: 'Loading options...'
};

// Delayed observer, like Form.Element.Observer,
// but waits for delay after last key input
// Ideal for live-search fields

Form.Element.DelayedObserver = Class.create({
  initialize: function(element, delay, callback) {
    this.delay     = delay || 0.5;
    this.element   = $(element);
    this.callback  = callback;
    this.timer     = null;
    this.lastValue = $F(this.element);
    Event.observe(this.element,'keyup',this.delayedListener.bindAsEventListener(this));
  },
  delayedListener: function(event) {
    if(this.lastValue == $F(this.element)) return;
    if(this.timer) clearTimeout(this.timer);
    this.timer = setTimeout(this.onTimerEvent.bind(this), this.delay * 1000);
    this.lastValue = $F(this.element);
  },
  onTimerEvent: function() {
    this.timer = null;
    this.callback(this.element, $F(this.element));
  }
});
/**
 * Magento
 *
 * NOTICE OF LICENSE
 *
 * This source file is subject to the Academic Free License (AFL 3.0)
 * that is bundled with this package in the file LICENSE_AFL.txt.
 * It is also available through the world-wide-web at this URL:
 * http://opensource.org/licenses/afl-3.0.php
 * If you did not receive a copy of the license and are unable to
 * obtain it through the world-wide-web, please send an email
 * to license@magentocommerce.com so we can send you a copy immediately.
 *
 * DISCLAIMER
 *
 * Do not edit or add to this file if you wish to upgrade Magento to newer
 * versions in the future. If you wish to customize Magento for your
 * needs please refer to http://www.magentocommerce.com for more information.
 *
 * @category    Varien
 * @package     js
 * @copyright   Copyright (c) 2010 Magento Inc. (http://www.magentocommerce.com)
 * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
 */
function popWin(url,win,para) {
    var win = window.open(url,win,para);
    win.focus();
}

function setLocation(url){
    window.location.href = url;
}

function setPLocation(url, setFocus){
    if( setFocus ) {
        window.opener.focus();
    }
    window.opener.location.href = url;
}

function setLanguageCode(code, fromCode){
    //TODO: javascript cookies have different domain and path than php cookies
    var href = window.location.href;
    var after = '', dash;
    if (dash = href.match(/\#(.*)$/)) {
        href = href.replace(/\#(.*)$/, '');
        after = dash[0];
    }

    if (href.match(/[?]/)) {
        var re = /([?&]store=)[a-z0-9_]*/;
        if (href.match(re)) {
            href = href.replace(re, '$1'+code);
        } else {
            href += '&store='+code;
        }

        var re = /([?&]from_store=)[a-z0-9_]*/;
        if (href.match(re)) {
            href = href.replace(re, '');
        }
    } else {
        href += '?store='+code;
    }
    if (typeof(fromCode) != 'undefined') {
        href += '&from_store='+fromCode;
    }
    href += after;

    setLocation(href);
}

/**
 * Add classes to specified elements.
 * Supported classes are: 'odd', 'even', 'first', 'last'
 *
 * @param elements - array of elements to be decorated
 * [@param decorateParams] - array of classes to be set. If omitted, all available will be used
 */
function decorateGeneric(elements, decorateParams)
{
    var allSupportedParams = ['odd', 'even', 'first', 'last'];
    var _decorateParams = {};
    var total = elements.length;

    if (total) {
        // determine params called
        if (typeof(decorateParams) == 'undefined') {
            decorateParams = allSupportedParams;
        }
        if (!decorateParams.length) {
            return;
        }
        for (var k in allSupportedParams) {
            _decorateParams[allSupportedParams[k]] = false;
        }
        for (var k in decorateParams) {
            _decorateParams[decorateParams[k]] = true;
        }

        // decorate elements
        // elements[0].addClassName('first'); // will cause bug in IE (#5587)
        if (_decorateParams.first) {
            Element.addClassName(elements[0], 'first');
        }
        if (_decorateParams.last) {
            Element.addClassName(elements[total-1], 'last');
        }
        for (var i = 0; i < total; i++) {
            if ((i + 1) % 2 == 0) {
                if (_decorateParams.even) {
                    Element.addClassName(elements[i], 'even');
                }
            }
            else {
                if (_decorateParams.odd) {
                    Element.addClassName(elements[i], 'odd');
                }
            }
        }
    }
}

/**
 * Decorate table rows and cells, tbody etc
 * @see decorateGeneric()
 */
function decorateTable(table, options) {
    var table = $(table);
    if (table) {
        // set default options
        var _options = {
            'tbody'    : false,
            'tbody tr' : ['odd', 'even', 'first', 'last'],
            'thead tr' : ['first', 'last'],
            'tfoot tr' : ['first', 'last'],
            'tr td'    : ['last']
        };
        // overload options
        if (typeof(options) != 'undefined') {
            for (var k in options) {
                _options[k] = options[k];
            }
        }
        // decorate
        if (_options['tbody']) {
            decorateGeneric(table.select('tbody'), _options['tbody']);
        }
        if (_options['tbody tr']) {
            decorateGeneric(table.select('tbody tr'), _options['tbody tr']);
        }
        if (_options['thead tr']) {
            decorateGeneric(table.select('thead tr'), _options['thead tr']);
        }
        if (_options['tfoot tr']) {
            decorateGeneric(table.select('tfoot tr'), _options['tfoot tr']);
        }
        if (_options['tr td']) {
            var allRows = table.select('tr');
            if (allRows.length) {
                for (var i = 0; i < allRows.length; i++) {
                    decorateGeneric(allRows[i].getElementsByTagName('TD'), _options['tr td']);
                }
            }
        }
    }
}

/**
 * Set "odd", "even" and "last" CSS classes for list items
 * @see decorateGeneric()
 */
function decorateList(list, nonRecursive) {
    if ($(list)) {
        if (typeof(nonRecursive) == 'undefined') {
            var items = $(list).select('li')
        }
        else {
            var items = $(list).childElements();
        }
        decorateGeneric(items, ['odd', 'even', 'last']);
    }
}

/**
 * Set "odd", "even" and "last" CSS classes for list items
 * @see decorateGeneric()
 */
function decorateDataList(list) {
    list = $(list);
    if (list) {
        decorateGeneric(list.select('dt'), ['odd', 'even', 'last']);
        decorateGeneric(list.select('dd'), ['odd', 'even', 'last']);
    }
}

/**
 * Parse SID and produces the correct URL
 */
function parseSidUrl(baseUrl, urlExt) {
    sidPos = baseUrl.indexOf('/?SID=');
    sid = '';
    urlExt = (urlExt != undefined) ? urlExt : '';

    if(sidPos > -1) {
        sid = '?' + baseUrl.substring(sidPos + 2);
        baseUrl = baseUrl.substring(0, sidPos + 1);
    }

    return baseUrl+urlExt+sid;
}

/**
 * Formats currency using patern
 * format - JSON (pattern, decimal, decimalsDelimeter, groupsDelimeter)
 * showPlus - true (always show '+'or '-'),
 *      false (never show '-' even if number is negative)
 *      null (show '-' if number is negative)
 */

function formatCurrency(price, format, showPlus){
    precision = isNaN(format.precision = Math.abs(format.precision)) ? 2 : format.precision;
    requiredPrecision = isNaN(format.requiredPrecision = Math.abs(format.requiredPrecision)) ? 2 : format.requiredPrecision;

    //precision = (precision > requiredPrecision) ? precision : requiredPrecision;
    //for now we don't need this difference so precision is requiredPrecision
    precision = requiredPrecision;

    integerRequired = isNaN(format.integerRequired = Math.abs(format.integerRequired)) ? 1 : format.integerRequired;

    decimalSymbol = format.decimalSymbol == undefined ? "," : format.decimalSymbol;
    groupSymbol = format.groupSymbol == undefined ? "." : format.groupSymbol;
    groupLength = format.groupLength == undefined ? 3 : format.groupLength;

    if (showPlus == undefined || showPlus == true) {
        s = price < 0 ? "-" : ( showPlus ? "+" : "");
    } else if (showPlus == false) {
        s = '';
    }

    i = parseInt(price = Math.abs(+price || 0).toFixed(precision)) + "";
    pad = (i.length < integerRequired) ? (integerRequired - i.length) : 0;
    while (pad) { i = '0' + i; pad--; }

    j = (j = i.length) > groupLength ? j % groupLength : 0;
    re = new RegExp("(\\d{" + groupLength + "})(?=\\d)", "g");

    /**
     * replace(/-/, 0) is only for fixing Safari bug which appears
     * when Math.abs(0).toFixed() executed on "0" number.
     * Result is "0.-0" :(
     */
    r = (j ? i.substr(0, j) + groupSymbol : "") + i.substr(j).replace(re, "$1" + groupSymbol) + (precision ? decimalSymbol + Math.abs(price - i).toFixed(precision).replace(/-/, 0).slice(2) : "")

    if (format.pattern.indexOf('{sign}') == -1) {
        pattern = s + format.pattern;
    } else {
        pattern = format.pattern.replace('{sign}', s);
    }

    return pattern.replace('%s', r).replace(/^\s\s*/, '').replace(/\s\s*$/, '');
};

function expandDetails(el, childClass) {
    if (Element.hasClassName(el,'show-details')) {
        $$(childClass).each(function(item){item.hide()});
        Element.removeClassName(el,'show-details');
    }
    else {
        $$(childClass).each(function(item){item.show()});
        Element.addClassName(el,'show-details');
    }
}

// Version 1.0
var isIE = navigator.appVersion.match(/MSIE/) == "MSIE";

if (!window.Varien)
    var Varien = new Object();

Varien.showLoading = function(){
    Element.show('loading-process');
}
Varien.hideLoading = function(){
    Element.hide('loading-process');
}
Varien.GlobalHandlers = {
    onCreate: function() {
        Varien.showLoading();
    },

    onComplete: function() {
        if(Ajax.activeRequestCount == 0) {
            Varien.hideLoading();
        }
    }
};

Ajax.Responders.register(Varien.GlobalHandlers);

/**
 * Quick Search form client model
 */
Varien.searchForm = Class.create();
Varien.searchForm.prototype = {
    initialize : function(form, field, emptyText){
        this.form   = $(form);
        this.field  = $(field);
        this.emptyText = emptyText;

        Event.observe(this.form,  'submit', this.submit.bind(this));
        Event.observe(this.field, 'focus', this.focus.bind(this));
        Event.observe(this.field, 'blur', this.blur.bind(this));
        this.blur();
    },

    submit : function(event){
        if (this.field.value == this.emptyText || this.field.value == ''){
            Event.stop(event);
            return false;
        }
        return true;
    },

    focus : function(event){
        if(this.field.value==this.emptyText){
            this.field.value='';
        }

    },

    blur : function(event){
        if(this.field.value==''){
            this.field.value=this.emptyText;
        }
    },

    initAutocomplete : function(url, destinationElement){
        new Ajax.Autocompleter(
            this.field,
            destinationElement,
            url,
            {
                paramName: this.field.name,
                method: 'get',
                minChars: 2,
                updateElement: this._selectAutocompleteItem.bind(this),
                onShow : function(element, update) {
                    if(!update.style.position || update.style.position=='absolute') {
                        update.style.position = 'absolute';
                        Position.clone(element, update, {
                            setHeight: false,
                            offsetTop: element.offsetHeight
                        });
                    }
                    Effect.Appear(update,{duration:0});
                }

            }
        );
    },

    _selectAutocompleteItem : function(element){
        if(element.title){
            this.field.value = element.title;
        }
        this.form.submit();
    }
}

Varien.Tabs = Class.create();
Varien.Tabs.prototype = {
  initialize: function(selector) {
    var self=this;
    $$(selector+' a').each(this.initTab.bind(this));
  },

  initTab: function(el) {
      el.href = 'javascript:void(0)';
      if ($(el.parentNode).hasClassName('active')) {
        this.showContent(el);
      }
      el.observe('click', this.showContent.bind(this, el));
  },

  showContent: function(a) {
    var li = $(a.parentNode), ul = $(li.parentNode);
    ul.getElementsBySelector('li', 'ol').each(function(el){
      var contents = $(el.id+'_contents');
      if (el==li) {
        el.addClassName('active');
        contents.show();
      } else {
        el.removeClassName('active');
        contents.hide();
      }
    });
  }
}

Varien.DOB = Class.create();
Varien.DOB.prototype = {
    initialize: function(selector, required, format) {
        var el        = $$(selector)[0];
        this.day      = Element.select($(el), '.dob-day input')[0];
        this.month    = Element.select($(el), '.dob-month input')[0];
        this.year     = Element.select($(el), '.dob-year input')[0];
        this.dob      = Element.select($(el), '.dob-full input')[0];
        this.advice   = Element.select($(el), '.validation-advice')[0];
        this.required = required;
        this.format   = format;

        this.day.validate = this.validate.bind(this);
        this.month.validate = this.validate.bind(this);
        this.year.validate = this.validate.bind(this);
        
        this.year.setAttribute('autocomplete','off');

        this.advice.hide();
    },

    validate: function() {
        var error = false;

        if (this.day.value=='' && this.month.value=='' && this.year.value=='') {
            if (this.required) {
                error = 'This date is a required value.';
            } else {
                this.dob.value = '';
            }
        } else if (this.day.value=='' || this.month.value=='' || this.year.value=='') {
            error = 'Please enter a valid full date.';
        } else {
            var date = new Date();
            if (this.day.value<1 || this.day.value>31) {
                error = 'Please enter a valid day (1-31).';
            } else if (this.month.value<1 || this.month.value>12) {
                error = 'Please enter a valid month (1-12).';
            } else if (this.year.value<1900 || this.year.value>date.getFullYear()) {
                error = 'Please enter a valid year (1900-'+date.getFullYear()+').';
            } else {
                this.dob.value = this.format.replace(/(%m|%b)/i, this.month.value).replace(/(%d|%e)/i, this.day.value).replace(/%y/i, this.year.value);
                var testDOB = this.month.value + '/' + this.day.value + '/'+ this.year.value;
                var test = new Date(testDOB);
                if (isNaN(test)) {
                    error = 'Please enter a valid date.';
                }
            }
        }

        if (error !== false) {
            try {
                this.advice.innerHTML = Translator.translate(error);
            }
            catch (e) {
                this.advice.innerHTML = error;
            }
            this.advice.show();
            return false;
        }

        this.advice.hide();
        return true;
    }
}

Validation.addAllThese([
    ['validate-custom', ' ', function(v,elm) {
        return elm.validate();
    }]
]);

function truncateOptions() {
    $$('.truncated').each(function(element){
        Event.observe(element, 'mouseover', function(){
            if (element.down('div.truncated_full_value')) {
                element.down('div.truncated_full_value').addClassName('show')
            }
        });
        Event.observe(element, 'mouseout', function(){
            if (element.down('div.truncated_full_value')) {
                element.down('div.truncated_full_value').removeClassName('show')
            }
        });

    });
}
Event.observe(window, 'load', function(){
   truncateOptions();
});

Element.addMethods({
    getInnerText: function(element)
    {
        element = $(element);
        if(element.innerText && !Prototype.Browser.Opera) {
            return element.innerText
        }
        return element.innerHTML.stripScripts().unescapeHTML().replace(/[\n\r\s]+/g, ' ').strip();
    }
});

if (!("console" in window) || !("firebug" in console))
{
    var names = ["log", "debug", "info", "warn", "error", "assert", "dir", "dirxml",
    "group", "groupEnd", "time", "timeEnd", "count", "trace", "profile", "profileEnd"];

    window.console = {};
    for (var i = 0; i < names.length; ++i)
        window.console[names[i]] = function() {}
}

/**
 * Executes event handler on the element. Works with event handlers attached by Prototype,
 * in a browser-agnostic fashion.
 * @param element The element object
 * @param event Event name, like 'change'
 *
 * @example fireEvent($('my-input', 'click'));
 */
function fireEvent(element, event){
    if (document.createEventObject){
        // dispatch for IE
        var evt = document.createEventObject();
        return element.fireEvent('on'+event,evt)
    }
    else{
        // dispatch for firefox + others
        var evt = document.createEvent("HTMLEvents");
        evt.initEvent(event, true, true ); // event type,bubbling,cancelable
        return !element.dispatchEvent(evt);
    }
}

/**
 * Magento
 *
 * NOTICE OF LICENSE
 *
 * This source file is subject to the Academic Free License (AFL 3.0)
 * that is bundled with this package in the file LICENSE_AFL.txt.
 * It is also available through the world-wide-web at this URL:
 * http://opensource.org/licenses/afl-3.0.php
 * If you did not receive a copy of the license and are unable to
 * obtain it through the world-wide-web, please send an email
 * to license@magentocommerce.com so we can send you a copy immediately.
 *
 * DISCLAIMER
 *
 * Do not edit or add to this file if you wish to upgrade Magento to newer
 * versions in the future. If you wish to customize Magento for your
 * needs please refer to http://www.magentocommerce.com for more information.
 *
 * @category    Varien
 * @package     js
 * @copyright   Copyright (c) 2010 Magento Inc. (http://www.magentocommerce.com)
 * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
 */
VarienForm = Class.create();
VarienForm.prototype = {
    initialize: function(formId, firstFieldFocus){
        this.form       = $(formId);
        if (!this.form) {
            return;
        }
        this.cache      = $A();
        this.currLoader = false;
        this.currDataIndex = false;
        this.validator  = new Validation(this.form);
        this.elementFocus   = this.elementOnFocus.bindAsEventListener(this);
        this.elementBlur    = this.elementOnBlur.bindAsEventListener(this);
        this.childLoader    = this.onChangeChildLoad.bindAsEventListener(this);
        this.highlightClass = 'highlight';
        this.extraChildParams = '';
        this.firstFieldFocus= firstFieldFocus || false;
        this.bindElements();
        if(this.firstFieldFocus){
            try{
                Form.Element.focus(Form.findFirstElement(this.form))
            }
            catch(e){}
        }
    },

    submit : function(url){
        if(this.validator && this.validator.validate()){
             this.form.submit();
        }
        return false;
    },

    bindElements:function (){
        var elements = Form.getElements(this.form);
        for (var row in elements) {
            if (elements[row].id) {
                Event.observe(elements[row],'focus',this.elementFocus);
                Event.observe(elements[row],'blur',this.elementBlur);
            }
        }
    },

    elementOnFocus: function(event){
        var element = Event.findElement(event, 'fieldset');
        if(element){
            Element.addClassName(element, this.highlightClass);
        }
    },

    elementOnBlur: function(event){
        var element = Event.findElement(event, 'fieldset');
        if(element){
            Element.removeClassName(element, this.highlightClass);
        }
    },

    setElementsRelation: function(parent, child, dataUrl, first){
        if (parent=$(parent)) {
            // TODO: array of relation and caching
            if (!this.cache[parent.id]){
                this.cache[parent.id] = $A();
                this.cache[parent.id]['child']     = child;
                this.cache[parent.id]['dataUrl']   = dataUrl;
                this.cache[parent.id]['data']      = $A();
                this.cache[parent.id]['first']      = first || false;
            }
            Event.observe(parent,'change',this.childLoader);
        }
    },

    onChangeChildLoad: function(event){
        element = Event.element(event);
        this.elementChildLoad(element);
    },

    elementChildLoad: function(element, callback){
        this.callback = callback || false;
        if (element.value) {
            this.currLoader = element.id;
            this.currDataIndex = element.value;
            if (this.cache[element.id]['data'][element.value]) {
                this.setDataToChild(this.cache[element.id]['data'][element.value]);
            }
            else{
                new Ajax.Request(this.cache[this.currLoader]['dataUrl'],{
                        method: 'post',
                        parameters: {"parent":element.value},
                        onComplete: this.reloadChildren.bind(this)
                });
            }
        }
    },

    reloadChildren: function(transport){
        var data = eval('(' + transport.responseText + ')');
        this.cache[this.currLoader]['data'][this.currDataIndex] = data;
        this.setDataToChild(data);
    },

    setDataToChild: function(data){
        if (data.length) {
            var child = $(this.cache[this.currLoader]['child']);
            if (child){
                var html = '<select name="'+child.name+'" id="'+child.id+'" class="'+child.className+'" title="'+child.title+'" '+this.extraChildParams+'>';
                if(this.cache[this.currLoader]['first']){
                    html+= '<option value="">'+this.cache[this.currLoader]['first']+'</option>';
                }
                for (var i in data){
                    if(data[i].value) {
                        html+= '<option value="'+data[i].value+'"';
                        if(child.value && (child.value == data[i].value || child.value == data[i].label)){
                            html+= ' selected';
                        }
                        html+='>'+data[i].label+'</option>';
                    }
                }
                html+= '</select>';
                Element.insert(child, {before: html});
                Element.remove(child);
            }
        }
        else{
            var child = $(this.cache[this.currLoader]['child']);
            if (child){
                var html = '<input type="text" name="'+child.name+'" id="'+child.id+'" class="'+child.className+'" title="'+child.title+'" '+this.extraChildParams+'>';
                Element.insert(child, {before: html});
                Element.remove(child);
            }
        }

        this.bindElements();
        if (this.callback) {
            this.callback();
        }
    }
}

RegionUpdater = Class.create();
RegionUpdater.prototype = {
    initialize: function (countryEl, regionTextEl, regionSelectEl, regions, disableAction, zipEl)
    {
        this.countryEl = $(countryEl);
        this.regionTextEl = $(regionTextEl);
        this.regionSelectEl = $(regionSelectEl);
        this.zipEl = $(zipEl);
        this.regions = regions;

        this.disableAction = (typeof disableAction=='undefined') ? 'hide' : disableAction;
        this.zipOptions = (typeof zipOptions=='undefined') ? false : zipOptions;

        if (this.regionSelectEl.options.length<=1) {
            this.update();
        }

        Event.observe(this.countryEl, 'change', this.update.bind(this));
    },

    update: function()
    {
        if (this.regions[this.countryEl.value]) {
            var i, option, region, def;

            if (this.regionTextEl) {
                def = this.regionTextEl.value.toLowerCase();
                this.regionTextEl.value = '';
            }
            if (!def) {
                def = this.regionSelectEl.getAttribute('defaultValue');
            }

            this.regionSelectEl.options.length = 1;
            for (regionId in this.regions[this.countryEl.value]) {
                region = this.regions[this.countryEl.value][regionId];

                option = document.createElement('OPTION');
                option.value = regionId;
                option.text = region.name;

                if (this.regionSelectEl.options.add) {
                    this.regionSelectEl.options.add(option);
                } else {
                    this.regionSelectEl.appendChild(option);
                }

                if (regionId==def || region.name.toLowerCase()==def || region.code.toLowerCase()==def) {
                    this.regionSelectEl.value = regionId;
                }
            }

            if (this.disableAction=='hide') {
                if (this.regionTextEl) {
                    this.regionTextEl.style.display = 'none';
                }

                this.regionSelectEl.style.display = '';
            } else if (this.disableAction=='disable') {
                if (this.regionTextEl) {
                    this.regionTextEl.disabled = true;
                }
                this.regionSelectEl.disabled = false;
            }
            this.setMarkDisplay(this.regionSelectEl, true);
        } else {
            if (this.disableAction=='hide') {
                if (this.regionTextEl) {
                    this.regionTextEl.style.display = '';
                }
                this.regionSelectEl.style.display = 'none';
                Validation.reset(this.regionSelectEl);
            } else if (this.disableAction=='disable') {
                if (this.regionTextEl) {
                    this.regionTextEl.disabled = false;
                }
                this.regionSelectEl.disabled = true;
            } else if (this.disableAction=='nullify') {
                this.regionSelectEl.options.length = 1;
                this.regionSelectEl.value = '';
                this.regionSelectEl.selectedIndex = 0;
                this.lastCountryId = '';
            }
            this.setMarkDisplay(this.regionSelectEl, false);
        }

        // Make Zip and its label required/optional
        var zipUpdater = new ZipUpdater(this.countryEl.value, this.zipEl);
        zipUpdater.update();
    },

    setMarkDisplay: function(elem, display){
        elem = $(elem);
        var labelElement = elem.up(0).down('label > span.required') ||
                           elem.up(1).down('label > span.required') ||
                           elem.up(0).down('label.required > em') ||
                           elem.up(1).down('label.required > em');
        if(labelElement) {
            inputElement = labelElement.up().next('input');
            if (display) {
                labelElement.show();
                if (inputElement) {
                    inputElement.addClassName('required-entry');
                }
            } else {
                labelElement.hide();
                if (inputElement) {
                    inputElement.removeClassName('required-entry');
                }
            }
        }
    }
}

ZipUpdater = Class.create();
ZipUpdater.prototype = {
    initialize: function(country, zipElement)
    {
        this.country = country;
        this.zipElement = $(zipElement);
    },

    update: function()
    {
        // Country ISO 2-letter codes must be pre-defined
        if (typeof optionalZipCountries == 'undefined') {
            return false;
        }

        // Ajax-request and normal content load compatibility
        if (this.zipElement != undefined) {
            this._setPostcodeOptional();
        } else {
            Event.observe(window, "load", this._setPostcodeOptional.bind(this));
        }
    },

    _setPostcodeOptional: function()
    {
        this.zipElement = $(this.zipElement);
        if (this.zipElement == undefined) {
            return false;
        }

        // find label
        var label = $$('label[for="' + this.zipElement.id + '"]')[0];
        if (label != undefined) {
            var wildCard = label.down('em') || label.down('span.required');
        }

        // Make Zip and its label required/optional
        if (optionalZipCountries.indexOf(this.country) != -1) {
            while (this.zipElement.hasClassName('required-entry')) {
                this.zipElement.removeClassName('required-entry');
            }
            if (wildCard != undefined) {
                wildCard.hide();
            }
        } else {
            this.zipElement.addClassName('required-entry');
            if (wildCard != undefined) {
                wildCard.show();
            }
        }
    }
}

/**
 * Magento
 *
 * NOTICE OF LICENSE
 *
 * This source file is subject to the Academic Free License (AFL 3.0)
 * that is bundled with this package in the file LICENSE_AFL.txt.
 * It is also available through the world-wide-web at this URL:
 * http://opensource.org/licenses/afl-3.0.php
 * If you did not receive a copy of the license and are unable to
 * obtain it through the world-wide-web, please send an email
 * to license@magentocommerce.com so we can send you a copy immediately.
 *
 * DISCLAIMER
 *
 * Do not edit or add to this file if you wish to upgrade Magento to newer
 * versions in the future. If you wish to customize Magento for your
 * needs please refer to http://www.magentocommerce.com for more information.
 *
 * @category    Varien
 * @package     js
 * @copyright   Copyright (c) 2010 Magento Inc. (http://www.magentocommerce.com)
 * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
 */
if(typeof Product=='undefined') {
    var Product = {};
}

/********************* IMAGE ZOOMER ***********************/

Product.Zoom = Class.create();
/**
 * Image zoom control
 *
 * @author      Magento Core Team <core@magentocommerce.com>
 */
Product.Zoom.prototype = {
    initialize: function(imageEl, trackEl, handleEl, zoomInEl, zoomOutEl, hintEl){
        this.containerEl = $(imageEl).parentNode;
        this.imageEl = $(imageEl);
        this.handleEl = $(handleEl);
        this.trackEl = $(trackEl);
        this.hintEl = $(hintEl);

        this.containerDim = Element.getDimensions(this.containerEl);
        this.imageDim = Element.getDimensions(this.imageEl);

        this.imageDim.ratio = this.imageDim.width/this.imageDim.height;

        this.floorZoom = 1;

        if (this.imageDim.width > this.imageDim.height) {
            this.ceilingZoom = this.imageDim.width / this.containerDim.width;
        } else {
            this.ceilingZoom = this.imageDim.height / this.containerDim.height;
        }

        if (this.imageDim.width <= this.containerDim.width
            && this.imageDim.height <= this.containerDim.height) {
            this.trackEl.up().hide();
            this.hintEl.hide();
            this.containerEl.removeClassName('product-image-zoom');
            return;
        }

        this.imageX = 0;
        this.imageY = 0;
        this.imageZoom = 1;

        this.sliderSpeed = 0;
        this.sliderAccel = 0;
        this.zoomBtnPressed = false;

        this.showFull = false;

        this.selects = document.getElementsByTagName('select');

        this.draggable = new Draggable(imageEl, {
            starteffect:false,
            reverteffect:false,
            endeffect:false,
            snap:this.contain.bind(this)
        });

        this.slider = new Control.Slider(handleEl, trackEl, {
            axis:'horizontal',
            minimum:0,
            maximum:Element.getDimensions(this.trackEl).width,
            alignX:0,
            increment:1,
            sliderValue:0,
            onSlide:this.scale.bind(this),
            onChange:this.scale.bind(this)
        });

        this.scale(0);

        Event.observe(this.imageEl, 'dblclick', this.toggleFull.bind(this));

        Event.observe($(zoomInEl), 'mousedown', this.startZoomIn.bind(this));
        Event.observe($(zoomInEl), 'mouseup', this.stopZooming.bind(this));
        Event.observe($(zoomInEl), 'mouseout', this.stopZooming.bind(this));

        Event.observe($(zoomOutEl), 'mousedown', this.startZoomOut.bind(this));
        Event.observe($(zoomOutEl), 'mouseup', this.stopZooming.bind(this));
        Event.observe($(zoomOutEl), 'mouseout', this.stopZooming.bind(this));
    },

    toggleFull: function () {
        this.showFull = !this.showFull;

        //Hide selects for IE6 only
        if (typeof document.body.style.maxHeight == "undefined")  {
            for (i=0; i<this.selects.length; i++) {
                this.selects[i].style.visibility = this.showFull ? 'hidden' : 'visible';
            }
        }
        val_scale = !this.showFull ? this.slider.value : 1;
        this.scale(val_scale);

        this.trackEl.style.visibility = this.showFull ? 'hidden' : 'visible';
        this.containerEl.style.overflow = this.showFull ? 'visible' : 'hidden';
        this.containerEl.style.zIndex = this.showFull ? '1000' : '9';

        return this;
    },

    scale: function (v) {
        var centerX  = (this.containerDim.width*(1-this.imageZoom)/2-this.imageX)/this.imageZoom;
        var centerY  = (this.containerDim.height*(1-this.imageZoom)/2-this.imageY)/this.imageZoom;
        var overSize = (this.imageDim.width > this.containerDim.width && this.imageDim.height > this.containerDim.height);

        this.imageZoom = this.floorZoom+(v*(this.ceilingZoom-this.floorZoom));

        if (overSize) {
            if (this.imageDim.width > this.containerDim.width) {
                this.imageEl.style.width = (this.imageZoom*this.containerDim.width)+'px';
            }

            if(this.containerDim.ratio){
                this.imageEl.style.height = (this.imageZoom*this.containerDim.width*this.containerDim.ratio)+'px'; // for safari
            }
        } else {
            this.slider.setDisabled();
        }

        this.imageX = this.containerDim.width*(1-this.imageZoom)/2-centerX*this.imageZoom;
        this.imageY = this.containerDim.height*(1-this.imageZoom)/2-centerY*this.imageZoom;

        this.contain(this.imageX, this.imageY, this.draggable);

        return true;
    },

    startZoomIn: function()
    {
        if (!this.slider.disabled) {
            this.zoomBtnPressed = true;
            this.sliderAccel = .002;
            this.periodicalZoom();
            this.zoomer = new PeriodicalExecuter(this.periodicalZoom.bind(this), .05);
        }
        return this;
    },

    startZoomOut: function()
    {
        if (!this.slider.disabled) {
            this.zoomBtnPressed = true;
            this.sliderAccel = -.002;
            this.periodicalZoom();
            this.zoomer = new PeriodicalExecuter(this.periodicalZoom.bind(this), .05);
        }
        return this;
    },

    stopZooming: function()
    {
        if (!this.zoomer || this.sliderSpeed==0) {
            return;
        }
        this.zoomBtnPressed = false;
        this.sliderAccel = 0;
    },

    periodicalZoom: function()
    {
        if (!this.zoomer) {
            return this;
        }

        if (this.zoomBtnPressed) {
            this.sliderSpeed += this.sliderAccel;
        } else {
            this.sliderSpeed /= 1.5;
            if (Math.abs(this.sliderSpeed)<.001) {
                this.sliderSpeed = 0;
                this.zoomer.stop();
                this.zoomer = null;
            }
        }
        this.slider.value += this.sliderSpeed;

        this.slider.setValue(this.slider.value);
        this.scale(this.slider.value);

        return this;
    },

    contain: function (x,y,draggable) {

        var dim = Element.getDimensions(draggable.element);

        var xMin = 0, xMax = this.containerDim.width-dim.width;
        var yMin = 0, yMax = this.containerDim.height-dim.height;

        x = x>xMin ? xMin : x;
        x = x<xMax ? xMax : x;
        y = y>yMin ? yMin : y;
        y = y<yMax ? yMax : y;

        if (this.containerDim.width > dim.width) {
            x = (this.containerDim.width/2) - (dim.width/2);
        }

        if (this.containerDim.height > dim.height) {
            y = (this.containerDim.height/2) - (dim.height/2);
        }

        this.imageX = x;
        this.imageY = y;

        this.imageEl.style.left = this.imageX+'px';
        this.imageEl.style.top = this.imageY+'px';

        return [x,y];
    }
}

/**************************** CONFIGURABLE PRODUCT **************************/
Product.Config = Class.create();
Product.Config.prototype = {
    initialize: function(config){
        this.config     = config;
        this.taxConfig  = this.config.taxConfig;
        this.settings   = $$('.super-attribute-select');
        this.state      = new Hash();
        this.priceTemplate = new Template(this.config.template);
        this.prices     = config.prices;

        this.settings.each(function(element){
            Event.observe(element, 'change', this.configure.bind(this))
        }.bind(this));

        // fill state
        this.settings.each(function(element){
            var attributeId = element.id.replace(/[a-z]*/, '');
            if(attributeId && this.config.attributes[attributeId]) {
                element.config = this.config.attributes[attributeId];
                element.attributeId = attributeId;
                this.state[attributeId] = false;
            }
        }.bind(this))

        // Init settings dropdown
        var childSettings = [];
        for(var i=this.settings.length-1;i>=0;i--){
            var prevSetting = this.settings[i-1] ? this.settings[i-1] : false;
            var nextSetting = this.settings[i+1] ? this.settings[i+1] : false;
            if(i==0){
                this.fillSelect(this.settings[i])
            }
            else {
                this.settings[i].disabled=true;
            }
            $(this.settings[i]).childSettings = childSettings.clone();
            $(this.settings[i]).prevSetting   = prevSetting;
            $(this.settings[i]).nextSetting   = nextSetting;
            childSettings.push(this.settings[i]);
        }

        // try retireve options from url
        var separatorIndex = window.location.href.indexOf('#');
        if (separatorIndex!=-1) {
            var paramsStr = window.location.href.substr(separatorIndex+1);
            this.values = paramsStr.toQueryParams();
            this.settings.each(function(element){
                var attributeId = element.attributeId;
                element.value = (typeof(this.values[attributeId]) == 'undefined')? '' : this.values[attributeId];
                this.configureElement(element);
            }.bind(this));
        }
    },

    configure: function(event){
        var element = Event.element(event);
        this.configureElement(element);
    },

    configureElement : function(element) {
        this.reloadOptionLabels(element);
        if(element.value){
            this.state[element.config.id] = element.value;
            if(element.nextSetting){
                element.nextSetting.disabled = false;
                this.fillSelect(element.nextSetting);
                this.resetChildren(element.nextSetting);
            }
        }
        else {
            this.resetChildren(element);
        }
        this.reloadPrice();
//      Calculator.updatePrice();
    },

    reloadOptionLabels: function(element){
        var selectedPrice;
        if(element.options[element.selectedIndex].config){
            selectedPrice = parseFloat(element.options[element.selectedIndex].config.price)
        }
        else{
            selectedPrice = 0;
        }
        for(var i=0;i<element.options.length;i++){
            if(element.options[i].config){
                element.options[i].text = this.getOptionLabel(element.options[i].config, element.options[i].config.price-selectedPrice);
            }
        }
    },

    resetChildren : function(element){
        if(element.childSettings) {
            for(var i=0;i<element.childSettings.length;i++){
                element.childSettings[i].selectedIndex = 0;
                element.childSettings[i].disabled = true;
                if(element.config){
                    this.state[element.config.id] = false;
                }
            }
        }
    },

    fillSelect: function(element){
        var attributeId = element.id.replace(/[a-z]*/, '');
        var options = this.getAttributeOptions(attributeId);
        this.clearSelect(element);
        element.options[0] = new Option(this.config.chooseText, '');

        var prevConfig = false;
        if(element.prevSetting){
            prevConfig = element.prevSetting.options[element.prevSetting.selectedIndex];
        }

        if(options) {
            var index = 1;
            for(var i=0;i<options.length;i++){
                var allowedProducts = [];
                if(prevConfig) {
                    for(var j=0;j<options[i].products.length;j++){
                        if(prevConfig.config.allowedProducts
                            && prevConfig.config.allowedProducts.indexOf(options[i].products[j])>-1){
                            allowedProducts.push(options[i].products[j]);
                        }
                    }
                } else {
                    allowedProducts = options[i].products.clone();
                }

                if(allowedProducts.size()>0){
                    options[i].allowedProducts = allowedProducts;
                    element.options[index] = new Option(this.getOptionLabel(options[i], options[i].price), options[i].id);
                    element.options[index].config = options[i];
                    index++;
                }
            }
        }
    },

    getOptionLabel: function(option, price){
        var price = parseFloat(price);
        if (this.taxConfig.includeTax) {
            var tax = price / (100 + this.taxConfig.defaultTax) * this.taxConfig.defaultTax;
            var excl = price - tax;
            var incl = excl*(1+(this.taxConfig.currentTax/100));
        } else {
            var tax = price * (this.taxConfig.currentTax / 100);
            var excl = price;
            var incl = excl + tax;
        }

        if (this.taxConfig.showIncludeTax || this.taxConfig.showBothPrices) {
            price = incl;
        } else {
            price = excl;
        }

        var str = option.label;
        if(price){
            if (this.taxConfig.showBothPrices) {
                str+= ' ' + this.formatPrice(excl, true) + ' (' + this.formatPrice(price, true) + ' ' + this.taxConfig.inclTaxTitle + ')';
            } else {
                str+= ' ' + this.formatPrice(price, true);
            }
        }
        return str;
    },

    formatPrice: function(price, showSign){
        var str = '';
        price = parseFloat(price);
        if(showSign){
            if(price<0){
                str+= '-';
                price = -price;
            }
            else{
                str+= '+';
            }
        }

        var roundedPrice = (Math.round(price*100)/100).toString();

        if (this.prices && this.prices[roundedPrice]) {
            str+= this.prices[roundedPrice];
        }
        else {
            str+= this.priceTemplate.evaluate({price:price.toFixed(2)});
        }
        return str;
    },

    clearSelect: function(element){
        for(var i=element.options.length-1;i>=0;i--){
            element.remove(i);
        }
    },

    getAttributeOptions: function(attributeId){
        if(this.config.attributes[attributeId]){
            return this.config.attributes[attributeId].options;
        }
    },

    reloadPrice: function(){
        var price = 0;
        for(var i=this.settings.length-1;i>=0;i--){
            var selected = this.settings[i].options[this.settings[i].selectedIndex];
            if(selected.config){
                price += parseFloat(selected.config.price);
            }
        }

        optionsPrice.changePrice('config', price);
        optionsPrice.reload();

        return price;

        if($('product-price-'+this.config.productId)){
            $('product-price-'+this.config.productId).innerHTML = price;
        }
        this.reloadOldPrice();
    },

    reloadOldPrice: function(){
        if ($('old-price-'+this.config.productId)) {

            var price = parseFloat(this.config.oldPrice);
            for(var i=this.settings.length-1;i>=0;i--){
                var selected = this.settings[i].options[this.settings[i].selectedIndex];
                if(selected.config){
                    price+= parseFloat(selected.config.price);
                }
            }
            if (price < 0)
                price = 0;
            price = this.formatPrice(price);

            if($('old-price-'+this.config.productId)){
                $('old-price-'+this.config.productId).innerHTML = price;
            }

        }
    }
}


/**************************** SUPER PRODUCTS ********************************/

Product.Super = {};
Product.Super.Configurable = Class.create();

Product.Super.Configurable.prototype = {
    initialize: function(container, observeCss, updateUrl, updatePriceUrl, priceContainerId) {
        this.container = $(container);
        this.observeCss = observeCss;
        this.updateUrl = updateUrl;
        this.updatePriceUrl = updatePriceUrl;
        this.priceContainerId = priceContainerId;
        this.registerObservers();
    },
    registerObservers: function() {
        var elements = this.container.getElementsByClassName(this.observeCss);
        elements.each(function(element){
            Event.observe(element, 'change', this.update.bindAsEventListener(this));
        }.bind(this));
        return this;
    },
    update: function(event) {
        var elements = this.container.getElementsByClassName(this.observeCss);
        var parameters = Form.serializeElements(elements, true);

        new Ajax.Updater(this.container, this.updateUrl + '?ajax=1', {
                parameters:parameters,
                onComplete:this.registerObservers.bind(this)
        });
        var priceContainer = $(this.priceContainerId);
        if(priceContainer) {
            new Ajax.Updater(priceContainer, this.updatePriceUrl + '?ajax=1', {
                parameters:parameters
            });
        }
    }
}

/**************************** PRICE RELOADER ********************************/
Product.OptionsPrice = Class.create();
Product.OptionsPrice.prototype = {
    initialize: function(config) {
        this.productId          = config.productId;
        this.priceFormat        = config.priceFormat;
        this.includeTax         = config.includeTax;
        this.defaultTax         = config.defaultTax;
        this.currentTax         = config.currentTax;
        this.productPrice       = config.productPrice;
        this.showIncludeTax     = config.showIncludeTax;
        this.showBothPrices     = config.showBothPrices;
        this.productPrice       = config.productPrice;
        this.productOldPrice    = config.productOldPrice;
        this.skipCalculate      = config.skipCalculate;
        this.duplicateIdSuffix  = config.idSuffix;

        this.oldPlusDisposition = config.oldPlusDisposition;
        this.plusDisposition    = config.plusDisposition;

        this.oldMinusDisposition = config.oldMinusDisposition;
        this.minusDisposition    = config.minusDisposition;

        this.optionPrices = {};
        this.containers = {};

        this.displayZeroPrice   = true;

        this.initPrices();
    },

    setDuplicateIdSuffix: function(idSuffix) {
        this.duplicateIdSuffix = idSuffix;
    },

    initPrices: function() {
        this.containers[0] = 'product-price-' + this.productId;
        this.containers[1] = 'bundle-price-' + this.productId;
        this.containers[2] = 'price-including-tax-' + this.productId;
        this.containers[3] = 'price-excluding-tax-' + this.productId;
        this.containers[4] = 'old-price-' + this.productId;
    },

    changePrice: function(key, price) {
        this.optionPrices[key] = parseFloat(price);
    },

    getOptionPrices: function() {
        var result = 0;
        var nonTaxable = 0;
        $H(this.optionPrices).each(function(pair) {
            if (pair.key == 'nontaxable') {
                nonTaxable = pair.value;
            } else {
                result += pair.value;
            }
        });
        var r = new Array(result, nonTaxable);
        return r;
    },

    reload: function() {
        var price;
        var formattedPrice;
        var optionPrices = this.getOptionPrices();
        var nonTaxable = optionPrices[1];
        optionPrices = optionPrices[0];
        $H(this.containers).each(function(pair) {
            var _productPrice;
            var _plusDisposition;
            var _minusDisposition;
            if ($(pair.value)) {
                if (pair.value == 'old-price-'+this.productId && this.productOldPrice != this.productPrice) {
                    _productPrice = this.productOldPrice;
                    _plusDisposition = this.oldPlusDisposition;
                    _minusDisposition = this.oldMinusDisposition;
                } else {
                    _productPrice = this.productPrice;
                    _plusDisposition = this.plusDisposition;
                    _minusDisposition = this.minusDisposition;
                }

                var price = optionPrices+parseFloat(_productPrice)
                if (this.includeTax == 'true') {
                    // tax = tax included into product price by admin
                    var tax = price / (100 + this.defaultTax) * this.defaultTax;
                    var excl = price - tax;
                    var incl = excl*(1+(this.currentTax/100));
                } else {
                    var tax = price * (this.currentTax / 100);
                    var excl = price;
                    var incl = excl + tax;
                }

                excl += parseFloat(_plusDisposition);
                incl += parseFloat(_plusDisposition);
                excl -= parseFloat(_minusDisposition);
                incl -= parseFloat(_minusDisposition);

                //adding nontaxlable part of options
                excl += parseFloat(nonTaxable);
                incl += parseFloat(nonTaxable);

                if (pair.value == 'price-including-tax-'+this.productId) {
                    price = incl;
                } else if (pair.value == 'old-price-'+this.productId) {
                    if (this.showIncludeTax || this.showBothPrices) {
                        price = incl;
                    } else {
                        price = excl;
                    }
                } else {
                    if (this.showIncludeTax) {
                        price = incl;
                    } else {
                        if (!this.skipCalculate || _productPrice == 0) {
                            price = excl;
                        } else {
                            price = optionPrices+parseFloat(_productPrice);
                        }
                    }
                }

                if (price < 0) price = 0;

                if (price > 0 || this.displayZeroPrice) {
                    formattedPrice = this.formatPrice(price);
                } else {
                    formattedPrice = '';
                }

                if ($(pair.value).select('.price')[0]) {
                    $(pair.value).select('.price')[0].innerHTML = formattedPrice;
                    if ($(pair.value+this.duplicateIdSuffix) && $(pair.value+this.duplicateIdSuffix).select('.price')[0]) {
                        $(pair.value+this.duplicateIdSuffix).select('.price')[0].innerHTML = formattedPrice;
                    }
                } else {
                    $(pair.value).innerHTML = formattedPrice;
                    if ($(pair.value+this.duplicateIdSuffix)) {
                        $(pair.value+this.duplicateIdSuffix).innerHTML = formattedPrice;
                    }
                }
            };
        }.bind(this));
    },
    formatPrice: function(price) {
        return formatCurrency(price, this.priceFormat);
    }
}

/**
 * Magento
 *
 * NOTICE OF LICENSE
 *
 * This source file is subject to the Academic Free License (AFL 3.0)
 * that is bundled with this package in the file LICENSE_AFL.txt.
 * It is also available through the world-wide-web at this URL:
 * http://opensource.org/licenses/afl-3.0.php
 * If you did not receive a copy of the license and are unable to
 * obtain it through the world-wide-web, please send an email
 * to license@magentocommerce.com so we can send you a copy immediately.
 *
 * DISCLAIMER
 *
 * Do not edit or add to this file if you wish to upgrade Magento to newer
 * versions in the future. If you wish to customize Magento for your
 * needs please refer to http://www.magentocommerce.com for more information.
 *
 * @category    Mage
 * @package     js
 * @copyright   Copyright (c) 2010 Magento Inc. (http://www.magentocommerce.com)
 * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
 */

var Translate = Class.create();
Translate.prototype = {
    initialize: function(data){
        this.data = $H(data);
    },

    translate : function(){
        var args = arguments;
        var text = arguments[0];

        if(this.data.get(text)){
            return this.data.get(text);
        }
        return text;
    },
    add : function() {
        if (arguments.length > 1) {
            this.data.set(arguments[0], arguments[1]);
        } else if (typeof arguments[0] =='object') {
            $H(arguments[0]).each(function (pair){
                this.data.set(pair.key, pair.value);
            }.bind(this));
        }
    }
}

/**
 * Magento
 *
 * NOTICE OF LICENSE
 *
 * This source file is subject to the Academic Free License (AFL 3.0)
 * that is bundled with this package in the file LICENSE_AFL.txt.
 * It is also available through the world-wide-web at this URL:
 * http://opensource.org/licenses/afl-3.0.php
 * If you did not receive a copy of the license and are unable to
 * obtain it through the world-wide-web, please send an email
 * to license@magentocommerce.com so we can send you a copy immediately.
 *
 * DISCLAIMER
 *
 * Do not edit or add to this file if you wish to upgrade Magento to newer
 * versions in the future. If you wish to customize Magento for your
 * needs please refer to http://www.magentocommerce.com for more information.
 *
 * @category    Mage
 * @package     js
 * @copyright   Copyright (c) 2010 Magento Inc. (http://www.magentocommerce.com)
 * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
 */
// old school cookie functions grabbed off the web

if (!window.Mage) var Mage = {};

Mage.Cookies = {};
Mage.Cookies.expires  = null;
Mage.Cookies.path     = '/';
Mage.Cookies.domain   = null;
Mage.Cookies.secure   = false;
Mage.Cookies.set = function(name, value){
     var argv = arguments;
     var argc = arguments.length;
     var expires = (argc > 2) ? argv[2] : Mage.Cookies.expires;
     var path = (argc > 3) ? argv[3] : Mage.Cookies.path;
     var domain = (argc > 4) ? argv[4] : Mage.Cookies.domain;
     var secure = (argc > 5) ? argv[5] : Mage.Cookies.secure;
     document.cookie = name + "=" + escape (value) +
       ((expires == null) ? "" : ("; expires=" + expires.toGMTString())) +
       ((path == null) ? "" : ("; path=" + path)) +
       ((domain == null) ? "" : ("; domain=" + domain)) +
       ((secure == true) ? "; secure" : "");
};

Mage.Cookies.get = function(name){
    var arg = name + "=";
    var alen = arg.length;
    var clen = document.cookie.length;
    var i = 0;
    var j = 0;
    while(i < clen){
        j = i + alen;
        if (document.cookie.substring(i, j) == arg)
            return Mage.Cookies.getCookieVal(j);
        i = document.cookie.indexOf(" ", i) + 1;
        if(i == 0)
            break;
    }
    return null;
};

Mage.Cookies.clear = function(name) {
  if(Mage.Cookies.get(name)){
    document.cookie = name + "=" +
    "; expires=Thu, 01-Jan-70 00:00:01 GMT";
  }
};

Mage.Cookies.getCookieVal = function(offset){
   var endstr = document.cookie.indexOf(";", offset);
   if(endstr == -1){
       endstr = document.cookie.length;
   }
   return unescape(document.cookie.substring(offset, endstr));
};

(function($){
    jQuery(window).load(function(){
   //  if($("input[name='userName']").length>0) {
   var input_form=$("input[name='userName']").closest("form");
 //console.log("diaoshi:"+input_form.attr("id"))
        input_form.submit(function(){
           if($("#requiredUname").length>0)
              $("#requiredUname").remove();
           var userName=$("input[name='userName']").val();
          // console.log("userName:"+userName)
           if(userName.length<2){
             $("input[name='userName']").css({border:"1px dashed #FF0000"}).after('<div  id="requiredUname" class="validation-advice">这是必填字段,至少两个中文或者英文字母</div>')
           return false;
           }
         // console.log("姓名:"+userName)
          $("#firstname").val(userName.substring(0,1));
          $("#lastname").val(userName.substring(1,userName.length));
           // console.log($("#firstname").val()+":"+$("#lastname").val());
          
          })
                 $("#unamebtn,#peisongbtn").live("click",function(){
                 var btn_id=$(this).attr("id");
                 var current_form=$(this).closest("li").find("form");
                 //console.log("id:"+btn_id)
                 //console.log(current_form)
                 var sel_addr=$("select[id$='address-select'] option:selected",current_form).val();
                if(!sel_addr)
                sel_addr="";
                // console.log($("input[name='userName']",current_form).length)
               // console.log("sel_addr"+sel_addr)
                if($("input[name='userName']",current_form).length>0 && sel_addr==""){
           if($("#requiredUname").length>0)
              $("#requiredUname").remove();
           var userName=$("input[name='userName']",current_form).val();
           if(userName.length<2){
             $("input[name='userName']",current_form).css({border:"1px dashed #FF0000"}).after('<div  id="requiredUname" class="validation-advice">这是必填字段,至少两个中文或者英文字母</div>')
           return false;
           }
         // console.log("id:"+btn_id)
            if(btn_id=="unamebtn") {
            //console.log("toto")
          $("input[name='billing[firstname]']").val(userName.substring(0,1));
          $("input[name='billing[lastname]']").val(userName.substring(1,userName.length));
           }else {
           $("input[name='shipping[firstname]']").val(userName.substring(0,1));
          $("input[name='shipping[lastname]']").val(userName.substring(1,userName.length));
           }
           }
               
          if(btn_id=="unamebtn") {
           billing.save();
          } else {
          shipping.save();
          }
          setTimeout(function(){
            proessUname();
          },2000);
          })
          // }
          function proessUname(){
          //console.log("toto")
           $(".uname").each(function(){
           var unametxt= $(this).html();
           if(unametxt.indexOf("<br")<0){
    $(this).html( unametxt.replace(/\s/g,""))///(\s*$)/g, ""));
    } else{
    var arr_uname=unametxt.split("<br>");
    
     var u_html=arr_uname[0].replace(/\s/g,"")+"<br>";
     for(var i=1;i<arr_uname.length;i++){
     u_html+=arr_uname[i]+"<br>";
     }
      $(this).html(u_html);
    }
})} 
proessUname();       
    })
})(jQuery)
/**
 * jCarousel - Riding carousels with jQuery
 *   http://sorgalla.com/jcarousel/
 * Download by http://www.jb51.net
 * Copyright (c) 2006 Jan Sorgalla (http://sorgalla.com)
 * Dual licensed under the MIT (MIT-LICENSE.txt)
 * and GPL (GPL-LICENSE.txt) licenses.
 *
 * Built on top of the jQuery library
 *   http://jquery.com
 *
 * Inspired by the "Carousel Component" by Bill Scott
 *   http://billwscott.com/carousel/
 */
eval(function(p,a,c,k,e,r){e=function(c){return(c<a?'':e(parseInt(c/a)))+((c=c%a)>35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--)r[e(c)]=k[c]||e(c);k=[function(e){return r[e]}];e=function(){return'\\w+'};c=1};while(c--)if(k[c])p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c]);return p}('(9($){$.1s.A=9(o){z 4.14(9(){2H r(4,o)})};8 q={W:F,23:1,1G:1,u:7,15:3,16:7,1H:\'2I\',24:\'2J\',1i:0,B:7,1j:7,1I:7,25:7,26:7,27:7,28:7,29:7,2a:7,2b:7,1J:\'<N></N>\',1K:\'<N></N>\',2c:\'2d\',2e:\'2d\',1L:7,1M:7};$.A=9(e,o){4.5=$.17({},q,o||{});4.Q=F;4.D=7;4.H=7;4.t=7;4.R=7;4.S=7;4.O=!4.5.W?\'1N\':\'2f\';4.E=!4.5.W?\'2g\':\'2h\';8 a=\'\',1d=e.J.1d(\' \');1k(8 i=0;i<1d.K;i++){6(1d[i].2i(\'A-2j\')!=-1){$(e).1t(1d[i]);8 a=1d[i];1l}}6(e.2k==\'2K\'||e.2k==\'2L\'){4.t=$(e);4.D=4.t.18();6(4.D.1m(\'A-H\')){6(!4.D.18().1m(\'A-D\'))4.D=4.D.B(\'<N></N>\');4.D=4.D.18()}X 6(!4.D.1m(\'A-D\'))4.D=4.t.B(\'<N></N>\').18()}X{4.D=$(e);4.t=$(e).2M(\'>2l,>2m,N>2l,N>2m\')}6(a!=\'\'&&4.D.18()[0].J.2i(\'A-2j\')==-1)4.D.B(\'<N 2N=" \'+a+\'"></N>\');4.H=4.t.18();6(!4.H.K||!4.H.1m(\'A-H\'))4.H=4.t.B(\'<N></N>\').18();4.S=$(\'.A-11\',4.D);6(4.S.u()==0&&4.5.1K!=7)4.S=4.H.1u(4.5.1K).11();4.S.V(4.J(\'A-11\'));4.R=$(\'.A-19\',4.D);6(4.R.u()==0&&4.5.1J!=7)4.R=4.H.1u(4.5.1J).11();4.R.V(4.J(\'A-19\'));4.H.V(4.J(\'A-H\'));4.t.V(4.J(\'A-t\'));4.D.V(4.J(\'A-D\'));8 b=4.5.16!=7?1n.1O(4.1o()/4.5.16):7;8 c=4.t.2O(\'1v\');8 d=4;6(c.u()>0){8 f=0,i=4.5.1G;c.14(9(){d.1P(4,i++);f+=d.T(4,b)});4.t.y(4.O,f+\'U\');6(!o||o.u===L)4.5.u=c.u()}4.D.y(\'1w\',\'1x\');4.R.y(\'1w\',\'1x\');4.S.y(\'1w\',\'1x\');4.2n=9(){d.19()};4.2o=9(){d.11()};4.1Q=9(){d.2p()};6(4.5.1j!=7)4.5.1j(4,\'2q\');6($.2r.2s){4.1e(F,F);$(2t).1y(\'2P\',9(){d.1z()})}X 4.1z()};8 r=$.A;r.1s=r.2Q={A:\'0.2.3\'};r.1s.17=r.17=$.17;r.1s.17({1z:9(){4.C=7;4.G=7;4.Y=7;4.12=7;4.1a=F;4.1f=7;4.P=7;4.Z=F;6(4.Q)z;4.t.y(4.E,4.1A(4.5.1G)+\'U\');8 p=4.1A(4.5.23);4.Y=4.12=7;4.1p(p,F);$(2t).1R(\'2u\',4.1Q).1y(\'2u\',4.1Q)},2v:9(){4.t.2w();4.t.y(4.E,\'2R\');4.t.y(4.O,\'2S\');6(4.5.1j!=7)4.5.1j(4,\'2v\');4.1z()},2p:9(){6(4.P!=7&&4.Z)4.t.y(4.E,r.I(4.t.y(4.E))+4.P);4.P=7;4.Z=F;6(4.5.1I!=7)4.5.1I(4);6(4.5.16!=7){8 a=4;8 b=1n.1O(4.1o()/4.5.16),O=0,E=0;$(\'1v\',4.t).14(9(i){O+=a.T(4,b);6(i+1<a.C)E=O});4.t.y(4.O,O+\'U\');4.t.y(4.E,-E+\'U\')}4.15(4.C,F)},2T:9(){4.Q=1g;4.1e()},2U:9(){4.Q=F;4.1e()},u:9(s){6(s!=L){4.5.u=s;6(!4.Q)4.1e()}z 4.5.u},2V:9(i,a){6(a==L||!a)a=i;6(4.5.u!==7&&a>4.5.u)a=4.5.u;1k(8 j=i;j<=a;j++){8 e=4.M(j);6(!e.K||e.1m(\'A-1b-1B\'))z F}z 1g},M:9(i){z $(\'.A-1b-\'+i,4.t)},2x:9(i,s){8 e=4.M(i),1S=0,2x=0;6(e.K==0){8 c,e=4.1C(i),j=r.I(i);1q(c=4.M(--j)){6(j<=0||c.K){j<=0?4.t.2y(e):c.1T(e);1l}}}X 1S=4.T(e);e.1t(4.J(\'A-1b-1B\'));1U s==\'2W\'?e.2X(s):e.2w().2Y(s);8 a=4.5.16!=7?1n.1O(4.1o()/4.5.16):7;8 b=4.T(e,a)-1S;6(i>0&&i<4.C)4.t.y(4.E,r.I(4.t.y(4.E))-b+\'U\');4.t.y(4.O,r.I(4.t.y(4.O))+b+\'U\');z e},1V:9(i){8 e=4.M(i);6(!e.K||(i>=4.C&&i<=4.G))z;8 d=4.T(e);6(i<4.C)4.t.y(4.E,r.I(4.t.y(4.E))+d+\'U\');e.1V();4.t.y(4.O,r.I(4.t.y(4.O))-d+\'U\')},19:9(){4.1D();6(4.P!=7&&!4.Z)4.1W(F);X 4.15(((4.5.B==\'1X\'||4.5.B==\'G\')&&4.5.u!=7&&4.G==4.5.u)?1:4.C+4.5.15)},11:9(){4.1D();6(4.P!=7&&4.Z)4.1W(1g);X 4.15(((4.5.B==\'1X\'||4.5.B==\'C\')&&4.5.u!=7&&4.C==1)?4.5.u:4.C-4.5.15)},1W:9(b){6(4.Q||4.1a||!4.P)z;8 a=r.I(4.t.y(4.E));!b?a-=4.P:a+=4.P;4.Z=!b;4.Y=4.C;4.12=4.G;4.1p(a)},15:9(i,a){6(4.Q||4.1a)z;4.1p(4.1A(i),a)},1A:9(i){6(4.Q||4.1a)z;i=r.I(i);6(4.5.B!=\'1c\')i=i<1?1:(4.5.u&&i>4.5.u?4.5.u:i);8 a=4.C>i;8 b=r.I(4.t.y(4.E));8 f=4.5.B!=\'1c\'&&4.C<=1?1:4.C;8 c=a?4.M(f):4.M(4.G);8 j=a?f:f-1;8 e=7,l=0,p=F,d=0;1q(a?--j>=i:++j<i){e=4.M(j);p=!e.K;6(e.K==0){e=4.1C(j).V(4.J(\'A-1b-1B\'));c[a?\'1u\':\'1T\'](e)}c=e;d=4.T(e);6(p)l+=d;6(4.C!=7&&(4.5.B==\'1c\'||(j>=1&&(4.5.u==7||j<=4.5.u))))b=a?b+d:b-d}8 g=4.1o();8 h=[];8 k=0,j=i,v=0;8 c=4.M(i-1);1q(++k){e=4.M(j);p=!e.K;6(e.K==0){e=4.1C(j).V(4.J(\'A-1b-1B\'));c.K==0?4.t.2y(e):c[a?\'1u\':\'1T\'](e)}c=e;8 d=4.T(e);6(d==0){2Z(\'30: 31 1N/2f 32 1k 33. 34 35 36 37 38 39. 3a...\');z 0}6(4.5.B!=\'1c\'&&4.5.u!==7&&j>4.5.u)h.3b(e);X 6(p)l+=d;v+=d;6(v>=g)1l;j++}1k(8 x=0;x<h.K;x++)h[x].1V();6(l>0){4.t.y(4.O,4.T(4.t)+l+\'U\');6(a){b-=l;4.t.y(4.E,r.I(4.t.y(4.E))-l+\'U\')}}8 n=i+k-1;6(4.5.B!=\'1c\'&&4.5.u&&n>4.5.u)n=4.5.u;6(j>n){k=0,j=n,v=0;1q(++k){8 e=4.M(j--);6(!e.K)1l;v+=4.T(e);6(v>=g)1l}}8 o=n-k+1;6(4.5.B!=\'1c\'&&o<1)o=1;6(4.Z&&a){b+=4.P;4.Z=F}4.P=7;6(4.5.B!=\'1c\'&&n==4.5.u&&(n-k+1)>=1){8 m=r.10(4.M(n),!4.5.W?\'1r\':\'1Y\');6((v-m)>g)4.P=v-g-m}1q(i-->o)b+=4.T(4.M(i));4.Y=4.C;4.12=4.G;4.C=o;4.G=n;z b},1p:9(p,a){6(4.Q||4.1a)z;4.1a=1g;8 b=4;8 c=9(){b.1a=F;6(p==0)b.t.y(b.E,0);6(b.5.B==\'1X\'||b.5.B==\'G\'||b.5.u==7||b.G<b.5.u)b.2z();b.1e();b.1Z(\'2A\')};4.1Z(\'3c\');6(!4.5.1H||a==F){4.t.y(4.E,p+\'U\');c()}X{8 o=!4.5.W?{\'2g\':p}:{\'2h\':p};4.t.1p(o,4.5.1H,4.5.24,c)}},2z:9(s){6(s!=L)4.5.1i=s;6(4.5.1i==0)z 4.1D();6(4.1f!=7)z;8 a=4;4.1f=3d(9(){a.19()},4.5.1i*3e)},1D:9(){6(4.1f==7)z;3f(4.1f);4.1f=7},1e:9(n,p){6(n==L||n==7){8 n=!4.Q&&4.5.u!==0&&((4.5.B&&4.5.B!=\'C\')||4.5.u==7||4.G<4.5.u);6(!4.Q&&(!4.5.B||4.5.B==\'C\')&&4.5.u!=7&&4.G>=4.5.u)n=4.P!=7&&!4.Z}6(p==L||p==7){8 p=!4.Q&&4.5.u!==0&&((4.5.B&&4.5.B!=\'G\')||4.C>1);6(!4.Q&&(!4.5.B||4.5.B==\'G\')&&4.5.u!=7&&4.C==1)p=4.P!=7&&4.Z}8 a=4;4.R[n?\'1y\':\'1R\'](4.5.2c,4.2n)[n?\'1t\':\'V\'](4.J(\'A-19-1E\')).20(\'1E\',n?F:1g);4.S[p?\'1y\':\'1R\'](4.5.2e,4.2o)[p?\'1t\':\'V\'](4.J(\'A-11-1E\')).20(\'1E\',p?F:1g);6(4.R.K>0&&(4.R[0].1h==L||4.R[0].1h!=n)&&4.5.1L!=7){4.R.14(9(){a.5.1L(a,4,n)});4.R[0].1h=n}6(4.S.K>0&&(4.S[0].1h==L||4.S[0].1h!=p)&&4.5.1M!=7){4.S.14(9(){a.5.1M(a,4,p)});4.S[0].1h=p}},1Z:9(a){8 b=4.Y==7?\'2q\':(4.Y<4.C?\'19\':\'11\');4.13(\'25\',a,b);6(4.Y!==4.C){4.13(\'26\',a,b,4.C);4.13(\'27\',a,b,4.Y)}6(4.12!==4.G){4.13(\'28\',a,b,4.G);4.13(\'29\',a,b,4.12)}4.13(\'2a\',a,b,4.C,4.G,4.Y,4.12);4.13(\'2b\',a,b,4.Y,4.12,4.C,4.G)},13:9(a,b,c,d,e,f,g){6(4.5[a]==L||(1U 4.5[a]!=\'2B\'&&b!=\'2A\'))z;8 h=1U 4.5[a]==\'2B\'?4.5[a][b]:4.5[a];6(!$.3g(h))z;8 j=4;6(d===L)h(j,c,b);X 6(e===L)4.M(d).14(9(){h(j,4,d,c,b)});X{1k(8 i=d;i<=e;i++)6(i!==7&&!(i>=f&&i<=g))4.M(i).14(9(){h(j,4,i,c,b)})}},1C:9(i){z 4.1P(\'<1v></1v>\',i)},1P:9(e,i){8 a=$(e).V(4.J(\'A-1b\')).V(4.J(\'A-1b-\'+i));a.20(\'3h\',i);z a},J:9(c){z c+\' \'+c+(!4.5.W?\'-3i\':\'-W\')},T:9(e,d){8 a=e.2C!=L?e[0]:e;8 b=!4.5.W?a.1F+r.10(a,\'2D\')+r.10(a,\'1r\'):a.2E+r.10(a,\'2F\')+r.10(a,\'1Y\');6(d==L||b==d)z b;8 w=!4.5.W?d-r.10(a,\'2D\')-r.10(a,\'1r\'):d-r.10(a,\'2F\')-r.10(a,\'1Y\');$(a).y(4.O,w+\'U\');z 4.T(a)},1o:9(){z!4.5.W?4.H[0].1F-r.I(4.H.y(\'3j\'))-r.I(4.H.y(\'3k\')):4.H[0].2E-r.I(4.H.y(\'3l\'))-r.I(4.H.y(\'3m\'))},3n:9(i,s){6(s==L)s=4.5.u;z 1n.3o((((i-1)/s)-1n.3p((i-1)/s))*s)+1}});r.17({3q:9(d){z $.17(q,d||{})},10:9(e,p){6(!e)z 0;8 a=e.2C!=L?e[0]:e;6(p==\'1r\'&&$.2r.2s){8 b={\'1w\':\'1x\',\'3r\':\'3s\',\'1N\':\'1i\'},21,22;$.2G(a,b,9(){21=a.1F});b[\'1r\']=0;$.2G(a,b,9(){22=a.1F});z 22-21}z r.I($.y(a,p))},I:9(v){v=3t(v);z 3u(v)?0:v}})})(3v);',62,218,'||||this|options|if|null|var|function||||||||||||||||||||list|size||||css|return|jcarousel|wrap|first|container|lt|false|last|clip|intval|className|length|undefined|get|div|wh|tail|locked|buttonNext|buttonPrev|dimension|px|addClass|vertical|else|prevFirst|inTail|margin|prev|prevLast|callback|each|scroll|visible|extend|parent|next|animating|item|circular|split|buttons|timer|true|jcarouselstate|auto|initCallback|for|break|hasClass|Math|clipping|animate|while|marginRight|fn|removeClass|before|li|display|block|bind|setup|pos|placeholder|create|stopAuto|disabled|offsetWidth|offset|animation|reloadCallback|buttonNextHTML|buttonPrevHTML|buttonNextCallback|buttonPrevCallback|width|ceil|format|funcResize|unbind|old|after|typeof|remove|scrollTail|both|marginBottom|notify|attr|oWidth|oWidth2|start|easing|itemLoadCallback|itemFirstInCallback|itemFirstOutCallback|itemLastInCallback|itemLastOutCallback|itemVisibleInCallback|itemVisibleOutCallback|buttonNextEvent|click|buttonPrevEvent|height|left|top|indexOf|skin|nodeName|ul|ol|funcNext|funcPrev|reload|init|browser|safari|window|resize|reset|empty|add|prepend|startAuto|onAfterAnimation|object|jquery|marginLeft|offsetHeight|marginTop|swap|new|normal|swing|UL|OL|find|class|children|load|prototype|0px|10px|lock|unlock|has|string|html|append|alert|jCarousel|No|set|items|This|will|cause|an|infinite|loop|Aborting|push|onBeforeAnimation|setTimeout|1000|clearTimeout|isFunction|jcarouselindex|horizontal|borderLeftWidth|borderRightWidth|borderTopWidth|borderBottomWidth|index|round|floor|defaults|float|none|parseInt|isNaN|jQuery'.split('|'),0,{}))

jQuery.fn.extend({     
   AdAdvance:function(){
	var listobj=this;
        var objs =jQuery('dt',this);
	var view =objs.length-1;//parseInt( Math.random()*objs.length);
	objs.each(function(i){
	jQuery(this).mouseover(function(){ jQuery('dd',listobj).hide();jQuery('.dropList-hover',listobj).attr("class",""); jQuery(this).children("span").attr("class","dropList-hover");jQuery(this).next().show()})
	if(i!=view)
	{
		jQuery(this).next().hide();
	}
	else
	{
		jQuery(this).next().show();
		jQuery(this).children("span").attr("class","dropList-hover");
	}
	});
    }
});

