

var Prototype={Version:'1.6.0',Browser:{IE:!!(window.attachEvent&&!window.opera),Opera:!!window.opera,WebKit:navigator.userAgent.indexOf('AppleWebKit/')>-1,Gecko:navigator.userAgent.indexOf('Gecko')>-1&&navigator.userAgent.indexOf('KHTML')==-1,MobileSafari:!!navigator.userAgent.match(/Apple.*Mobile.*Safari/)},BrowserFeatures:{XPath:!!document.evaluate,ElementExtensions:!!window.HTMLElement,SpecificElementExtensions:document.createElement('div').__proto__&&document.createElement('div').__proto__!==document.createElement('form').__proto__},ScriptFragment:'<script[^>]*>([\\S\\s]*?)<\/script>',JSONFilter:/^\/\*-secure-([\s\S]*)\*\/\s*$/,emptyFunction:function(){},K:function(x){return x}};if(Prototype.Browser.MobileSafari)Prototype.BrowserFeatures.SpecificElementExtensions=false;if(Prototype.Browser.WebKit)Prototype.BrowserFeatures.XPath=false;var Class={create:function(){var a=null,properties=$A(arguments);if(Object.isFunction(properties[0]))a=properties.shift();function klass(){this.initialize.apply(this,arguments)}Object.extend(klass,Class.Methods);klass.superclass=a;klass.subclasses=[];if(a){var b=function(){};b.prototype=a.prototype;klass.prototype=new b;a.subclasses.push(klass)}for(var i=0;i<properties.length;i++)klass.addMethods(properties[i]);if(!klass.prototype.initialize)klass.prototype.initialize=Prototype.emptyFunction;klass.prototype.constructor=klass;return klass}};Class.Methods={addMethods:function(a){var b=this.superclass&&this.superclass.prototype;var c=Object.keys(a);if(!Object.keys({toString:true}).length)c.push("toString","valueOf");for(var i=0,length=c.length;i<length;i++){var d=c[i],value=a[d];if(b&&Object.isFunction(value)&&value.argumentNames().first()=="$super"){var e=value,value=Object.extend((function(m){return function(){return b[m].apply(this,arguments)}})(d).wrap(e),{valueOf:function(){return e},toString:function(){return e.toString()}})}this.prototype[d]=value}return this}};var Abstract={};Object.extend=function(a,b){for(var c in b)a[c]=b[c];return a};Object.extend(Object,{inspect:function(a){try{if(a===undefined)return'undefined';if(a===null)return'null';return a.inspect?a.inspect():a.toString()}catch(e){if(e instanceof RangeError)return'...';throw e;}},toJSON:function(a){var b=typeof a;switch(b){case'undefined':case'function':case'unknown':return;case'boolean':return a.toString()}if(a===null)return'null';if(a.toJSON)return a.toJSON();if(Object.isElement(a))return;var c=[];for(var d in a){var e=Object.toJSON(a[d]);if(e!==undefined)c.push(d.toJSON()+': '+e)}return'{'+c.join(', ')+'}'},toQueryString:function(a){return $H(a).toQueryString()},toHTML:function(a){return a&&a.toHTML?a.toHTML():String.interpret(a)},keys:function(a){var b=[];for(var c in a)b.push(c);return b},values:function(a){var b=[];for(var c in a)b.push(a[c]);return b},clone:function(a){return Object.extend({},a)},isElement:function(a){return a&&a.nodeType==1},isArray:function(a){return a&&a.constructor===Array},isHash:function(a){return a instanceof Hash},isFunction:function(a){return typeof a=="function"},isString:function(a){return typeof a=="string"},isNumber:function(a){return typeof a=="number"},isUndefined:function(a){return typeof a=="undefined"}});Object.extend(Function.prototype,{argumentNames:function(){var a=this.toString().match(/^[\s\(]*function[^(]*\((.*?)\)/)[1].split(",").invoke("strip");return a.length==1&&!a[0]?[]:a},bind:function(){if(arguments.length<2&&arguments[0]===undefined)return this;var a=this,args=$A(arguments),object=args.shift();return function(){return a.apply(object,args.concat($A(arguments)))}},bindAsEventListener:function(){var b=this,args=$A(arguments),object=args.shift();return function(a){return b.apply(object,[a||window.event].concat(args))}},curry:function(){if(!arguments.length)return this;var a=this,args=$A(arguments);return function(){return a.apply(this,args.concat($A(arguments)))}},delay:function(){var a=this,args=$A(arguments),timeout=args.shift()*1000;return window.setTimeout(function(){return a.apply(a,args)},timeout)},wrap:function(a){var b=this;return function(){return a.apply(this,[b.bind(this)].concat($A(arguments)))}},methodize:function(){if(this._methodized)return this._methodized;var a=this;return this._methodized=function(){return a.apply(null,[this].concat($A(arguments)))}}});Function.prototype.defer=Function.prototype.delay.curry(0.01);Date.prototype.toJSON=function(){return'"'+this.getUTCFullYear()+'-'+(this.getUTCMonth()+1).toPaddedString(2)+'-'+this.getUTCDate().toPaddedString(2)+'T'+this.getUTCHours().toPaddedString(2)+':'+this.getUTCMinutes().toPaddedString(2)+':'+this.getUTCSeconds().toPaddedString(2)+'Z"'};var Try={these:function(){var a;for(var i=0,length=arguments.length;i<length;i++){var b=arguments[i];try{a=b();break}catch(e){}}return a}};RegExp.prototype.match=RegExp.prototype.test;RegExp.escape=function(a){return String(a).replace(/([.*+?^=!:${}()|[\]\/\\])/g,'\\$1')};var PeriodicalExecuter=Class.create({initialize:function(a,b){this.callback=a;this.frequency=b;this.currentlyExecuting=false;this.registerCallback()},registerCallback:function(){this.timer=setInterval(this.onTimerEvent.bind(this),this.frequency*1000)},execute:function(){this.callback(this)},stop:function(){if(!this.timer)return;clearInterval(this.timer);this.timer=null},onTimerEvent:function(){if(!this.currentlyExecuting){try{this.currentlyExecuting=true;this.execute()}finally{this.currentlyExecuting=false}}}});Object.extend(String,{interpret:function(a){return a==null?'':String(a)},specialChar:{'\b':'\\b','\t':'\\t','\n':'\\n','\f':'\\f','\r':'\\r','\\':'\\\\'}});Object.extend(String.prototype,{gsub:function(a,b){var c='',source=this,match;b=arguments.callee.prepareReplacement(b);while(source.length>0){if(match=source.match(a)){c+=source.slice(0,match.index);c+=String.interpret(b(match));source=source.slice(match.index+match[0].length)}else{c+=source,source=''}}return c},sub:function(b,c,d){c=this.gsub.prepareReplacement(c);d=d===undefined?1:d;return this.gsub(b,function(a){if(--d<0)return a[0];return c(a)})},scan:function(a,b){this.gsub(a,b);return String(this)},truncate:function(a,b){a=a||30;b=b===undefined?'...':b;return this.length>a?this.slice(0,a-b.length)+b:String(this)},strip:function(){return this.replace(/^\s+/,'').replace(/\s+$/,'')},stripTags:function(){return this.replace(/<\/?[^>]+>/gi,'')},stripScripts:function(){return this.replace(new RegExp(Prototype.ScriptFragment,'img'),'')},extractScripts:function(){var b=new RegExp(Prototype.ScriptFragment,'img');var c=new RegExp(Prototype.ScriptFragment,'im');return(this.match(b)||[]).map(function(a){return(a.match(c)||['',''])[1]})},evalScripts:function(){return this.extractScripts().map(function(a){return eval(a)})},escapeHTML:function(){var a=arguments.callee;a.text.data=this;return a.div.innerHTML},unescapeHTML:function(){var c=new Element('div');c.innerHTML=this.stripTags();return c.childNodes[0]?(c.childNodes.length>1?$A(c.childNodes).inject('',function(a,b){return a+b.nodeValue}):c.childNodes[0].nodeValue):''},toQueryParams:function(e){var f=this.strip().match(/([^?#]*)(#.*)?$/);if(!f)return{};return f[1].split(e||'&').inject({},function(a,b){if((b=b.split('='))[0]){var c=decodeURIComponent(b.shift());var d=b.length>1?b.join('='):b[0];if(d!=undefined)d=decodeURIComponent(d);if(c in a){if(!Object.isArray(a[c]))a[c]=[a[c]];a[c].push(d)}else a[c]=d}return a})},toArray:function(){return this.split('')},succ:function(){return this.slice(0,this.length-1)+String.fromCharCode(this.charCodeAt(this.length-1)+1)},times:function(a){return a<1?'':new Array(a+1).join(this)},camelize:function(){var a=this.split('-'),len=a.length;if(len==1)return a[0];var b=this.charAt(0)=='-'?a[0].charAt(0).toUpperCase()+a[0].substring(1):a[0];for(var i=1;i<len;i++)b+=a[i].charAt(0).toUpperCase()+a[i].substring(1);return b},capitalize:function(){return this.charAt(0).toUpperCase()+this.substring(1).toLowerCase()},underscore:function(){return this.gsub(/::/,'/').gsub(/([A-Z]+)([A-Z][a-z])/,'#{1}_#{2}').gsub(/([a-z\d])([A-Z])/,'#{1}_#{2}').gsub(/-/,'_').toLowerCase()},dasherize:function(){return this.gsub(/_/,'-')},inspect:function(c){var d=this.gsub(/[\x00-\x1f\\]/,function(a){var b=String.specialChar[a[0]];return b?b:'\\u00'+a[0].charCodeAt().toPaddedString(2,16)});if(c)return'"'+d.replace(/"/g,'\\"')+'"';return"'"+d.replace(/'/g,'\\\'')+"'"},toJSON:function(){return this.inspect(true)},unfilterJSON:function(a){return this.sub(a||Prototype.JSONFilter,'#{1}')},isJSON:function(){var a=this.replace(/\\./g,'@').replace(/"[^"\\\n\r]*"/g,'');return(/^[,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t]*$/).test(a)},evalJSON:function(a){var b=this.unfilterJSON();try{if(!a||b.isJSON())return eval('('+b+')')}catch(e){}throw new SyntaxError('Badly formed JSON string: '+this.inspect());},include:function(a){return this.indexOf(a)>-1},startsWith:function(a){return this.indexOf(a)===0},endsWith:function(a){var d=this.length-a.length;return d>=0&&this.lastIndexOf(a)===d},empty:function(){return this==''},blank:function(){return/^\s*$/.test(this)},interpolate:function(a,b){return new Template(this,b).evaluate(a)}});if(Prototype.Browser.WebKit||Prototype.Browser.IE)Object.extend(String.prototype,{escapeHTML:function(){return this.replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;')},unescapeHTML:function(){return this.replace(/&amp;/g,'&').replace(/&lt;/g,'<').replace(/&gt;/g,'>')}});String.prototype.gsub.prepareReplacement=function(b){if(Object.isFunction(b))return b;var c=new Template(b);return function(a){return c.evaluate(a)}};String.prototype.parseQuery=String.prototype.toQueryParams;Object.extend(String.prototype.escapeHTML,{div:document.createElement('div'),text:document.createTextNode('')});with(String.prototype.escapeHTML)div.appendChild(text);var Template=Class.create({initialize:function(a,b){this.template=a.toString();this.pattern=b||Template.Pattern},evaluate:function(f){if(Object.isFunction(f.toTemplateReplacements))f=f.toTemplateReplacements();return this.template.gsub(this.pattern,function(a){if(f==null)return'';var b=a[1]||'';if(b=='\\')return a[2];var c=f,expr=a[3];var d=/^([^.[]+|\[((?:.*?[^\\])?)\])(\.|\[|$)/,a=d.exec(expr);if(a==null)return b;while(a!=null){var e=a[1].startsWith('[')?a[2].gsub('\\\\]',']'):a[1];c=c[e];if(null==c||''==a[3])break;expr=expr.substring('['==a[3]?a[1].length:a[0].length);a=d.exec(expr)}return b+String.interpret(c)}.bind(this))}});Template.Pattern=/(^|.|\r|\n)(#\{(.*?)\})/;var $break={};var Enumerable={each:function(b,c){var d=0;b=b.bind(c);try{this._each(function(a){b(a,d++)})}catch(e){if(e!=$break)throw e;}return this},eachSlice:function(a,b,c){b=b?b.bind(c):Prototype.K;var d=-a,slices=[],array=this.toArray();while((d+=a)<array.length)slices.push(array.slice(d,d+a));return slices.collect(b,c)},all:function(c,d){c=c?c.bind(d):Prototype.K;var e=true;this.each(function(a,b){e=e&&!!c(a,b);if(!e)throw $break;});return e},any:function(c,d){c=c?c.bind(d):Prototype.K;var e=false;this.each(function(a,b){if(e=!!c(a,b))throw $break;});return e},collect:function(c,d){c=c?c.bind(d):Prototype.K;var e=[];this.each(function(a,b){e.push(c(a,b))});return e},detect:function(c,d){c=c.bind(d);var e;this.each(function(a,b){if(c(a,b)){e=a;throw $break;}});return e},findAll:function(c,d){c=c.bind(d);var e=[];this.each(function(a,b){if(c(a,b))e.push(a)});return e},grep:function(c,d,e){d=d?d.bind(e):Prototype.K;var f=[];if(Object.isString(c))c=new RegExp(c);this.each(function(a,b){if(c.match(a))f.push(d(a,b))});return f},include:function(b){if(Object.isFunction(this.indexOf))if(this.indexOf(b)!=-1)return true;var c=false;this.each(function(a){if(a==b){c=true;throw $break;}});return c},inGroupsOf:function(b,c){c=c===undefined?null:c;return this.eachSlice(b,function(a){while(a.length<b)a.push(c);return a})},inject:function(c,d,e){d=d.bind(e);this.each(function(a,b){c=d(c,a,b)});return c},invoke:function(b){var c=$A(arguments).slice(1);return this.map(function(a){return a[b].apply(a,c)})},max:function(c,d){c=c?c.bind(d):Prototype.K;var e;this.each(function(a,b){a=c(a,b);if(e==undefined||a>=e)e=a});return e},min:function(c,d){c=c?c.bind(d):Prototype.K;var e;this.each(function(a,b){a=c(a,b);if(e==undefined||a<e)e=a});return e},partition:function(c,d){c=c?c.bind(d):Prototype.K;var e=[],falses=[];this.each(function(a,b){(c(a,b)?e:falses).push(a)});return[e,falses]},pluck:function(b){var c=[];this.each(function(a){c.push(a[b])});return c},reject:function(c,d){c=c.bind(d);var e=[];this.each(function(a,b){if(!c(a,b))e.push(a)});return e},sortBy:function(e,f){e=e.bind(f);return this.map(function(a,b){return{value:a,criteria:e(a,b)}}).sort(function(c,d){var a=c.criteria,b=d.criteria;return a<b?-1:a>b?1:0}).pluck('value')},toArray:function(){return this.map()},zip:function(){var c=Prototype.K,args=$A(arguments);if(Object.isFunction(args.last()))c=args.pop();var d=[this].concat(args).map($A);return this.map(function(a,b){return c(d.pluck(b))})},size:function(){return this.toArray().length},inspect:function(){return'#<Enumerable:'+this.toArray().inspect()+'>'}};Object.extend(Enumerable,{map:Enumerable.collect,find:Enumerable.detect,select:Enumerable.findAll,filter:Enumerable.findAll,member:Enumerable.include,entries:Enumerable.toArray,every:Enumerable.all,some:Enumerable.any});function $A(a){if(!a)return[];if(a.toArray)return a.toArray();var b=a.length,results=new Array(b);while(b--)results[b]=a[b];return results}if(Prototype.Browser.WebKit){function $A(a){if(!a)return[];if(!(Object.isFunction(a)&&a=='[object NodeList]')&&a.toArray)return a.toArray();var b=a.length,results=new Array(b);while(b--)results[b]=a[b];return results}}Array.from=$A;Object.extend(Array.prototype,Enumerable);if(!Array.prototype._reverse)Array.prototype._reverse=Array.prototype.reverse;Object.extend(Array.prototype,{_each:function(a){for(var i=0,length=this.length;i<length;i++)a(this[i])},clear:function(){this.length=0;return this},first:function(){return this[0]},last:function(){return this[this.length-1]},compact:function(){return this.select(function(a){return a!=null})},flatten:function(){return this.inject([],function(a,b){return a.concat(Object.isArray(b)?b.flatten():[b])})},without:function(){var b=$A(arguments);return this.select(function(a){return!b.include(a)})},reverse:function(a){return(a!==false?this:this.toArray())._reverse()},reduce:function(){return this.length>1?this:this[0]},uniq:function(d){return this.inject([],function(a,b,c){if(0==c||(d?a.last()!=b:!a.include(b)))a.push(b);return a})},intersect:function(c){return this.uniq().findAll(function(b){return c.detect(function(a){return b===a})})},clone:function(){return[].concat(this)},size:function(){return this.length},inspect:function(){return'['+this.map(Object.inspect).join(', ')+']'},toJSON:function(){var c=[];this.each(function(a){var b=Object.toJSON(a);if(b!==undefined)c.push(b)});return'['+c.join(', ')+']'}});if(Object.isFunction(Array.prototype.forEach))Array.prototype._each=Array.prototype.forEach;if(!Array.prototype.indexOf)Array.prototype.indexOf=function(a,i){i||(i=0);var b=this.length;if(i<0)i=b+i;for(;i<b;i++)if(this[i]===a)return i;return-1};if(!Array.prototype.lastIndexOf)Array.prototype.lastIndexOf=function(a,i){i=isNaN(i)?this.length:(i<0?this.length+i:i)+1;var n=this.slice(0,i).reverse().indexOf(a);return(n<0)?n:i-n-1};Array.prototype.toArray=Array.prototype.clone;function $w(a){if(!Object.isString(a))return[];a=a.strip();return a?a.split(/\s+/):[]}if(Prototype.Browser.Opera){Array.prototype.concat=function(){var a=[];for(var i=0,length=this.length;i<length;i++)a.push(this[i]);for(var i=0,length=arguments.length;i<length;i++){if(Object.isArray(arguments[i])){for(var j=0,arrayLength=arguments[i].length;j<arrayLength;j++)a.push(arguments[i][j])}else{a.push(arguments[i])}}return a}}Object.extend(Number.prototype,{toColorPart:function(){return this.toPaddedString(2,16)},succ:function(){return this+1},times:function(a){$R(0,this,true).each(a);return this},toPaddedString:function(a,b){var c=this.toString(b||10);return'0'.times(a-c.length)+c},toJSON:function(){return isFinite(this)?this.toString():'null'}});$w('abs round ceil floor').each(function(a){Number.prototype[a]=Math[a].methodize()});function $H(a){return new Hash(a)};var Hash=Class.create(Enumerable,(function(){if(function(){var i=0,Test=function(a){this.key=a};Test.prototype.key='foo';for(var b in new Test('bar'))i++;return i>1}()){function each(a){var b=[];for(var c in this._object){var d=this._object[c];if(b.include(c))continue;b.push(c);var e=[c,d];e.key=c;e.value=d;a(e)}}}else{function each(a){for(var b in this._object){var c=this._object[b],pair=[b,c];pair.key=b;pair.value=c;a(pair)}}}function toQueryPair(a,b){if(Object.isUndefined(b))return a;return a+'='+encodeURIComponent(String.interpret(b))}return{initialize:function(a){this._object=Object.isHash(a)?a.toObject():Object.clone(a)},_each:each,set:function(a,b){return this._object[a]=b},get:function(a){return this._object[a]},unset:function(a){var b=this._object[a];delete this._object[a];return b},toObject:function(){return Object.clone(this._object)},keys:function(){return this.pluck('key')},values:function(){return this.pluck('value')},index:function(b){var c=this.detect(function(a){return a.value===b});return c&&c.key},merge:function(a){return this.clone().update(a)},update:function(c){return new Hash(c).inject(this,function(a,b){a.set(b.key,b.value);return a})},toQueryString:function(){return this.map(function(a){var b=encodeURIComponent(a.key),values=a.value;if(values&&typeof values=='object'){if(Object.isArray(values))return values.map(toQueryPair.curry(b)).join('&')}return toQueryPair(b,values)}).join('&')},inspect:function(){return'#<Hash:{'+this.map(function(a){return a.map(Object.inspect).join(': ')}).join(', ')+'}>'},toJSON:function(){return Object.toJSON(this.toObject())},clone:function(){return new Hash(this)}}})());Hash.prototype.toTemplateReplacements=Hash.prototype.toObject;Hash.from=$H;var ObjectRange=Class.create(Enumerable,{initialize:function(a,b,c){this.start=a;this.end=b;this.exclusive=c},_each:function(a){var b=this.start;while(this.include(b)){a(b);b=b.succ()}},include:function(a){if(a<this.start)return false;if(this.exclusive)return a<this.end;return a<=this.end}});var $R=function(a,b,c){return new ObjectRange(a,b,c)};var Ajax={getTransport:function(){return Try.these(function(){return new XMLHttpRequest()},function(){return new ActiveXObject('Msxml2.XMLHTTP')},function(){return new ActiveXObject('Microsoft.XMLHTTP')})||false},activeRequestCount:0};Ajax.Responders={responders:[],_each:function(a){this.responders._each(a)},register:function(a){if(!this.include(a))this.responders.push(a)},unregister:function(a){this.responders=this.responders.without(a)},dispatch:function(b,c,d,f){this.each(function(a){if(Object.isFunction(a[b])){try{a[b].apply(a,[c,d,f])}catch(e){}}})}};Object.extend(Ajax.Responders,Enumerable);Ajax.Responders.register({onCreate:function(){Ajax.activeRequestCount++},onComplete:function(){Ajax.activeRequestCount--}});Ajax.Base=Class.create({initialize:function(a){this.options={method:'post',asynchronous:true,contentType:'application/x-www-form-urlencoded',encoding:'UTF-8',parameters:'',evalJSON:true,evalJS:true};Object.extend(this.options,a||{});this.options.method=this.options.method.toLowerCase();if(Object.isString(this.options.parameters))this.options.parameters=this.options.parameters.toQueryParams()}});Ajax.Request=Class.create(Ajax.Base,{_complete:false,initialize:function($super,b,c){$super(c);this.transport=Ajax.getTransport();this.request(b)},request:function(a){this.url=a;this.method=this.options.method;var b=Object.clone(this.options.parameters);if(!['get','post'].include(this.method)){b['_method']=this.method;this.method='post'}this.parameters=b;if(b=Object.toQueryString(b)){if(this.method=='get')this.url+=(this.url.include('?')?'&':'?')+b;else if(/Konqueror|Safari|KHTML/.test(navigator.userAgent))b+='&_='}try{var c=new Ajax.Response(this);if(this.options.onCreate)this.options.onCreate(c);Ajax.Responders.dispatch('onCreate',this,c);this.transport.open(this.method.toUpperCase(),this.url,this.options.asynchronous);if(this.options.asynchronous)this.respondToReadyState.bind(this).defer(1);this.transport.onreadystatechange=this.onStateChange.bind(this);this.setRequestHeaders();this.body=this.method=='post'?(this.options.postBody||b):null;this.transport.send(this.body);if(!this.options.asynchronous&&this.transport.overrideMimeType)this.onStateChange()}catch(e){this.dispatchException(e)}},onStateChange:function(){var a=this.transport.readyState;if(a>1&&!((a==4)&&this._complete))this.respondToReadyState(this.transport.readyState)},setRequestHeaders:function(){var b={'X-Requested-With':'XMLHttpRequest','X-Prototype-Version':Prototype.Version,'Accept':'text/javascript, text/html, application/xml, text/xml, */*'};if(this.method=='post'){b['Content-type']=this.options.contentType+(this.options.encoding?'; charset='+this.options.encoding:'');if(this.transport.overrideMimeType&&(navigator.userAgent.match(/Gecko\/(\d{4})/)||[0,2005])[1]<2005)b['Connection']='close'}if(typeof this.options.requestHeaders=='object'){var c=this.options.requestHeaders;if(Object.isFunction(c.push))for(var i=0,length=c.length;i<length;i+=2)b[c[i]]=c[i+1];else $H(c).each(function(a){b[a.key]=a.value})}for(var d in b)this.transport.setRequestHeader(d,b[d])},success:function(){var a=this.getStatus();return!a||(a>=200&&a<300)},getStatus:function(){try{return this.transport.status||0}catch(e){return 0}},respondToReadyState:function(a){var b=Ajax.Request.Events[a],response=new Ajax.Response(this);if(b=='Complete'){try{this._complete=true;(this.options['on'+response.status]||this.options['on'+(this.success()?'Success':'Failure')]||Prototype.emptyFunction)(response,response.headerJSON)}catch(e){this.dispatchException(e)}var c=response.getHeader('Content-type');if(this.options.evalJS=='force'||(this.options.evalJS&&c&&c.match(/^\s*(text|application)\/(x-)?(java|ecma)script(;.*)?\s*$/i)))this.evalResponse()}try{(this.options['on'+b]||Prototype.emptyFunction)(response,response.headerJSON);Ajax.Responders.dispatch('on'+b,this,response,response.headerJSON)}catch(e){this.dispatchException(e)}if(b=='Complete'){this.transport.onreadystatechange=Prototype.emptyFunction}},getHeader:function(a){try{return this.transport.getResponseHeader(a)}catch(e){return null}},evalResponse:function(){try{return eval((this.transport.responseText||'').unfilterJSON())}catch(e){this.dispatchException(e)}},dispatchException:function(a){(this.options.onException||Prototype.emptyFunction)(this,a);Ajax.Responders.dispatch('onException',this,a)}});Ajax.Request.Events=['Uninitialized','Loading','Loaded','Interactive','Complete'];Ajax.Response=Class.create({initialize:function(a){this.request=a;var b=this.transport=a.transport,readyState=this.readyState=b.readyState;if((readyState>2&&!Prototype.Browser.IE)||readyState==4){this.status=this.getStatus();this.statusText=this.getStatusText();this.responseText=String.interpret(b.responseText);this.headerJSON=this._getHeaderJSON()}if(readyState==4){var c=b.responseXML;this.responseXML=c===undefined?null:c;this.responseJSON=this._getResponseJSON()}},status:0,statusText:'',getStatus:Ajax.Request.prototype.getStatus,getStatusText:function(){try{return this.transport.statusText||''}catch(e){return''}},getHeader:Ajax.Request.prototype.getHeader,getAllHeaders:function(){try{return this.getAllResponseHeaders()}catch(e){return null}},getResponseHeader:function(a){return this.transport.getResponseHeader(a)},getAllResponseHeaders:function(){return this.transport.getAllResponseHeaders()},_getHeaderJSON:function(){var a=this.getHeader('X-JSON');if(!a)return null;a=decodeURIComponent(escape(a));try{return a.evalJSON(this.request.options.sanitizeJSON)}catch(e){this.request.dispatchException(e)}},_getResponseJSON:function(){var a=this.request.options;if(!a.evalJSON||(a.evalJSON!='force'&&!(this.getHeader('Content-type')||'').include('application/json')))return null;try{return this.transport.responseText.evalJSON(a.sanitizeJSON)}catch(e){this.request.dispatchException(e)}}});Ajax.Updater=Class.create(Ajax.Request,{initialize:function($super,d,e,f){this.container={success:(d.success||d),failure:(d.failure||(d.success?null:d))};f=f||{};var g=f.onComplete;f.onComplete=(function(a,b){this.updateContent(a.responseText);if(Object.isFunction(g))g(a,b)}).bind(this);$super(e,f)},updateContent:function(a){var b=this.container[this.success()?'success':'failure'],options=this.options;if(!options.evalScripts)a=a.stripScripts();if(b=$(b)){if(options.insertion){if(Object.isString(options.insertion)){var c={};c[options.insertion]=a;b.insert(c)}else options.insertion(b,a)}else b.update(a)}if(this.success()){if(this.onComplete)this.onComplete.bind(this).defer()}}});Ajax.PeriodicalUpdater=Class.create(Ajax.Base,{initialize:function($super,b,c,d){$super(d);this.onComplete=this.options.onComplete;this.frequency=(this.options.frequency||2);this.decay=(this.options.decay||1);this.updater={};this.container=b;this.url=c;this.start()},start:function(){this.options.onComplete=this.updateComplete.bind(this);this.onTimerEvent()},stop:function(){this.updater.options.onComplete=undefined;clearTimeout(this.timer);(this.onComplete||Prototype.emptyFunction).apply(this,arguments)},updateComplete:function(a){if(this.options.decay){this.decay=(a.responseText==this.lastText?this.decay*this.options.decay:1);this.lastText=a.responseText}this.timer=this.onTimerEvent.bind(this).delay(this.decay*this.frequency)},onTimerEvent:function(){this.updater=new Ajax.Updater(this.container,this.url,this.options)}});function $(a){if(arguments.length>1){for(var i=0,elements=[],length=arguments.length;i<length;i++)elements.push($(arguments[i]));return elements}if(Object.isString(a))a=document.getElementById(a);return Element.extend(a)}if(Prototype.BrowserFeatures.XPath){document._getElementsByXPath=function(a,b){var c=[];var d=document.evaluate(a,$(b)||document,null,XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,null);for(var i=0,length=d.snapshotLength;i<length;i++)c.push(Element.extend(d.snapshotItem(i)));return c}}if(!window.Node)var Node={};if(!Node.ELEMENT_NODE){Object.extend(Node,{ELEMENT_NODE:1,ATTRIBUTE_NODE:2,TEXT_NODE:3,CDATA_SECTION_NODE:4,ENTITY_REFERENCE_NODE:5,ENTITY_NODE:6,PROCESSING_INSTRUCTION_NODE:7,COMMENT_NODE:8,DOCUMENT_NODE:9,DOCUMENT_TYPE_NODE:10,DOCUMENT_FRAGMENT_NODE:11,NOTATION_NODE:12})}(function(){var d=this.Element;this.Element=function(a,b){b=b||{};a=a.toLowerCase();var c=Element.cache;if(Prototype.Browser.IE&&b.name){a='<'+a+' name="'+b.name+'">';delete b.name;return Element.writeAttribute(document.createElement(a),b)}if(!c[a])c[a]=Element.extend(document.createElement(a));return Element.writeAttribute(c[a].cloneNode(false),b)};Object.extend(this.Element,d||{})}).call(window);Element.cache={};Element.Methods={visible:function(a){return $(a).style.display!='none'},toggle:function(a){a=$(a);Element[Element.visible(a)?'hide':'show'](a);return a},hide:function(a){$(a).style.display='none';return a},show:function(a){$(a).style.display='';return a},remove:function(a){a=$(a);a.parentNode.removeChild(a);return a},update:function(a,b){a=$(a);if(b&&b.toElement)b=b.toElement();if(Object.isElement(b))return a.update().insert(b);b=Object.toHTML(b);a.innerHTML=b.stripScripts();b.evalScripts.bind(b).defer();return a},replace:function(a,b){a=$(a);if(b&&b.toElement)b=b.toElement();else if(!Object.isElement(b)){b=Object.toHTML(b);var c=a.ownerDocument.createRange();c.selectNode(a);b.evalScripts.bind(b).defer();b=c.createContextualFragment(b.stripScripts())}a.parentNode.replaceChild(b,a);return a},insert:function(a,b){a=$(a);if(Object.isString(b)||Object.isNumber(b)||Object.isElement(b)||(b&&(b.toElement||b.toHTML)))b={bottom:b};var c,t,range;for(position in b){c=b[position];position=position.toLowerCase();t=Element._insertionTranslations[position];if(c&&c.toElement)c=c.toElement();if(Object.isElement(c)){t.insert(a,c);continue}c=Object.toHTML(c);range=a.ownerDocument.createRange();t.initializeRange(a,range);t.insert(a,range.createContextualFragment(c.stripScripts()));c.evalScripts.bind(c).defer()}return a},wrap:function(a,b,c){a=$(a);if(Object.isElement(b))$(b).writeAttribute(c||{});else if(Object.isString(b))b=new Element(b,c);else b=new Element('div',b);if(a.parentNode)a.parentNode.replaceChild(b,a);b.appendChild(a);return b},inspect:function(d){d=$(d);var e='<'+d.tagName.toLowerCase();$H({'id':'id','className':'class'}).each(function(a){var b=a.first(),attribute=a.last();var c=(d[b]||'').toString();if(c)e+=' '+attribute+'='+c.inspect(true)});return e+'>'},recursivelyCollect:function(a,b){a=$(a);var c=[];while(a=a[b])if(a.nodeType==1)c.push(Element.extend(a));return c},ancestors:function(a){return $(a).recursivelyCollect('parentNode')},descendants:function(a){return $A($(a).getElementsByTagName('*')).each(Element.extend)},firstDescendant:function(a){a=$(a).firstChild;while(a&&a.nodeType!=1)a=a.nextSibling;return $(a)},immediateDescendants:function(a){if(!(a=$(a).firstChild))return[];while(a&&a.nodeType!=1)a=a.nextSibling;if(a)return[a].concat($(a).nextSiblings());return[]},previousSiblings:function(a){return $(a).recursivelyCollect('previousSibling')},nextSiblings:function(a){return $(a).recursivelyCollect('nextSibling')},siblings:function(a){a=$(a);return a.previousSiblings().reverse().concat(a.nextSiblings())},match:function(a,b){if(Object.isString(b))b=new Selector(b);return b.match($(a))},up:function(a,b,c){a=$(a);if(arguments.length==1)return $(a.parentNode);var d=a.ancestors();return b?Selector.findElement(d,b,c):d[c||0]},down:function(a,b,c){a=$(a);if(arguments.length==1)return a.firstDescendant();var d=a.descendants();return b?Selector.findElement(d,b,c):d[c||0]},previous:function(a,b,c){a=$(a);if(arguments.length==1)return $(Selector.handlers.previousElementSibling(a));var d=a.previousSiblings();return b?Selector.findElement(d,b,c):d[c||0]},next:function(a,b,c){a=$(a);if(arguments.length==1)return $(Selector.handlers.nextElementSibling(a));var d=a.nextSiblings();return b?Selector.findElement(d,b,c):d[c||0]},select:function(){var a=$A(arguments),element=$(a.shift());return Selector.findChildElements(element,a)},adjacent:function(){var a=$A(arguments),element=$(a.shift());return Selector.findChildElements(element.parentNode,a).without(element)},identify:function(a){a=$(a);var b=a.readAttribute('id'),self=arguments.callee;if(b)return b;do{b='anonymous_element_'+self.counter++}while($(b));a.writeAttribute('id',b);return b},readAttribute:function(a,b){a=$(a);if(Prototype.Browser.IE){var t=Element._attributeTranslations.read;if(t.values[b])return t.values[b](a,b);if(t.names[b])b=t.names[b];if(b.include(':')){return(!a.attributes||!a.attributes[b])?null:a.attributes[b].value}}return a.getAttribute(b)},writeAttribute:function(a,b,c){a=$(a);var d={},t=Element._attributeTranslations.write;if(typeof b=='object')d=b;else d[b]=c===undefined?true:c;for(var e in d){var b=t.names[e]||e,c=d[e];if(t.values[e])b=t.values[e](a,c);if(c===false||c===null)a.removeAttribute(b);else if(c===true)a.setAttribute(b,b);else a.setAttribute(b,c)}return a},getHeight:function(a){return $(a).getDimensions().height},getWidth:function(a){return $(a).getDimensions().width},classNames:function(a){return new Element.ClassNames(a)},hasClassName:function(a,b){if(!(a=$(a)))return;var c=a.className;return(c.length>0&&(c==b||new RegExp("(^|\\s)"+b+"(\\s|$)").test(c)))},addClassName:function(a,b){if(!(a=$(a)))return;if(!a.hasClassName(b))a.className+=(a.className?' ':'')+b;return a},removeClassName:function(a,b){if(!(a=$(a)))return;a.className=a.className.replace(new RegExp("(^|\\s+)"+b+"(\\s+|$)"),' ').strip();return a},toggleClassName:function(a,b){if(!(a=$(a)))return;return a[a.hasClassName(b)?'removeClassName':'addClassName'](b)},cleanWhitespace:function(a){a=$(a);var b=a.firstChild;while(b){var c=b.nextSibling;if(b.nodeType==3&&!/\S/.test(b.nodeValue))a.removeChild(b);b=c}return a},empty:function(a){return $(a).innerHTML.blank()},descendantOf:function(b,c){b=$(b),c=$(c);if(b.compareDocumentPosition)return(b.compareDocumentPosition(c)&8)===8;if(b.sourceIndex&&!Prototype.Browser.Opera){var e=b.sourceIndex,a=c.sourceIndex,nextAncestor=c.nextSibling;if(!nextAncestor){do{c=c.parentNode}while(!(nextAncestor=c.nextSibling)&&c.parentNode)}if(nextAncestor)return(e>a&&e<nextAncestor.sourceIndex)}while(b=b.parentNode)if(b==c)return true;return false},scrollTo:function(a){a=$(a);var b=a.cumulativeOffset();window.scrollTo(b[0],b[1]);return a},getStyle:function(a,b){a=$(a);b=b=='float'?'cssFloat':b.camelize();var c=a.style[b];if(!c){var d=document.defaultView.getComputedStyle(a,null);c=d?d[b]:null}if(b=='opacity')return c?parseFloat(c):1.0;return c=='auto'?null:c},getOpacity:function(a){return $(a).getStyle('opacity')},setStyle:function(a,b){a=$(a);var c=a.style,match;if(Object.isString(b)){a.style.cssText+=';'+b;return b.include('opacity')?a.setOpacity(b.match(/opacity:\s*(\d?\.?\d*)/)[1]):a}for(var d in b)if(d=='opacity')a.setOpacity(b[d]);else c[(d=='float'||d=='cssFloat')?(c.styleFloat===undefined?'cssFloat':'styleFloat'):d]=b[d];return a},setOpacity:function(a,b){a=$(a);a.style.opacity=(b==1||b==='')?'':(b<0.00001)?0:b;return a},getDimensions:function(a){a=$(a);var b=$(a).getStyle('display');if(b!='none'&&b!=null)return{width:a.offsetWidth,height:a.offsetHeight};var c=a.style;var d=c.visibility;var e=c.position;var f=c.display;c.visibility='hidden';c.position='absolute';c.display='block';var g=a.clientWidth;var h=a.clientHeight;c.display=f;c.position=e;c.visibility=d;return{width:g,height:h}},makePositioned:function(a){a=$(a);var b=Element.getStyle(a,'position');if(b=='static'||!b){a._madePositioned=true;a.style.position='relative';if(window.opera){a.style.top=0;a.style.left=0}}return a},undoPositioned:function(a){a=$(a);if(a._madePositioned){a._madePositioned=undefined;a.style.position=a.style.top=a.style.left=a.style.bottom=a.style.right=''}return a},makeClipping:function(a){a=$(a);if(a._overflow)return a;a._overflow=Element.getStyle(a,'overflow')||'auto';if(a._overflow!=='hidden')a.style.overflow='hidden';return a},undoClipping:function(a){a=$(a);if(!a._overflow)return a;a.style.overflow=a._overflow=='auto'?'':a._overflow;a._overflow=null;return a},cumulativeOffset:function(a){var b=0,valueL=0;do{b+=a.offsetTop||0;valueL+=a.offsetLeft||0;a=a.offsetParent}while(a);return Element._returnOffset(valueL,b)},positionedOffset:function(a){var b=0,valueL=0;do{b+=a.offsetTop||0;valueL+=a.offsetLeft||0;a=a.offsetParent;if(a){if(a.tagName=='BODY')break;var p=Element.getStyle(a,'position');if(p=='relative'||p=='absolute')break}}while(a);return Element._returnOffset(valueL,b)},absolutize:function(a){a=$(a);if(a.getStyle('position')=='absolute')return;var b=a.positionedOffset();var c=b[1];var d=b[0];var e=a.clientWidth;var f=a.clientHeight;a._originalLeft=d-parseFloat(a.style.left||0);a._originalTop=c-parseFloat(a.style.top||0);a._originalWidth=a.style.width;a._originalHeight=a.style.height;a.style.position='absolute';a.style.top=c+'px';a.style.left=d+'px';a.style.width=e+'px';a.style.height=f+'px';return a},relativize:function(a){a=$(a);if(a.getStyle('position')=='relative')return;a.style.position='relative';var b=parseFloat(a.style.top||0)-(a._originalTop||0);var c=parseFloat(a.style.left||0)-(a._originalLeft||0);a.style.top=b+'px';a.style.left=c+'px';a.style.height=a._originalHeight;a.style.width=a._originalWidth;return a},cumulativeScrollOffset:function(a){var b=0,valueL=0;do{b+=a.scrollTop||0;valueL+=a.scrollLeft||0;a=a.parentNode}while(a);return Element._returnOffset(valueL,b)},getOffsetParent:function(a){if(a.offsetParent)return $(a.offsetParent);if(a==document.body)return $(a);while((a=a.parentNode)&&a!=document.body)if(Element.getStyle(a,'position')!='static')return $(a);return $(document.body)},viewportOffset:function(a){var b=0,valueL=0;var c=a;do{b+=c.offsetTop||0;valueL+=c.offsetLeft||0;if(c.offsetParent==document.body&&Element.getStyle(c,'position')=='absolute')break}while(c=c.offsetParent);c=a;do{if(!Prototype.Browser.Opera||c.tagName=='BODY'){b-=c.scrollTop||0;valueL-=c.scrollLeft||0}}while(c=c.parentNode);return Element._returnOffset(valueL,b)},clonePosition:function(a,b){var c=Object.extend({setLeft:true,setTop:true,setWidth:true,setHeight:true,offsetTop:0,offsetLeft:0},arguments[2]||{});b=$(b);var p=b.viewportOffset();a=$(a);var d=[0,0];var e=null;if(Element.getStyle(a,'position')=='absolute'){e=a.getOffsetParent();d=e.viewportOffset()}if(e==document.body){d[0]-=document.body.offsetLeft;d[1]-=document.body.offsetTop}if(c.setLeft)a.style.left=(p[0]-d[0]+c.offsetLeft)+'px';if(c.setTop)a.style.top=(p[1]-d[1]+c.offsetTop)+'px';if(c.setWidth)a.style.width=b.offsetWidth+'px';if(c.setHeight)a.style.height=b.offsetHeight+'px';return a}};Element.Methods.identify.counter=1;Object.extend(Element.Methods,{getElementsBySelector:Element.Methods.select,childElements:Element.Methods.immediateDescendants});Element._attributeTranslations={write:{names:{className:'class',htmlFor:'for'},values:{}}};if(!document.createRange||Prototype.Browser.Opera){Element.Methods.insert=function(a,b){a=$(a);if(Object.isString(b)||Object.isNumber(b)||Object.isElement(b)||(b&&(b.toElement||b.toHTML)))b={bottom:b};var t=Element._insertionTranslations,content,position,pos,tagName;for(position in b){content=b[position];position=position.toLowerCase();pos=t[position];if(content&&content.toElement)content=content.toElement();if(Object.isElement(content)){pos.insert(a,content);continue}content=Object.toHTML(content);tagName=((position=='before'||position=='after')?a.parentNode:a).tagName.toUpperCase();if(t.tags[tagName]){var c=Element._getContentFromAnonymousElement(tagName,content.stripScripts());if(position=='top'||position=='after')c.reverse();c.each(pos.insert.curry(a))}else a.insertAdjacentHTML(pos.adjacency,content.stripScripts());content.evalScripts.bind(content).defer()}return a}}if(Prototype.Browser.Opera){Element.Methods._getStyle=Element.Methods.getStyle;Element.Methods.getStyle=function(a,b){switch(b){case'left':case'top':case'right':case'bottom':if(Element._getStyle(a,'position')=='static')return null;default:return Element._getStyle(a,b)}};Element.Methods._readAttribute=Element.Methods.readAttribute;Element.Methods.readAttribute=function(a,b){if(b=='title')return a.title;return Element._readAttribute(a,b)}}else if(Prototype.Browser.IE){$w('positionedOffset getOffsetParent viewportOffset').each(function(e){Element.Methods[e]=Element.Methods[e].wrap(function(a,b){b=$(b);var c=b.getStyle('position');if(c!='static')return a(b);b.setStyle({position:'relative'});var d=a(b);b.setStyle({position:c});return d})});Element.Methods.getStyle=function(a,b){a=$(a);b=(b=='float'||b=='cssFloat')?'styleFloat':b.camelize();var c=a.style[b];if(!c&&a.currentStyle)c=a.currentStyle[b];if(b=='opacity'){if(c=(a.getStyle('filter')||'').match(/alpha\(opacity=(.*)\)/))if(c[1])return parseFloat(c[1])/100;return 1.0}if(c=='auto'){if((b=='width'||b=='height')&&(a.getStyle('display')!='none'))return a['offset'+b.capitalize()]+'px';return null}return c};Element.Methods.setOpacity=function(b,c){function stripAlpha(a){return a.replace(/alpha\([^\)]*\)/gi,'')}b=$(b);var d=b.currentStyle;if((d&&!d.hasLayout)||(!d&&b.style.zoom=='normal'))b.style.zoom=1;var e=b.getStyle('filter'),style=b.style;if(c==1||c===''){(e=stripAlpha(e))?style.filter=e:style.removeAttribute('filter');return b}else if(c<0.00001)c=0;style.filter=stripAlpha(e)+'alpha(opacity='+(c*100)+')';return b};Element._attributeTranslations={read:{names:{'class':'className','for':'htmlFor'},values:{_getAttr:function(a,b){return a.getAttribute(b,2)},_getAttrNode:function(a,b){var c=a.getAttributeNode(b);return c?c.value:""},_getEv:function(a,b){var b=a.getAttribute(b);return b?b.toString().slice(23,-2):null},_flag:function(a,b){return $(a).hasAttribute(b)?b:null},style:function(a){return a.style.cssText.toLowerCase()},title:function(a){return a.title}}}};Element._attributeTranslations.write={names:Object.clone(Element._attributeTranslations.read.names),values:{checked:function(a,b){a.checked=!!b},style:function(a,b){a.style.cssText=b?b:''}}};Element._attributeTranslations.has={};$w('colSpan rowSpan vAlign dateTime accessKey tabIndex '+'encType maxLength readOnly longDesc').each(function(a){Element._attributeTranslations.write.names[a.toLowerCase()]=a;Element._attributeTranslations.has[a.toLowerCase()]=a});(function(v){Object.extend(v,{href:v._getAttr,src:v._getAttr,type:v._getAttr,action:v._getAttrNode,disabled:v._flag,checked:v._flag,readonly:v._flag,multiple:v._flag,onload:v._getEv,onunload:v._getEv,onclick:v._getEv,ondblclick:v._getEv,onmousedown:v._getEv,onmouseup:v._getEv,onmouseover:v._getEv,onmousemove:v._getEv,onmouseout:v._getEv,onfocus:v._getEv,onblur:v._getEv,onkeypress:v._getEv,onkeydown:v._getEv,onkeyup:v._getEv,onsubmit:v._getEv,onreset:v._getEv,onselect:v._getEv,onchange:v._getEv})})(Element._attributeTranslations.read.values)}else if(Prototype.Browser.Gecko&&/rv:1\.8\.0/.test(navigator.userAgent)){Element.Methods.setOpacity=function(a,b){a=$(a);a.style.opacity=(b==1)?0.999999:(b==='')?'':(b<0.00001)?0:b;return a}}else if(Prototype.Browser.WebKit){Element.Methods.setOpacity=function(a,b){a=$(a);a.style.opacity=(b==1||b==='')?'':(b<0.00001)?0:b;if(b==1)if(a.tagName=='IMG'&&a.width){a.width++;a.width--}else try{var n=document.createTextNode(' ');a.appendChild(n);a.removeChild(n)}catch(e){}return a};Element.Methods.cumulativeOffset=function(a){var b=0,valueL=0;do{b+=a.offsetTop||0;valueL+=a.offsetLeft||0;if(a.offsetParent==document.body)if(Element.getStyle(a,'position')=='absolute')break;a=a.offsetParent}while(a);return Element._returnOffset(valueL,b)}}if(Prototype.Browser.IE||Prototype.Browser.Opera){Element.Methods.update=function(b,c){b=$(b);if(c&&c.toElement)c=c.toElement();if(Object.isElement(c))return b.update().insert(c);c=Object.toHTML(c);var d=b.tagName.toUpperCase();if(d in Element._insertionTranslations.tags){$A(b.childNodes).each(function(a){b.removeChild(a)});Element._getContentFromAnonymousElement(d,c.stripScripts()).each(function(a){b.appendChild(a)})}else b.innerHTML=c.stripScripts();c.evalScripts.bind(c).defer();return b}}if(document.createElement('div').outerHTML){Element.Methods.replace=function(b,c){b=$(b);if(c&&c.toElement)c=c.toElement();if(Object.isElement(c)){b.parentNode.replaceChild(c,b);return b}c=Object.toHTML(c);var d=b.parentNode,tagName=d.tagName.toUpperCase();if(Element._insertionTranslations.tags[tagName]){var e=b.next();var f=Element._getContentFromAnonymousElement(tagName,c.stripScripts());d.removeChild(b);if(e)f.each(function(a){d.insertBefore(a,e)});else f.each(function(a){d.appendChild(a)})}else b.outerHTML=c.stripScripts();c.evalScripts.bind(c).defer();return b}}Element._returnOffset=function(l,t){var a=[l,t];a.left=l;a.top=t;return a};Element._getContentFromAnonymousElement=function(a,b){var c=new Element('div'),t=Element._insertionTranslations.tags[a];c.innerHTML=t[0]+b+t[1];t[2].times(function(){c=c.firstChild});return $A(c.childNodes)};Element._insertionTranslations={before:{adjacency:'beforeBegin',insert:function(a,b){a.parentNode.insertBefore(b,a)},initializeRange:function(a,b){b.setStartBefore(a)}},top:{adjacency:'afterBegin',insert:function(a,b){a.insertBefore(b,a.firstChild)},initializeRange:function(a,b){b.selectNodeContents(a);b.collapse(true)}},bottom:{adjacency:'beforeEnd',insert:function(a,b){a.appendChild(b)}},after:{adjacency:'afterEnd',insert:function(a,b){a.parentNode.insertBefore(b,a.nextSibling)},initializeRange:function(a,b){b.setStartAfter(a)}},tags:{TABLE:['<table>','</table>',1],TBODY:['<table><tbody>','</tbody></table>',2],TR:['<table><tbody><tr>','</tr></tbody></table>',3],TD:['<table><tbody><tr><td>','</td></tr></tbody></table>',4],SELECT:['<select>','</select>',1]}};(function(){this.bottom.initializeRange=this.top.initializeRange;Object.extend(this.tags,{THEAD:this.tags.TBODY,TFOOT:this.tags.TBODY,TH:this.tags.TD})}).call(Element._insertionTranslations);Element.Methods.Simulated={hasAttribute:function(a,b){b=Element._attributeTranslations.has[b]||b;var c=$(a).getAttributeNode(b);return c&&c.specified}};Element.Methods.ByTag={};Object.extend(Element,Element.Methods);if(!Prototype.BrowserFeatures.ElementExtensions&&document.createElement('div').__proto__){window.HTMLElement={};window.HTMLElement.prototype=document.createElement('div').__proto__;Prototype.BrowserFeatures.ElementExtensions=true}Element.extend=(function(){if(Prototype.BrowserFeatures.SpecificElementExtensions)return Prototype.K;var c={},ByTag=Element.Methods.ByTag;var d=Object.extend(function(a){if(!a||a._extendedByPrototype||a.nodeType!=1||a==window)return a;var b=Object.clone(c),tagName=a.tagName,property,value;if(ByTag[tagName])Object.extend(b,ByTag[tagName]);for(property in b){value=b[property];if(Object.isFunction(value)&&!(property in a))a[property]=value.methodize()}a._extendedByPrototype=Prototype.emptyFunction;return a},{refresh:function(){if(!Prototype.BrowserFeatures.ElementExtensions){Object.extend(c,Element.Methods);Object.extend(c,Element.Methods.Simulated)}}});d.refresh();return d})();Element.hasAttribute=function(a,b){if(a.hasAttribute)return a.hasAttribute(b);return Element.Methods.Simulated.hasAttribute(a,b)};Element.addMethods=function(f){var F=Prototype.BrowserFeatures,T=Element.Methods.ByTag;if(!f){Object.extend(Form,Form.Methods);Object.extend(Form.Element,Form.Element.Methods);Object.extend(Element.Methods.ByTag,{"FORM":Object.clone(Form.Methods),"INPUT":Object.clone(Form.Element.Methods),"SELECT":Object.clone(Form.Element.Methods),"TEXTAREA":Object.clone(Form.Element.Methods)})}if(arguments.length==2){var g=f;f=arguments[1]}if(!g)Object.extend(Element.Methods,f||{});else{if(Object.isArray(g))g.each(extend);else extend(g)}function extend(a){a=a.toUpperCase();if(!Element.Methods.ByTag[a])Element.Methods.ByTag[a]={};Object.extend(Element.Methods.ByTag[a],f)}function copy(a,b,c){c=c||false;for(var d in a){var e=a[d];if(!Object.isFunction(e))continue;if(!c||!(d in b))b[d]=e.methodize()}}function findDOMClass(a){var b;var c={"OPTGROUP":"OptGroup","TEXTAREA":"TextArea","P":"Paragraph","FIELDSET":"FieldSet","UL":"UList","OL":"OList","DL":"DList","DIR":"Directory","H1":"Heading","H2":"Heading","H3":"Heading","H4":"Heading","H5":"Heading","H6":"Heading","Q":"Quote","INS":"Mod","DEL":"Mod","A":"Anchor","IMG":"Image","CAPTION":"TableCaption","COL":"TableCol","COLGROUP":"TableCol","THEAD":"TableSection","TFOOT":"TableSection","TBODY":"TableSection","TR":"TableRow","TH":"TableCell","TD":"TableCell","FRAMESET":"FrameSet","IFRAME":"IFrame"};if(c[a])b='HTML'+c[a]+'Element';if(window[b])return window[b];b='HTML'+a+'Element';if(window[b])return window[b];b='HTML'+a.capitalize()+'Element';if(window[b])return window[b];window[b]={};window[b].prototype=document.createElement(a).__proto__;return window[b]}if(F.ElementExtensions){copy(Element.Methods,HTMLElement.prototype);copy(Element.Methods.Simulated,HTMLElement.prototype,true)}if(F.SpecificElementExtensions){for(var h in Element.Methods.ByTag){var i=findDOMClass(h);if(Object.isUndefined(i))continue;copy(T[h],i.prototype)}}Object.extend(Element,Element.Methods);delete Element.ByTag;if(Element.extend.refresh)Element.extend.refresh();Element.cache={}};document.viewport={getDimensions:function(){var a={};$w('width height').each(function(d){var D=d.capitalize();a[d]=self['inner'+D]||(document.documentElement['client'+D]||document.body['client'+D])});return a},getWidth:function(){return this.getDimensions().width},getHeight:function(){return this.getDimensions().height},getScrollOffsets:function(){return Element._returnOffset(window.pageXOffset||document.documentElement.scrollLeft||document.body.scrollLeft,window.pageYOffset||document.documentElement.scrollTop||document.body.scrollTop)}};var Selector=Class.create({initialize:function(a){this.expression=a.strip();this.compileMatcher()},compileMatcher:function(){if(Prototype.BrowserFeatures.XPath&&!(/(\[[\w-]*?:|:checked)/).test(this.expression))return this.compileXPathMatcher();var e=this.expression,ps=Selector.patterns,h=Selector.handlers,c=Selector.criteria,le,p,m;if(Selector._cache[e]){this.matcher=Selector._cache[e];return}this.matcher=["this.matcher = function(root) {","var r = root, h = Selector.handlers, c = false, n;"];while(e&&le!=e&&(/\S/).test(e)){le=e;for(var i in ps){p=ps[i];if(m=e.match(p)){this.matcher.push(Object.isFunction(c[i])?c[i](m):new Template(c[i]).evaluate(m));e=e.replace(m[0],'');break}}}this.matcher.push("return h.unique(n);\n}");eval(this.matcher.join('\n'));Selector._cache[this.expression]=this.matcher},compileXPathMatcher:function(){var e=this.expression,ps=Selector.patterns,x=Selector.xpath,le,m;if(Selector._cache[e]){this.xpath=Selector._cache[e];return}this.matcher=['.//*'];while(e&&le!=e&&(/\S/).test(e)){le=e;for(var i in ps){if(m=e.match(ps[i])){this.matcher.push(Object.isFunction(x[i])?x[i](m):new Template(x[i]).evaluate(m));e=e.replace(m[0],'');break}}}this.xpath=this.matcher.join('');Selector._cache[this.expression]=this.xpath},findElements:function(a){a=a||document;if(this.xpath)return document._getElementsByXPath(this.xpath,a);return this.matcher(a)},match:function(a){this.tokens=[];var e=this.expression,ps=Selector.patterns,as=Selector.assertions;var b,p,m;while(e&&b!==e&&(/\S/).test(e)){b=e;for(var i in ps){p=ps[i];if(m=e.match(p)){if(as[i]){this.tokens.push([i,Object.clone(m)]);e=e.replace(m[0],'')}else{return this.findElements(document).include(a)}}}}var c=true,name,matches;for(var i=0,token;token=this.tokens[i];i++){name=token[0],matches=token[1];if(!Selector.assertions[name](a,matches)){c=false;break}}return c},toString:function(){return this.expression},inspect:function(){return"#<Selector:"+this.expression.inspect()+">"}});Object.extend(Selector,{_cache:{},xpath:{descendant:"//*",child:"/*",adjacent:"/following-sibling::*[1]",laterSibling:'/following-sibling::*',tagName:function(m){if(m[1]=='*')return'';return"[local-name()='"+m[1].toLowerCase()+"' or local-name()='"+m[1].toUpperCase()+"']"},className:"[contains(concat(' ', @class, ' '), ' #{1} ')]",id:"[@id='#{1}']",attrPresence:"[@#{1}]",attr:function(m){m[3]=m[5]||m[6];return new Template(Selector.xpath.operators[m[2]]).evaluate(m)},pseudo:function(m){var h=Selector.xpath.pseudos[m[1]];if(!h)return'';if(Object.isFunction(h))return h(m);return new Template(Selector.xpath.pseudos[m[1]]).evaluate(m)},operators:{'=':"[@#{1}='#{3}']",'!=':"[@#{1}!='#{3}']",'^=':"[starts-with(@#{1}, '#{3}')]",'$=':"[substring(@#{1}, (string-length(@#{1}) - string-length('#{3}') + 1))='#{3}']",'*=':"[contains(@#{1}, '#{3}')]",'~=':"[contains(concat(' ', @#{1}, ' '), ' #{3} ')]",'|=':"[contains(concat('-', @#{1}, '-'), '-#{3}-')]"},pseudos:{'first-child':'[not(preceding-sibling::*)]','last-child':'[not(following-sibling::*)]','only-child':'[not(preceding-sibling::* or following-sibling::*)]','empty':"[count(*) = 0 and (count(text()) = 0 or translate(text(), ' \t\r\n', '') = '')]",'checked':"[@checked]",'disabled':"[@disabled]",'enabled':"[not(@disabled)]",'not':function(m){var e=m[6],p=Selector.patterns,x=Selector.xpath,le,m,v;var a=[];while(e&&le!=e&&(/\S/).test(e)){le=e;for(var i in p){if(m=e.match(p[i])){v=Object.isFunction(x[i])?x[i](m):new Template(x[i]).evaluate(m);a.push("("+v.substring(1,v.length-1)+")");e=e.replace(m[0],'');break}}}return"[not("+a.join(" and ")+")]"},'nth-child':function(m){return Selector.xpath.pseudos.nth("(count(./preceding-sibling::*) + 1) ",m)},'nth-last-child':function(m){return Selector.xpath.pseudos.nth("(count(./following-sibling::*) + 1) ",m)},'nth-of-type':function(m){return Selector.xpath.pseudos.nth("position() ",m)},'nth-last-of-type':function(m){return Selector.xpath.pseudos.nth("(last() + 1 - position()) ",m)},'first-of-type':function(m){m[6]="1";return Selector.xpath.pseudos['nth-of-type'](m)},'last-of-type':function(m){m[6]="1";return Selector.xpath.pseudos['nth-last-of-type'](m)},'only-of-type':function(m){var p=Selector.xpath.pseudos;return p['first-of-type'](m)+p['last-of-type'](m)},nth:function(c,m){var d,formula=m[6],predicate;if(formula=='even')formula='2n+0';if(formula=='odd')formula='2n+1';if(d=formula.match(/^(\d+)$/))return'['+c+"= "+d[1]+']';if(d=formula.match(/^(-?\d*)?n(([+-])(\d+))?/)){if(d[1]=="-")d[1]=-1;var a=d[1]?Number(d[1]):1;var b=d[2]?Number(d[2]):0;predicate="[((#{fragment} - #{b}) mod #{a} = 0) and "+"((#{fragment} - #{b}) div #{a} >= 0)]";return new Template(predicate).evaluate({fragment:c,a:a,b:b})}}}},criteria:{tagName:'n = h.tagName(n, r, "#{1}", c);   c = false;',className:'n = h.className(n, r, "#{1}", c); c = false;',id:'n = h.id(n, r, "#{1}", c);        c = false;',attrPresence:'n = h.attrPresence(n, r, "#{1}"); c = false;',attr:function(m){m[3]=(m[5]||m[6]);return new Template('n = h.attr(n, r, "#{1}", "#{3}", "#{2}"); c = false;').evaluate(m)},pseudo:function(m){if(m[6])m[6]=m[6].replace(/"/g,'\\"');return new Template('n = h.pseudo(n, "#{1}", "#{6}", r, c); c = false;').evaluate(m)},descendant:'c = "descendant";',child:'c = "child";',adjacent:'c = "adjacent";',laterSibling:'c = "laterSibling";'},patterns:{laterSibling:/^\s*~\s*/,child:/^\s*>\s*/,adjacent:/^\s*\+\s*/,descendant:/^\s/,tagName:/^\s*(\*|[\w\-]+)(\b|$)?/,id:/^#([\w\-\*]+)(\b|$)/,className:/^\.([\w\-\*]+)(\b|$)/,pseudo:/^:((first|last|nth|nth-last|only)(-child|-of-type)|empty|checked|(en|dis)abled|not)(\((.*?)\))?(\b|$|(?=\s)|(?=:))/,attrPresence:/^\[([\w]+)\]/,attr:/\[((?:[\w-]*:)?[\w-]+)\s*(?:([!^$*~|]?=)\s*((['"])([^\4]*?)\4|([^'"][^\]]*?)))?\]/},assertions:{tagName:function(a,b){return b[1].toUpperCase()==a.tagName.toUpperCase()},className:function(a,b){return Element.hasClassName(a,b[1])},id:function(a,b){return a.id===b[1]},attrPresence:function(a,b){return Element.hasAttribute(a,b[1])},attr:function(a,b){var c=Element.readAttribute(a,b[1]);return Selector.operators[b[2]](c,b[3])}},handlers:{concat:function(a,b){for(var i=0,node;node=b[i];i++)a.push(node);return a},mark:function(a){for(var i=0,node;node=a[i];i++)node._counted=true;return a},unmark:function(a){for(var i=0,node;node=a[i];i++)node._counted=undefined;return a},index:function(a,b,c){a._counted=true;if(b){for(var d=a.childNodes,i=d.length-1,j=1;i>=0;i--){var e=d[i];if(e.nodeType==1&&(!c||e._counted))e.nodeIndex=j++}}else{for(var i=0,j=1,d=a.childNodes;e=d[i];i++)if(e.nodeType==1&&(!c||e._counted))e.nodeIndex=j++}},unique:function(a){if(a.length==0)return a;var b=[],n;for(var i=0,l=a.length;i<l;i++)if(!(n=a[i])._counted){n._counted=true;b.push(Element.extend(n))}return Selector.handlers.unmark(b)},descendant:function(a){var h=Selector.handlers;for(var i=0,results=[],node;node=a[i];i++)h.concat(results,node.getElementsByTagName('*'));return results},child:function(a){var h=Selector.handlers;for(var i=0,results=[],node;node=a[i];i++){for(var j=0,children=[],child;child=node.childNodes[j];j++)if(child.nodeType==1&&child.tagName!='!')results.push(child)}return results},adjacent:function(a){for(var i=0,results=[],node;node=a[i];i++){var b=this.nextElementSibling(node);if(b)results.push(b)}return results},laterSibling:function(a){var h=Selector.handlers;for(var i=0,results=[],node;node=a[i];i++)h.concat(results,Element.nextSiblings(node));return results},nextElementSibling:function(a){while(a=a.nextSibling)if(a.nodeType==1)return a;return null},previousElementSibling:function(a){while(a=a.previousSibling)if(a.nodeType==1)return a;return null},tagName:function(a,b,c,d){c=c.toUpperCase();var e=[],h=Selector.handlers;if(a){if(d){if(d=="descendant"){for(var i=0,node;node=a[i];i++)h.concat(e,node.getElementsByTagName(c));return e}else a=this[d](a);if(c=="*")return a}for(var i=0,node;node=a[i];i++)if(node.tagName.toUpperCase()==c)e.push(node);return e}else return b.getElementsByTagName(c)},id:function(a,b,c,d){var e=$(c),h=Selector.handlers;if(!e)return[];if(!a&&b==document)return[e];if(a){if(d){if(d=='child'){for(var i=0,node;node=a[i];i++)if(e.parentNode==node)return[e]}else if(d=='descendant'){for(var i=0,node;node=a[i];i++)if(Element.descendantOf(e,node))return[e]}else if(d=='adjacent'){for(var i=0,node;node=a[i];i++)if(Selector.handlers.previousElementSibling(e)==node)return[e]}else a=h[d](a)}for(var i=0,node;node=a[i];i++)if(node==e)return[e];return[]}return(e&&Element.descendantOf(e,b))?[e]:[]},className:function(a,b,c,d){if(a&&d)a=this[d](a);return Selector.handlers.byClassName(a,b,c)},byClassName:function(a,b,c){if(!a)a=Selector.handlers.descendant([b]);var d=' '+c+' ';for(var i=0,results=[],node,nodeClassName;node=a[i];i++){nodeClassName=node.className;if(nodeClassName.length==0)continue;if(nodeClassName==c||(' '+nodeClassName+' ').include(d))results.push(node)}return results},attrPresence:function(a,b,c){if(!a)a=b.getElementsByTagName("*");var d=[];for(var i=0,node;node=a[i];i++)if(Element.hasAttribute(node,c))d.push(node);return d},attr:function(a,b,c,d,e){if(!a)a=b.getElementsByTagName("*");var f=Selector.operators[e],results=[];for(var i=0,node;node=a[i];i++){var g=Element.readAttribute(node,c);if(g===null)continue;if(f(g,d))results.push(node)}return results},pseudo:function(a,b,c,d,e){if(a&&e)a=this[e](a);if(!a)a=d.getElementsByTagName("*");return Selector.pseudos[b](a,c,d)}},pseudos:{'first-child':function(a,b,c){for(var i=0,results=[],node;node=a[i];i++){if(Selector.handlers.previousElementSibling(node))continue;results.push(node)}return results},'last-child':function(a,b,c){for(var i=0,results=[],node;node=a[i];i++){if(Selector.handlers.nextElementSibling(node))continue;results.push(node)}return results},'only-child':function(a,b,c){var h=Selector.handlers;for(var i=0,results=[],node;node=a[i];i++)if(!h.previousElementSibling(node)&&!h.nextElementSibling(node))results.push(node);return results},'nth-child':function(a,b,c){return Selector.pseudos.nth(a,b,c)},'nth-last-child':function(a,b,c){return Selector.pseudos.nth(a,b,c,true)},'nth-of-type':function(a,b,c){return Selector.pseudos.nth(a,b,c,false,true)},'nth-last-of-type':function(a,b,c){return Selector.pseudos.nth(a,b,c,true,true)},'first-of-type':function(a,b,c){return Selector.pseudos.nth(a,"1",c,false,true)},'last-of-type':function(a,b,c){return Selector.pseudos.nth(a,"1",c,true,true)},'only-of-type':function(a,b,c){var p=Selector.pseudos;return p['last-of-type'](p['first-of-type'](a,b,c),b,c)},getIndices:function(a,b,d){if(a==0)return b>0?[b]:[];return $R(1,d).inject([],function(c,i){if(0==(i-b)%a&&(i-b)/a>=0)c.push(i);return c})},nth:function(c,d,e,f,g){if(c.length==0)return[];if(d=='even')d='2n+0';if(d=='odd')d='2n+1';var h=Selector.handlers,results=[],indexed=[],m;h.mark(c);for(var i=0,node;node=c[i];i++){if(!node.parentNode._counted){h.index(node.parentNode,f,g);indexed.push(node.parentNode)}}if(d.match(/^\d+$/)){d=Number(d);for(var i=0,node;node=c[i];i++)if(node.nodeIndex==d)results.push(node)}else if(m=d.match(/^(-?\d*)?n(([+-])(\d+))?/)){if(m[1]=="-")m[1]=-1;var a=m[1]?Number(m[1]):1;var b=m[2]?Number(m[2]):0;var k=Selector.pseudos.getIndices(a,b,c.length);for(var i=0,node,l=k.length;node=c[i];i++){for(var j=0;j<l;j++)if(node.nodeIndex==k[j])results.push(node)}}h.unmark(c);h.unmark(indexed);return results},'empty':function(a,b,c){for(var i=0,results=[],node;node=a[i];i++){if(node.tagName=='!'||(node.firstChild&&!node.innerHTML.match(/^\s*$/)))continue;results.push(node)}return results},'not':function(a,b,c){var h=Selector.handlers,selectorType,m;var d=new Selector(b).findElements(c);h.mark(d);for(var i=0,results=[],node;node=a[i];i++)if(!node._counted)results.push(node);h.unmark(d);return results},'enabled':function(a,b,c){for(var i=0,results=[],node;node=a[i];i++)if(!node.disabled)results.push(node);return results},'disabled':function(a,b,c){for(var i=0,results=[],node;node=a[i];i++)if(node.disabled)results.push(node);return results},'checked':function(a,b,c){for(var i=0,results=[],node;node=a[i];i++)if(node.checked)results.push(node);return results}},operators:{'=':function(a,v){return a==v},'!=':function(a,v){return a!=v},'^=':function(a,v){return a.startsWith(v)},'$=':function(a,v){return a.endsWith(v)},'*=':function(a,v){return a.include(v)},'~=':function(a,v){return(' '+a+' ').include(' '+v+' ')},'|=':function(a,v){return('-'+a.toUpperCase()+'-').include('-'+v.toUpperCase()+'-')}},matchElements:function(a,b){var c=new Selector(b).findElements(),h=Selector.handlers;h.mark(c);for(var i=0,results=[],element;element=a[i];i++)if(element._counted)results.push(element);h.unmark(c);return results},findElement:function(a,b,c){if(Object.isNumber(b)){c=b;b=false}return Selector.matchElements(a,b||'*')[c||0]},findChildElements:function(a,b){var c=b.join(','),b=[];c.scan(/(([\w#:.~>+()\s-]+|\*|\[.*?\])+)\s*(,|$)/,function(m){b.push(m[1].strip())});var d=[],h=Selector.handlers;for(var i=0,l=b.length,selector;i<l;i++){selector=new Selector(b[i].strip());h.concat(d,selector.findElements(a))}return(l>1)?h.unique(d):d}});function $$(){return Selector.findChildElements(document,$A(arguments))}var Form={reset:function(a){$(a).reset();return a},serializeElements:function(c,d){if(typeof d!='object')d={hash:!!d};else if(d.hash===undefined)d.hash=true;var e,value,submitted=false,submit=d.submit;var f=c.inject({},function(a,b){if(!b.disabled&&b.name){e=b.name;value=$(b).getValue();if(value!=null&&(b.type!='submit'||(!submitted&&submit!==false&&(!submit||e==submit)&&(submitted=true)))){if(e in a){if(!Object.isArray(a[e]))a[e]=[a[e]];a[e].push(value)}else a[e]=value}}return a});return d.hash?f:Object.toQueryString(f)}};Form.Methods={serialize:function(a,b){return Form.serializeElements(Form.getElements(a),b)},getElements:function(c){return $A($(c).getElementsByTagName('*')).inject([],function(a,b){if(Form.Element.Serializers[b.tagName.toLowerCase()])a.push(Element.extend(b));return a})},getInputs:function(a,b,c){a=$(a);var d=a.getElementsByTagName('input');if(!b&&!c)return $A(d).map(Element.extend);for(var i=0,matchingInputs=[],length=d.length;i<length;i++){var e=d[i];if((b&&e.type!=b)||(c&&e.name!=c))continue;matchingInputs.push(Element.extend(e))}return matchingInputs},disable:function(a){a=$(a);Form.getElements(a).invoke('disable');return a},enable:function(a){a=$(a);Form.getElements(a).invoke('enable');return a},findFirstElement:function(b){var c=$(b).getElements().findAll(function(a){return'hidden'!=a.type&&!a.disabled});var d=c.findAll(function(a){return a.hasAttribute('tabIndex')&&a.tabIndex>=0}).sortBy(function(a){return a.tabIndex}).first();return d?d:c.find(function(a){return['input','select','textarea'].include(a.tagName.toLowerCase())})},focusFirstElement:function(a){a=$(a);a.findFirstElement().activate();return a},request:function(a,b){a=$(a),b=Object.clone(b||{});var c=b.parameters,action=a.readAttribute('action')||'';if(action.blank())action=window.location.href;b.parameters=a.serialize(true);if(c){if(Object.isString(c))c=c.toQueryParams();Object.extend(b.parameters,c)}if(a.hasAttribute('method')&&!b.method)b.method=a.method;return new Ajax.Request(action,b)}};Form.Element={focus:function(a){$(a).focus();return a},select:function(a){$(a).select();return a}};Form.Element.Methods={serialize:function(a){a=$(a);if(!a.disabled&&a.name){var b=a.getValue();if(b!=undefined){var c={};c[a.name]=b;return Object.toQueryString(c)}}return''},getValue:function(a){a=$(a);var b=a.tagName.toLowerCase();return Form.Element.Serializers[b](a)},setValue:function(a,b){a=$(a);var c=a.tagName.toLowerCase();Form.Element.Serializers[c](a,b);return a},clear:function(a){$(a).value='';return a},present:function(a){return $(a).value!=''},activate:function(a){a=$(a);try{a.focus();if(a.select&&(a.tagName.toLowerCase()!='input'||!['button','reset','submit'].include(a.type)))a.select()}catch(e){}return a},disable:function(a){a=$(a);a.blur();a.disabled=true;return a},enable:function(a){a=$(a);a.disabled=false;return a}};var Field=Form.Element;var $F=Form.Element.Methods.getValue;Form.Element.Serializers={input:function(a,b){switch(a.type.toLowerCase()){case'checkbox':case'radio':return Form.Element.Serializers.inputSelector(a,b);default:return Form.Element.Serializers.textarea(a,b)}},inputSelector:function(a,b){if(b===undefined)return a.checked?a.value:null;else a.checked=!!b},textarea:function(a,b){if(b===undefined)return a.value;else a.value=b},select:function(a,b){if(b===undefined)return this[a.type=='select-one'?'selectOne':'selectMany'](a);else{var c,value,single=!Object.isArray(b);for(var i=0,length=a.length;i<length;i++){c=a.options[i];value=this.optionValue(c);if(single){if(value==b){c.selected=true;return}}else c.selected=b.include(value)}}},selectOne:function(a){var b=a.selectedIndex;return b>=0?this.optionValue(a.options[b]):null},selectMany:function(a){var b,length=a.length;if(!length)return null;for(var i=0,b=[];i<length;i++){var c=a.options[i];if(c.selected)b.push(this.optionValue(c))}return b},optionValue:function(a){return Element.extend(a).hasAttribute('value')?a.value:a.text}};Abstract.TimedObserver=Class.create(PeriodicalExecuter,{initialize:function($super,b,c,d){$super(d,c);this.element=$(b);this.lastValue=this.getValue()},execute:function(){var a=this.getValue();if(Object.isString(this.lastValue)&&Object.isString(a)?this.lastValue!=a:String(this.lastValue)!=String(a)){this.callback(this.element,a);this.lastValue=a}}});Form.Element.Observer=Class.create(Abstract.TimedObserver,{getValue:function(){return Form.Element.getValue(this.element)}});Form.Observer=Class.create(Abstract.TimedObserver,{getValue:function(){return Form.serialize(this.element)}});Abstract.EventObserver=Class.create({initialize:function(a,b){this.element=$(a);this.callback=b;this.lastValue=this.getValue();if(this.element.tagName.toLowerCase()=='form')this.registerFormCallbacks();else this.registerCallback(this.element)},onElementEvent:function(){var a=this.getValue();if(this.lastValue!=a){this.callback(this.element,a);this.lastValue=a}},registerFormCallbacks:function(){Form.getElements(this.element).each(this.registerCallback,this)},registerCallback:function(a){if(a.type){switch(a.type.toLowerCase()){case'checkbox':case'radio':Event.observe(a,'click',this.onElementEvent.bind(this));break;default:Event.observe(a,'change',this.onElementEvent.bind(this));break}}}});Form.Element.EventObserver=Class.create(Abstract.EventObserver,{getValue:function(){return Form.Element.getValue(this.element)}});Form.EventObserver=Class.create(Abstract.EventObserver,{getValue:function(){return Form.serialize(this.element)}});if(!window.Event)var Event={};Object.extend(Event,{KEY_BACKSPACE:8,KEY_TAB:9,KEY_RETURN:13,KEY_ESC:27,KEY_LEFT:37,KEY_UP:38,KEY_RIGHT:39,KEY_DOWN:40,KEY_DELETE:46,KEY_HOME:36,KEY_END:35,KEY_PAGEUP:33,KEY_PAGEDOWN:34,KEY_INSERT:45,cache:{},relatedTarget:function(a){var b;switch(a.type){case'mouseover':b=a.fromElement;break;case'mouseout':b=a.toElement;break;default:return null}return Element.extend(b)}});Event.Methods=(function(){var d;if(Prototype.Browser.IE){var e={0:1,1:4,2:2};d=function(a,b){return a.button==e[b]}}else if(Prototype.Browser.WebKit){d=function(a,b){switch(b){case 0:return a.which==1&&!a.metaKey;case 1:return a.which==1&&a.metaKey;default:return false}}}else{d=function(a,b){return a.which?(a.which===b+1):(a.button===b)}}return{isLeftClick:function(a){return d(a,0)},isMiddleClick:function(a){return d(a,1)},isRightClick:function(a){return d(a,2)},element:function(a){var b=Event.extend(a).target;return Element.extend(b.nodeType==Node.TEXT_NODE?b.parentNode:b)},findElement:function(a,b){var c=Event.element(a);return c.match(b)?c:c.up(b)},pointer:function(a){return{x:a.pageX||(a.clientX+(document.documentElement.scrollLeft||document.body.scrollLeft)),y:a.pageY||(a.clientY+(document.documentElement.scrollTop||document.body.scrollTop))}},pointerX:function(a){return Event.pointer(a).x},pointerY:function(a){return Event.pointer(a).y},stop:function(a){Event.extend(a);a.preventDefault();a.stopPropagation();a.stopped=true}}})();Event.extend=(function(){var c=Object.keys(Event.Methods).inject({},function(m,a){m[a]=Event.Methods[a].methodize();return m});if(Prototype.Browser.IE){Object.extend(c,{stopPropagation:function(){this.cancelBubble=true},preventDefault:function(){this.returnValue=false},inspect:function(){return"[object Event]"}});return function(a){if(!a)return false;if(a._extendedByPrototype)return a;a._extendedByPrototype=Prototype.emptyFunction;var b=Event.pointer(a);Object.extend(a,{target:a.srcElement,relatedTarget:Event.relatedTarget(a),pageX:b.x,pageY:b.y});return Object.extend(a,c)}}else{Event.prototype=Event.prototype||document.createEvent("HTMLEvents").__proto__;Object.extend(Event.prototype,c);return Prototype.K}})();Object.extend(Event,(function(){var h=Event.cache;function getEventID(a){if(a._eventID)return a._eventID;arguments.callee.id=arguments.callee.id||1;return a._eventID=++arguments.callee.id}function getDOMEventName(a){if(a&&a.include(':'))return"dataavailable";return a}function getCacheForID(a){return h[a]=h[a]||{}}function getWrappersForEventName(a,b){var c=getCacheForID(a);return c[b]=c[b]||[]}function createWrapper(b,d,e){var f=getEventID(b);var c=getWrappersForEventName(f,d);if(c.pluck("handler").include(e))return false;var g=function(a){if(!Event||!Event.extend||(a.eventName&&a.eventName!=d))return false;Event.extend(a);e.call(b,a)};g.handler=e;c.push(g);return g}function findWrapper(b,d,e){var c=getWrappersForEventName(b,d);return c.find(function(a){return a.handler==e})}function destroyWrapper(a,b,d){var c=getCacheForID(a);if(!c[b])return false;c[b]=c[b].without(findWrapper(a,b,d))}function destroyCache(){for(var a in h)for(var b in h[a])h[a][b]=null}if(window.attachEvent){window.attachEvent("onunload",destroyCache)}return{observe:function(a,b,c){a=$(a);var d=getDOMEventName(b);var e=createWrapper(a,b,c);if(!e)return a;if(a.addEventListener){a.addEventListener(d,e,false)}else{a.attachEvent("on"+d,e)}return a},stopObserving:function(b,c,d){b=$(b);var e=getEventID(b),name=getDOMEventName(c);if(!d&&c){getWrappersForEventName(e,c).each(function(a){b.stopObserving(c,a.handler)});return b}else if(!c){Object.keys(getCacheForID(e)).each(function(a){b.stopObserving(a)});return b}var f=findWrapper(e,c,d);if(!f)return b;if(b.removeEventListener){b.removeEventListener(name,f,false)}else{b.detachEvent("on"+name,f)}destroyWrapper(e,c,d);return b},fire:function(a,b,c){a=$(a);if(a==document&&document.createEvent&&!a.dispatchEvent)a=document.documentElement;if(document.createEvent){var d=document.createEvent("HTMLEvents");d.initEvent("dataavailable",true,true)}else{var d=document.createEventObject();d.eventType="ondataavailable"}d.eventName=b;d.memo=c||{};if(document.createEvent){a.dispatchEvent(d)}else{a.fireEvent(d.eventType,d)}return d}}})());Object.extend(Event,Event.Methods);Element.addMethods({fire:Event.fire,observe:Event.observe,stopObserving:Event.stopObserving});Object.extend(document,{fire:Element.Methods.fire.methodize(),observe:Element.Methods.observe.methodize(),stopObserving:Element.Methods.stopObserving.methodize()});(function(){var a,fired=false;function fireContentLoadedEvent(){if(fired)return;if(a)window.clearInterval(a);document.fire("dom:loaded");fired=true}if(document.addEventListener){if(Prototype.Browser.WebKit){a=window.setInterval(function(){if(/loaded|complete/.test(document.readyState))fireContentLoadedEvent()},0);Event.observe(window,"load",fireContentLoadedEvent)}else{document.addEventListener("DOMContentLoaded",fireContentLoadedEvent,false)}}else{document.write("<script id=__onDOMContentLoaded defer src=//:><\/script>");$("__onDOMContentLoaded").onreadystatechange=function(){if(this.readyState=="complete"){this.onreadystatechange=null;fireContentLoadedEvent()}}}})();Hash.toQueryString=Object.toQueryString;var Toggle={display:Element.toggle};Element.Methods.childOf=Element.Methods.descendantOf;var Insertion={Before:function(a,b){return Element.insert(a,{before:b})},Top:function(a,b){return Element.insert(a,{top:b})},Bottom:function(a,b){return Element.insert(a,{bottom:b})},After:function(a,b){return Element.insert(a,{after:b})}};var $continue=new Error('"throw $continue" is deprecated, use "return" instead');var Position={includeScrollOffsets:false,prepare:function(){this.deltaX=window.pageXOffset||document.documentElement.scrollLeft||document.body.scrollLeft||0;this.deltaY=window.pageYOffset||document.documentElement.scrollTop||document.body.scrollTop||0},within:function(a,x,y){if(this.includeScrollOffsets)return this.withinIncludingScrolloffsets(a,x,y);this.xcomp=x;this.ycomp=y;this.offset=Element.cumulativeOffset(a);return(y>=this.offset[1]&&y<this.offset[1]+a.offsetHeight&&x>=this.offset[0]&&x<this.offset[0]+a.offsetWidth)},withinIncludingScrolloffsets:function(a,x,y){var b=Element.cumulativeScrollOffset(a);this.xcomp=x+b[0]-this.deltaX;this.ycomp=y+b[1]-this.deltaY;this.offset=Element.cumulativeOffset(a);return(this.ycomp>=this.offset[1]&&this.ycomp<this.offset[1]+a.offsetHeight&&this.xcomp>=this.offset[0]&&this.xcomp<this.offset[0]+a.offsetWidth)},overlap:function(a,b){if(!a)return 0;if(a=='vertical')return((this.offset[1]+b.offsetHeight)-this.ycomp)/b.offsetHeight;if(a=='horizontal')return((this.offset[0]+b.offsetWidth)-this.xcomp)/b.offsetWidth},cumulativeOffset:Element.Methods.cumulativeOffset,positionedOffset:Element.Methods.positionedOffset,absolutize:function(a){Position.prepare();return Element.absolutize(a)},relativize:function(a){Position.prepare();return Element.relativize(a)},realOffset:Element.Methods.cumulativeScrollOffset,offsetParent:Element.Methods.getOffsetParent,page:Element.Methods.viewportOffset,clone:function(a,b,c){c=c||{};return Element.clonePosition(b,a,c)}};if(!document.getElementsByClassName)document.getElementsByClassName=function(f){function iter(a){return a.blank()?null:"[contains(concat(' ', @class, ' '), ' "+a+" ')]"}f.getElementsByClassName=Prototype.BrowserFeatures.XPath?function(a,b){b=b.toString().strip();var c=/\s/.test(b)?$w(b).map(iter).join(''):iter(b);return c?document._getElementsByXPath('.//*'+c,a):[]}:function(b,c){c=c.toString().strip();var d=[],classNames=(/\s/.test(c)?$w(c):null);if(!classNames&&!c)return d;var e=$(b).getElementsByTagName('*');c=' '+c+' ';for(var i=0,child,cn;child=e[i];i++){if(child.className&&(cn=' '+child.className+' ')&&(cn.include(c)||(classNames&&classNames.all(function(a){return!a.toString().blank()&&cn.include(' '+a+' ')}))))d.push(Element.extend(child))}return d};return function(a,b){return $(b||document.body).getElementsByClassName(a)}}(Element.Methods);Element.ClassNames=Class.create();Element.ClassNames.prototype={initialize:function(a){this.element=$(a)},_each:function(b){this.element.className.split(/\s+/).select(function(a){return a.length>0})._each(b)},set:function(a){this.element.className=a},add:function(a){if(this.include(a))return;this.set($A(this).concat(a).join(' '))},remove:function(a){if(!this.include(a))return;this.set($A(this).without(a).join(' '))},toString:function(){return $A(this).join(' ')}};Object.extend(Element.ClassNames.prototype,Enumerable);Element.addMethods();

// script.aculo.us builder.js v1.8.0, Tue Nov 06 15:01:40 +0300 2007

// Copyright (c) 2005-2007 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
//
// 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/

var Builder = {
  NODEMAP: {
    AREA: 'map',
    CAPTION: 'table',
    COL: 'table',
    COLGROUP: 'table',
    LEGEND: 'fieldset',
    OPTGROUP: 'select',
    OPTION: 'select',
    PARAM: 'object',
    TBODY: 'table',
    TD: 'table',
    TFOOT: 'table',
    TH: 'table',
    THEAD: 'table',
    TR: 'table'
  },
  // note: For Firefox < 1.5, OPTION and OPTGROUP tags are currently broken,
  //       due to a Firefox bug
  node: function(elementName) {
    elementName = elementName.toUpperCase();
    
    // try innerHTML approach
    var parentTag = this.NODEMAP[elementName] || 'div';
    var parentElement = document.createElement(parentTag);
    try { // prevent IE "feature": http://dev.rubyonrails.org/ticket/2707
      parentElement.innerHTML = "<" + elementName + "></" + elementName + ">";
    } catch(e) {}
    var element = parentElement.firstChild || null;
      
    // see if browser added wrapping tags
    if(element && (element.tagName.toUpperCase() != elementName))
      element = element.getElementsByTagName(elementName)[0];
    
    // fallback to createElement approach
    if(!element) element = document.createElement(elementName);
    
    // abort if nothing could be created
    if(!element) return;

    // attributes (or text)
    if(arguments[1])
      if(this._isStringOrNumber(arguments[1]) ||
        (arguments[1] instanceof Array) ||
        arguments[1].tagName) {
          this._children(element, arguments[1]);
        } else {
          var attrs = this._attributes(arguments[1]);
          if(attrs.length) {
            try { // prevent IE "feature": http://dev.rubyonrails.org/ticket/2707
              parentElement.innerHTML = "<" +elementName + " " +
                attrs + "></" + elementName + ">";
            } catch(e) {}
            element = parentElement.firstChild || null;
            // workaround firefox 1.0.X bug
            if(!element) {
              element = document.createElement(elementName);
              for(attr in arguments[1]) 
                element[attr == 'class' ? 'className' : attr] = arguments[1][attr];
            }
            if(element.tagName.toUpperCase() != elementName)
              element = parentElement.getElementsByTagName(elementName)[0];
          }
        } 

    // text, or array of children
    if(arguments[2])
      this._children(element, arguments[2]);

     return element;
  },
  _text: function(text) {
     return document.createTextNode(text);
  },

  ATTR_MAP: {
    'className': 'class',
    'htmlFor': 'for'
  },

  _attributes: function(attributes) {
    var attrs = [];
    for(attribute in attributes)
      attrs.push((attribute in this.ATTR_MAP ? this.ATTR_MAP[attribute] : attribute) +
          '="' + attributes[attribute].toString().escapeHTML().gsub(/"/,'&quot;') + '"');
    return attrs.join(" ");
  },
  _children: function(element, children) {
    if(children.tagName) {
      element.appendChild(children);
      return;
    }
    if(typeof children=='object') { // array can hold nodes and text
      children.flatten().each( function(e) {
        if(typeof e=='object')
          element.appendChild(e)
        else
          if(Builder._isStringOrNumber(e))
            element.appendChild(Builder._text(e));
      });
    } else
      if(Builder._isStringOrNumber(children))
        element.appendChild(Builder._text(children));
  },
  _isStringOrNumber: function(param) {
    return(typeof param=='string' || typeof param=='number');
  },
  build: function(html) {
    var element = this.node('div');
    $(element).update(html.strip());
    return element.down();
  },
  dump: function(scope) { 
    if(typeof scope != 'object' && typeof scope != 'function') scope = window; //global scope 
  
    var tags = ("A ABBR ACRONYM ADDRESS APPLET AREA B BASE BASEFONT BDO BIG BLOCKQUOTE BODY " +
      "BR BUTTON CAPTION CENTER CITE CODE COL COLGROUP DD DEL DFN DIR DIV DL DT EM FIELDSET " +
      "FONT FORM FRAME FRAMESET H1 H2 H3 H4 H5 H6 HEAD HR HTML I IFRAME IMG INPUT INS ISINDEX "+
      "KBD LABEL LEGEND LI LINK MAP MENU META NOFRAMES NOSCRIPT OBJECT OL OPTGROUP OPTION P "+
      "PARAM PRE Q S SAMP SCRIPT SELECT SMALL SPAN STRIKE STRONG STYLE SUB SUP TABLE TBODY TD "+
      "TEXTAREA TFOOT TH THEAD TITLE TR TT U UL VAR").split(/\s+/);
  
    tags.each( function(tag){ 
      scope[tag] = function() { 
        return Builder.node.apply(Builder, [tag].concat($A(arguments)));  
      } 
    });
  }
}


// script.aculo.us effects.js v1.7.1_beta1, Mon Mar 12 14:40:50 +0100 2007

// Copyright (c) 2005-2007 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) { }
};

/*--------------------------------------------------------------------------*/

Array.prototype.call = function() {
  var args = arguments;
  this.each(function(f){ f.apply(this, args) });
}

/*--------------------------------------------------------------------------*/

var Effect = {
  _elementDoesNotExistError: {
    name: 'ElementDoesNotExistError',
    message: 'The specified DOM element does not exist, but is required for this effect to operate'
  },
  tagifyText: function(element) {
    if(typeof Builder == 'undefined')
      throw("Effect.tagifyText requires including script.aculo.us' builder.js library");
      
    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(
            Builder.node('span',{style: tagifyStyle},
              character == ' ' ? String.fromCharCode(160) : character), 
              child);
        });
        Element.remove(child);
      }
    });
  },
  multiple: function(element, effect) {
    var elements;
    if(((typeof element == 'object') || 
        (typeof element == 'function')) && 
       (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);
  }
};

var Effect2 = Effect; // deprecated

/* ------------- transitions ------------- */

Effect.Transitions = {
  linear: Prototype.K,
  sinoidal: function(pos) {
    return (-Math.cos(pos*Math.PI)/2) + 0.5;
  },
  reverse: function(pos) {
    return 1-pos;
  },
  flicker: function(pos) {
    var pos = ((-Math.cos(pos*Math.PI)/4) + 0.75) + Math.random()/4;
    return (pos > 1 ? 1 : pos);
  },
  wobble: function(pos) {
    return (-Math.cos(pos*Math.PI*(9*pos))/2) + 0.5;
  },
  pulse: function(pos, pulses) { 
    pulses = pulses || 5; 
    return (
      Math.round((pos % (1/pulses)) * pulses) == 0 ? 
            ((pos * pulses * 2) - Math.floor(pos * pulses * 2)) : 
        1 - ((pos * pulses * 2) - Math.floor(pos * pulses * 2))
      );
  },
  none: function(pos) {
    return 0;
  },
  full: function(pos) {
    return 1;
  }
};

/* ------------- core effects ------------- */

Effect.ScopedQueue = Class.create();
Object.extend(Object.extend(Effect.ScopedQueue.prototype, 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 = (typeof effect.options.queue == 'string') ? 
      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(typeof queueName != 'string') return queueName;
    
    if(!this.instances[queueName])
      this.instances[queueName] = new Effect.ScopedQueue();
      
    return this.instances[queueName];
  }
}
Effect.Queue = Effect.Queues.get('global');

Effect.DefaultOptions = {
  transition: Effect.Transitions.sinoidal,
  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'
}

Effect.Base = function() {};
Effect.Base.prototype = {
  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.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;
    
    eval('this.render = function(pos){ '+
      'if(this.state=="idle"){this.state="running";'+
      codeForEvent(options,'beforeSetup')+
      (this.setup ? 'this.setup();':'')+ 
      codeForEvent(options,'afterSetup')+
      '};if(this.state=="running"){'+
      'pos=this.options.transition(pos)*'+this.fromToDelta+'+'+this.options.from+';'+
      'this.position=pos;'+
      codeForEvent(options,'beforeUpdate')+
      (this.update ? 'this.update(pos);':'')+
      codeForEvent(options,'afterUpdate')+
      '}}');
    
    this.event('beforeStart');
    if(!this.options.sync)
      Effect.Queues.get(typeof this.options.queue == 'string' ? 
        '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 = Math.round(pos * this.totalFrames);
      if(frame > this.currentFrame) {
        this.render(pos);
        this.currentFrame = frame;
      }
    }
  },
  cancel: function() {
    if(!this.options.sync)
      Effect.Queues.get(typeof this.options.queue == 'string' ? 
        '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(typeof this[property] != 'function') data[property] = this[property];
    return '#<Effect:' + data.inspect() + ',options:' + $H(this.options).inspect() + '>';
  }
}

Effect.Parallel = Class.create();
Object.extend(Object.extend(Effect.Parallel.prototype, Effect.Base.prototype), {
  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.Event = Class.create();
Object.extend(Object.extend(Effect.Event.prototype, Effect.Base.prototype), {
  initialize: function() {
    var options = Object.extend({
      duration: 0
    }, arguments[0] || {});
    this.start(options);
  },
  update: Prototype.emptyFunction
});

Effect.Opacity = Class.create();
Object.extend(Object.extend(Effect.Opacity.prototype, Effect.Base.prototype), {
  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();
Object.extend(Object.extend(Effect.Move.prototype, Effect.Base.prototype), {
  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() {
    // Bug in Opera: Opera returns the "real" position of a static element or
    // relative element that does not have top/left explicitly set.
    // ==> Always set top and left for position relative elements in your stylesheets 
    // (to 0 if you do not need them) 
    this.element.makePositioned();
    this.originalLeft = parseFloat(this.element.getStyle('left') || '0');
    this.originalTop  = parseFloat(this.element.getStyle('top')  || '0');
    if(this.options.mode == 'absolute') {
      // absolute movement, so we need to calc deltaX and deltaY
      this.options.x = this.options.x - this.originalLeft;
      this.options.y = this.options.y - this.originalTop;
    }
  },
  update: function(position) {
    this.element.setStyle({
      left: Math.round(this.options.x  * position + this.originalLeft) + 'px',
      top:  Math.round(this.options.y  * position + this.originalTop)  + '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();
Object.extend(Object.extend(Effect.Scale.prototype, Effect.Base.prototype), {
  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 = Math.round(width) + 'px';
    if(this.options.scaleY) d.height = Math.round(height) + '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();
Object.extend(Object.extend(Effect.Highlight.prototype, Effect.Base.prototype), {
  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+(Math.round(this._base[i]+(this._delta[i]*position)).toColorPart()); }.bind(this)) });
  },
  finish: function() {
    this.element.setStyle(Object.extend(this.oldStyle, {
      backgroundColor: this.options.restorecolor
    }));
  }
});

Effect.ScrollTo = Class.create();
Object.extend(Object.extend(Effect.ScrollTo.prototype, Effect.Base.prototype), {
  initialize: function(element) {
    this.element = $(element);
    this.start(arguments[1] || {});
  },
  setup: function() {
    Position.prepare();
    var offsets = Position.cumulativeOffset(this.element);
    if(this.options.offset) offsets[1] += this.options.offset;
    var max = window.innerHeight ? 
      window.height - window.innerHeight :
      document.body.scrollHeight - 
        (document.documentElement.clientHeight ? 
          document.documentElement.clientHeight : document.body.clientHeight);
    this.scrollStart = Position.deltaY;
    this.delta = (offsets[1] > max ? max : offsets[1]) - this.scrollStart;
  },
  update: function(position) {
    Position.prepare();
    window.scrollTo(Position.deltaX, 
      this.scrollStart + (position*this.delta));
  }
});

/* ------------- 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 oldStyle = {
    top: element.getStyle('top'),
    left: element.getStyle('left') };
    return new Effect.Move(element, 
      { x:  20, y: 0, duration: 0.05, afterFinishInternal: function(effect) {
    new Effect.Move(effect.element,
      { x: -40, y: 0, duration: 0.1,  afterFinishInternal: function(effect) {
    new Effect.Move(effect.element,
      { x:  40, y: 0, duration: 0.1,  afterFinishInternal: function(effect) {
    new Effect.Move(effect.element,
      { x: -40, y: 0, duration: 0.1,  afterFinishInternal: function(effect) {
    new Effect.Move(effect.element,
      { x:  40, y: 0, duration: 0.1,  afterFinishInternal: function(effect) {
    new Effect.Move(effect.element,
      { x: -20, y: 0, duration: 0.05, 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');
  return new Effect.Scale(element, window.opera ? 0 : 1,
   Object.extend({ scaleContent: false, 
    scaleX: false, 
    scaleMode: 'box',
    scaleFrom: 100,
    restoreAfterFinish: true,
    beforeStartInternal: 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().setStyle({bottom: oldInnerBottom});
      effect.element.down().undoPositioned();
    }
   }, 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] || {};
  var oldOpacity = element.getInlineOpacity();
  var transition = options.transition || Effect.Transitions.sinoidal;
  var reverser   = function(pos){ return transition(1-Effect.Transitions.pulse(pos, options.pulses)) };
  reverser.bind(transition);
  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();
Object.extend(Object.extend(Effect.Morph.prototype, Effect.Base.prototype), {
  initialize: function(element) {
    this.element = $(element);
    if(!this.element) throw(Effect._elementDoesNotExistError);
    var options = Object.extend({
      style: {}
    }, arguments[1] || {});
    if (typeof options.style == 'string') {
      if(options.style.indexOf(':') == -1) {
        var cssText = '', selector = '.' + options.style;
        $A(document.styleSheets).reverse().each(function(styleSheet) {
          if (styleSheet.cssRules) cssRules = styleSheet.cssRules;
          else if (styleSheet.rules) cssRules = styleSheet.rules;
          $A(cssRules).reverse().each(function(rule) {
            if (selector == rule.selectorText) {
              cssText = rule.style.cssText;
              throw $break;
            }
          });
          if (cssText) throw $break;
        });
        this.style = cssText.parseStyle();
        options.afterFinishInternal = function(effect){
          effect.element.addClassName(effect.options.style);
          effect.transforms.each(function(transform) {
            if(transform.style != 'opacity')
              effect.element.style[transform.style] = '';
          });
        }
      } else this.style = options.style.parseStyle();
    } else this.style = $H(options.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 + Math.round(
          ((transform.targetValue - transform.originalValue) * position) * 1000)/1000 + transform.unit;
    this.element.setStyle(style, true);
  }
});

Effect.Transform = Class.create();
Object.extend(Effect.Transform.prototype, {
  initialize: function(tracks){
    this.tracks  = [];
    this.options = arguments[1] || {};
    this.addTracks(tracks);
  },
  addTracks: function(tracks){
    tracks.each(function(track){
      var data = $H(track).values().first();
      this.tracks.push($H({
        ids:     $H(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 elements = [$(track.ids) || $$(track.ids)].flatten();
        return elements.map(function(e){ return new track.effect(e, Object.extend({ sync:true }, track.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.prototype.parseStyle = function(){
  var element = document.createElement('div');
  element.innerHTML = '<div style="' + this + '"></div>';
  var style = element.childNodes[0].style, styleRules = $H();
  
  Element.CSS_PROPERTIES.each(function(property){
    if(style[property]) styleRules[property] = style[property]; 
  });
  if(Prototype.Browser.IE && this.indexOf('opacity') > -1) {
    styleRules.opacity = this.match(/opacity:\s*((?:0|1)?(?:\.\d*)?)/)[1];
  }
  return styleRules;
};

Element.morph = function(element, style) {
  new Effect.Morph(element, Object.extend({ style: style }, arguments[2] || {}));
  return element;
};

['getInlineOpacity','forceRerendering','setContentZoom',
 'collectTextNodes','collectTextNodesIgnoreClass','morph'].each( 
  function(f) { Element.Methods[f] = Element[f]; }
);

Element.Methods.visualEffect = function(element, effect, options) {
  s = effect.dasherize().camelize();
  effect_class = s.charAt(0).toUpperCase() + s.substring(1);
  new Effect[effect_class](element, options);
  return $(element);
};

Element.addMethods();

//  Prototip 1.2.0_pre1 - 17-12-2007

//  Copyright (c) 2007 Nick Stakenburg (http://www.nickstakenburg.com)
//
//  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.

//  More information on this project:
//  http://www.nickstakenburg.com/projects/prototip/

var Prototip = {
  Version: '1.2.0_pre1',

  REQUIRED_Prototype: '1.6.0',
  REQUIRED_Scriptaculous: '1.8.0',

  start: function() {
    this.require('Prototype');
    Tips.initialize();
    Element.observe(window, 'unload', this.unload);
  },

  require: function(library) {
    if ((typeof window[library] == 'undefined') ||
      (this.convertVersionString(window[library].Version) < this.convertVersionString(this['REQUIRED_' + library])))
      throw('Prototip requires ' + library + ' >= ' + this['REQUIRED_' + library]);
  },

  convertVersionString: function(versionString) {
    var r = versionString.split('.');
    return parseInt(r[0])*100000 + parseInt(r[1])*1000 + parseInt(r[2]);
  },

  viewport: {
    getDimensions: function() {
      var dimensions = { };
      var B = Prototype.Browser;
      $w('width height').each(function(d) {
        var D = d.capitalize();
        dimensions[d] = (B.WebKit && !document.evaluate) ? self['inner' + D] :
          (B.Opera) ? document.body['client' + D] : document.documentElement['client' + D];
        });
      return dimensions;
    }
  },

  capture: function(func) {
    if (!Prototype.Browser.IE) {
      func = func.wrap(function(proceed, event) {
      var rel = event.relatedTarget, cur = event.currentTarget;
      if (rel && rel.nodeType == Node.TEXT_NODE) rel = rel.parentNode;
      if (rel && rel != cur && rel.descendantOf && !(rel.descendantOf(cur)))
        proceed(event);
      });
    }
    return func;
  },

  unload: function() { Tips.removeAll(); }
};

var Tips = {
  // Configuration
  closeButtons: false,
  zIndex: 1200,

  tips : [],
  visible : [],

  initialize: function() {
    this.zIndexTop = this.zIndex;
  },

  useEvent : (function(IE) { return {
    'mouseover': (IE ? 'mouseenter' : 'mouseover'),
    'mouseout': (IE ? 'mouseleave' : 'mouseout'),
    'mouseenter': (IE ? 'mouseenter' : 'mouseover'),
    'mouseleave': (IE ? 'mouseleave' : 'mouseout')
  };})(Prototype.Browser.IE),

  fixIE: (function(agent) {
    var version = new RegExp('MSIE ([\\d.]+)').exec(agent);
    return version ? (parseFloat(version[1]) <= 6) : false;
  })(navigator.userAgent),

  add: function(tip) {
    this.tips.push(tip);
  },

  remove: function(element) {
    var tip = this.tips.find(function(t){ return t.element == $(element); });
    if (tip) {
      tip.deactivate();
      if (tip.tooltip) {
        tip.wrapper.remove();
        if (Tips.fixIE) tip.iframeShim.remove();
      }
      this.tips = this.tips.without(tip);
    }
  },

  removeAll: function() {
    this.tips.each(function(tip) { this.remove(tip.element); }.bind(this));
  },

  raise: function(tip) {
    if (tip.highest) return;
    if (this.visible.length == 0) {
      this.zIndexTop = this.zIndex;
      for (var i=0;i<this.tips.length;i++) {
        this.tips[i].wrapper.style.zIndex = this.zIndex;
      }
    }
    tip.style.zIndex = this.zIndexTop++;
    for (var i=0;i<this.tips.length;i++) { this.tips[i].wrapper.highest = false; };
    tip.highest = true;
  },

  addVisibile: function(tip) {
    this.removeVisible(tip);
    this.visible.push(tip);
  },

  removeVisible: function(tip) {
    this.visible = this.visible.without(tip);
  }
};
Tips.initialize();

var Tip = Class.create({
  initialize: function(element, content) {
    this.element = $(element);
    Tips.remove(this.element);

    this.content = content;

    var isHooking = (arguments[2] && arguments[2].hook);
    var isShowOnClick = (arguments[2] && arguments[2].showOn == 'click');

    this.options = Object.extend({
      className: 'default',                 // see css, this will lead to .prototip .default
      closeButton: Tips.closeButtons,       // true, false
      delay: !isShowOnClick ? 0.2 : false,  // seconds before tooltip appears
      duration: 0.3,                        // duration of the effect
      effect: false,                        // false, 'appear' or 'blind'
      hideAfter: false,                     // second before hide after no hover/activity
      hideOn: 'mouseleave',                 // or any other event, false
      hook: false,                          // { element: topLeft|topRight|bottomLeft|bottomRight, tip: see element }
      offset: isHooking ? {x:0, y:0} : {x:16, y:16},
      fixed: isHooking ? true : false,      // follow the mouse if false
      showOn: 'mousemove',
      target: this.element,                 // or another element
      title: false,
      viewport: isHooking ? false : true    // keep within viewport if mouse is followed
    }, arguments[2] || {});

    this.target = $(this.options.target);

    this.setup();

    if (this.options.effect) {
      Prototip.require('Scriptaculous');
      this.queue = { position: 'end', limit: 1, scope: this.wrapper.identify() }
    }

    Tips.add(this);
    this.activate();
  },

  setup: function() {
    this.wrapper = new Element('div', { 'class' : 'prototip' }).setStyle({
      display: 'none', zIndex: Tips.zIndex });
    this.wrapper.identify();

    if (Tips.fixIE) {
      this.iframeShim = new Element('iframe', { 'class' : 'iframeShim', src: 'javascript:false;' }).setStyle({
        display: 'none', zIndex: Tips.zIndex - 1 });
    }

    this.tip = new Element('div', { 'class' : 'content' }).insert(this.content);
    this.tip.insert(new Element('div').setStyle({ clear: 'both' }));

    if (this.options.closeButton || (this.options.hideOn.element && this.options.hideOn.element == 'closeButton'))
      this.closeButton = new Element('a', { href: '#', 'class' : 'close' });
  },

  build: function() {
    if (Tips.fixIE) document.body.appendChild(this.iframeShim).setOpacity(0);

    // effects go smooth with extra wrapper
    var wrapper = 'wrapper';
    if (this.options.effect) {
      this.effectWrapper = this.wrapper.appendChild(new Element('div', { 'class' : 'effectWrapper' }));
      wrapper = 'effectWrapper';
    }

    this.tooltip = this[wrapper].appendChild(new Element('div', { 'class' : 'tooltip ' + this.options.className }));

    if (this.options.title || this.options.closeButton) {
      this.toolbar = this.tooltip.appendChild(new Element('div', { 'class' : 'toolbar' }));
      this.title = this.toolbar.appendChild(new Element('div', { 'class' : 'title' }).update(this.options.title || ' '));
    }

    this.tooltip.insert(this.tip);
    document.body.appendChild(this.wrapper);

    // fixate elements for better positioning and effects
    var fixate = (this.options.effect) ? [this.wrapper, this.effectWrapper]: [this.wrapper];
    if (Tips.fixIE) fixate.push(this.iframeShim);

    // fix width
    var fixedWidth = this.wrapper.getWidth();
    fixate.invoke('setStyle', { width: fixedWidth + 'px' });

    // make toolbar width fixed
    if(this.toolbar) {
      this.wrapper.setStyle({ visibility : 'hidden' }).show();
      this.toolbar.setStyle({ width: this.toolbar.getWidth() + 'px'});
      this.wrapper.hide().setStyle({ visibility : 'visible' });
    }

    // add close button
    if (this.closeButton)
      this.title.insert({ top: this.closeButton }).insert(new Element('div').setStyle({ clear: 'both' }));

    var fixedHeight = this.wrapper.getHeight();
    fixate.invoke('setStyle', { width: fixedWidth + 'px', height: fixedHeight + 'px' });

    this[this.options.effect ? wrapper : 'tooltip'].hide();
  },

  activate: function() {
    this.eventShow = this.showDelayed.bindAsEventListener(this);
    this.eventHide = this.hide.bindAsEventListener(this);

    // if fixed use mouseover instead of mousemove for less event calls
    if (this.options.fixed && this.options.showOn == 'mousemove') this.options.showOn = 'mouseover';

    if(this.options.showOn == this.options.hideOn) {
      this.eventToggle = this.toggle.bindAsEventListener(this);
      this.element.observe(this.options.showOn, this.eventToggle);
    }

    var hideOptions = {
      'element': this.eventToggle ? [] : [this.element],
      'target': this.eventToggle ? [] : [this.target],
      'tip': this.eventToggle ? [] : [this.wrapper],
      'closeButton': [],
      'none': []
    };
    var el = this.options.hideOn.element;
    this.hideElement = el || (!this.options.hideOn ? 'none' : 'element');
    this.hideTargets = hideOptions[this.hideElement];
    if (!this.hideTargets && el && Object.isString(el)) this.hideTargets = this.tip.select(el);

    var realEvent = {'mouseenter': 'mouseover', 'mouseleave': 'mouseout'};
    $w('show hide').each(function(e) {
      var E = e.capitalize();
      var event = (this.options[e + 'On'].event || this.options[e + 'On']);
      this[e + 'Action'] = event;
      if (['mouseenter', 'mouseleave', 'mouseover', 'mouseout'].include(event)) {
        this[e + 'Action'] = (Tips.useEvent[event] || event);
        this['event' + E] = Prototip.capture(this['event' + E]);
      }
    }.bind(this));

    if (!this.eventToggle) this.element.observe(this.options.showOn, this.eventShow);
    if (this.hideTargets) this.hideTargets.invoke('observe', this.hideAction, this.eventHide);

    // add postion observer to moving showOn click tips
    if (!this.options.fixed && this.options.showOn == 'click') {
      this.eventPosition = this.position.bindAsEventListener(this);
      this.element.observe('mousemove', this.eventPosition);
    }

    // close button
    this.buttonEvent = this.hide.wrap(function(proceed, event) {
      event.stop();
      proceed(event);
    }).bindAsEventListener(this);
    if (this.closeButton) this.closeButton.observe('click', this.buttonEvent);

    // delay timeout
    if (this.options.showOn != 'click' && (this.hideElement != 'element')) {
      this.eventCheckDelay = Prototip.capture(function() {
        this.clearTimer('show');
      }).bindAsEventListener(this);
      this.element.observe(Tips.useEvent['mouseout'], this.eventCheckDelay);
    }

    // activity (hideAfter, raise)
    var elements = [this.element, this.wrapper];
    this.activityEnter = Prototip.capture(function() {
      Tips.raise(this.wrapper);
      this.cancelHideAfter();
    }).bindAsEventListener(this);
    this.activityLeave = Prototip.capture(this.hideAfter).bindAsEventListener(this);
    elements.invoke('observe', Tips.useEvent['mouseover'], this.activityEnter);
    elements.invoke('observe', Tips.useEvent['mouseout'], this.activityLeave);
  },

  deactivate: function() {
    if(this.options.showOn == this.options.hideOn)
      this.element.stopObserving(this.options.showOn, this.eventToggle);
    else {
      this.element.stopObserving(this.options.showOn, this.eventShow);
      if (this.hideTargets) this.hideTargets.invoke('stopObserving');
    }

    if (this.eventPosition) this.element.stopObserving('mousemove', this.eventPosition);
    if (this.closeButton) this.closeButton.stopObserving();
    if (this.eventCheckDelay) this.element.stopObserving('mouseout', this.eventCheckDelay);
    this.wrapper.stopObserving();
    this.element.stopObserving(Tips.useEvent['mouseover'], this.activityEnter);
    this.element.stopObserving(Tips.useEvent['mouseout'], this.activityLeave);
  },

  showDelayed: function(event) {
    if (!this.tooltip) this.build();
    this.position(event); // follow mouse
    if (this.wrapper.visible()) return;

    this.clearTimer('show');
    this.showTimer = this.show.bind(this).delay(this.options.delay);
  },

  clearTimer: function(timer) {
    if (this[timer + 'Timer']) clearTimeout(this[timer + 'Timer']);
  },

  show: function() {
    if (this.wrapper.visible() && this.options.effect != 'appear') return;

    if (Tips.fixIE) this.iframeShim.show();
    Tips.addVisibile(this.wrapper);
    this.wrapper.show();

    if (!this.options.effect) this.tooltip.show();
    else {
      if (this.activeEffect) Effect.Queues.get(this.queue.scope).remove(this.activeEffect);
      this.activeEffect = Effect[Effect.PAIRS[this.options.effect][0]](this.effectWrapper,
        { duration: this.options.duration, queue: this.queue});
    }
  },

  hideAfter: function(event) {
    if (!this.options.hideAfter) return;
    this.cancelHideAfter();
    this.hideAfterTimer = this.hide.bind(this).delay(this.options.hideAfter);
  },

  cancelHideAfter: function() {
    if (this.options.hideAfter) this.clearTimer('hideAfter');
  },

  hide: function() {
    this.clearTimer('show');
    if(!this.wrapper.visible()) return;

    if (!this.options.effect) {
      if (Tips.fixIE) this.iframeShim.hide();
      this.tooltip.hide();
      this.wrapper.hide();
      Tips.removeVisible(this.wrapper);
    }
    else {
      if (this.activeEffect) Effect.Queues.get(this.queue.scope).remove(this.activeEffect);
      this.activeEffect = Effect[Effect.PAIRS[this.options.effect][1]](this.effectWrapper,
        { duration: this.options.duration, queue: this.queue, afterFinish: function() {
        if (Tips.fixIE) this.iframeShim.hide();
        this.wrapper.hide();
        Tips.removeVisible(this.wrapper);
      }.bind(this)});
    }
  },

  toggle: function(event) {
    if (this.wrapper && this.wrapper.visible()) this.hide(event);
    else this.showDelayed(event);
  },

  position: function(event) {
    Tips.raise(this.wrapper);

    var offset = {left: this.options.offset.x, top: this.options.offset.y};
    var targetPosition = Position.cumulativeOffset(this.target);
    var tipd = this.wrapper.getDimensions();
    var pos = { left: (this.options.fixed) ? targetPosition[0] : Event.pointerX(event),
      top: (this.options.fixed) ? targetPosition[1] : Event.pointerY(event) };

    // add offsets
    pos.left += offset.left;
    pos.top += offset.top;

    if (this.options.hook) {
      var dims = {target: this.target.getDimensions(), tip: tipd}
      var hooks = {target: Position.cumulativeOffset(this.target), tip: Position.cumulativeOffset(this.target)}

      for (var z in hooks) {
        switch (this.options.hook[z]) {
          case 'topRight':
            hooks[z][0] += dims[z].width;
            break;
          case 'topMiddle':
            hooks[z][0] += (dims[z].width / 2);
            break;
          case 'rightMiddle':
            hooks[z][0] += dims[z].width;
            hooks[z][1] += (dims[z].height / 2);
            break;
          case 'bottomLeft':
            hooks[z][1] += dims[z].height;
            break;
          case 'bottomRight':
            hooks[z][0] += dims[z].width;
            hooks[z][1] += dims[z].height;
            break;
          case 'bottomMiddle':
            hooks[z][0] += (dims[z].width / 2);
            hooks[z][1] += dims[z].height;
            break;
          case 'leftMiddle':
            hooks[z][1] += (dims[z].height / 2);
            break;
        }
      }

      // move based on hooks
      pos.left += -1*(hooks.tip[0] - hooks.target[0]);
      pos.top += -1*(hooks.tip[1] - hooks.target[1]);
    }

    // move tooltip when there is a different target
    if (!this.options.fixed && this.element !== this.target) {
      var elementPosition = Position.cumulativeOffset(this.element);
      pos.left += -1*(elementPosition[0] - targetPosition[0]);
      pos.top += -1*(elementPosition[1] - targetPosition[1]);
    }

    if (!this.options.fixed && this.options.viewport) {
      var scroll = document.viewport.getScrollOffsets();
      var viewport = Prototip.viewport.getDimensions();
      var pair = {left: 'width', top: 'height'};

      for(var z in pair) {
        if ((pos[z] + tipd[pair[z]] - scroll[z]) > viewport[pair[z]])
          pos[z] = pos[z] - tipd[pair[z]] - 2*offset[z];
      }
    }

    var setPos = { left: pos.left + 'px', top: pos.top + 'px' };
    this.wrapper.setStyle(setPos);
    if (Tips.fixIE) this.iframeShim.setStyle(setPos);
  }
});

Prototip.start();

/*
ModalBox - The pop-up window thingie with AJAX, based on prototype and script.aculo.us.

Copyright Andrey Okonetchnikov (andrej.okonetschnikow@gmail.com), 2006-2007
All rights reserved.
 
VERSION 1.5.5.1
Last Modified: 09/21/2007
*/

if (!window.Modalbox)
	var Modalbox = new Object();

Modalbox.Methods = {
	overrideAlert: false, // Override standard browser alert message with ModalBox
	focusableElements: new Array,
	options: {
		title: "ModalBox Window", // Title of the ModalBox window
		overlayClose: true, // Close modal box by clicking on overlay
		width: 500, // Default width in px
		height: 90, // Default height in px
		overlayOpacity: .75, // Default overlay opacity
		overlayDuration: .25, // Default overlay fade in/out duration in seconds
		slideDownDuration: .5, // Default Modalbox appear slide down effect in seconds
		slideUpDuration: .15, // Default Modalbox hiding slide up effect in seconds
		resizeDuration: .2, // Default resize duration seconds
		inactiveFade: true, // Fades MB window on inactive state
		transitions: true, // Toggles transition effects. Transitions are enabled by default
		loadingString: "Please wait. Loading...", // Default loading string message
		closeString: "Close window", // Default title attribute for close window link
		params: {},
		method: 'get' // Default Ajax request method
	},
	_options: new Object,
	
	setOptions: function(options) {
		Object.extend(this.options, options || {});
	},
	
	_init: function(options) {
		// Setting up original options with default options
		Object.extend(this._options, this.options);
		this.setOptions(options);
		//Create the overlay
		this.MBoverlay = Builder.node("div", { id: "MB_overlay", opacity: "0" });
		//Create the window
		this.MBwindow = Builder.node("div", {id: "MB_window", style: "display: none"}, [
			this.MBframe = Builder.node("div", {id: "MB_frame"}, [
				this.MBheader = Builder.node("div", {id: "MB_header"}, [
					this.MBcaption = Builder.node("div", {id: "MB_caption"}),
					this.MBclose = Builder.node("a", {id: "MB_close", title: this.options.closeString, href: "#"}, [
						Builder.build("<span>Close Window</span>"),
					]),
				]),
				this.MBcontent = Builder.node("div", {id: "MB_content"}, [
					this.MBloading = Builder.node("div", {id: "MB_loading"}, this.options.loadingString),
				]),
			]),
		]);
		
		// If title isn't given, the header will not displayed 
		if(!this.options.title) this.MBheader.hide();
		
		// Inserting into DOM
		document.body.insertBefore(this.MBwindow, document.body.childNodes[0]);
		document.body.insertBefore(this.MBoverlay, document.body.childNodes[0]);
		
		// Initial scrolling position of the window. To be used for remove scrolling effect during ModalBox appearing
		this.initScrollX = window.pageXOffset || document.body.scrollLeft || document.documentElement.scrollLeft;
		this.initScrollY = window.pageYOffset || document.body.scrollTop || document.documentElement.scrollTop;
		
		//Adding event observers
		this.hide = this.hide.bindAsEventListener(this);
		this.close = this._hide.bindAsEventListener(this);
		this.kbdHandler = this.kbdHandler.bindAsEventListener(this);
		this._initObservers();

		this.initialized = true; // Mark as initialized
		this.active = true; // Mark as active
		this.currFocused = 0;
	},
	
	show: function(content, options) {
		if(!this.initialized) this._init(options); // Check for is already initialized
		
		this.content = content;
		this.setOptions(options);
		
		Element.update(this.MBcaption, this.options.title); // Updating title of the MB
		
		if(this.MBwindow.style.display == "none") { // First modal box appearing
			this._appear();
			this.event("onShow"); // Passing onShow callback
		}
		else { // If MB already on the screen, update it
			this._update();
			this.event("onUpdate"); // Passing onUpdate callback
		} 
	},
	
	hide: function(options) { // External hide method to use from external HTML and JS
		if(this.initialized) {
			if(options) Object.extend(this.options, options); // Passing callbacks
			if(this.options.transitions)
				Effect.SlideUp(this.MBwindow, { duration: this.options.slideUpDuration, afterFinish: this._deinit.bind(this) } );
			else {
				Element.hide(this.MBwindow);
				this._deinit();
			}
		} else throw("Modalbox isn't initialized");
	},
	
	alert: function(message){
		var html = '<div class="MB_alert"><p>' + message + '</p><input type="button" onclick="Modalbox.hide()" value="OK" /></div>';
		Modalbox.show(html, {title: 'Alert: ' + document.title, width: 300});
	},
		
	_hide: function(event) { // Internal hide method to use inside MB class
		if(event) Event.stop(event);
		this.hide();
	},
	
	_appear: function() { // First appearing of MB
		if(navigator.appVersion.match(/\bMSIE\b/))
			this._toggleSelects();
		this._setOverlay();
		this._setWidth();
		this._setPosition();
		if(this.options.transitions) {
			Element.setStyle(this.MBoverlay, {opacity: 0});
			new Effect.Fade(this.MBoverlay, {
					from: 0, 
					to: this.options.overlayOpacity, 
					duration: this.options.overlayDuration, 
					afterFinish: function() {
						new Effect.SlideDown(this.MBwindow, {
							duration: this.options.slideDownDuration, 
							afterFinish: function(){ 
								this._setPosition(); 
								this.loadContent();
							}.bind(this)
						});
					}.bind(this)
			});
		} else {
			Element.setStyle(this.MBoverlay, {opacity: this.options.overlayOpacity});
			Element.show(this.MBwindow);
			this._setPosition(); 
			this.loadContent();
		}
		this._setWidthAndPosition = this._setWidthAndPosition.bindAsEventListener(this);
		Event.observe(window, "resize", this._setWidthAndPosition);
	},
	
	resize: function(byWidth, byHeight, options) { // Change size of MB without loading content
		var wHeight = Element.getHeight(this.MBwindow);
		var wWidth = Element.getWidth(this.MBwindow);
		var hHeight = Element.getHeight(this.MBheader);
		var cHeight = Element.getHeight(this.MBcontent);
		var newHeight = ((wHeight - hHeight + byHeight) < cHeight) ? (cHeight + hHeight - wHeight) : byHeight;
		this.setOptions(options); // Passing callbacks
		if(this.options.transitions) {
			new Effect.ScaleBy(this.MBwindow, byWidth, newHeight, {
					duration: this.options.resizeDuration, 
				  	afterFinish: function() { 
						this.event("_afterResize"); // Passing internal callback
						this.event("afterResize"); // Passing callback
					}.bind(this)
				});
		} else {
			this.MBwindow.setStyle({width: wWidth + byWidth + "px", height: wHeight + newHeight + "px"});
			setTimeout(function() {
				this.event("_afterResize"); // Passing internal callback
				this.event("afterResize"); // Passing callback
			}.bind(this), 1);
			
		}
		
	},
	
	_update: function() { // Updating MB in case of wizards
		Element.update(this.MBcontent, "");
		this.MBcontent.appendChild(this.MBloading);
		Element.update(this.MBloading, this.options.loadingString);
		this.currentDims = [this.MBwindow.offsetWidth, this.MBwindow.offsetHeight];
		Modalbox.resize((this.options.width - this.currentDims[0]), (this.options.height - this.currentDims[1]), {_afterResize: this._loadAfterResize.bind(this) });
	},
	
	loadContent: function () {
		if(this.event("beforeLoad") != false) { // If callback passed false, skip loading of the content
			if(typeof this.content == 'string') {
				
				var htmlRegExp = new RegExp(/<\/?[^>]+>/gi);
				if(htmlRegExp.test(this.content)) { // Plain HTML given as a parameter
					this._insertContent(this.content);
					this._putContent();
				} else 
					new Ajax.Request( this.content, { method: this.options.method.toLowerCase(), parameters: this.options.params, 
						onComplete: function(transport) {
							var response = new String(transport.responseText);
							this._insertContent(transport.responseText.stripScripts());
							response.extractScripts().map(function(script) { 
								return eval(script.replace("<!--", "").replace("// -->", ""));
							}.bind(window));
							this._putContent();
						}.bind(this)
					});
					
			} else if (typeof this.content == 'object') {// HTML Object is given
				this._insertContent(this.content);
				this._putContent();
			} else {
				Modalbox.hide();
				throw('Please specify correct URL or HTML element (plain HTML or object)');
			}
		}
	},
	
	_insertContent: function(content){
		Element.extend(this.MBcontent);
		this.MBcontent.update("");
		if(typeof content == 'string')
			this.MBcontent.hide().update(content);
		else if (typeof this.content == 'object') { // HTML Object is given
			var _htmlObj = content.cloneNode(true); // If node already a part of DOM we'll clone it
			// If clonable element has ID attribute defined, modifying it to prevent duplicates
			if(this.content.id) this.content.id = "MB_" + this.content.id;
			/* Add prefix for IDs on all elements inside the DOM node */
			this.content.getElementsBySelector('*[id]').each(function(el){ el.id = "MB_" + el.id });
			this.MBcontent.hide().appendChild(_htmlObj);
			this.MBcontent.down().show(); // Toggle visibility for hidden nodes
			if(navigator.appVersion.match(/\bMSIE\b/)) // Toggling back visibility for hidden selects in IE
				$$("#MB_content select").invoke('setStyle', {'visibility': ''});
		}
	},
	
	_putContent: function(){
		// Prepare and resize modal box for content
		if(this.options.height == this._options.height)
			Modalbox.resize(0, this.MBcontent.getHeight() - Element.getHeight(this.MBwindow) + Element.getHeight(this.MBheader), {
				afterResize: function(){
					this.MBcontent.show();
					this.focusableElements = this._findFocusableElements();
					this._setFocus(); // Setting focus on first 'focusable' element in content (input, select, textarea, link or button)
					this.event("afterLoad"); // Passing callback
				}.bind(this)
			});
		else { // Height is defined. Creating a scrollable window
			this._setWidth();
			this.MBcontent.setStyle({overflow: 'auto', height: Element.getHeight(this.MBwindow) - Element.getHeight(this.MBheader) - 13 + 'px'});
			this.MBcontent.show();
			this.focusableElements = this._findFocusableElements();
			this._setFocus(); // Setting focus on first 'focusable' element in content (input, select, textarea, link or button)
			this.event("afterLoad"); // Passing callback
		}
	},
	
	activate: function(options){
		this.setOptions(options);
		this.active = true;
		Event.observe(this.MBclose, "click", this.close);
		if(this.options.overlayClose) Event.observe(this.MBoverlay, "click", this.hide);
		Element.show(this.MBclose);
		if(this.options.transitions && this.options.inactiveFade) new Effect.Appear(this.MBwindow, {duration: this.options.slideUpDuration});
	},
	
	deactivate: function(options) {
		this.setOptions(options);
		this.active = false;
		Event.stopObserving(this.MBclose, "click", this.close);
		if(this.options.overlayClose) Event.stopObserving(this.MBoverlay, "click", this.hide);
		Element.hide(this.MBclose);
		if(this.options.transitions && this.options.inactiveFade) new Effect.Fade(this.MBwindow, {duration: this.options.slideUpDuration, to: .75});
	},
	
	_initObservers: function(){
		Event.observe(this.MBclose, "click", this.close);
		if(this.options.overlayClose) Event.observe(this.MBoverlay, "click", this.hide);
		Event.observe(document, "keypress", Modalbox.kbdHandler );
	},
	
	_removeObservers: function(){
		Event.stopObserving(this.MBclose, "click", this.close);
		if(this.options.overlayClose) Event.stopObserving(this.MBoverlay, "click", this.hide);
		Event.stopObserving(document, "keypress", Modalbox.kbdHandler );
	},
	
	_loadAfterResize: function() {
		this._setWidth();
		this._setPosition();
		this.loadContent();
	},
	
	_setFocus: function() { // Setting focus to be looped inside current MB
		if(this.focusableElements.length > 0) {
			var i = 0;
			var firstEl = this.focusableElements.find(function (el){
				i++;
				return el.tabIndex == 1;
			}) || this.focusableElements.first();
			this.currFocused = (i == this.focusableElements.length - 1) ? (i-1) : 0;
			firstEl.focus(); // Focus on first focusable element except close button
		} else
			$("MB_close").focus(); // If no focusable elements exist focus on close button
	},
	
	_findFocusableElements: function(){ // Collect form elements or links from MB content
		var els = this.MBcontent.getElementsBySelector('input:not([type~=hidden]), select, textarea, button, a[href]');
		els.invoke('addClassName', 'MB_focusable');
		return this.MBcontent.getElementsByClassName('MB_focusable');
	},
	
	kbdHandler: function(e) {
		var node = Event.element(e);
		switch(e.keyCode) {
			case Event.KEY_TAB:
				Event.stop(e);
				if(!e.shiftKey) { //Focusing in direct order
					if(this.currFocused == this.focusableElements.length - 1) {
						this.focusableElements.first().focus();
						this.currFocused = 0;
					} else {
						this.currFocused++;
						this.focusableElements[this.currFocused].focus();
					}
				} else { // Shift key is pressed. Focusing in reverse order
					if(this.currFocused == 0) {
						this.focusableElements.last().focus();
						this.currFocused = this.focusableElements.length - 1;
					} else {
						this.currFocused--;
						this.focusableElements[this.currFocused].focus();
					}
				}
				break;			
			case Event.KEY_ESC:
				if(this.active) this._hide(e);
				break;
			case 32:
				this._preventScroll(e);
				break;
			case 0: // For Gecko browsers compatibility
				if(e.which == 32) this._preventScroll(e);
				break;
			case Event.KEY_UP:
			case Event.KEY_DOWN:
			case Event.KEY_PAGEDOWN:
			case Event.KEY_PAGEUP:
			case Event.KEY_HOME:
			case Event.KEY_END:
				// Safari operates in slightly different way. This realization is still buggy in Safari.
				if(/Safari|KHTML/.test(navigator.userAgent) && !["textarea", "select"].include(node.tagName.toLowerCase()))
					Event.stop(e);
				else if( (node.tagName.toLowerCase() == "input" && ["submit", "button"].include(node.type)) || (node.tagName.toLowerCase() == "a") )
					Event.stop(e);
				break;
		}
	},
	
	_preventScroll: function(event) { // Disabling scrolling by "space" key
		if(!["input", "textarea", "select", "button"].include(Event.element(event).tagName.toLowerCase())) 
			Event.stop(event);
	},
	
	_deinit: function()
	{	
		this._removeObservers();
		Event.stopObserving(window, "resize", this._setWidthAndPosition );
		if(this.options.transitions) {
			Effect.toggle(this.MBoverlay, 'appear', {duration: this.options.overlayDuration, afterFinish: this._removeElements.bind(this) });
		} else {
			this.MBoverlay.hide();
			this._removeElements();
		}
		Element.setStyle(this.MBcontent, {overflow: '', height: ''});
	},
	
	_removeElements: function () {
		if(navigator.appVersion.match(/\bMSIE\b/)) {
			this._prepareIE("", ""); // If set to auto MSIE will show horizontal scrolling
			window.scrollTo(this.initScrollX, this.initScrollY);
		}
		Element.remove(this.MBoverlay);
		Element.remove(this.MBwindow);
		
		/* Replacing prefixes 'MB_' in IDs for the original content */
		if(typeof this.content == 'object' && this.content.id && this.content.id.match(/MB_/)) {
			this.content.getElementsBySelector('*[id]').each(function(el){ el.id = el.id.replace(/MB_/, ""); });
			this.content.id = this.content.id.replace(/MB_/, "");
		}
		/* Initialized will be set to false */
		this.initialized = false;
		
		if(navigator.appVersion.match(/\bMSIE\b/))
			this._toggleSelects(); // Toggle back 'select' elements in IE
		this.event("afterHide"); // Passing afterHide callback
		this.setOptions(this._options); //Settings options object into intial state
	},
	
	_setOverlay: function () {
		if(navigator.appVersion.match(/\bMSIE\b/)) {
			this._prepareIE("100%", "hidden");
			if (!navigator.appVersion.match(/\b7.0\b/)) window.scrollTo(0,0); // Disable scrolling on top for IE7
		}
	},
	
	_setWidth: function () { //Set size
		Element.setStyle(this.MBwindow, {width: this.options.width + "px", height: this.options.height + "px"});
	},
	
	_setPosition: function () {
		Element.setStyle(this.MBwindow, {left: Math.round((Element.getWidth(document.body) - Element.getWidth(this.MBwindow)) / 2 ) + "px"});
	},
	
	_setWidthAndPosition: function () {
		Element.setStyle(this.MBwindow, {width: this.options.width + "px"});
		this._setPosition();
	},
	
	_getScrollTop: function () { //From: http://www.quirksmode.org/js/doctypes.html
		var theTop;
		if (document.documentElement && document.documentElement.scrollTop)
			theTop = document.documentElement.scrollTop;
		else if (document.body)
			theTop = document.body.scrollTop;
		return theTop;
	},
	// For IE browsers -- IE requires height to 100% and overflow hidden (taken from lightbox)
	_prepareIE: function(height, overflow){
		var body = document.getElementsByTagName('body')[0];
		body.style.height = height;
		body.style.overflow = overflow;
  
		var html = document.getElementsByTagName('html')[0];
		html.style.height = height;
		html.style.overflow = overflow; 
	},
	// For IE browsers -- hiding all SELECT elements
	_toggleSelects: function() {
		var selects = $$("select");
		if(this.initialized) {
			selects.invoke('setStyle', {'visibility': 'hidden'});
		} else {
			selects.invoke('setStyle', {'visibility': ''});
		}
			
	},
	event: function(eventName) {
		if(this.options[eventName]) {
			var returnValue = this.options[eventName](); // Executing callback
			this.options[eventName] = null; // Removing callback after execution
			if(returnValue != undefined) 
				return returnValue;
			else 
				return true;
		}
		return true;
	}
}

Object.extend(Modalbox, Modalbox.Methods);

if(Modalbox.overrideAlert) window.alert = Modalbox.alert;

Effect.ScaleBy = Class.create();
Object.extend(Object.extend(Effect.ScaleBy.prototype, Effect.Base.prototype), {
  initialize: function(element, byWidth, byHeight, options) {
    this.element = $(element)
    var options = Object.extend({
	  scaleFromTop: true,
      scaleMode: 'box',        // 'box' or 'contents' or {} with provided values
      scaleByWidth: byWidth,
	  scaleByHeight: byHeight
    }, arguments[3] || {});
    this.start(options);
  },
  setup: function() {
    this.elementPositioning = this.element.getStyle('position');
      
    this.originalTop  = this.element.offsetTop;
    this.originalLeft = this.element.offsetLeft;
	
    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];
	  
	this.deltaY = this.options.scaleByHeight;
	this.deltaX = this.options.scaleByWidth;
  },
  update: function(position) {
    var currentHeight = this.dims[0] + (this.deltaY * position);
	var currentWidth = this.dims[1] + (this.deltaX * position);
	
	currentHeight = (currentHeight > 0) ? currentHeight : 0;
	currentWidth = (currentWidth > 0) ? currentWidth : 0;
	
    this.setDimensions(currentHeight, currentWidth);
  },

  setDimensions: function(height, width) {
    var d = {};
    d.width = width + 'px';
    d.height = height + 'px';
    
	var topd  = Math.round((height - this.dims[0])/2);
	var leftd = Math.round((width  - this.dims[1])/2);
	if(this.elementPositioning == 'absolute' || this.elementPositioning == 'fixed') {
		if(!this.options.scaleFromTop) d.top = this.originalTop-topd + 'px';
		d.left = this.originalLeft-leftd + 'px';
	} else {
		if(!this.options.scaleFromTop) d.top = -topd + 'px';
		d.left = -leftd + 'px';
	}
    this.element.setStyle(d);
  }
});

// script.aculo.us slider.js v1.8.0, Tue Nov 06 15:01:40 +0300 2007

// Copyright (c) 2005-2007 Marty Haught, Thomas Fuchs 
//
// 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/

if (!Control) var Control = { };

// options:
//  axis: 'vertical', or 'horizontal' (default)
//
// callbacks:
//  onChange(value)
//  onSlide(value)
Control.Slider = Class.create({
  initialize: function(handle, track, options) {
    var slider = this;
    
    if (Object.isArray(handle)) {
      this.handles = handle.collect( function(e) { return $(e) });
    } else {
      this.handles = [$(handle)];
    }
    
    this.track   = $(track);
    this.options = options || { };

    this.axis      = this.options.axis || 'horizontal';
    this.increment = this.options.increment || 1;
    this.step      = parseInt(this.options.step || '1');
    this.range     = this.options.range || $R(0,1);
    
    this.value     = 0; // assure backwards compat
    this.values    = this.handles.map( function() { return 0 });
    this.spans     = this.options.spans ? this.options.spans.map(function(s){ return $(s) }) : false;
    this.options.startSpan = $(this.options.startSpan || null);
    this.options.endSpan   = $(this.options.endSpan || null);

    this.restricted = this.options.restricted || false;

    this.maximum   = this.options.maximum || this.range.end;
    this.minimum   = this.options.minimum || this.range.start;

    // Will be used to align the handle onto the track, if necessary
    this.alignX = parseInt(this.options.alignX || '0');
    this.alignY = parseInt(this.options.alignY || '0');
    
    this.trackLength = this.maximumOffset() - this.minimumOffset();

    this.handleLength = this.isVertical() ? 
      (this.handles[0].offsetHeight != 0 ? 
        this.handles[0].offsetHeight : this.handles[0].style.height.replace(/px$/,"")) : 
      (this.handles[0].offsetWidth != 0 ? this.handles[0].offsetWidth : 
        this.handles[0].style.width.replace(/px$/,""));

    this.active   = false;
    this.dragging = false;
    this.disabled = false;

    if (this.options.disabled) this.setDisabled();

    // Allowed values array
    this.allowedValues = this.options.values ? this.options.values.sortBy(Prototype.K) : false;
    if (this.allowedValues) {
      this.minimum = this.allowedValues.min();
      this.maximum = this.allowedValues.max();
    }

    this.eventMouseDown = this.startDrag.bindAsEventListener(this);
    this.eventMouseUp   = this.endDrag.bindAsEventListener(this);
    this.eventMouseMove = this.update.bindAsEventListener(this);

    // Initialize handles in reverse (make sure first handle is active)
    this.handles.each( function(h,i) {
      i = slider.handles.length-1-i;
      slider.setValue(parseFloat(
        (Object.isArray(slider.options.sliderValue) ? 
          slider.options.sliderValue[i] : slider.options.sliderValue) || 
         slider.range.start), i);
      h.makePositioned().observe("mousedown", slider.eventMouseDown);
    });
    
    this.track.observe("mousedown", this.eventMouseDown);
    document.observe("mouseup", this.eventMouseUp);
    document.observe("mousemove", this.eventMouseMove);
    
    this.initialized = true;
  },
  dispose: function() {
    var slider = this;    
    Event.stopObserving(this.track, "mousedown", this.eventMouseDown);
    Event.stopObserving(document, "mouseup", this.eventMouseUp);
    Event.stopObserving(document, "mousemove", this.eventMouseMove);
    this.handles.each( function(h) {
      Event.stopObserving(h, "mousedown", slider.eventMouseDown);
    });
  },
  setDisabled: function(){
    this.disabled = true;
  },
  setEnabled: function(){
    this.disabled = false;
  },  
  getNearestValue: function(value){
    if (this.allowedValues){
      if (value >= this.allowedValues.max()) return(this.allowedValues.max());
      if (value <= this.allowedValues.min()) return(this.allowedValues.min());
      
      var offset = Math.abs(this.allowedValues[0] - value);
      var newValue = this.allowedValues[0];
      this.allowedValues.each( function(v) {
        var currentOffset = Math.abs(v - value);
        if (currentOffset <= offset){
          newValue = v;
          offset = currentOffset;
        } 
      });
      return newValue;
    }
    if (value > this.range.end) return this.range.end;
    if (value < this.range.start) return this.range.start;
    return value;
  },
  setValue: function(sliderValue, handleIdx){
    if (!this.active) {
      this.activeHandleIdx = handleIdx || 0;
      this.activeHandle    = this.handles[this.activeHandleIdx];
      this.updateStyles();
    }
    handleIdx = handleIdx || this.activeHandleIdx || 0;
    if (this.initialized && this.restricted) {
      if ((handleIdx>0) && (sliderValue<this.values[handleIdx-1]))
        sliderValue = this.values[handleIdx-1];
      if ((handleIdx < (this.handles.length-1)) && (sliderValue>this.values[handleIdx+1]))
        sliderValue = this.values[handleIdx+1];
    }
    sliderValue = this.getNearestValue(sliderValue);
    this.values[handleIdx] = sliderValue;
    this.value = this.values[0]; // assure backwards compat
    
    this.handles[handleIdx].style[this.isVertical() ? 'top' : 'left'] = 
      this.translateToPx(sliderValue);
    
    this.drawSpans();
    if (!this.dragging || !this.event) this.updateFinished();
  },
  setValueBy: function(delta, handleIdx) {
    this.setValue(this.values[handleIdx || this.activeHandleIdx || 0] + delta, 
      handleIdx || this.activeHandleIdx || 0);
  },
  translateToPx: function(value) {
    return Math.round(
      ((this.trackLength-this.handleLength)/(this.range.end-this.range.start)) * 
      (value - this.range.start)) + "px";
  },
  translateToValue: function(offset) {
    return ((offset/(this.trackLength-this.handleLength) * 
      (this.range.end-this.range.start)) + this.range.start);
  },
  getRange: function(range) {
    var v = this.values.sortBy(Prototype.K); 
    range = range || 0;
    return $R(v[range],v[range+1]);
  },
  minimumOffset: function(){
    return(this.isVertical() ? this.alignY : this.alignX);
  },
  maximumOffset: function(){
    return(this.isVertical() ? 
      (this.track.offsetHeight != 0 ? this.track.offsetHeight :
        this.track.style.height.replace(/px$/,"")) - this.alignY : 
      (this.track.offsetWidth != 0 ? this.track.offsetWidth : 
        this.track.style.width.replace(/px$/,"")) - this.alignX);
  },  
  isVertical:  function(){
    return (this.axis == 'vertical');
  },
  drawSpans: function() {
    var slider = this;
    if (this.spans)
      $R(0, this.spans.length-1).each(function(r) { slider.setSpan(slider.spans[r], slider.getRange(r)) });
    if (this.options.startSpan)
      this.setSpan(this.options.startSpan,
        $R(0, this.values.length>1 ? this.getRange(0).min() : this.value ));
    if (this.options.endSpan)
      this.setSpan(this.options.endSpan, 
        $R(this.values.length>1 ? this.getRange(this.spans.length-1).max() : this.value, this.maximum));
  },
  setSpan: function(span, range) {
    if (this.isVertical()) {
      span.style.top = this.translateToPx(range.start);
      span.style.height = this.translateToPx(range.end - range.start + this.range.start);
    } else {
      span.style.left = this.translateToPx(range.start);
      span.style.width = this.translateToPx(range.end - range.start + this.range.start);
    }
  },
  updateStyles: function() {
    this.handles.each( function(h){ Element.removeClassName(h, 'selected') });
    Element.addClassName(this.activeHandle, 'selected');
  },
  startDrag: function(event) {
    if (Event.isLeftClick(event)) {
      if (!this.disabled){
        this.active = true;
        
        var handle = Event.element(event);
        var pointer  = [Event.pointerX(event), Event.pointerY(event)];
        var track = handle;
        if (track==this.track) {
          var offsets  = Position.cumulativeOffset(this.track); 
          this.event = event;
          this.setValue(this.translateToValue( 
           (this.isVertical() ? pointer[1]-offsets[1] : pointer[0]-offsets[0])-(this.handleLength/2)
          ));
          var offsets  = Position.cumulativeOffset(this.activeHandle);
          this.offsetX = (pointer[0] - offsets[0]);
          this.offsetY = (pointer[1] - offsets[1]);
        } else {
          // find the handle (prevents issues with Safari)
          while((this.handles.indexOf(handle) == -1) && handle.parentNode) 
            handle = handle.parentNode;
            
          if (this.handles.indexOf(handle)!=-1) {
            this.activeHandle    = handle;
            this.activeHandleIdx = this.handles.indexOf(this.activeHandle);
            this.updateStyles();
            
            var offsets  = Position.cumulativeOffset(this.activeHandle);
            this.offsetX = (pointer[0] - offsets[0]);
            this.offsetY = (pointer[1] - offsets[1]);
          }
        }
      }
      Event.stop(event);
    }
  },
  update: function(event) {
   if (this.active) {
      if (!this.dragging) this.dragging = true;
      this.draw(event);
      if (Prototype.Browser.WebKit) window.scrollBy(0,0);
      Event.stop(event);
   }
  },
  draw: function(event) {
    var pointer = [Event.pointerX(event), Event.pointerY(event)];
    var offsets = Position.cumulativeOffset(this.track);
    pointer[0] -= this.offsetX + offsets[0];
    pointer[1] -= this.offsetY + offsets[1];
    this.event = event;
    this.setValue(this.translateToValue( this.isVertical() ? pointer[1] : pointer[0] ));
    if (this.initialized && this.options.onSlide)
      this.options.onSlide(this.values.length>1 ? this.values : this.value, this);
  },
  endDrag: function(event) {
    if (this.active && this.dragging) {
      this.finishDrag(event, true);
      Event.stop(event);
    }
    this.active = false;
    this.dragging = false;
  },  
  finishDrag: function(event, success) {
    this.active = false;
    this.dragging = false;
    this.updateFinished();
  },
  updateFinished: function() {
    if (this.initialized && this.options.onChange) 
      this.options.onChange(this.values.length>1 ? this.values : this.value, this);
    this.event = null;
  }
});


/*
Class: Scroller
    Adds a scrollbar to a specific div. The scrollbar is implemented using a Script.aculo.us slider.
    The class reparents the original div, creates a slider and ties the reparented div to the slider,
    setting any properties necessary on the divs to make it all work. The scrollbar can be styled using
    CSS. The track of the scrollbar has class 'scroll-track', the thumb has class 'scroll-handle'.
    
properties:
    myIndex - an integer used to generate a unique ID for use in, for example, div ids.
    outerBox - the div that holds the scrollpane + scrollbar
    innerBox - the div that holds the scrollpane
    innerHeight - the height of the inner box.
    viewportHeight - the height of the view onto the scrolled div.
    track - a div that holds the script.aculo.us slider (the scrollbar)
    trackHeight - the height of the slider
    handle - the div for the 'thumb' of the scrollbar
    handleHeight - the height of the thumb
    slider - the script.aculo.us slider itself
    ieDecreaseBy - a fudge factor used when calculating the width of innerBox
    
*/
var Scroller = Class.create();

/*
property: Scroller.ids
    A cache of Scrollers indexed by the ID of the original div.
 */
Scroller.ids = new Object();

/*
property: Scroller.i
    A unique ID generator.
 */
Scroller.i = 0;

Scroller.prototype = {
    /*
    constructor: initialize 
        Wrap the passed div in a scrollpane.
    
    parameters: 
        el - the div to add a scrollbar to.
     */
  initialize: function(el) {
      this.outerBox = el;
      this.decorate();
  },
  
  /*
  function: decorate  
    create the necessary elements to implement the scrollbar and wire up events.
   */
  decorate: function() {
    Element.makePositioned(this.outerBox); // Fix IE
    
    // Seed a unique ID
    Scroller.i = Scroller.i + 1;
    this.myIndex = Scroller.i;
    
    //wrap the existing content in an intermediate inner box
    this.innerBox = document.createElement("DIV");
    this.innerBox.className="scroll-innerBox";
    Element.makePositioned(this.innerBox);  // Fix IE
    this.innerBox.style.cssFloat=this.innerBox.style.styleFloat='left'; // Need the scrollbar to appear next to the scrollpane
    this.innerBox.innerHTML = this.outerBox.innerHTML;
    this.outerBox.innerHTML="";
    this.outerBox.appendChild(this.innerBox);
    
    //now build a slider, and put it next to the inner box
    this.track=document.createElement("DIV");
    this.track.className="scroll-track";
    Element.makePositioned(this.track); // Fix IE
    this.track.style.cssFloat=this.track.style.styleFloat='left';   // Need the scrollbar to appear next to the scrollpane
    this.track.id="scroll-track"+Scroller.i;
    this.track.style.display = 'none';
    
    // Save the size of our little window onto the content
    this.viewportHeight = this.getHeight(this.outerBox);
    
    this.trackHeight = this.viewportHeight;
    this.track.style.height=this.trackHeight+"px";
    
    // Now create the 'thumb' of the scrollbar
    this.handle=document.createElement("DIV");
    this.handle.className="scroll-handle";
    this.handle.id="scroll-handle"+Scroller.i;
    
    // Height of thumb is proportional, but minimum height is 10px
    this.innerHeight=this.getHeight(this.innerBox);         
    if (this.innerHeight > 0)
        this.handleHeight = Math.round((this.trackHeight * this.viewportHeight) / this.innerHeight);
    else
        this.handleHeight = 10;
    if(this.handleHeight < 10) this.handleHeight = 10;
    this.handle.style.height = this.handleHeight + "px";
    
    this.track.appendChild(this.handle);
    this.outerBox.appendChild(this.track);
    
    //turn off scrolling on the outer div
    this.outerBox.style.overflow="hidden";
    
    //layout complete.  if you exit here, you get nice looking box with an inactive scroll bar.
    //create the slider functionality
    this.slider = new Control.Slider(this.handle.id, this.track.id, {axis:'vertical',
                                                            minimum:0,
                                                            maximum:this.trackHeight});
    
    //scroll set up is complete. Work through the actual scrolling fuctions
    //run the same function while scrollin, and at the end of scrolling (handles jumping up/down)
    this.slider.options.onSlide = this.slider.options.onChange = this.onChange.bind(this);
    
    // Give the browser 10ms to render the DIVs and resolve their geometry.
    setTimeout(this.resetScrollbar.bind(this, false), 10);
  },
  
  /*
  function: resetScrollbar  
    Re-calculate the geometry of the scrollbar. Typically called from an event handler.
    
    args:   
        full - if true, re-calculate the geometry of the scrollpane as well as the scrollbar.
   */
  resetScrollbar: function(full) {
    // If its a full reset, set scrollbar to invisible.
    if (full)
        this.track.style.display='none';
    
    //need to get height of innerBox.
    this.innerHeight = this.getHeight(this.innerBox);
    
    this.viewportHeight = this.getHeight(this.outerBox);// Need to refetch height of outerbox too since it might've stretched.
    this.trackHeight = this.viewportHeight;             // One day trackHeight might be different than viewportHeight if we have scroll buttons too.
    this.slider.trackLength = this.trackHeight;         // Reset slider geometry
    this.track.style.height=this.trackHeight+"px";
    
    // Reset thumb geometry
    this.handleHeight = Math.round((this.trackHeight * this.viewportHeight) / this.innerHeight);
    if(this.handleHeight < 10) this.handleHeight = 10;
    this.handle.style.height = this.handleHeight + "px";
    
    // Reset handle height
    this.slider.handleLength = this.handleHeight;
    if (this.handleHeight < this.trackHeight) {
         // Scrolbar should be displayed.
         if (Element.getStyle(this.track, "display") == 'none') {
             // If scrollbar was not previously displayed, we have to squeeze the viewport width by the width of the scrollbar
            this.track.style.display='inline';
            
            //now adjust the size of the inner box to make room for the slider
            //if the outer box has a border on it (common for scroll boxes) we need to compensate for different box models
            //fortunately, mozilla will work by default - so only if IE  has a border do we care.  Which is good, we can only check borders in IE...
            this.ieDecreaseBy=0;
            if (this.outerBox.currentStyle){
                var borderWidth = this.outerBox.currentStyle["borderWidth"].replace("px","");   //no way to isolate left and right border (which is all we care about) so we'll just assume consistent border width
                if(!isNaN(borderWidth)){
                    this.ieDecreaseBy=(borderWidth)*2;  //compensate for left and right border
                }
            }
            this.setWidth();
         }
            
    } else {
        this.track.style.display='none';
    }
  },
  
  /*
  function: setWidth  
    Set the width of of the scrollpane (aka innerBox).
   */
  setWidth: function() {
    var newWidth = (this.getWidth(this.outerBox) - this.getWidth(this.track) - this.ieDecreaseBy) + "px";
    this.innerBox.style.width = newWidth;
    
    // The sad thing is that all of this might change innerHeight, so need to schedule a refresh
    setTimeout(this.resetScrollbar.bind(this, false), 10);
  },
  
  /*
  function: getHeight  
    Get the height of the passed element.
    
    args:   
        el - the element to get the height of.
   */
  getHeight: function(el) {
    if (el.currentStyle){
        return el.offsetHeight;                                 //ie
    }else{
        return Element.getStyle(el,"height").replace("px","");  //moz
    }
  },
  
  /*
  function: getWidth  
    Get the width of the passed element.
    
    args:   
        el - the element to get the width of.
   */
  getWidth: function(el) {
    var w = "0";
    if (el.currentStyle){
        w = el.offsetWidth;                                 //ie
    } else {
        w = Element.getStyle(el,"width");
        if (w) {
            w = w.replace("px",""); //moz
        }
    }
    
    return w;
  },
  
  /*
  function: onChange  
    Called when the script.aculo.us slider has changed (i.e. when it has been dragged). Scroll the inner box.
    
    args:   
        val - not used.
   */
  onChange: function(val) {
    if(this.track){
        //assume 100 ticks in the scrollbar
        //for each tick need to move:  The amount the inner box overruns the outer box, divided by 100
        var moveRatio = (this.innerHeight - this.getHeight(this.outerBox))/100;
        //move the box up (negative) for every TickVal, move the box by moveRatio
        this.innerBox.style.top = (val*100*moveRatio*-1) + "px";
    }
  }
}

/*
function: Scroller.setAll
    Search for divs of the class 'makeScroll' and wrap them in a Scroller.
 */
Scroller.setAll = function () {
    //get all the boxes we want to scroll
    var sliderBoxes = document.getElementsByClassName("makeScroll");
    //build scroll functionality for each scrollable box
    for(i=0; i<sliderBoxes.length; i++){
        Scroller.ids[sliderBoxes[i].id] = new Scroller(sliderBoxes[i]);
    }
}

/*
function: Scroller.reset
    If the passed element has class 'makeScroll', wrap it in a Scroller.
 */
Scroller.reset = function (body_id) {
    if ($(body_id).className.match(new RegExp("(^|\\s)makeScroll(\\s|$)"))) {
        Scroller.ids[body_id] = new Scroller($(body_id));
    }
}

/*
property: Scroller.updateAll
    Reset all of the scrollbars.
 */
Scroller.updateAll = function () {
    for (var key in Scroller.ids) {
        Scroller.ids[key].resetScrollbar(true);
    }
}

/*
    Hook up some global event handlers.
 */
Event.observe(window, "load", Scroller.setAll);
Event.observe(window, "resize", Scroller.updateAll);

      Event.observe(window, 'load', 
	  function() 
	  {
        if($('searchform'))
		{
		  $('postalcode').addClassName('searchinput'); 
		  $('search').addClassName('searchinput'); 
		  $('postalcode').focus(); 
        }
        if($('resultsanswer'))
		{
		  $('postalcode').focus(); 
          Event.observe('search','keypress',function(event) {
            if(event.keyCode == Event.KEY_RETURN)
            {
              searchIndex();
            }
          });
        }
        if($('searchbat'))
        {
          Event.observe('searchbat','keypress',function(event) {
            if(event.keyCode == Event.KEY_RETURN)
            {
              searchlibrarybats();
            }
          });
        }
        if($('searchexp'))
        {
          Event.observe('searchexp','keypress',function(event) {
            if(event.keyCode == Event.KEY_RETURN)
            {
              searchPros();
            }
          });
        }
        if($('searchbatcat'))
        {
          Event.observe('searchbatcat','keypress',function(event) {
            if(event.keyCode == Event.KEY_RETURN)
            {
              searchcatbats(); 
            }
          });
        }
        if($('CategoryID'))
        {
          quoteDisableForm();
		}
	  }
  );


function emailCheck(emailaddr) {
var s=/^(.+)@(.+)\.(.+)$/;
if (emailaddr.match(s)==null) {       
	return false;       
}
return true;
}

function checkPhone (strng) {

var stripped = strng.replace(/[\(\)\.\-\ ]/g, ''); //strip out acceptable non-numeric characters
	if (isNaN(parseInt(stripped))) {
	   return false; 
	}
	if (!(stripped.length == 10)) {
		return false; 
	} 		
return true;
}	

function frmValidate(theForm) {
	var ziplength;
	var tzip;
    var theError = new Array(); 
	theError[0] = 'ok'; 

    $('Zip').style.backgroundColor = '#FFFFFF';
	$('DayPhone').style.backgroundColor = '#FFFFFF';
	$('Email').style.backgroundColor = '#FFFFFF';
	$('State').style.backgroundColor = '#FFFFFF';
	$('City').style.backgroundColor = '#FFFFFF';
	$('Address').style.backgroundColor = '#FFFFFF';
	$('LName').style.backgroundColor = '#FFFFFF';
	$('FName').style.backgroundColor = '#FFFFFF';
    $('ServiceID').style.backgroundColor = '#FFFFFF'; 
    $('CategoryID').style.backgroundColor = '#FFFFFF'; 
    $('Zip').style.backgroundColor = '#FFFFFF'; 

	if ($('terms').checked == false)
	{
		$('terms').style.backgroundColor = '#FFCCCC';
 	}
    else
	{
		$('terms').checked == true; 
		var terms = '1'; 
 	}

	var expert_id =  $('expert_id').getValue();
	var BTCNotes =  $('BTCNotes').getValue();
	var BTCID =  $('BTCID').getValue();
	var EvePhone =  $('EvePhone').getValue();
    var DayPhone =  $('DayPhone').getValue();
	if (DayPhone == "") {
		$('DayPhone').style.backgroundColor = '#FFCCCC';
        theError[0] = theForm+'.DayPhone.focus()';
	}
	if (!(checkPhone(DayPhone))) 
	{
		$('DayPhone').style.backgroundColor = '#FFCCCC';
        theError[0] = theForm+'.DayPhone.focus()';
	}			
    var Email =  $('Email').getValue();
	if (!(emailCheck(Email))) {
		$('Email').style.backgroundColor = '#FFCCCC';
        theError[0] = theForm+'.Email.focus()';
	}
	if (Email == "") {
		$('Email').style.backgroundColor = '#FFCCCC';
        theError[0] = theForm+'.Email.focus()';
	}

	var State =  $('State').getValue();
	if (State == "") {
		$('State').style.backgroundColor = '#FFCCCC';
        theError[0] = theForm+'.State.focus()';
	}
    var City =  $('City').getValue();
	if (City == "") {
		$('City').style.backgroundColor = '#FFCCCC';
        theError[0] = theForm+'.City.focus()';
	}

    var Address2 =  $('Address2').getValue();

	var Address =  $('Address').getValue();
	if (Address == "") {
		$('Address').style.backgroundColor = '#FFCCCC';
        theError[0] = theForm+'.Address.focus()';
	}
    var LName =  $('LName').getValue();
	if (LName == "") {
		$('LName').style.backgroundColor = '#FFCCCC';
        theError[0] = theForm+'.LName.focus()';
	}
    var FName =  $('FName').getValue();
	if (FName == "") {
		$('FName').style.backgroundColor = '#FFCCCC';
        theError[0] = theForm+'.FName.focus()';
	}

	var OrderNotes =  $('OrderNotes').getValue();

	var ProjectToBegin =  $('ProjectToBegin').getValue();
	if (ProjectToBegin == "Not Selected") 
	{
	  $('ProjectToBegin').style.backgroundColor = '#FFCCCC'; 
      theError[0] = theForm+'.ProjectToBegin.focus()'; 
	}

	var Budget =  $('Budget').getValue();
	if (Budget == "Not Selected") 
	{
	  $('Budget').style.backgroundColor = '#FFCCCC'; 
      theError[0] = theForm+'.Budget.focus()'; 
	}

    var ServiceID =  $('ServiceID').getValue();
	if (ServiceID == "0") 
	{
	  $('ServiceID').style.backgroundColor = '#FFCCCC'; 
      theError[0] = theForm+'.ServiceID.focus()'; 
	}
    var CategoryID = $('CategoryID').getValue();
	if (CategoryID == "0") {
	  $('CategoryID').style.backgroundColor = '#FFCCCC';
	  theError[0] = theForm+'.CategoryID.focus()';
	}				
	tzip = $('Zip').getValue();
	ziplength = tzip.length;		
	if (ziplength != 5){
      $('Zip').style.backgroundColor = '#FFCCCC';
      theError[0] = theForm+'.Zip.focus()';
	}
	if (tzip == "") {
		$('Zip').style.backgroundColor = '#FFCCCC';
		theError[0] = theForm+'.theForm.Zip.focus()';
	}	 		
	if(theError[0] == 'ok')
	{ 	
      var pamtt = new Ajax.Request('/ajax/modalexpertquote.php',
      {
        asynchronous : false,
        method: 'post',
		parameters:{terms:terms,expert_id:expert_id,BTCNotes:BTCNotes,BTCID:BTCID,OrderNotes:OrderNotes,Budget:Budget,DayPhone:DayPhone,Email:Email,City:City,State:State,Address2:Address2,Address:Address,FName:FName,LName:LName,tzip:tzip,CategoryID:CategoryID,ServiceID:ServiceID},
		onSuccess: function(transport)
		{
		  $('mainquote').innerHTML = "<br><br><br><b>Thank You for your quote request.<br><br>We will get back to you ASAP!</b><br><br><a class='thelink' href='#' onclick='Modalbox.hide(); return false;'><b>Close Window</b></a>"; 
		},
		onFailure: function(){ alert('183') }
	  });
	}
    else
	{ 	
      eval(theError[0]);
    }
}

var category = new Array(); 
category[0] = new Array('Select a Service','0','Additions - Major','4','Additions - Minor','104','Arbors/Trellis/Patio Covers','6','Architectural & Plan Designs','7','Asphalt/Black Top','105','Basement Remodeling','8','Bath Remodeling - Major','9','Bath Remodeling - Minor','99','Brick Work','10','Cabinet - Install','11','Cabinet - Refacing','12','Carpentry - Interior Woodwork','13','Carpet - Cleaning','14','Carpet - Installation','15','Carpet - Repair','16','Chimney Cleaning','17','Concrete - Flatwork','18','Concrete - Foundation/Wall','19','Concrete - Removal','20','Concrete - Repair','21','Concrete - Stamped/Color','22','Countertops - Install','23','Countertops - Repair','24','Custom Homes w/ Lot','102','Custom Homes w/o Lot','103','Debris Hauling','25','Deck - New','26','Deck - Repair/Modification','27','Deck Cleaning/Treatment','28','Doors - Garage','29','Doors - Install','30','Doors - Repair','31','Drainage','32','Dryrot Repair - Non-Structural','33','Dryrot Repair - Structural','34','Drywall/Sheetrock - Install','35','Drywall/Sheetrock - Repair','36','Electrical - Install','37','Electrical - Repair','38','Excavation','39','Fence - Chainlink','40','Fence - Repair','41','Fence - Vinyl','42','Fence - Wood','43','Flooring - Hardwood Install','44','Flooring - Hardwood Refinishing','45','Flooring - Laminate','46','Flooring - Sub Floors','47','Flooring - Vinyl/Linoleum','48','Framing','49','Gazebos','50','Gutter Cleaning','51','Gutters - Install','52','Gutters - Repair','53','Handyman','54','Home/Office Cleaning','55','Hot Tubs','108','HVAC - Install','56','HVAC - Servicing','58','Insulation','60','Kitchen Remodeling - Major','61','Kitchen Remodeling - Minor','100','Landscaping - Design/Install','62','Landscaping - Maintenance','63','Low Voltage Wiring','64','Marble & Granite','65','Masonry/Stone Work','66','Painting - Exterior','67','Painting - Interior','68','Painting - Minor','106','Plumbing - Install','69','Plumbing - Servicing','70','Power Washing','71','Remodeling - Major','72','Remodeling - Minor','101','Retaining Walls','73','Roof Cleaning/Treatment','74','Roofing - Cedar Shake','75','Roofing - Composite','76','Roofing - Metal','77','Roofing - Repair','78','Roofing - Tar/Torch-down','79','Roofing - Tile','80','Septic/Sewer','107','Sheds','81','Siding - Aluminum','82','Siding - Composite/Wood','83','Siding - Repair','84','Siding - Vinyl','85','Skylights - Install','86','Solar Panels','109','Sprinkler - Install/Repair','87','Stucco/Texture - Exterior','88','Stucco/Texture - Interior','89','Sunrooms','90','Swimming Pools','91','Tile - Exterior','92','Tile - Interior','93','Wallpaper - Install/Removal','94','Window - Repair','97','Window Cleaning','95','Window Install - Major','96','Window Install - Minor','98'); category[1] = new Array('Select a Service','0','Additions - Major','4','Additions - Minor','104','Basement Remodeling','8','Bath Remodeling - Major','9','Excavation','39','Framing','49','Kitchen Remodeling - Major','61','Remodeling - Major','72','Remodeling - Minor','101','Sunrooms','90'); category[19] = new Array('Select a Service','0','Architectural & Plan Designs','7'); category[3] = new Array('Select a Service','0','Bath Remodeling - Major','9','Bath Remodeling - Minor','99','Cabinet - Install','11','Cabinet - Refacing','12','Countertops - Install','23','Framing','49','Remodeling - Major','72','Remodeling - Minor','101'); category[13] = new Array('Select a Service','0','Carpentry - Interior Woodwork','13'); category[12] = new Array('Select a Service','0','Brick Work','10','Chimney Cleaning','17','Concrete - Flatwork','18','Concrete - Foundation/Wall','19','Concrete - Removal','20','Concrete - Repair','21','Concrete - Stamped/Color','22','Marble & Granite','65','Masonry/Stone Work','66','Retaining Walls','73','Stucco/Texture - Exterior','88','Stucco/Texture - Interior','89','Swimming Pools','91'); category[7] = new Array('Select a Service','0','Countertops - Install','23','Countertops - Repair','24','Marble & Granite','65'); category[2] = new Array('Select a Service','0','Custom Homes w/ Lot','102','Custom Homes w/o Lot','103','Framing','49'); category[5] = new Array('Select a Service','0','Arbors/Trellis/Patio Covers','6','Deck - New','26','Deck - Repair/Modification','27','Deck Cleaning/Treatment','28','Fence - Chainlink','40','Fence - Repair','41','Fence - Vinyl','42','Fence - Wood','43','Hot Tubs','108'); category[16] = new Array('Select a Service','0','Electrical - Install','37','Electrical - Repair','38','Hot Tubs','108','Low Voltage Wiring','64','Solar Panels','109'); category[11] = new Array('Select a Service','0','Flooring - Hardwood Install','44','Flooring - Hardwood Refinishing','45','Flooring - Laminate','46','Flooring - Sub Floors','47','Flooring - Vinyl/Linoleum','48'); category[18] = new Array('Select a Service','0','HVAC - Install','56','HVAC - Servicing','58','Solar Panels','109'); category[4] = new Array('Select a Service','0','Cabinet - Install','11','Cabinet - Refacing','12','Countertops - Install','23','Framing','49','Kitchen Remodeling - Major','61','Kitchen Remodeling - Minor','100','Remodeling - Major','72','Remodeling - Minor','101'); category[21] = new Array('Select a Service','0','Arbors/Trellis/Patio Covers','6','Concrete - Stamped/Color','22','Deck - New','26','Drainage','32','Electrical - Install','37','Gazebos','50','Hot Tubs','108','Landscaping - Design/Install','62','Landscaping - Maintenance','63','Retaining Walls','73','Solar Panels','109','Sprinkler - Install/Repair','87','Swimming Pools','91','Tile - Exterior','92'); category[10] = new Array('Select a Service','0','Drywall/Sheetrock - Install','35','Drywall/Sheetrock - Repair','36','Painting - Exterior','67','Painting - Interior','68','Painting - Minor','106','Stucco/Texture - Interior','89','Wallpaper - Install/Removal','94'); category[17] = new Array('Select a Service','0','Hot Tubs','108','Plumbing - Install','69','Plumbing - Servicing','70','Septic/Sewer','107','Solar Panels','109'); category[8] = new Array('Select a Service','0','Gutters - Install','52','Roofing - Cedar Shake','75','Roofing - Composite','76','Roofing - Metal','77','Roofing - Tar/Torch-down','79','Roofing - Tile','80','Solar Panels','109'); category[14] = new Array('Select a Service','0','Siding - Aluminum','82','Siding - Composite/Wood','83','Siding - Vinyl','85','Stucco/Texture - Exterior','88'); category[6] = new Array('Select a Service','0','Cabinet - Refacing','12','Carpet - Cleaning','14','Carpet - Installation','15','Carpet - Repair','16','Chimney Cleaning','17','Concrete - Repair','21','Countertops - Repair','24','Debris Hauling','25','Deck - Repair/Modification','27','Deck Cleaning/Treatment','28','Doors - Garage','29','Doors - Install','30','Doors - Repair','31','Drainage','32','Dryrot Repair - Non-Structural','33','Dryrot Repair - Structural','34','Drywall/Sheetrock - Install','35','Drywall/Sheetrock - Repair','36','Electrical - Repair','38','Excavation','39','Fence - Repair','41','Gazebos','50','Gutter Cleaning','51','Gutters - Install','52','Gutters - Repair','53','Handyman','54','Home/Office Cleaning','55','Insulation','60','Plumbing - Servicing','70','Power Washing','71','Roof Cleaning/Treatment','74','Roofing - Repair','78','Sheds','81','Siding - Repair','84','Solar Panels','109','Wallpaper - Install/Removal','94','Window - Repair','97','Window Cleaning','95'); category[20] = new Array('Select a Service','0','Additions - Major','4','Gazebos','50','Remodeling - Major','72','Solar Panels','109','Sunrooms','90'); category[15] = new Array('Select a Service','0','Marble & Granite','65','Tile - Exterior','92','Tile - Interior','93'); category[9] = new Array('Select a Service','0','Doors - Install','30','Doors - Install','30','Skylights - Install','86','Sunrooms','90','Window Install - Major','96','Window Install - Minor','98'); 
function populateServices() {
var box = document.forms[0].CategoryID; 
var number = box.options[box.selectedIndex].value;
if (!number) return;
var list = category[number];
var box2 = document.forms[0].ServiceID;
box2.options.length = 0;
  for(i=0;i<list.length;i+=2)
  {
    box2.options[i/2] = new Option(list[i],list[i+1]);
  }
}

function signmeup(radio) 
{
  var val = getRadioValue(radio);
  if(val == 'f')
  {
    document.location.href = 'https://www.rsmhomeimprovement.com/freeaccount.html'; 
    return true; 
  }
  else 
  {
    document.location.href = 'https://www.rsmhomeimprovement.com/checkout.html'; 
    return true; 
  }
}

function changecategories(id) {
  var url = $F(id);
  window.location.href = url;
  return true;
}

function getRadioValue(idOrName) {
        var value = null;
        var element = document.getElementById(idOrName);
        var radioGroupName = null;  
        
        // if null, then the id must be the radio group name
        if (element == null) {
                radioGroupName = idOrName;
        } else {
                radioGroupName = element.name;     
        }
        if (radioGroupName == null) {
                return null;
        }
        var radios = document.getElementsByTagName('input');
        for (var i=0; i<radios.length; i++) {
                var input = radios[ i ];    
                if (input.type == 'radio' && input.name == radioGroupName && input.checked) {                          
                        value = input.value;
                        break;
                }
        }
        return value;
}

var whitespace = " \t\n\r";
var validUSPhoneChars = digits + phoneNumberDelimiters;
var digits = "0123456789";
var phoneNumberDelimiters = "()- ";
var validUSPhoneChars = digits + phoneNumberDelimiters;
var digitsInUSPhoneNumber = 10;
var ZIPCodeDelimiters = "-";
var ZIPCodeDelimeters = "-";
var validZIPCodeChars = digits + ZIPCodeDelimiters;
var digitsInZIPCode1 = 5;
var digitsInZIPCode2 = 9;

var Validate = Class.create(); 
Validate.prototype = {
  initialize: function() {},
  isValidCreditCardNumber: function(cardNumber, cardType)
  {
	  var isValid = false;
	  var ccCheckRegExp = /[^\d ]/;
	  isValid = !ccCheckRegExp.test(cardNumber);

	  if (isValid)
	  {
		var cardNumbersOnly = cardNumber.replace(/ /g,"");
		var cardNumberLength = cardNumbersOnly.length;
		var lengthIsValid = false;
		var prefixIsValid = false;
		var prefixRegExp;

		switch(cardType)
		{
		  case "mastercard":
			lengthIsValid = (cardNumberLength == 16);
			prefixRegExp = /^5[1-5]/;
			break;

		  case "visa":
			lengthIsValid = (cardNumberLength == 16 || cardNumberLength == 13);
			prefixRegExp = /^4/;
			break;

		  case "amex":
			lengthIsValid = (cardNumberLength == 15);
			prefixRegExp = /^3(4|7)/;
			break;

		  case "discover":
			lengthIsValid = (cardNumberLength == 16);
			prefixRegExp = /^6011/;
			break;

		  default:
			prefixRegExp = /^$/; 
			return false; 
		}

		prefixIsValid = prefixRegExp.test(cardNumbersOnly);
		isValid = prefixIsValid && lengthIsValid;
	  }

	  if (isValid)
	  {
		var numberProduct;
		var numberProductDigitIndex;
		var checkSumTotal = 0;

		for (digitCounter = cardNumberLength - 1; 
		  digitCounter >= 0; 
		  digitCounter--)
		{
		  checkSumTotal += parseInt (cardNumbersOnly.charAt(digitCounter));
		  digitCounter--;
		  numberProduct = String((cardNumbersOnly.charAt(digitCounter) * 2));
		  for (var productDigitCounter = 0;
			productDigitCounter < numberProduct.length; 
			productDigitCounter++)
		  {
			checkSumTotal += 
			  parseInt(numberProduct.charAt(productDigitCounter));
		  }
		}

		isValid = (checkSumTotal % 10 == 0);
	  }

	  return isValid;
	},
    alphanumeric: function(alphane)
    {
	  var numaric = alphane;
	  for(var j=0; j<numaric.length; j++)
	  {
		  var alphaa = numaric.charAt(j);
		  var hh = alphaa.charCodeAt(0);
		  if((hh > 47 && hh<58) || (hh > 64 && hh<91) || (hh > 96 && hh<123) || (hh == 32))
		  {
		  }
		else	
		{
		  return false;
		}
	  }
       return true;
    },
	isWhitespace: function  (s)
    {   
      var i;
      if (this.isEmpty(s)) return true;
      for (i = 0; i < s.length; i++)
      {   
        var c = s.charAt(i);
        if (whitespace.indexOf(c) == -1) return false;
      }
      return true;
    },
    hasWhitespace: function  (s)  {   
      var i;
      for (i = 0; i < s.length; i++)
      {   
        var c = s.charAt(i);
        if (whitespace.indexOf(c) != -1) return true;
      }
      return false;
    },
    isEmpty: function (s)
    {   
      return ((s == null) || (s.length == 0))
    },
    isEmail: function (s)
    {   
      if (this.isEmpty(s)) 
      {
        return false;
      }
      if (this.isWhitespace(s)) return false;
      var i = 1;
      var sLength = s.length;
      while ((i < sLength) && (s.charAt(i) != "@"))
      { i++
      }
      if ((i >= sLength) || (s.charAt(i) != "@")) return false;
      else i += 2;
      while ((i < sLength) && (s.charAt(i) != "."))
      { i++
      }
      if ((i >= sLength - 1) || (s.charAt(i) != ".")) 
  	  {
        return false;
      }
      else
	  {
	    return true;
	  }
    },
    reformat: function (s)
    { var arg;
      var sPos = 0;
      var resultString = "";
      for (var i = 1; i < this.reformat.arguments.length; i++) 
	  {
        arg = this.reformat.arguments[i];
         if (i % 2 == 1) resultString += arg;
         else 
		 {
           resultString += s.substring(sPos, sPos + arg);
           sPos += arg;
         }
      }
      return resultString;
    },
    isDigit: function (c)
    {   
	  return ((c >= "0") && (c <= "9"));
    },
    isInteger: function (s)
    { 
	  var i;
      if (this.isEmpty(s)) 
      {
        return false;
	  }
      for (i = 0; i < s.length; i++)
      {   
        var c = s.charAt(i);
        if (!this.isDigit(c)) return false;
      }
      return true;
    },
    stripCharsInBag: function (s, bag)
    {   
	  var i;
      var returnString = "";
      for (i = 0; i < s.length; i++)
      {   
        var c = s.charAt(i);
        if (bag.indexOf(c) == -1) returnString += c;
      }
      return returnString;
    },
    reformatUSPhone: function (USPhone)
    {
       return (this.reformat (USPhone, "(", 3, ") ", 3, "-", 4));
    },
    isUSPhoneNumber: function  (s)
    {   
	  if (this.isEmpty(s))
      {
       return false;
      }
	  return (this.isInteger(s) && s.length == digitsInUSPhoneNumber);
    },
    checkUSPhone: function  (theField)
    { 
      var normalizedPhone = this.stripCharsInBag(theField, phoneNumberDelimiters);
      if(normalizedPhone.charAt(0) == '1') 
	  {
       normalizedPhone = normalizedPhone.substring(1);
      }
	  if (!this.isUSPhoneNumber(normalizedPhone)) 
	  {
        return false;
	  }
      else 
      {  
         theField = this.reformatUSPhone(normalizedPhone);
         return true;
      }
    },
    isZIPCode: function  (s)
    {  
      var t = this.stripCharsInBag(s, ZIPCodeDelimiters);
      if (this.isEmpty(t)) 
      {
        return false;
	  }
      return (this.isInteger(t) && ((t.length == digitsInZIPCode1) || (t.length == digitsInZIPCode2)));
    }
};


var Proadmin = Class.create(); 
Proadmin.prototype = {
  initialize: function() {},
  mycompany: function(expertid)
  {
	  $('qcontentadmin').style.display = "none"; 
	  $('admincontent').style.display = "block"; 
	  $('admincontent').innerHTML = '<img src="/images/ajax-loading.gif">'; 
	  var t = new Ajax.Request('/ajax/myaccount.php',
	  {
		method:'get',
        parameters: {expertid: expertid},
		onSuccess: function(transport){
	    var rese = transport.responseText || " empty ";
		$('admincontent').innerHTML = rese; 

		var u = new Ajax.Request('/ajax/getaddresses.php',
	    {
		  method:'get',
          parameters: {expertid: expertid},
		  onSuccess: function(transport){
	      var resd = transport.responseText || " Enter Your Address To The Right."; 
		  $('addresseshere').innerHTML = resd; 
		  },
		  onFailure: function(){ alert('334..') }
	    });

			var select_multiple_two = new Control.SelectMultiple('select_multiple_two','select_multiple_two_options',{
				checkboxSelector: 'table.select_multiple_table tr td input[type=checkbox]',
				nameSelector: 'table.select_multiple_table tr td.select_multiple_name',
				afterChange: function(){
					if(select_multiple_two && select_multiple_two.setSelectedRows)
						select_multiple_two.setSelectedRows();
				}
			});
			
			//adds and removes highlighting from table rows
			select_multiple_two.setSelectedRows = function()
			{
				this.checkboxes.each(function(checkbox){
					var tr = $(checkbox.parentNode.parentNode);
					tr.removeClassName('selected');
					if(checkbox.checked)
						tr.addClassName('selected');
				});
			}.bind(select_multiple_two);
			select_multiple_two.checkboxes.each(function(checkbox){
				$(checkbox).observe('click',select_multiple_two.setSelectedRows);
			});
			
			//link open and closing
			$('select_multiple_two_open').observe('click',function(event){
				$(this.select).style.visibility = 'hidden';
				new Effect.BlindDown(this.container,{
					duration: 0.3
				});
				Event.stop(event);

                var tsels = $('theselections').getValue();
				var atsels = tsels.split('|');
				var selectedCategories = $$('#isselected input[type=checkbox]');
				selectedCategories.each(function lookCellsover (s) { 
                  atsels.each(function att (f) {
				    if(s.value == f)
			        {
          			  s.checked = true;
			        }
                  });
                });
				return false;
			}.bindAsEventListener(select_multiple_two));
			$('select_multiple_two_close').observe('click',function(event){
				$(this.select).style.visibility = 'visible';
				new Effect.BlindUp(this.container,{
					duration: 0.3
				});
				Event.stop(event);
				var selectedCategories = $$('#isselected input[type=checkbox]');
                var categories = '*';
				selectedCategories.each(function lookThemover (s) { 
                  if(s.checked == true)
				  {
                    categories += s.value+'-';
				  }
				}
				); 
				var u = new Ajax.Request('/ajax/updatecategories.php',
				{
				  method:'get',
				  parameters: {expertid: expertid, topcat: categories},
				  onSuccess: function(transport){
				  var resd = transport.responseText || "find dogs"; 
				  },
				  onFailure: function(){ alert(' error 393') }
				});

				return false;
			}.bindAsEventListener(select_multiple_two));
		},
		onFailure: function(){ alert('409') }
	  });
  },
  deleteimagepam: function(id)
  {
    var rand=Math.random()*5;
    var rand=Math.floor(rand);
    var pamtt = new Ajax.Request('/ajax/deleteimagepam.php',
    {
      asynchronous : false,
      method : 'get',
      parameters:{rand:rand,id:id},
      onSuccess:function(pamtransport)
	  {
         var pamarr = pamtransport.responseText; 
      }
    }); 
    var frameEl = window.frameElement;
	if (frameEl)
	frameEl.src = frameEl.src;
  },
  mylogo: function(expertid)
  {
	  $('admincontent').hide(); 
	  $('qcontentadmin').show(); 
	  $('tlogo').src  = '/html/upload-logo.php'; 
  },
  myvideos: function(expertid)
  {
	  $('admincontent').style.display = "none"; 
	  $('qcontentadmin').style.display = "block"; 
	  $('tlogo').src  = '/html/upload-videos.php'; 
  },
  myaudios: function(expertid)
  {
	  $('admincontent').style.display = "none"; 
	  $('qcontentadmin').style.display = "block"; 
	  $('tlogo').src  = '/html/upload-audios.php'; 
  },
  mypics: function(expertid)
  {
	  $('admincontent').style.display = "none"; 
	  $('qcontentadmin').style.display = "block"; 
	  $('tlogo').src  = '/html/upload-pics.php'; 
  },
  myaccount: function(expertid)
  {
	  $('admincontent').style.display = "none"; 
	  $('qcontentadmin').style.display = "block"; 
	  $('tlogo').src  = '/ajax/payments.php'; 
  },
  activateme: function(expertid)
  {
	  $('admincontent').style.display = "none"; 
	  $('qcontentadmin').style.display = "block"; 
	  $('tlogo').src  = '/ajax/activateme.php'; 
  },
  checkurl: function(expertid)
  {
	  var fvalid = new Validate;
	  var expertlink = $('link').value;
      if(!fvalid.alphanumeric(expertlink))
      {
        $('accepturl').show(); 
		$('accepturl').innerHTML = 'Numbers,letters and spaces only.'; 
		$('accepturl').style.backgroundColor = 'red';
        return false; 
      }
	  var ztt = new Ajax.Request('/ajax/checkurl.php',
	  {
		method : 'get',
        parameters : {expertid : expertid, expertlink : expertlink },
		onSuccess : function(tttransport)
		{
          var arr = tttransport.responseText || " empty "; 
          if(arr == 'x')
		  {
            $('accepturl').show();
			$('accepturl').innerHTML = 'Please Change Your Default URL';
			$('accepturl').style.color = '#ff7751';
		  }
          else if(arr == 'y') 		  
		  {
            $('accepturl').show();
			$('accepturl').innerHTML = "This link is available- <a href='#' onclick=\"myadmin.finalurl('"+expertid+"','"+expertlink+"')\"><b>Click Here to Accept this as your Expert Link.</b></a>"; 
			$('accepturl').style.color = '#abba01';
		  }
          else if(arr == 'n') 		  
		  {
            $('accepturl').show(); 
			$('accepturl').innerHTML = 'URL Not Available'; 
			$('accepturl').style.color = '#ff7751';
		  }
		}  
	  }); 
  },
  finalurl: function(expertid,expertlink)
  {
	  var link = Url.encode(expertlink); 
	  var zztt = new Ajax.Request('/ajax/finalurl.php',
	  {
        asynchronous: false, 
		method : 'get',
        parameters : {expertid : expertid, expertlink : link },
		onSuccess : function(tttransport)
		{
          var arr = tttransport.responseText || "find dogs"; 
          $('accepturl').show();
		  $('accepturl').innerHTML = 'URL Accepted';
		  $('accepturl').style.color = '#abba01';
		  $('msgbutton').disabled = false;
		  $('link').value = arr;
		  $('link').disabled = true;
		  $('linkdude').innerHTML = '<span style="color: #90dd17">Completed</span>';
		  $('lilmsg').innerHTML = '<span style="color: #90dd17">Expert Link Created</span>';
		  $('status3').innerHTML = '<span style="color: #90dd17">Completed</span>';
		}  
	  }); 
  },
  activatenow: function(expertid)
  {
	  var ttx = new Ajax.Request('/ajax/activatenow.php',
	  {
		method : 'get',
        parameters : {expertid : expertid },
		onSuccess : function(xttransport)
		{
	      var rrese = xttransport.responseText || "find dogs"; 
		  if(rrese == 'd')
		  {
		    $('msgbutton').value = 'Put My Page Online';
          }
		  else
		  {
		    $('msgbutton').value = 'Take My Page Offline';
          }
		}  
	  });
  },
  deleteaccount: function(expertid)
  {
    var answer = confirm("Are you sure you want to cancel your account?")
	if (answer)
	{
	  var t = new Ajax.Request('/ajax/deleteaccount.php',
	  {
		method:'get',
        parameters: {expertid: expertid},
		onSuccess: function(transport){
	    var rese = transport.responseText || " 551 ";
//alert(rese);
        parent.window.location.href = "/come-back-soon.html"; 
		},
		onFailure: function(){ alert('770') }
	  });
	}
	else
	{
	  alert("RSM thanks you for sticking around!")
	}
  },
  setrange: function(id,expertid)
  {
	  var tt = new Ajax.Request('/ajax/setrange.php',
	  {
		method : 'get',
        parameters : {id : id, expertid : expertid },
		onSuccess : function(ttransport)
		{
	      var rrese = transport.responseText || "find dogs"; 
		}  
	  });
  },
  deleteaudio: function(id)
  {
      var rand=Math.random()*5;
      var rand=Math.floor(rand);
	  var tt = new Ajax.Request('/ajax/deleteaudio.php',
	  {
        asynchronous : false,
		method : 'get',
        parameters : {rand:rand,id : id},
		onSuccess : function(ttransport)
		{
	      var rrese = transport
			  .responseText || " empty "; 
		}  
	  });
		var frameEl = window.frameElement;
		if (frameEl)
		frameEl.src = frameEl.src;
  },
  deletevideo: function(id)
  {
      var rand=Math.random()*5;
      var rand=Math.floor(rand);
	  var t = new Ajax.Request('/ajax/deletevideo.php',
	  {
        asynchronous : false,
		method : 'get',
        parameters : {rand:rand,id : id},
		onSuccess : function(transport)
		{
          var arr = transport.responseText || " error "; 
		}  
	  }); 
		var frameEl = window.frameElement;
		if (frameEl)
		frameEl.src = frameEl.src;
  },
  removeaddress: function(id,expertid)
  {
	  var rand=Math.random()*5;
      var rand=Math.floor(rand);
	  var t = new Ajax.Request('/ajax/removeaddress.php',
	  {
        asynchronous : false,
		method:'get',
        parameters: {rand : rand,id : id,expertid : expertid},
		onSuccess: function(transport)
		{
	      var rese = transport.responseText || "629"; 
//        $('admincontent').innerHTML = rese; 
          var u = new Ajax.Request('/ajax/getaddresses.php',
	      {
            asynchronous : false,
	        method:'get',
            parameters: {expertid : expertid},
	        onSuccess: function(transport)
			{
	        var resds = transport.responseText || "638"; 
            $('addresseshere').innerHTML = ""; 
            $('addresseshere').innerHTML = resds; 
			$('secondary_name').value = ""; 
			$('secondary_business_description').value = ""; 
			$('secondary_address').value = ""; 
			$('secondary_city').value = ""; 
			$('secondary_state').value = ""; 
			$('secondary_zip').value = ""; 
			$('secondary_phone').value = ""; 
			$('secondary_fax').value = ""; 
			$('msg').style.display = "inline"; 
            $('msg').innerHTML = "Address Deleted"; 
			},
	        onFailure: function(){ alert('652') }
	      });
		}  
	  });
  },
  editaddress: function(addrid)
  {
    $('msg').style.display = "none"; 
    $('theaddress').value = addrid;
    var rand=Math.random()*5;
    var rand=Math.floor(rand);
	var u = new Ajax.Request('/ajax/getaddress.php',
    {
      asynchronous : false,
      method:'get',
      parameters: {rand:rand,addrid: addrid},
      onSuccess: function(transport){
      var res = transport.responseText || "find dogs"; 
	  var resd = res.split('|');
	  $('secondary_name').value = resd[0]; 
	  $('secondary_business_description').value = resd[1]; 
	  $('secondary_address').value = resd[2]; 
	  $('secondary_city').value = resd[3]; 
      $('secondary_state').value = resd[4]; 
	  $('secondary_zip').value = resd[5]; 
	  $('secondary_phone').value = resd[6]; 
	  $('secondary_fax').value = resd[7]; 
	  $('msg').style.display = "inline"; 
	  $('msg').innerHTML = "Edit Address"; 
	  },
	  onFailure: function(){ alert('Call doodley...Something went wrong...'); }
	});
  },
  saveaddress: function(expertid)
  {
    $('msg').style.display = "none"; 
    var error = "";
	var theaddressid = $('theaddress').value;
	var secondary_name = $('secondary_name').value; 
    var secondary_business_description = $('secondary_business_description').value; 
    var secondary_address = $('secondary_address').value; 
    var secondary_city = $('secondary_city').value; 
    var secondary_state = $('secondary_state').value; 
    var secondary_zip = $('secondary_zip').value; 
    var secondary_phone = $('secondary_phone').value; 
    var secondary_fax = $('secondary_fax').value; 
	var fvalid = new Validate;
    if(fvalid.isEmpty(secondary_name))
	{
	  error += "Please enter your name\n";
	}
    if(fvalid.isEmpty(secondary_business_description))
	{
	  error += "Please enter your business description\n";
	}
    if(fvalid.isEmpty(secondary_zip))
	{
	  error += "Please enter your postal code\n";
	}
    else
	{
      var validZip = fvalid.isZIPCode(secondary_zip); 
      if(validZip == false)
      {
	    error += "Postal code invalid...5 or 9 digits\n";
	  }
    }
	var validPhone = fvalid.isEmpty(secondary_phone); 
    if(validPhone == false)
	{
      validPhone = fvalid.checkUSPhone(secondary_phone); 
      if(validPhone == false)
      {
	    error += "Invalid US phone number ...10 digits\n";
	  }
	}
	var validFax = fvalid.isEmpty(secondary_fax); 
    if(validFax == false)
	{
      validFax = fvalid.checkUSPhone(secondary_fax); 
      if(validFax == false)
      {
	    error += "Invalid US fax number ...10 digits\n";
	  }
	}

    if(error != "")
	{
      alert(error);
	  return false;
	}

	secondary_name = Url.encode(secondary_name); 
    secondary_business_description = Url.encode(secondary_business_description); 
    secondary_address = Url.encode(secondary_address); 
    secondary_city = Url.encode(secondary_city); 
    secondary_state = Url.encode(secondary_state); 
    secondary_zip = Url.encode(secondary_zip); 
    secondary_phone = Url.encode(secondary_phone); 
    secondary_fax = Url.encode(secondary_fax); 
      var sand=Math.random()*5;
      var rand=Math.floor(sand);
      var tss = new Ajax.Request('/ajax/saveaddress.php',
	  {
        asynchronous : false,
		method:'get',
        parameters: {rand:rand ,expertid: expertid,secondary_name:secondary_name,secondary_business_description:secondary_business_description,secondary_address:secondary_address,secondary_city:secondary_city,secondary_state:secondary_state,secondary_zip:secondary_zip,secondary_phone:secondary_phone,secondary_fax:secondary_fax,theaddressid:theaddressid},
		onSuccess: function(btransport){
	    var rese = btransport.responseText || "find 708"; 
//alert(rese);
//        $('admincontent').innerHTML = rese; 
          var uu = new Ajax.Request('/ajax/getaddresses.php',
	      {
	        method:'get',
            parameters: {rand:rand,expertid: expertid},
	        onSuccess: function(utransport){
	        var resdz = utransport.responseText || "find 715"; 

            $('addresseshere').innerHTML = ""; 
            $('addresseshere').innerHTML = resdz; 
			$('secondary_name').value = ""; 
			$('secondary_business_description').value = ""; 
			$('secondary_address').value = ""; 
			$('secondary_city').value = ""; 
			$('secondary_state').value = ""; 
			$('secondary_zip').value = ""; 
			$('secondary_phone').value = ""; 
			$('secondary_fax').value = ""; 
            $('theaddress').value = "";
            $('msg').style.display = "inline"; 
            $('msg').innerHTML = "Address Saved"; 
			},
	        onFailure: function(){ alert('Call doodley...Something went wrong...') }
	      });
		},
		onFailure: function(){ alert('Call Ghostbusters...Something went wrong...'); }
	  });
  },
  updatecardedit : function(expert_id,card_id,update_or_close)
  {
	if(update_or_close == 'y')
	{
      var m = $('expm').getValue();
      var y = $('expy').getValue();
      var a = $('act').getValue();
      var rand=Math.random()*5;
      var rand=Math.floor(rand);
	  var t = new Ajax.Request('/ajax/updatecardedit.php',
	  {
        asynchronous : false,
		method:'get',
        parameters: {rand:rand,card_id: card_id,m:m,y:y,a:a},
		onSuccess: function(transport){
	    var rese = transport.responseText || "751";
		$('paymentdetails').innerHTML = ""; 
        $('paymentdetails').hide(); 
		var frameEl = window.frameElement;
		if (frameEl)
		frameEl.src = frameEl.src;
		},
		onFailure: function(){ alert('761') }
	  });
    }
	else
    {
        $('paymentdetails').innerHTML = ""; 
        $('paymentdetails').hide(); 
    }
  },
  editccnum: function(card_id,expert_id)
  {
	  var t = new Ajax.Request('/ajax/editccnum.php',
	  {
		method:'get',
        parameters: {card_id: card_id, expert_id: expert_id},
		onSuccess: function(transport){
	    var rese = transport.responseText || "751";
        $('paymentdetails').show(); 
        $('paymentdetails').innerHTML = rese; 
		},
		onFailure: function(){ alert('Call Ghostbusters...Something went wrong...') }
	  });
  },
  deletepaymentcard: function(expert_id,card_id)
  {
      var rand=Math.random()*5;
      var rand=Math.floor(rand);
	  var t = new Ajax.Request('/ajax/deletepaymentcard.php',
	  {
            asynchronous : false,
			method:'get',
			parameters: {rand:rand,expert_id:expert_id,card_id:card_id},
			onSuccess: function(transport){
			var rese = transport.responseText || "815";
			$('paymentdetails').innerHTML = ""; 
			$('paymentdetails').hide(); 
			var frameEl = window.frameElement;
			if (frameEl)
			frameEl.src = frameEl.src;
			},
			onFailure: function(){ alert('822') }
	  });
  },
  addcreditcardNoFree: function(expert_id,add_or_close)
  {
    var err = ""; 
	if(add_or_close == 'y')
	{
        var cctype = $('cctype').getValue();
        var expmon = $('expmon').getValue();
        var expyear = $('expyear').getValue();
        var act = $('act').getValue();
        var ccnum = $('ccnum').getValue();
        var cardname = $('cardname').getValue();
        var cvv2 = $('cvv2').getValue();

		var fvalid = new Validate;
		var vccnum = fvalid.isValidCreditCardNumber(ccnum,cctype);
		var vcardname = fvalid.isEmpty(cardname);
		var vcardtype = fvalid.isEmpty(cctype);
		var vcvv2 = fvalid.isEmpty(cvv2);
		var vexpmon = fvalid.isEmpty(expmon);
		var vexpyear = fvalid.isEmpty(expyear);
		 
	    $('cctype').style.backgroundColor = "#FFFFFF";
	    $('ccnum').style.backgroundColor =  "#FFFFFF";
	    $('cardname').style.backgroundColor = "#FFFFFF";
	    $('expmon').style.backgroundColor = "#FFFFFF"; 
	    $('expyear').style.backgroundColor = "#FFFFFF"; 
	    $('cvv2').style.backgroundColor = "#FFFFFF";		

		if (vcardtype == true)
		{
		  err += " - ";
		  $('cctype').style.backgroundColor = "#FF6666";
		}
		if (vccnum == false)
		{
		  err += " Invalid CC ";
		  $('ccnum').style.backgroundColor = "#FF6666";
		}
		if (vcardname == true)
		{
		  err += " - ";
		  $('cardname').style.backgroundColor = "#FF6666";
		}
		else if (vcardname == false)
		{
			var vfcardname = fvalid.hasWhitespace(cardname);
			if (vfcardname == false)
			{
			  err += " First & last name ";
			  $('cardname').style.backgroundColor = "#FF6666";
			}
		}
		if (vexpmon == true || vexpyear == true)
		{
		  err += " - ";
		  $('expmon').style.backgroundColor = "#FF6666"; 
		  $('expyear').style.backgroundColor = "#FF6666"; 
        }
		if (vcvv2 == true)
		{
		  err += " - ";
		  $('cvv2').style.backgroundColor = "#FF6666";		
		}
        if(err == "")
        {
          var rand=Math.random()*5;
          var rand=Math.floor(rand);
		  var t = new Ajax.Request('/ajax/addcreditcardNoFree.php',
		  {
            asynchronous : false,
			method:'get',
			parameters: {rand:rand,cctype:cctype,expert_id:expert_id,ccnum:ccnum,cardname:cardname,cvv2:cvv2,expmon:expmon,expyear:expyear},
			onSuccess: function(transport)
			{
			  var response = transport.responseText || "1234"; 
			  var res = response.split('|');
			  if(res[0] == 'Success')
			  {
			    $('paymentdetails').innerHTML = "Success! A confirmation email has been sent. Click <a href='#' onClick='dorefresh();'>HERE</a> to continue.";  
		      }
			  else
		      {
				$('paymentdetails').innerHTML = "An error occured processing your request. Please refresh this page and try again.";  
		      }  
			},
			onFailure: function(){ alert('1163') }
		  });
        }
		else
	    {
			return false;
        }
	}
	else
    {
      $('paymentdetails').innerHTML = ""; 
      $('paymentdetails').hide(); 
    }
  },
  addcreditcard: function(expert_id,add_or_close)
  {
    var err = ""; 
	if(add_or_close == 'y')
	{
        var cctype = $('cctype').getValue();
        var expmon = $('expmon').getValue();
        var expyear = $('expyear').getValue();
        var act = $('act').getValue();
        var ccnum = $('ccnum').getValue();
        var cardname = $('cardname').getValue();
        var cvv2 = $('cvv2').getValue();

		var fvalid = new Validate;
		var vccnum = fvalid.isValidCreditCardNumber(ccnum,cctype);
		var vcardname = fvalid.isEmpty(cardname);
		var vcardtype = fvalid.isEmpty(cctype);
		var vcvv2 = fvalid.isEmpty(cvv2);
		var vexpmon = fvalid.isEmpty(expmon);
		var vexpyear = fvalid.isEmpty(expyear);
		 
	    $('cctype').style.backgroundColor = "#FFFFFF";
	    $('ccnum').style.backgroundColor =  "#FFFFFF";
	    $('cardname').style.backgroundColor = "#FFFFFF";
	    $('expmon').style.backgroundColor = "#FFFFFF"; 
	    $('expyear').style.backgroundColor = "#FFFFFF"; 
	    $('cvv2').style.backgroundColor = "#FFFFFF";		

		if (vcardtype == true)
		{
		  err += " - ";
		  $('cctype').style.backgroundColor = "#FF6666";
		}
		if (vccnum == false)
		{
		  err += " Invalid CC ";
		  $('ccnum').style.backgroundColor = "#FF6666";
		}
		if (vcardname == true)
		{
		  err += " - ";
		  $('cardname').style.backgroundColor = "#FF6666";
		}
		else if (vcardname == false)
		{
			var vfcardname = fvalid.hasWhitespace(cardname);
			if (vfcardname == false)
			{
			  err += " First & last name ";
			  $('cardname').style.backgroundColor = "#FF6666";
			}
		}
		if (vexpmon == true || vexpyear == true)
		{
		  err += " - ";
		  $('expmon').style.backgroundColor = "#FF6666"; 
		  $('expyear').style.backgroundColor = "#FF6666"; 
        }
		if (vcvv2 == true)
		{
		  err += " - ";
		  $('cvv2').style.backgroundColor = "#FF6666";		
		}
        if(err == "")
        {
          var rand=Math.random()*5;
          var rand=Math.floor(rand);
		  var t = new Ajax.Request('/ajax/addcreditcard.php',
		  {
            asynchronous : false,
			method:'get',
			parameters: {rand:rand,cctype:cctype,expert_id:expert_id,act:act,ccnum:ccnum,cardname:cardname,cvv2:cvv2,expmon:expmon,expyear:expyear},
			onSuccess: function(transport){
			var rese = transport.responseText || "751";
			$('paymentdetails').innerHTML = ""; 
			$('paymentdetails').hide(); 
			var frameEl = window.frameElement;
			if (frameEl)
			frameEl.src = frameEl.src;
			},
			onFailure: function(){ alert('761') }
		  });
        }
		else
	    {
			return false;
        }
	}
	else
    {
      $('paymentdetails').innerHTML = ""; 
      $('paymentdetails').hide(); 
    }
  },
  activateaddccnum: function(expert_id)
  {
	  var t = new Ajax.Request('/ajax/activateaddccnum.php',
	  {
		method:'get',
        parameters: {expert_id: expert_id},
		onSuccess: function(transport){
	    var rese = transport.responseText || "987";
        $('paymentdetails').show(); 
        $('paymentdetails').innerHTML = rese; 
		},
		onFailure: function(){ alert('Something went wrong...') }
	  });
  },
  addccnum: function(expert_id)
  {
	  var t = new Ajax.Request('/ajax/addccnum.php',
	  {
		method:'get',
        parameters: {expert_id: expert_id},
		onSuccess: function(transport){
	    var rese = transport.responseText || "751";
        $('paymentdetails').show(); 
        $('paymentdetails').innerHTML = rese; 
		},
		onFailure: function(){ alert('Call Ghostbusters...Something went wrong...') }
	  });
  },
  viewpaymenthistory: function(expertid)
  {
	  var t = new Ajax.Request('/ajax/downloadpayments.php',
	  {
		method:'get',
        parameters: {expertid: expertid},
		onSuccess: function(transport){
	    var rese = transport.responseText || " 948 "; 
//alert(rese);
		$('psent').innerHTML = " (Payment Sent)"; 
		},
		onFailure: function(){ alert('951') }
	  }); 
  },
  logmeout: function(expertid)
  {
	  var t = new Ajax.Request('/ajax/logmeout.php',
	  {
		method:'get',
        parameters: {expertid: expertid},
		onSuccess: function(transport){
	    var rese = transport.responseText || "find pros";
        window.location.href = rese; 
        return true;
		},
		onFailure: function(){ alert('770') }
	  });
  }
};

var myadmin = new Proadmin;

function myquestion(expert_id)
{
    var err = "";
	var fvalid = new Validate;
	var email = $('email').getValue(); 
	var name = $('name').getValue(); 
	var phone = $('phone').getValue(); 
	var addr = $('addr').getValue(); 
	var csz = $('csz').getValue(); 
	var question = $('question').getValue(); 
	var zip = $('zip').getValue(); 
	var vzip = fvalid.isZIPCode(zip);

	var vemail = fvalid.isEmail(email);

    if(phone == "" || csz == "" || addr == "" || email == "" || question == "" || name == "" || zip == "")
    {
      err += "Required fields missing -";
      $('errorexpert').show(); 
      $('errorexpert').innerHTML = "Required fields missing.";
	  return false; 
    }
	if(vemail == false)
    {
      err += "Invalid email address - ";
	}
	if(phone == "")
    {
      err += "Phone required - ";
	}
	if(vzip == false)
    {
      err += "Invalid postal code - ";
	}
    if(phone != "")
    {
      var vphone = fvalid.checkUSPhone(phone);
	  if(vphone == false)
      {
        err += "Invalid phone number - ";
	  }
    }
    if(err != "")
    {
      $('errorexpert').show();
      $('errorexpert').innerHTML = err;
	  return false;
    }
	else
    {
	  question = Url.encode(question); 
	  name = Url.encode(name); 
	  var trex = new Ajax.Request('/ajax/sendemail.php',
	  {
		method:'get',
        parameters: {expert_id : expert_id,zip:zip,name:name,email:email,question:question,phone:phone,addr:addr,csz:csz},
		onSuccess: function(transport){
		  var rese = transport.responseText || "find ";
//alert(rese);
		  $('errorexpert').hide(); 
	      $('emailtheexpert').innerHTML = '<br /><br /><h4>Email Sent</h4><br /><br /><br /><br /><p align=\"center\"><a href=\"#\" onclick=\"Modalbox.hide(); return false;\">Close Window</a>';
		},
		onFailure: function(){ alert(' 795 ') }
	  });
    }
}

function rmssearchexpertsearch()
{
    var err = "";
	var fvalid = new Validate;
	var email = $('email').getValue(); 
	var name = $('name').getValue(); 
	var phone = $('phone').getValue(); 
	var addr = $('addr').getValue(); 
	var csz = $('csz').getValue(); 
	var question = $('question').getValue(); 
	var zip = $('zip').getValue(); 
	var vzip = fvalid.isZIPCode(zip);
	var notify = getRadioValue('notify');
	var stooge = "";
    if( $('stooge').checked == true) 
    {
      stooge = 'y';
    }    
	else
	{
	  stooge = 'n';
	}
	var category = $F('cat');
	var vemail = fvalid.isEmail(email);

    if(phone == "" || csz == "" || addr == "" || email == "" || question == "" || name == "" || zip == "")
    {
      err += "Required fields missing -";
      $('error').show(); 
      $('error').innerHTML = "Required fields missing.";
	  return false; 
    }
	if(vemail == false)
    {
      err += "Invalid email address - ";
	}
	if(phone == "")
    {
      err += "Phone required - ";
	}
	if(vzip == false)
    {
      err += "Invalid postal code - ";
	}
    if(phone != "")
    {
      var vphone = fvalid.checkUSPhone(phone);
	  if(vphone == false)
      {
        err += "Invalid phone number - ";
	  }
    }
    if(err != "")
    {
      $('error').show();
      $('error').innerHTML = err;
	  return false;
    }


	if(err == "")
    {
	  question = Url.encode(question); 
	  name = Url.encode(name); 
	  var trex = new Ajax.Request('/ajax/rsmsearchtopro.php',
	  {
		method:'get',
        parameters: {stooge:stooge,notify:notify,zip:zip,name:name,email:email,question:question,category:category,phone:phone,addr:addr,csz:csz},
		onSuccess: function(transport){
		  var zrese = transport.responseText || " hey ";
//        alert(zrese);
		  $('error').hide(); 
		  $('rsmfindanexpert').innerHTML = '<br /><br /><h3 class=\"thead\">Email Sent</h3><br /><br /><br /><br /><p align=\"center\">Thank you for your inquiry.<br>RSM will pass this information to an expert in your area.<br><br><a class=\"thelink\" href=\"#\" onclick=\"Modalbox.hide(); return false;\"><b>Close Window</b></a>';
		},
		onFailure: function(){ alert(' 918 ...Something went wrong...') }
	  });
    }
}

function nextstep()
{
	var fvalid = new Validate;
	var name = $('name').getValue(); 
	var email = $('email').getValue(); 
	var cemail = $('cemail').getValue(); 
	var business_name = $('business_name').getValue(); 
	var business_address = $('business_address').getValue(); 
	var business_phone = $('business_phone').getValue(); 

	var vemail = fvalid.isEmail(email);
    var validPhone = fvalid.checkUSPhone(business_phone); 

    if(name=="" || email == "" || business_name == "" || business_address == ""  || business_phone == "")
    {
      $('errormybusiness').show(); 
      $('errormybusiness').innerHTML = "Please fill in all information- thanks!"; 
    }
    else if(vemail == false)
    {
      $('errormybusiness').show(); 
      $('errormybusiness').innerHTML = "Invalid email address."; 
	}
    else if(email != cemail)
    {
      $('errormybusiness').show(); 
      $('errormybusiness').innerHTML = "Email addresses do not match, please re-enter- thanks!"; 
	}
    else if(validPhone == false)
    {
      $('errormybusiness').show(); 
      $('errormybusiness').innerHTML = "Invalid US phone number- please re-enter & thanks!"; 
    }
	else
    {
	  name = Url.encode(name); 
	  business_name = Url.encode(business_name); 
	  business_address = Url.encode(business_address); 
	  business_phone = Url.encode(business_phone); 
	  var trex = new Ajax.Request('/ajax/mybusiness.php',
	  {
		method:'get',
		parameters: {name : name,email : email,business_name : business_name, business_address : business_address,  business_phone : business_phone},
		onSuccess: function(transport){
	    var rese = transport.responseText || "find "; 
	    $('errormybusiness').hide(); 
		window.location.href = "/checkout.html";  
	  },
		onFailure: function(){ alert(' 1138 ') }
	  });
    }
}

function rsmfindexpert()
{
    var err = "";
	var fvalid = new Validate;
	var email = $('email').getValue(); 
	var name = $('name').getValue(); 
	var phone = $('phone').getValue(); 
	var addr = $('addr').getValue(); 
	var csz = $('csz').getValue(); 
	var question = $('question').getValue(); 
	var zip = $('zip').getValue(); 
	var vzip = fvalid.isZIPCode(zip);
	var notify = getRadioValue('notify');
    var category = $F('cat');
	var vemail = fvalid.isEmail(email);
	var stooge = "";
    if( $('stooge').checked == true) 
    {
      stooge = 'y';
    }    
	else
	{
	  stooge = 'n';
	}
	
    if(csz == "" || addr == "" || email == "" || question == "" || name == "" || zip == "")
    {
      err += "Required fields missing -";
      $('error').show(); 
      $('error').innerHTML = "Required fields missing.";
	  return false; 
    }
	if(vemail == false)
    {
      err += "Invalid email address - ";
	}
	if(vzip == false)
    {
      err += "Invalid postal code - ";
	}
    if(phone == "")
    {
      err += "Phone required - ";
    }
    if(phone != "")
    {
      var vphone = fvalid.checkUSPhone(phone);
	  if(vphone == false)
      {
        err += "Invalid phone number - ";
	  }
    }
    if(err != "")
    {
      $('error').show();
      $('error').innerHTML = err;
	  return false;
    }
//alert("ll "+err+" ll"); 
	if(err == "")
    {
	  question = Url.encode(question); 
	  name = Url.encode(name); 
	  var trex = new Ajax.Request('/ajax/rsmfindexpert.php',
	  {
		method:'get',
        parameters: {stooge:stooge,notify:notify,zip:zip,name:name,email:email,question:question,category:category,phone:phone,addr:addr,csz:csz},
		onSuccess: function(transport){
		  var zrese = transport.responseText || " hey ";
//        alert(zrese);
		  $('error').hide(); 
		  $('rsmfindanexpert').innerHTML = '<br /><br /><h3 class=\"thead\">Email Sent</h3><br /><br /><br /><br /><p align=\"center\">Thank you for your inquiry.<br>RSM will respond as soon as is possible.<br><br><a class=\"thelink\" href=\"#\" onclick=\"Modalbox.hide(); return false;\"><b>Close Window</b></a>';
		},
		onFailure: function(){ alert(' 1071 ') }
	  });
    }
}

function rsmtellfriend()
{
    var err = "";
	var fvalid = new Validate;
	var email = $('email').getValue(); 
	var email1= $('email1').getValue(); 
	var email2= $('email2').getValue(); 
	var email3= $('email3').getValue(); 
	var email4= $('email4').getValue(); 
	var email5= $('email5').getValue(); 
	var rec = $('rec').getValue(); 
      $('0').hide(); 
      $('1').hide(); 
      $('2').hide(); 
      $('3').hide(); 
      $('4').hide(); 
      $('5').hide(); 
      $('6').hide(); 

	var vemail = fvalid.isEmail(email);
	var vemail1 = fvalid.isEmail(email1);

    if(email == "")
    {
      err += "Required fields missing -";
      $('0').show(); 
      $('0').innerHTML = " *Required";
    }
	else if(vemail == false)
    {
      err += "Invalid email address ";
      $('0').show(); 
      $('0').innerHTML = " *Invalid Email";
	}
	if(email1 == "")
    {
      err += "Required fields missing -";
      $('1').show(); 
      $('1').innerHTML = " *Required";
    }
	else if(vemail1 == false)
    {
      err += "Invalid email address ";
      $('1').show(); 
      $('1').innerHTML = " *Invalid Email";
	}

	if(email2 != "")
    {
      var vemailx = fvalid.isEmail(email2);
      if(vemailx == false)
      {
        err += "Invalid email address ";
        $('2').show(); 
        $('2').innerHTML = " *Invalid Email";
	  }
	}

	if(email3 != "")
    {
      var vemailx = fvalid.isEmail(email3);
      if(vemailx == false)
      {
        err += "Invalid email address ";
        $('3').show(); 
        $('3').innerHTML = " *Invalid Email";
	  }
	}
	if(email4 != "")
    {
      var vemailx = fvalid.isEmail(email4);
      if(vemailx == false)
      {
        err += "Invalid email address ";
        $('4').show(); 
        $('4').innerHTML = " *Invalid Email";
	  }
	}
	if(email5 != "")
    {
      var vemailx = fvalid.isEmail(email5);
      if(vemailx == false)
      {
        err += "Invalid email address ";
        $('5').show(); 
        $('5').innerHTML = " *Invalid Email";
	  }
	}


	if(rec == "")
    {
        err += "required";
        $('6').show(); 
        $('6').innerHTML = " *Required";
	}

	if(err == "")
    {
	  rec = Url.encode(rec); 
	  var trex = new Ajax.Request('/ajax/rsmtellafriend.php',
	  {
		method:'get',
        parameters: {email:email,email1:email1,email2:email2,email3:email3,email4:email4,email5:email5,rec:rec},
		onSuccess: function(transport){
		  var zrese = transport.responseText || " hey ";
//        alert(zrese);
		  $('tellfriend').innerHTML = "<br /><br /><h3 align='center'>Recommendation Email Sent!</h3><br /><br /><br /><br /><p align='center'>Thank you for your recommendations.<br>RSM has emailed your comments to your friends.<br><br>";
		},
		onFailure: function(){ alert(' 1163 ') }
	  });
    }
}

function itsmybusiness()
{
	var err = "";
	var fvalid = new Validate;
	var email = $('email').getValue(); 
	var phone = $('phone').getValue(); 
	var comments = $('comments').getValue(); 
	var expert_id = $('expert_id').getValue(); 

    $('0').hide(); 

	var vemail = fvalid.isEmail(email);

    if(email == "" || (vemail === false))
    {
      err = "Required email missing or invalid.";
      $('0').show(); 
      $('0').innerHTML = "*Required email missing or invalid.";
    }

	if(err == "")
    {
	  var trex = new Ajax.Request('/ajax/itsmybusiness.php',
	  {
		method:'get',
        parameters: {email:email,phone:phone,comments:comments,expert_id:expert_id},
		onSuccess: function(transport){
		  var zrese = transport.responseText || " hey ";
//        alert(zrese);
		  $('tellfriend').innerHTML = "<br /><br /><h3 align='center'>Thank You. We will retrieve and send your login ASAP!</h3><br /><br /><br /><p align='center'>Best wishes from RSM Home Improvement.</p>";
		},
		onFailure: function(){ alert(' 1163 ') }
	  });
    }
}


function rsmsearchaddcontent()
{
    var err = "";
	var fvalid = new Validate;
	var email = $('email').getValue(); 
	var name = $('name').getValue(); 
	var question = $('question').getValue(); 
	var addr = $('addr').getValue(); 
	var csz = $('csz').getValue(); 
	var zip = $('zip').getValue(); 
	var vzip = fvalid.isZIPCode(zip);
	var notify = getRadioValue('notify');
	var stooge = "";
    if( $('stooge').checked == true) 
    {
      stooge = 'y';
    }    
	else
	{
	  stooge = 'n';
	}

	var category = $F('cat');
	var vemail = fvalid.isEmail(email);

    if(csz == "" || addr == "" || email == "" || question == "" || name == "" || zip == "")
    {
      err += "Required fields missing -";
      $('error').show(); 
      $('error').innerHTML = "Required fields missing.";
	  return false; 
    }
	if(vemail == false)
    {
      err += "Invalid email address - ";
	}
	if(vzip == false)
    {
      err += "Invalid postal code - ";
	}
    if(err != "")
    {
      $('error').show();
      $('error').innerHTML = err;
	  return false;
    }
//alert("ll "+err+" ll"); 
//alert(stooge);
	if(err == "")
    {
	  question = Url.encode(question); 
	  name = Url.encode(name); 
	  var trex = new Ajax.Request('/ajax/rsmsearchaddcontent.php',
	  {
		method:'get',
        parameters: {stooge:stooge,addr:addr,csz:csz,notify:notify,zip:zip,name:name,email:email,question:question,category:category},
		onSuccess: function(transport){
		  var zrese = transport.responseText || " hey ";
//        alert(zrese);
		  $('error').hide(); 
		  $('rsmaddcontent').innerHTML = '<br /><br /><h3 class=\"thead\">Email Sent</h3><br /><br /><br /><br /><p align=\"center\">Thank you for your addition to the library.<br>We will be reviewing your content soon.<br><br><a class=\"thelink\" href=\"#\" onclick=\"Modalbox.hide(); return false;\"><b>Close Window</b></a>';
		},
		onFailure: function(){ alert(' 1308 ') }
	  });
    }
}

function rsmrecommendexpert()
{
    var err = "";
	var fvalid = new Validate;
	var mname = $('mname').getValue(); 
	var memail = $('memail').getValue(); 
	var maddr = $('maddr').getValue(); 
	var mcsz = $('mcsz').getValue(); 
	var mzip = $('mzip').getValue(); 
	var mphone = $('mphone').getValue(); 
	var ename = $('ename').getValue(); 
	var eaddr = $('eaddr').getValue(); 
	var ecsz = $('ecsz').getValue(); 
	var ephone = $('ephone').getValue(); 
	var equestion = $('equestion').getValue(); 
    var category = $F('cat');
	var vemail = fvalid.isEmail(memail);

	var stooge = "";
    if( $('stooge').checked == true) 
    {
      stooge = 'y';
    }    
	else
	{
	  stooge = 'n';
	}

    if(equestion == "" || ephone == "" || ecsz == "" || eaddr == "" || ename == "" || mzip == "" || memail == "" || mname == "" || mcsz == ""  || maddr == "")
    {
      err += "Required fields missing -";
      $('error').show(); 
      $('error').innerHTML = "Required fields missing.";
	  return false; 
    }
	if(vemail == false)
    {
      err += "Invalid email address - ";
	}
    if(mphone != "")
    {
      var vphone = fvalid.checkUSPhone(mphone);
	  if(vphone == false)
      {
        err += "Invalid phone number - ";
	  }
    }
    if(err != "")
    {
      $('error').show();
      $('error').innerHTML = err;
	  return false;
    }
	if(err == "")
    {
	  ename = Url.encode(ename); 
	  eaddr = Url.encode(eaddr); 
	  ecsz = Url.encode(ecsz); 
	  mname = Url.encode(mname); 
	  memail = Url.encode(memail);  
	  maddr = Url.encode(maddr);  
	  mcsz = Url.encode(mcsz);  
	  equestion = Url.encode(equestion); 
	  var trex = new Ajax.Request('/ajax/rsmrecommendexpert.php',
	  {
		method:'get',
        parameters: {stooge:stooge,mname:mname,memail:memail,maddr:maddr,mcsz:mcsz,mzip:mzip,mphone:mphone,ename:ename,eaddr:eaddr,ecsz:ecsz,ephone:ephone,equestion:equestion,category:category},
		onSuccess: function(transport){
		  var zrese = transport.responseText || " 1366 ";
		  $('error').hide(); 
		  $('rsmrecommendexpert').innerHTML = '<br /><br /><h3 class=\"thead\">Recommendation Email Sent</h3><br /><br /><br /><br /><p align=\"center\">Thank you for your recommendation.<br>RSM will respond as soon as possible.<br><br><a class=\"thelink\" href=\"#\" onclick=\"Modalbox.hide(); return false;\"><b>Close Window</b></a>';
		},
		onFailure: function(){ alert(' 1373 ') }
	  });
    }
}

function selectproduct(radio)
{
  var val = getRadioValue(radio);
  if(val == null)
  {
    $('error').show(); 
  }
  else 
  {
    document.buy.submit(); 
	return true; 
  }
}

var Url = {  
     encode : function (string) {  
         return escape(this._utf8_encode(string));  
     },  
     decode : function (string) {  
         return this._utf8_decode(unescape(string));  
     },  
     _utf8_encode : function (string) {  
         string = string.replace(/\r\n/g,"\n");  
         var utftext = "";  
   
         for (var n = 0; n < string.length; n++) {  
   
             var c = string.charCodeAt(n);  
   
             if (c < 128) {  
                 utftext += String.fromCharCode(c);  
             }  
             else if((c > 127) && (c < 2048)) {  
                 utftext += String.fromCharCode((c >> 6) | 192);  
                 utftext += String.fromCharCode((c & 63) | 128);  
             }  
             else {  
                 utftext += String.fromCharCode((c >> 12) | 224);  
                 utftext += String.fromCharCode(((c >> 6) & 63) | 128);  
                 utftext += String.fromCharCode((c & 63) | 128);  
             }  
         }  
         return utftext;  
     },  
     _utf8_decode : function (utftext) {  
         var string = "";  
         var i = 0;  
         var c = c1 = c2 = 0;  
         while ( i < utftext.length ) {  
             c = utftext.charCodeAt(i);  
             if (c < 128) {  
                 string += String.fromCharCode(c);  
                 i++;  
             }  
             else if((c > 191) && (c < 224)) {  
                 c2 = utftext.charCodeAt(i+1);  
                 string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));  
                 i += 2;  
             }  
             else {  
                 c2 = utftext.charCodeAt(i+1);  
                 c3 = utftext.charCodeAt(i+2);  
                 string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));  
                 i += 3;  
             }  
         }  
         return string;  
     }  
 };

function getDateObject(dateString,dateSeperator)
{
	//This function return a date object after accepting 
	//a date string ans dateseparator as arguments
	var curValue=dateString;
	var sepChar=dateSeperator;
	var curPos=0;
	var cDate,cMonth,cYear;

	//extract day portion
	curPos=dateString.indexOf(sepChar);
	cDate=dateString.substring(0,curPos);
	
	//extract month portion				
	endPos=dateString.indexOf(sepChar,curPos+1);			
	cMonth=dateString.substring(curPos+1,endPos);

	//extract year portion				
	curPos=endPos;
	endPos=curPos+5;			
	cYear=curValue.substring(curPos+1,endPos);
	
	//Create Date Object
	dtObject=new Date(cYear,cMonth,cDate);	
	return dtObject;
}

var emailinuse = ""; 
function freepay(curdate)
{ 
//  $('error').show(); 
	$('email').style.backgroundColor = "#FFFFFF";
    $('password').style.backgroundColor = "#FFFFFF";
    $('name').style.backgroundColor = "#FFFFFF";
    $('phone').style.backgroundColor = "#FFFFFF";
	$('changecategory').style.backgroundColor = "#FFFFFF";
    $('bname').style.backgroundColor = "#FFFFFF";
    $('baddr').style.backgroundColor = "#FFFFFF";
    $('bcity').style.backgroundColor = "#FFFFFF";
    $('bstate').style.backgroundColor = "#FFFFFF";
    $('bzip').style.backgroundColor = "#FFFFFF";

	var email = $('email').getValue(); 
    var pass1 = $('password').getValue();
    var name = $('name').getValue();
    var phone = $('phone').getValue();
	var fvalid = new Validate;
    var changecategory = $('changecategory').getValue();
    var bname = $('bname').getValue();
    var baddr = $('baddr').getValue();
    var bcity = $('bcity').getValue();
    var bstate = $('bstate').getValue();
    var bzip = $('bzip').getValue();

    var err = "";
    var vemail = fvalid.isEmail(email);
	 
	if (vemail == false)
	{
	  err += " Email invalid - ";
      $('email').style.backgroundColor = "#FF6666";
	}
	if(fvalid.isEmpty(pass1) )
	{
	  err += " Password required -";
      $('password').style.backgroundColor = "#FF6666";
	}
    if(fvalid.isEmpty(name))
	{
	  err += " Please enter your name ";
      $('name').style.backgroundColor = "#FF6666";
	}
    if(fvalid.isEmpty(phone))
	{
	  err += " Please enter your phone number ";
      $('phone').style.backgroundColor = "#FF6666";
	}
   else if(fvalid.checkUSPhone(phone) == false )
	{
	  err += " Please enter a valid business phone number  ";
      $('phone').style.backgroundColor = "#FF6666";
	}
	if(fvalid.isEmpty(bname))
	{
	  err += " Please enter your business name ";
      $('bname').style.backgroundColor = "#FF6666";
	}
    if(fvalid.isEmpty(baddr))
	{
	  err += " Please enter your business address ";
      $('baddr').style.backgroundColor = "#FF6666";
	}
    if(fvalid.isEmpty(bcity))
	{
	  err += " Please enter your business city ";
      $('bcity').style.backgroundColor = "#FF6666";
	}
    if(fvalid.isEmpty(bstate))
	{
	  err += " Please enter your business state ";
      $('bstate').style.backgroundColor = "#FF6666";
	}
    if(fvalid.isEmpty(bzip))
	{
	  err += " Please enter your business postal code ";
      $('bzip').style.backgroundColor = "#FF6666";
	}
   else if(fvalid.isZIPCode(bzip) == false )
	{
	  err += " Please enter a valid business postal code ";
      $('bzip').style.backgroundColor = "#FF6666";
	}

  if(err != "")
  {
    $('error1').show(); 
	$('error1').innerHTML = err;
  }
  else  //put in url decode thing tomorrow
  {
	  var t = new Ajax.Request('/ajax/checkemail.php',
	  {
		method:'get',
        parameters: {email: email},
		onSuccess: function(transport){
		  var rese = transport.responseText || " "; 
		  if(rese ==  "0")
		  {
			emailinuse = " *** Email IN USE *** "; 
            err += " Email IN USE "; 
            $('error1').show(); 
        	$('error1').innerHTML = err;
		  }
          else
		  {			  
			  Modalbox.show($('working'), {title:'Authorizing',width: 425, height:325, overlayClose: false}); 
			  Modalbox.deactivate();
			  var r = new Ajax.Request('/ajax/freepay.php',
			  {
				method:'get',
				parameters: {bname:bname,baddr:baddr,bcity:bcity,bstate:bstate,bzip:bzip,name:name,phone:phone,email:email,pass1:pass1,changecategory:changecategory},
				onSuccess: function(transport){
				  var response = transport.responseText || " empty ";
				  res = response.split('|');
				  if(res[0] == 'Success')
				  {
					Modalbox.hide(); 
					window.location.href = "/freethankyou.html"; 
				  }
				  else
				  {
					Modalbox.hide(); 
					$('error1').show(); 
					$('error1').innerHTML = res[0]+res[1]; 
				  }
				},
				onFailure: function(){
				  Modalbox.hide(); 
				  $('error1').show(); 
				  $('error1').innerHTML = err+emailinuse;
				}
			  });
		  }
		},
		onFailure: function(){ alert(' error 1174 ') }
	  });
  }
}


function directpay(radio,curdate)
{
  var subscription = getRadioValue(radio);
  var err = "";
  if(subscription == null)
  {
    err += "Choose Program Type";
    $('error1').show(); 
  }
  else
  {
	var email = $('email').getValue(); 
	var email2 = $('cemail').getValue(); 
	var ccnum = $('ccnum').getValue(); 
    var pass1 = $('password').getValue();
    var pass2 = $('rpassword').getValue();
    var cardname = $('cardname').getValue();
    var cvv2 = $('cvv2').getValue();
    var cardtype = $F('cctype');

	var expmon = $F('expmon');
    var expyear = $F('expyear');
//	var curdate = '<?php $dt = date("m/d/Y",time()); echo $dt; ?>';
    var inputdate = expmon+"/01/"+expyear;

	var fvalid = new Validate;
    var vccnum = fvalid.isValidCreditCardNumber(ccnum,cardtype);
    var vemail = fvalid.isEmail(email);
    var vcardname = fvalid.isEmpty(cardname);
    var vcardtype = fvalid.isEmpty(cardtype);
	var vcvv2 = fvalid.isEmpty(cvv2);
    var vexpmon = fvalid.isEmpty(expmon);
    var vexpyear = fvalid.isEmpty(expyear);
     
	if (vemail == false)
	{
	  err += " Email invalid - ";
      $('email').style.backgroundColor = "#FF6666";
	}
	else if (email != email2)
	{
	  err += " Email mismatch - ";
      $('email').style.backgroundColor = "#FF6666"; 
      $('email2').style.backgroundColor = "#FF6666"; 
	}
	if((pass1 != pass2) || (pass1 == "" && pass2 == ""))
	{
	  err += " Password mismatch -";
      $('password').style.backgroundColor = "#FF6666";
      $('rpassword').style.backgroundColor = "#FF6666";
	}
	if (vcardtype == true)
	{
	  err += " - ";
      $('cctype').style.backgroundColor = "#FF6666";
	}
	if (vccnum == false)
	{
	  err += " Invalid CC ";
      $('ccnum').style.backgroundColor = "#FF6666";
	}
	if (vcardname == true)
	{
	  err += " - ";
      $('cardname').style.backgroundColor = "#FF6666";
	}
	else if (vcardname == false)
	{
	    var vfcardname = fvalid.hasWhitespace(cardname);
		if (vfcardname == false)
	    {
	      err += " First & last name ";
          $('cardname').style.backgroundColor = "#FF6666";
	    }
 	}
	if (vexpmon == true || vexpyear == true)
	{
	  err += " - ";
	}
	if (vcvv2 == true)
	{
	  err += " - ";
	}

    var lastdate = getDateObject(curdate,"/");
    var cmpdate = getDateObject(inputdate,"/");
    if(cmpdate < lastdate)
	{
	  err += " Expired card date ";
    }
  }
  if(err != "")
  {
    $('error1').show(); 
	$('error1').innerHTML = err;
  }
  else  //put in url decode thing tomorrow
  {
	  var t = new Ajax.Request('/ajax/checkemail.php',
	  {
		method:'get',
        parameters: {email: email},
		onSuccess: function(transport){
		  var rese = transport.responseText || " "; 
		  if(rese ==  "0")
		  {
			emailinuse = " *** Email IN USE *** "; 
            err += " Email IN USE "; 
            $('error1').show(); 
        	$('error1').innerHTML = err;
		  }
          else
		  {			  
			  Modalbox.show($('working'), {title:'Authorizing',width: 425, height:325, overlayClose: false}); 
			  Modalbox.deactivate();
			  cardname = Url.encode(cardname);
			  var r = new Ajax.Request('/ajax/directpay.php',
			  {
				method:'get',
				parameters: {subscription:subscription,email:email,ccnum:ccnum,pass1:pass1,cardname:cardname,cvv2:cvv2,cardtype:cardtype,expmon:expmon,expyear:expyear},
				onSuccess: function(transport){
				  var response = transport.responseText || " empty ";
				  res = response.split('|');
				  if(res[0] == 'Success')
				  {
					Modalbox.hide(); 
					window.location.href = "/ccthankyou.html"; 
				  }
				  else
				  {
					Modalbox.hide(); 
					$('error1').show(); 
					$('error1').innerHTML = res[0]+res[1]; 
				  }
				},
				onFailure: function(){
				  Modalbox.hide(); 
				  $('error1').show(); 
//alert(res[0]+res[1]);
				  $('error1').innerHTML = err+emailinuse;
				}
			  });
		  }
		},
		onFailure: function(){ alert(' error 1174 ') }
	  });
  }
}

function xpress(radio)
{
  var err = ""; 
  var schedule = getRadioValue(radio);
  if(schedule == null)
  {
    err += " Please select product ";
    $('error').show(); 
    $('error').innerHTML = err; 
  }
  else
  {
	  var r = new Ajax.Request('/ajax/xpress.php',
	  {
		method:'get',
		parameters: {schedule: schedule},
		onSuccess: function(transport){
		  var response = transport.responseText || " empty";
		  res = response.split('|');
		  if(res[0] == 'Success')
		  {
			window.location.href='https://www.paypal.com/cgi-bin/webscr?cmd=_customer-billing-agreement&token='+res[1]; 
		  }
		  else 
		  {
			alert(" paypal error 1672 "); 
		  }
		},
		onFailure: function(){ alert('1675'); }
	  });
  }
}

function joinus(val)
{
  var p = val+'';
  $('joinrun').show(); 
  var r = new Ajax.Request('/ajax/joinus.php',
  {
    method:'get',
    parameters: {p : p},
    onSuccess: function(transport){
      $('joinrun').hide(); 
      var response = transport.responseText || "";
      $('joincontent').innerHTML = response; 
    },
    onFailure: function(){ alert('Call Ghostbusters...Something went wrong...'); }
  });
}

function confirmpaypal()
{
  var err = ""; 
  var email = $('email').getValue();
  var pass = $('password').getValue();
  var pass1 = $('rpassword').getValue();
  var fvalid = new Validate;
  var schedule = getRadioValue('buyrsm');
  var vemail = fvalid.isEmail(email);

  if (vemail == false)
  {
    err += " Email invalid - "; 
    $('email').style.backgroundColor = "#FF6666"; 
  }
  else if (email == "")
  {
    err += " Email required - "; 
    $('email').style.backgroundColor = "#FF6666"; 
  }
  if((pass != pass1) || (pass == "" && pass1 == ""))
  {
    err += " Password mismatch or password empty ";
    $('password').style.backgroundColor = "#FF6666";
    $('rpassword').style.backgroundColor = "#FF6666";
  }
  if(err != "")
  {
    $('error').show(); 
    $('error').innerHTML = err; 
  }
  else
  {
	  var t = new Ajax.Request('/ajax/checkemail.php',
	  {
		method:'get',
        parameters: {email: email},
		onSuccess: function(transport)
		{
		  var rese = transport.responseText || " "; 
		  if(rese ==  "0")
		  {
			emailinuse = " *** Email IN USE *** "; 
            err += " Email IN USE "; 
            $('error').show(); 
        	$('error').innerHTML = err;
		  }
          else
		  {			  
			  Modalbox.show($('working'), {title:'Authorizing',width: 425, height:325, overlayClose: false}); 
			  Modalbox.deactivate();
			  var r = new Ajax.Request('/ajax/confirm.php',
			  {
				method:'get',
				parameters: {schedule: schedule, email: email, pass: pass},
				onSuccess: function(transport)
				{ 
				  var response = transport.responseText || " empty "; 
				  var res = response.split('|'); 
				  Modalbox.hide(); 

				  if(res[0] == 'Success')
				  {
					window.location.href='/rrswelcome.html'; 
				  }
				  else
				  {
					Modalbox.hide(); 
                    $('error').show(); 
                    $('error').innerHTML = "Error returned from Paypal"; 
				  }
				},
				onFailure: function(){ 
				  Modalbox.hide(); 
                  $('error').show(); 
                  $('error').innerHTML = "Paypal general error returned"; 
				}
			  });
		  }
		},
		onFailure: function(){ alert(' error 1174 ') }
	  });
  }
}

function dofocus(el)
{
  if($(el).value == 'required') $(el).value == "";
  $(el).style.backgroundColor = '#228B22';
}

function doblur(el)
{
  var pc = $(el).value+"";

  if(pc == "")
  {
    $(el).value == 'required';
    $(el).style.backgroundColor = '#EE3B3B';    
  }
  else
  {
    $(el).style.backgroundColor = '#838B8B';
    $(el).blur();
  }
}

function searchPros()
{
//  $('postalerror').hide();
  var pc = $('postalcode').value;
  var search = $F('searchexp');
//  $('search').style.borderColor = '#000000';    
//  $('search').style.backgroundColor = 'rgb(219, 219, 219)';    
//  $('postalcode').style.borderColor = '#000000';    
//  $('postalcode').style.backgroundColor = 'rgb(219, 219, 219)';    
  var error = "";
  if(search == "-1")
  {
    $('searchexp').style.backgroundColor = '#EE3B3B';    
	error = 'search';
  }

  var fvalid = new Validate;
  var validZip = fvalid.isZIPCode(pc); 

  if(pc == "" || (!validZip))
  {
    $('postalcode').style.backgroundColor = '#EE3B3B';    
	error = 'postalcode';
  }

  if(error != "")
  {
    if(error == 'postalcode')
	{
	  $('postalcode').focus();
//	  $('postalerror').show();
//	  $('postalerror').innerHTML = '5 Digit Postal code';
	}
    if(error == 'search')
	{
	  $('searchexp').focus();
	}
	return false;
  }

  $('resultsexperts').innerHTML = "";
  $('gogetemz').show();

  var r = new Ajax.Request('/ajax/searchpros.php',
  {
	method:'get',
    parameters: {zip: pc, category_id: search},
	onSuccess: function(transport){
      var response = transport.responseText || "no experts found";
	  res = response.split('|'); 
	  if(res[0] == 'Z')
	  {
        window.location.href = res[1]; 
	  }
      else
	  {
	    $('gogetemz').hide();
	    $('resultsexperts').style.backgroundImage="url('/images/spacer.gif')";
        $('resultsexperts').innerHTML = res[1];
	    Scroller.reset('resultsexperts')
      }
    },
    onFailure: function(){ alert('1753'); }
  });
}

function forgotpassword()
{
  var theun = $('un').value;
  var fvalid = new Validate;
  var vun = fvalid.isEmpty(theun);
  var error = "";
  if(vun == true)
  {
	error += 'Enter account email address, then click "Forgot Password" link<br />';
  }
  if(error != "")
  {
    $('errorlogin').show();
    $('errorlogin').innerHTML = error;
    return false;
  }

  var r = new Ajax.Request('/ajax/forgotpassword.php', 
  {
	method:'get', 
    parameters: {un: theun}, 
	onSuccess: function(transport)
	{
      var response = transport.responseText || ""; 
      $('login').innerHTML = "<div style='width:300px; margin-left: 35px;'>Password sent to email entered<br><br><a href='#' onclick='Modalbox.hide(); return false;'>Close Window</a></div>";
	},
    onFailure: function(){ alert(' 1443 '); }
  });
}

function trylogin()
{
  var theun = $('un').value;
  var thepw = $('pass').value;
  var fvalid = new Validate;
  var vun = fvalid.isEmpty(theun);
  var vpw = fvalid.isEmpty(thepw);
  var error = "";
  if(vun == true)
  {
	error += 'Username required<br />';
  }
  if(vpw == true)
  {
	error += 'Password required<br />';
  }
  if(error != "")
  {
    $('errorlogin').show();
    $('errorlogin').innerHTML = error;
    return false;
  }

  var r = new Ajax.Request('/ajax/trylogin.php', 
  {
	method:'get', 
    parameters: {un: theun, pw: thepw}, 
	onSuccess: function(transport){
      var response = transport.responseText || ""; 
      res = response.split('|'); 
	  if(res[0] == '1')
	  {
        window.location.href = res[1]+".html"; 
	  }
      else if(res[0] == '0')
	  {
        $('errorlogin').show();
        $('errorlogin').innerHTML = 'Username/Password mismatch';	  
	  }
	},
    onFailure: function(){ alert(' 1942 '); }
  });
}

function searchlibrarybats()
{
  var pc = $('postalcode').value;
  var search = $('searchbat').value;
  var error = "";
  var fvalid = new Validate;
  if(search == "")
  {
    $('searchbat').style.borderColor = '#8B2323';    
    $('searchbat').style.backgroundColor = '#EE3B3B';    
	error = 'search';
  }

  var validZip = fvalid.isZIPCode(pc); 
  if(pc == "" || validZip == false)
  {
    $('postalcode').style.backgroundColor = '#EE3B3B';    
	error = 'postalcode';
  }

  if(error != "")
  {
    if(error == 'postalcode')
	{
	  $('postalcode').focus();
	}
    if(error == 'search')
	{
	  $('searchbat').focus();
	}
	return false;
  }

  $('searchbat').style.borderColor = '#FFFFFF';    
  $('searchbat').style.backgroundColor = '#FFFFFF';   

  $('postalcode').style.borderColor = '#FFFFFF';    
  $('postalcode').style.backgroundColor = '#FFFFFF';   

  $('resultsliba').innerHTML = "";
  $('gogetemz').show();

  var nolink = 'Y';
  var r = new Ajax.Request('/ajax/search.php',
  {
	method:'get',
    parameters: {zip: pc, search: search, nolink : nolink},
	onSuccess: function(transport){
      var response = transport.responseText || "  empty ";
      $('gogetemz').hide();
	  $('resultsliba').innerHTML = response;
	  $('resultsliba').style.backgroundImage="url('/images/spacer.gif')";
	  Scroller.reset('resultsliba');
	},
    onFailure: function(){ alert('1255...Something went wrong...'); }
  });
}

function searchcatbats()
{
  var pc = $('postalcode').value;
  var search = $('searchbatcat').value;
  var error = "";
  var fvalid = new Validate;
  if(search == "")
  {
    $('searchbatcat').style.borderColor = '#8B2323';    
    $('searchbatcat').style.backgroundColor = '#EE3B3B';    
	error = 'search';
  }

  var validZip = fvalid.isZIPCode(pc); 
  if(pc == "" || validZip == false)
  {
    $('postalcode').style.backgroundColor = '#EE3B3B';    
	error = 'postalcode';
  }

  if(error != "")
  {
    if(error == 'postalcode')
	{
	  $('postalcode').focus();
	}
    if(error == 'search')
	{
	  $('searchbatcat').focus();
	}
	return false;
  }

  $('searchbatcat').style.borderColor = '#FFFFFF';    
  $('searchbatcat').style.backgroundColor = '#FFFFFF';   

  $('postalcode').style.borderColor = '#FFFFFF';    
  $('postalcode').style.backgroundColor = '#FFFFFF';   

  $('resultslib').innerHTML = "";
  $('gogetemz').show();
  var nolink = 'Y';
  var r = new Ajax.Request('/ajax/search.php',
  {
	method:'get',
    parameters: {zip: pc, search: search, nolink: nolink},
	onSuccess: function(transport){
      var response = transport.responseText || "  empty ";
      $('gogetemz').hide();
//alert(response);
	  $('resultslib').innerHTML = response;
	  $('resultslib').style.backgroundImage="url('/images/spacer.gif')";
	  Scroller.reset('resultslib');
	},
    onFailure: function(){ alert(' 1786 '); }
  });
}


function searchcatsbats()
{
  var pc = $('postalcode').value;
  var search = $('search').value;
  var error = "";

  if(search == "")
  {
    $('search').style.borderColor = '#8B2323';    
    $('search').style.backgroundColor = '#EE3B3B';    
	error = 'search';
  }

  if(pc == "")
  {
    $('postalcode').style.backgroundColor = '#EE3B3B';    
	error = 'postalcode';
  }

  if(error != "")
  {
    if(error == 'postalcode')
	{
	  $('postalcode').focus();
	}
    if(error == 'search')
	{
	  $('search').focus();
	}
	return false;
  }

   $('search').style.borderColor = '#FFFFFF';    
   $('search').style.backgroundColor = '#FFFFFF';   

   $('postalcode').style.borderColor = '#FFFFFF';    
   $('postalcode').style.backgroundColor = '#FFFFFF';   

  $('resultslibrary').innerHTML = "";
  $('gogetemz').show();

  var r = new Ajax.Request('/ajax/search.php',
  {
	method:'get',
    parameters: {zip: pc, search: search},
	onSuccess: function(transport){
      var response = transport.responseText || " empty ";
      $('gogetemz').hide();
	  var str = '<table class=\"libraryintro\" width=\"100%\">\n';
	  str += '<tr><th align=\"center\">Search Topic: '+search+'</th></tr>\n';
	  str += '</table>\n';
	  $('titlemessage').innerHTML = str;
	  $('resultslibrary').innerHTML = response;
	  Scroller.reset('resultslibrary');
	  $$('#resultslibrary a').each(function(celement)
	    {
          if(celement.rel == 'q' && celement.id == 'natl') 
  		  {
			new Tip(celement, celement.rev, {title : 'Click For A Quote', className: 'silver' , showOn: 'mousemove', hideOn: {element: '.close', event: 'mouseover' }, viewport: true, fixed: true, offset: { x: 0, y:0 }, closeButton: true, target: 'href7'}); 
          }
          else if(celement.rel == 'q' && celement.id != 'natl') 
  		  {
			new Tip(celement, celement.rev, {title : 'Click For A Quote', className: 'silver' , showOn: 'mousemove', hideOn: {element: '.close', event: 'mouseover' }, viewport: true, fixed: true, offset: { x: 0, y:0 }, closeButton: true, target: 'href7'}); 
          }
		  else
		  {
		    new Tip(celement, celement.rel, {title : 'Quotes and Questions', className: 'silver', showOn: 'mousemove', hideOn: {element: '.close', event: 'mouseover' }, viewport: true, fixed: true, offset: { x: 0, y:0 }, closeButton: true, target: 'href7'}); 
          }
		}
	  )
	},
    onFailure: function(){ alert('Call Ghostbusters...Something went wrong...'); }
  });
}

function showanswerexpert(thepros)
{
  var r = new Ajax.Request('/ajax/showanswerexpert.php',
  {
    method:'get',
    parameters: {thepros: thepros},
    onSuccess: function(transport){
      var response = transport.responseText || " 2064 "; 
//    alert(response); 
      window.location.href = response; 
	},
    onFailure: function(){ alert(' fail 2067 '); }
  });
}

function showanswerquote(thepros)
{
  var r = new Ajax.Request('/ajax/showanswerquote.php',
  {
    method:'get',
    parameters: {thepros: thepros},
    onSuccess: function(transport){
      var response = transport.responseText || " 2064 "; 
//    alert(response); 
      window.location.href = response; 
	},
    onFailure: function(){ alert(' fail 2067 '); }
  });
}

function searchIndex()
{
  var pc = $('postalcode').value;
  var search = $('search').value;
//  $('search').style.borderColor = '#000000';    
  $('search').style.backgroundColor = 'rgb(219, 219, 219)';    
//  $('postalcode').style.borderColor = '#000000';    
  $('postalcode').style.backgroundColor = 'rgb(219, 219, 219)';    
  var error = "";

  if(search == "")
  {
    $('search').style.borderColor = '#8B2323';    
    $('search').style.backgroundColor = '#EE3B3B';    
	error = 'search';
  }

  var fvalid = new Validate;
  var validZip = fvalid.isZIPCode(pc); 

  if(pc == "" || (!validZip))
  {
    $('postalcode').style.backgroundColor = '#EE3B3B';    
	error = 'postalcode';
  }

  if(error != "")
  {
    if(error == 'postalcode')
	{
	  $('postalcode').focus();
	}
    if(error == 'search')
	{
	  $('search').focus();
	}
    return false;
  }

  $('resultsanswer').innerHTML = "";
  $('gogetemz').show();

  var r = new Ajax.Request('/ajax/search.php',
  {
    method:'get',
    parameters: {zip: pc, search: search},
    onSuccess: function(transport){
      var response = transport.responseText || " empty "; 
//alert(response);
      $('gogetemz').hide();
	  $('resultsanswer').innerHTML = response;
	  $('resultsanswer').style.backgroundImage="url('/images/spacer.gif')";
	  Scroller.reset('resultsanswer');
	},
    onFailure: function(){ alert(' fail 2119 '); }
  });
}

function searchIndexQuote()
{
  var pc = $('postalcode').value;
  var search = $('search').value;
  $('search').style.backgroundColor = 'rgb(219, 219, 219)';    
  $('postalcode').style.backgroundColor = 'rgb(219, 219, 219)';    
  var error = "";

  if(search == "")
  {
    $('search').style.borderColor = '#8B2323';    
    $('search').style.backgroundColor = '#EE3B3B';    
	error = 'search';
  }

  var fvalid = new Validate;
  var validZip = fvalid.isZIPCode(pc); 

  if(pc == "" || (!validZip))
  {
    $('postalcode').style.backgroundColor = '#EE3B3B';    
	error = 'postalcode';
  }

  if(error != "")
  {
    if(error == 'postalcode')
	{
	  $('postalcode').focus();
	}
    if(error == 'search')
	{
	  $('search').focus();
	}
    return false;
  }

  $('resultsanswerquote').innerHTML = "";
  $('gogetemquotez').show();

  var r = new Ajax.Request('/ajax/searchquote.php',
  {
    method:'get',
    parameters: {zip: pc, search: search},
    onSuccess: function(transport){
      var response = transport.responseText || " empty "; 
      $('gogetemquotez').hide();
	  $('resultsanswerquote').innerHTML = response;
	  $('resultsanswerquote').style.backgroundImage="url('/images/spacer.gif')";
	  Scroller.reset('resultsanswerquote');
	},
    onFailure: function(){ alert(' fail 2119 '); }
  });
}

/*
function searchIndex()
{
  var pc = $('postalcode').value;
  var search = $('search').value;
  $('search').style.borderColor = '#000000';    
  $('search').style.backgroundColor = 'rgb(219, 219, 219)';    
  $('postalcode').style.borderColor = '#000000';    
  $('postalcode').style.backgroundColor = 'rgb(219, 219, 219)';    
  var error = "";

  if(search == "")
  {
    $('search').style.borderColor = '#8B2323';    
    $('search').style.backgroundColor = '#EE3B3B';    
	error = 'search';
  }

  var fvalid = new Validate;
  var validZip = fvalid.isZIPCode(pc); 

  if(pc == "" || (!validZip))
  {
    $('postalcode').style.backgroundColor = '#EE3B3B';    
	error = 'postalcode';
  }

  if(error != "")
  {
    if(error == 'postalcode')
	{
	  $('postalcode').focus();
	}
    if(error == 'search')
	{
	  $('search').focus();
	}
    return false;
  }

  $('results').innerHTML = "";
  $('gogetemz').show();

  var r = new Ajax.Request('/ajax/search.php',
  {
    method:'get',
    parameters: {zip: pc, search: search},
    onSuccess: function(transport){
      var response = transport.responseText || " empty "; 
//alert(response);
      $('gogetemz').hide();
	  $('results').innerHTML = response;
	  $('results').style.backgroundImage="url('/images/spacer.gif')";
	  Scroller.reset('results');
	},
    onFailure: function(){ alert(' fail 2119 '); }
  });
}
*/