// ########################### JQUERY.COMBINED.JS ##### START

// ----------------- jquery.cluetip.min.js -------------------

/*
 * jQuery clueTip plugin
 * Version 0.9.6  (02/02/2008)
 * @requires jQuery v1.1.1+
 * @requires Dimensions plugin 
 *
 * Dual licensed under the MIT and GPL licenses:
 * http://www.opensource.org/licenses/mit-license.php
 * http://www.gnu.org/licenses/gpl.html
 *
*/
(function($){var $cluetip,$cluetipInner,$cluetipOuter,$cluetipTitle,$cluetipArrows,$dropShadow,imgCount;jQuery.fn.cluetip=function(options){var opts=jQuery.extend({},jQuery.fn.cluetip.defaults,options);if(options&&options.ajaxSettings){jQuery.extend(opts.ajaxSettings,options.ajaxSettings);delete options.ajaxSettings;}
if(options&&options.hoverIntent){jQuery.extend(opts.hoverIntent,options.hoverIntent);delete options.hoverIntent;}
if(options&&options.fx){jQuery.extend(opts.fx,options.fx);delete options.fx;}
return this.each(function(index){var cluetipContents=false;var cluezIndex=parseInt(opts.cluezIndex,10)-1;var isActive=false,closeOnDelay=0;if(!$cluetip){$cluetipInner=jQuery('<div id="cluetip-inner"></div>');$cluetipTitle=jQuery('<h3 id="cluetip-title"></h3>');$cluetipOuter=jQuery('<div id="cluetip-outer"></div>').append($cluetipInner).prepend($cluetipTitle);$cluetip=jQuery('<div id="cluetip"></div>').css({zIndex:opts.cluezIndex}).append($cluetipOuter).append('<div id="cluetip-extra"></div>')[insertionType](insertionElement).hide();jQuery('<div id="cluetip-waitimage"></div>').css({position:'absolute',zIndex:cluezIndex-1}).insertBefore('#cluetip').hide();$cluetip.css({position:'absolute',zIndex:cluezIndex});$cluetipOuter.css({position:'relative',zIndex:cluezIndex+1});$cluetipArrows=jQuery('<div id="cluetip-arrows" class="cluetip-arrows"></div>').css({zIndex:cluezIndex+1}).appendTo('#cluetip');}
var dropShadowSteps=(opts.dropShadow)?+opts.dropShadowSteps:0;if(!$dropShadow){$dropShadow=jQuery([]);for(var i=0;i<dropShadowSteps;i++){$dropShadow=$dropShadow.add(jQuery('<div></div>').css({zIndex:cluezIndex-i-1,opacity:.1,top:1+i,left:1+i}));};$dropShadow.css({position:'absolute',backgroundColor:'#000'}).prependTo($cluetip);}
var $this=jQuery(this);var tipAttribute=$this.attr(opts.attribute),ctClass=opts.cluetipClass;if(!tipAttribute&&!opts.splitTitle)return true;if(opts.local&&opts.hideLocal){jQuery(tipAttribute+':first').hide();}
var tOffset=parseInt(opts.topOffset,10),lOffset=parseInt(opts.leftOffset,10);var tipHeight,wHeight;var defHeight=isNaN(parseInt(opts.height,10))?'auto':(/\D/g).test(opts.height)?opts.height:opts.height+'px';var sTop,linkTop,posY,tipY,mouseY,baseline;var tipInnerWidth=isNaN(parseInt(opts.width,10))?275:parseInt(opts.width,10);var tipWidth=tipInnerWidth+(parseInt($cluetip.css('paddingLeft'))||0)+(parseInt($cluetip.css('paddingRight'))||0)+dropShadowSteps;var linkWidth=this.offsetWidth;var linkLeft,posX,tipX,mouseX,winWidth;var tipParts;var tipTitle=(opts.attribute!='title')?$this.attr(opts.titleAttribute):'';if(opts.splitTitle){if(tipTitle==undefined){tipTitle='';}
tipParts=tipTitle.split(opts.splitTitle);tipTitle=tipParts.shift();}
var localContent;var activate=function(event){if(!opts.onActivate($this)){return false;}
isActive=true;$cluetip.removeClass().css({width:tipInnerWidth});if(tipAttribute==$this.attr('href')){$this.css('cursor',opts.cursor);}
$this.attr('title','');if(opts.hoverClass){$this.addClass(opts.hoverClass);}
linkTop=posY=$this.offset().top;linkLeft=$this.offset().left;mouseX=event.pageX;mouseY=event.pageY;if($this[0].tagName.toLowerCase()!='area'){sTop=jQuery(document).scrollTop();winWidth=jQuery(window).width();}
if(opts.positionBy=='fixed'){posX=linkWidth+linkLeft+lOffset;$cluetip.css({left:posX});}else{posX=(linkWidth>linkLeft&&linkLeft>tipWidth)||linkLeft+linkWidth+tipWidth+lOffset>winWidth?linkLeft-tipWidth-lOffset:linkWidth+linkLeft+lOffset;if($this[0].tagName.toLowerCase()=='area'||opts.positionBy=='mouse'||linkWidth+tipWidth>winWidth){if(mouseX+20+tipWidth>winWidth){$cluetip.addClass(' cluetip-'+ctClass);posX=(mouseX-tipWidth-lOffset)>=0?mouseX-tipWidth-lOffset-parseInt($cluetip.css('marginLeft'),10)+parseInt($cluetipInner.css('marginRight'),10):mouseX-(tipWidth/2);}else{posX=mouseX+lOffset;}}
var pY=posX<0?event.pageY+tOffset:event.pageY;$cluetip.css({left:(posX>0&&opts.positionBy!='bottomTop')?posX:(mouseX+(tipWidth/2)>winWidth)?winWidth/2-tipWidth/2:Math.max(mouseX-(tipWidth/2),0)});}
wHeight=jQuery(window).height();if(tipParts){var tpl=tipParts.length;for(var i=0;i<tpl;i++){if(i==0){if(!options.renderText){$cluetipInner.html(tipParts[i]);}else{$cluetipInner.text(tipParts[i]);}}else{$cluetipInner.append('<div class="split-body">'+tipParts[i]+'</div>');}};cluetipShow(pY);}
else if(!opts.local&&tipAttribute.indexOf('#')!=0){if(cluetipContents&&opts.ajaxCache){$cluetipInner.html(cluetipContents);cluetipShow(pY);}
else{var ajaxSettings=opts.ajaxSettings;ajaxSettings.url=tipAttribute;ajaxSettings.beforeSend=function(){$cluetipOuter.children().empty();if(opts.waitImage){jQuery('#cluetip-waitimage').css({top:mouseY+20,left:mouseX+20}).show();}};ajaxSettings.error=function(){if(isActive){$cluetipInner.html('<i>sorry, the contents could not be loaded</i>');}};ajaxSettings.success=function(data){cluetipContents=opts.ajaxProcess(data);if(isActive){$cluetipInner.html(cluetipContents);}};ajaxSettings.complete=function(){imgCount=jQuery('#cluetip-inner img').length;if(imgCount){jQuery('#cluetip-inner img').load(function(){imgCount--;if(imgCount<1){jQuery('#cluetip-waitimage').hide();if(isActive)cluetipShow(pY);}});}else{jQuery('#cluetip-waitimage').hide();if(isActive)cluetipShow(pY);}};jQuery.ajax(ajaxSettings);}}else if(opts.local){var $localContent=jQuery(tipAttribute+':first');var localCluetip=jQuery.fn.wrapInner?$localContent.wrapInner('<div></div>').children().clone(true):$localContent.html();jQuery.fn.wrapInner?$cluetipInner.empty().append(localCluetip):$cluetipInner.html(localCluetip);cluetipShow(pY);}};var cluetipShow=function(bpY){$cluetip.addClass('cluetip-'+ctClass);if(opts.truncate){var $truncloaded=$cluetipInner.text().slice(0,opts.truncate)+'...';$cluetipInner.html($truncloaded);}
function doNothing(){};tipTitle?$cluetipTitle.show().html(tipTitle):(opts.showTitle)?$cluetipTitle.show().html('&nbsp;'):$cluetipTitle.hide();if(opts.sticky){var $closeLink=jQuery('<div id="cluetip-close"><a href="#">'+opts.closeText+'</a></div>');(opts.closePosition=='bottom')?$closeLink.appendTo($cluetipInner):(opts.closePosition=='title')?$closeLink.prependTo($cluetipTitle):$closeLink.prependTo($cluetipInner);$closeLink.click(function(){cluetipClose();return false;});if(opts.mouseOutClose){if(jQuery.fn.hoverIntent&&opts.hoverIntent){$cluetip.hoverIntent({over:doNothing,timeout:opts.hoverIntent.timeout,out:function(){$closeLink.trigger('click');}});}else{$cluetip.hover(doNothing,function(){$closeLink.trigger('click');});}}else{$cluetip.unbind('mouseout');}}
var direction='';$cluetipOuter.css({overflow:defHeight=='auto'?'visible':'auto',height:defHeight});tipHeight=defHeight=='auto'?$cluetip.outerHeight():parseInt(defHeight,10);tipY=posY;baseline=sTop+wHeight;if(opts.positionBy=='fixed'){tipY=posY-opts.dropShadowSteps+tOffset;}else if((posX<mouseX&&Math.max(posX,0)+tipWidth>mouseX)||opts.positionBy=='bottomTop'){if(posY+tipHeight+tOffset>baseline&&mouseY-sTop>tipHeight+tOffset){tipY=mouseY-tipHeight-tOffset;direction='top';}else{tipY=mouseY+tOffset;direction='bottom';}}else if(posY+tipHeight+tOffset>baseline){tipY=(tipHeight>=wHeight)?sTop:baseline-tipHeight-tOffset;}else if($this.css('display')=='block'||$this[0].tagName.toLowerCase()=='area'||opts.positionBy=="mouse"){tipY=bpY-tOffset;}else{tipY=posY-opts.dropShadowSteps;}
if(direction==''){posX<linkLeft?direction='left':direction='right';}
$cluetip.css({top:tipY+'px'}).removeClass().addClass('clue-'+direction+'-'+ctClass).addClass(' cluetip-'+ctClass);if(opts.arrows){var bgY=(posY-tipY-opts.dropShadowSteps);$cluetipArrows.css({top:(/(left|right)/.test(direction)&&posX>=0&&bgY>0)?bgY+'px':/(left|right)/.test(direction)?0:''}).show();}else{$cluetipArrows.hide();}
$dropShadow.hide();$cluetip.hide()[opts.fx.open](opts.fx.open!='show'&&opts.fx.openSpeed);if(opts.dropShadow)$dropShadow.css({height:tipHeight,width:tipInnerWidth}).show();if(jQuery.fn.bgiframe){$cluetip.bgiframe();}
if(opts.delayedClose>0){closeOnDelay=setTimeout(cluetipClose,opts.delayedClose);}
opts.onShow($cluetip,$cluetipInner);};var inactivate=function(){isActive=false;jQuery('#cluetip-waitimage').hide();if(!opts.sticky||(/click|toggle/).test(opts.activation)){cluetipClose();clearTimeout(closeOnDelay);};if(opts.hoverClass){$this.removeClass(opts.hoverClass);}
jQuery('.cluetip-clicked').removeClass('cluetip-clicked');};var cluetipClose=function(){$cluetipOuter.parent().hide().removeClass().end().children().empty();if(tipTitle){$this.attr('title',tipTitle);}
$this.css('cursor','');if(opts.arrows)$cluetipArrows.css({top:''});};if((/click|toggle/).test(opts.activation)){$this.click(function(event){if($cluetip.is(':hidden')||!$this.is('.cluetip-clicked')){activate(event);jQuery('.cluetip-clicked').removeClass('cluetip-clicked');$this.addClass('cluetip-clicked');}else{inactivate(event);}
this.blur();return false;});}else if(opts.activation=='focus'){$this.focus(function(event){activate(event);});$this.blur(function(event){inactivate(event);});}else{$this.click(function(){if($this.attr('href')&&$this.attr('href')==tipAttribute&&!opts.clickThrough){return false;}});var mouseTracks=function(evt){if(opts.tracking==true){var trackX=posX-evt.pageX;var trackY=tipY?tipY-evt.pageY:posY-evt.pageY;$this.mousemove(function(evt){$cluetip.css({left:evt.pageX+trackX,top:evt.pageY+trackY});});}};if(jQuery.fn.hoverIntent&&opts.hoverIntent){$this.mouseover(function(){$this.attr('title','');}).hoverIntent({sensitivity:opts.hoverIntent.sensitivity,interval:opts.hoverIntent.interval,over:function(event){activate(event);mouseTracks(event);},timeout:opts.hoverIntent.timeout,out:function(event){inactivate(event);$this.unbind('mousemove');}});}else{$this.hover(function(event){activate(event);mouseTracks(event);},function(event){inactivate(event);$this.unbind('mousemove');});}}});};jQuery.fn.cluetip.defaults={width:275,height:'auto',cluezIndex:97,positionBy:'auto',topOffset:15,leftOffset:15,local:false,hideLocal:true,attribute:'rel',titleAttribute:'title',splitTitle:'',showTitle:true,cluetipClass:'default',hoverClass:'',waitImage:true,cursor:'help',arrows:false,dropShadow:true,dropShadowSteps:6,sticky:false,mouseOutClose:false,activation:'hover',clickThrough:false,tracking:false,delayedClose:0,closePosition:'top',closeText:'Close',truncate:0,renderText:false,fx:{open:'show',openSpeed:''},hoverIntent:{sensitivity:3,interval:50,timeout:0},onActivate:function(e){return true;},onShow:function(ct,c){},ajaxCache:true,ajaxProcess:function(data){data=data.replace(/<s(cript|tyle)(.|\s)*?\/s(cript|tyle)>/g,'').replace(/<(link|title)(.|\s)*?\/(link|title)>/g,'');return data;},ajaxSettings:{dataType:'html'}};var insertionType='appendTo',insertionElement='body';jQuery.cluetip={};jQuery.cluetip.setup=function(options){if(options&&options.insertionType&&(options.insertionType).match(/appendTo|prependTo|insertBefore|insertAfter/)){insertionType=options.insertionType;}
if(options&&options.insertionElement){insertionElement=options.insertionElement;}};})(jQuery);


// ----------------- jquery.form.js -------------------

/*
 * jQuery Form Plugin
 * version: 2.04 (02/05/2008)
 * @requires jQuery v1.1 or later
 *
 * Examples at: http://malsup.com/jquery/form/
 * Dual licensed under the MIT and GPL licenses:
 *   http://www.opensource.org/licenses/mit-license.php
 *   http://www.gnu.org/licenses/gpl.html
 *
 * Revision: $Id$
 */
 (function($) {
/**
 * ajaxSubmit() provides a mechanism for submitting an HTML form using AJAX.
 *
 * ajaxSubmit accepts a single argument which can be either a success callback function
 * or an options Object.  If a function is provided it will be invoked upon successful
 * completion of the submit and will be passed the response from the server.
 * If an options Object is provided, the following attributes are supported:
 *
 *  target:   Identifies the element(s) in the page to be updated with the server response.
 *            This value may be specified as a jQuery selection string, a jQuery object,
 *            or a DOM element.
 *            default value: null
 *
 *  url:      URL to which the form data will be submitted.
 *            default value: value of form's 'action' attribute
 *
 *  type:     The method in which the form data should be submitted, 'GET' or 'POST'.
 *            default value: value of form's 'method' attribute (or 'GET' if none found)
 *
 *  data:     Additional data to add to the request, specified as key/value pairs (see $.ajax).
 *
 *  beforeSubmit:  Callback method to be invoked before the form is submitted.
 *            default value: null
 *
 *  success:  Callback method to be invoked after the form has been successfully submitted
 *            and the response has been returned from the server
 *            default value: null
 *
 *  dataType: Expected dataType of the response.  One of: null, 'xml', 'script', or 'json'
 *            default value: null
 *
 *  semantic: Boolean flag indicating whether data must be submitted in semantic order (slower).
 *            default value: false
 *
 *  resetForm: Boolean flag indicating whether the form should be reset if the submit is successful
 *
 *  clearForm: Boolean flag indicating whether the form should be cleared if the submit is successful
 *
 *
 * The 'beforeSubmit' callback can be provided as a hook for running pre-submit logic or for
 * validating the form data.  If the 'beforeSubmit' callback returns false then the form will
 * not be submitted. The 'beforeSubmit' callback is invoked with three arguments: the form data
 * in array format, the jQuery object, and the options object passed into ajaxSubmit.
 * The form data array takes the following form:
 *
 *     [ { name: 'username', value: 'jresig' }, { name: 'password', value: 'secret' } ]
 *
 * If a 'success' callback method is provided it is invoked after the response has been returned
 * from the server.  It is passed the responseText or responseXML value (depending on dataType).
 * See jQuery.ajax for further details.
 *
 *
 * The dataType option provides a means for specifying how the server response should be handled.
 * This maps directly to the jQuery.httpData method.  The following values are supported:
 *
 *      'xml':    if dataType == 'xml' the server response is treated as XML and the 'success'
 *                   callback method, if specified, will be passed the responseXML value
 *      'json':   if dataType == 'json' the server response will be evaluted and passed to
 *                   the 'success' callback, if specified
 *      'script': if dataType == 'script' the server response is evaluated in the global context
 *
 *
 * Note that it does not make sense to use both the 'target' and 'dataType' options.  If both
 * are provided the target will be ignored.
 *
 * The semantic argument can be used to force form serialization in semantic order.
 * This is normally true anyway, unless the form contains input elements of type='image'.
 * If your form must be submitted with name/value pairs in semantic order and your form
 * contains an input of type='image" then pass true for this arg, otherwise pass false
 * (or nothing) to avoid the overhead for this logic.
 *
 *
 * When used on its own, ajaxSubmit() is typically bound to a form's submit event like this:
 *
 * $("#form-id").submit(function() {
 *     $(this).ajaxSubmit(options);
 *     return false; // cancel conventional submit
 * });
 *
 * When using ajaxForm(), however, this is done for you.
 *
 * @example
 * $('#myForm').ajaxSubmit(function(data) {
 *     alert('Form submit succeeded! Server returned: ' + data);
 * });
 * @desc Submit form and alert server response
 *
 *
 * @example
 * var options = {
 *     target: '#myTargetDiv'
 * };
 * $('#myForm').ajaxSubmit(options);
 * @desc Submit form and update page element with server response
 *
 *
 * @example
 * var options = {
 *     success: function(responseText) {
 *         alert(responseText);
 *     }
 * };
 * $('#myForm').ajaxSubmit(options);
 * @desc Submit form and alert the server response
 *
 *
 * @example
 * var options = {
 *     beforeSubmit: function(formArray, jqForm) {
 *         if (formArray.length == 0) {
 *             alert('Please enter data.');
 *             return false;
 *         }
 *     }
 * };
 * $('#myForm').ajaxSubmit(options);
 * @desc Pre-submit validation which aborts the submit operation if form data is empty
 *
 *
 * @example
 * var options = {
 *     url: myJsonUrl.php,
 *     dataType: 'json',
 *     success: function(data) {
 *        // 'data' is an object representing the the evaluated json data
 *     }
 * };
 * $('#myForm').ajaxSubmit(options);
 * @desc json data returned and evaluated
 *
 *
 * @example
 * var options = {
 *     url: myXmlUrl.php,
 *     dataType: 'xml',
 *     success: function(responseXML) {
 *        // responseXML is XML document object
 *        var data = $('myElement', responseXML).text();
 *     }
 * };
 * $('#myForm').ajaxSubmit(options);
 * @desc XML data returned from server
 *
 *
 * @example
 * var options = {
 *     resetForm: true
 * };
 * $('#myForm').ajaxSubmit(options);
 * @desc submit form and reset it if successful
 *
 * @example
 * $('#myForm).submit(function() {
 *    $(this).ajaxSubmit();
 *    return false;
 * });
 * @desc Bind form's submit event to use ajaxSubmit
 *
 *
 * @name ajaxSubmit
 * @type jQuery
 * @param options  object literal containing options which control the form submission process
 * @cat Plugins/Form
 * @return jQuery
 */
$.fn.ajaxSubmit = function(options) {
		if (typeof options == 'function')
				options = { success: options };

		options = $.extend({
				url:  this.attr('action') || window.location.toString(),
				type: this.attr('method') || 'GET'
		}, options || {});

		// hook for manipulating the form data before it is extracted;
		// convenient for use with rich editors like tinyMCE or FCKEditor
		var veto = {};
		$.event.trigger('form.pre.serialize', [this, options, veto]);
		if (veto.veto) return this;

		var a = this.formToArray(options.semantic);
		if (options.data) {
				for (var n in options.data)
						a.push( { name: n, value: options.data[n] } );
		}

		// give pre-submit callback an opportunity to abort the submit
		if (options.beforeSubmit && options.beforeSubmit(a, this, options) === false) return this;

		// fire vetoable 'validate' event
		$.event.trigger('form.submit.validate', [a, this, options, veto]);
		if (veto.veto) return this;

		var q = $.param(a);//.replace(/%20/g,'+');

		if (options.type.toUpperCase() == 'GET') {
				options.url += (options.url.indexOf('?') >= 0 ? '&' : '?') + q;
				options.data = null;  // data is null for 'get'
		}
		else
				options.data = q; // data is the query string for 'post'

		var $form = this, callbacks = [];
		if (options.resetForm) callbacks.push(function() { $form.resetForm(); });
		if (options.clearForm) callbacks.push(function() { $form.clearForm(); });

		// perform a load on the target only if dataType is not provided
		if (!options.dataType && options.target) {
				var oldSuccess = options.success || function(){};
				callbacks.push(function(data) {
						if (this.evalScripts)
								$(options.target).attr("innerHTML", data).evalScripts().each(oldSuccess, arguments);
						else // jQuery v1.1.4
								$(options.target).html(data).each(oldSuccess, arguments);
				});
		}
		else if (options.success)
				callbacks.push(options.success);

		options.success = function(data, status) {
				for (var i=0, max=callbacks.length; i < max; i++)
						callbacks[i](data, status, $form);
		};

		// are there files to upload?
		var files = $('input:file', this).fieldValue();
		var found = false;
		for (var j=0; j < files.length; j++)
				if (files[j])
						found = true;

		// options.iframe allows user to force iframe mode
	 if (options.iframe || found) { 
			 // hack to fix Safari hang (thanks to Tim Molendijk for this)
			 // see:  http://groups.google.com/group/jquery-dev/browse_thread/thread/36395b7ab510dd5d
			 if ($.browser.safari && options.closeKeepAlive)
					 $.get(options.closeKeepAlive, fileUpload);
			 else
					 fileUpload();
			 }
	 else
			 $.ajax(options);

		// fire 'notify' event
		$.event.trigger('form.submit.notify', [this, options]);
		return this;


		// private function for handling file uploads (hat tip to YAHOO!)
		function fileUpload() {
				var form = $form[0];
				var opts = $.extend({}, $.ajaxSettings, options);

				var id = 'jqFormIO' + $.fn.ajaxSubmit.counter++;
				var $io = $('<iframe id="' + id + '" name="' + id + '" />');
				var io = $io[0];
				var op8 = $.browser.opera && window.opera.version() < 9;
				if ($.browser.msie || op8) io.src = 'javascript:false;document.write("");';
				$io.css({ position: 'absolute', top: '-1000px', left: '-1000px' });

				var xhr = { // mock object
						responseText: null,
						responseXML: null,
						status: 0,
						statusText: 'n/a',
						getAllResponseHeaders: function() {},
						getResponseHeader: function() {},
						setRequestHeader: function() {}
				};

				var g = opts.global;
				// trigger ajax global events so that activity/block indicators work like normal
				if (g && ! $.active++) $.event.trigger("ajaxStart");
				if (g) $.event.trigger("ajaxSend", [xhr, opts]);

				var cbInvoked = 0;
				var timedOut = 0;

				// take a breath so that pending repaints get some cpu time before the upload starts
				setTimeout(function() {
						// make sure form attrs are set
						var encAttr = form.encoding ? 'encoding' : 'enctype';
						var t = $form.attr('target'), a = $form.attr('action');
						$form.attr({
								target:   id,
								method:  'POST',
								action:   opts.url
						});
						form[encAttr] = 'multipart/form-data';

						// support timout
						if (opts.timeout)
								setTimeout(function() { timedOut = true; cb(); }, opts.timeout);

						// add iframe to doc and submit the form
						$io.appendTo('body');
						io.attachEvent ? io.attachEvent('onload', cb) : io.addEventListener('load', cb, false);
						form.submit();
						// reset attrs
						$form.attr({ action: a, target: t });
				}, 10);

				function cb() {
						if (cbInvoked++) return;

						io.detachEvent ? io.detachEvent('onload', cb) : io.removeEventListener('load', cb, false);

						var ok = true;
						try {
								if (timedOut) throw 'timeout';
								// extract the server response from the iframe
								var data, doc;
								doc = io.contentWindow ? io.contentWindow.document : io.contentDocument ? io.contentDocument : io.document;
								xhr.responseText = doc.body ? doc.body.innerHTML : null;
								xhr.responseXML = doc.XMLDocument ? doc.XMLDocument : doc;
								xhr.getResponseHeader = function(header){
										var headers = {'content-type': opts.dataType};
										return headers[header];
								};

								if (opts.dataType == 'json' || opts.dataType == 'script') {
										var ta = doc.getElementsByTagName('textarea')[0];
										xhr.responseText = ta ? ta.value : xhr.responseText;
								}
								else if (opts.dataType == 'xml' && !xhr.responseXML && xhr.responseText != null) {
										xhr.responseXML = toXml(xhr.responseText);
								}
								data = $.httpData(xhr, opts.dataType);
						}
						catch(e){
								ok = false;
								$.handleError(opts, xhr, 'error', e);
						}

						// ordering of these callbacks/triggers is odd, but that's how $.ajax does it
						if (ok) {
								opts.success(data, 'success');
								if (g) $.event.trigger("ajaxSuccess", [xhr, opts]);
						}
						if (g) $.event.trigger("ajaxComplete", [xhr, opts]);
						if (g && ! --$.active) $.event.trigger("ajaxStop");
						if (opts.complete) opts.complete(xhr, ok ? 'success' : 'error');

						// clean up
						setTimeout(function() {
								$io.remove();
								xhr.responseXML = null;
						}, 100);
				};

				function toXml(s, doc) {
						if (window.ActiveXObject) {
								doc = new ActiveXObject('Microsoft.XMLDOM');
								doc.async = 'false';
								doc.loadXML(s);
						}
						else
								doc = (new DOMParser()).parseFromString(s, 'text/xml');
						return (doc && doc.documentElement && doc.documentElement.tagName != 'parsererror') ? doc : null;
				};
		};
};
$.fn.ajaxSubmit.counter = 0; // used to create unique iframe ids

/**
 * ajaxForm() provides a mechanism for fully automating form submission.
 *
 * The advantages of using this method instead of ajaxSubmit() are:
 *
 * 1: This method will include coordinates for <input type="image" /> elements (if the element
 *    is used to submit the form).
 * 2. This method will include the submit element's name/value data (for the element that was
 *    used to submit the form).
 * 3. This method binds the submit() method to the form for you.
 *
 * Note that for accurate x/y coordinates of image submit elements in all browsers
 * you need to also use the "dimensions" plugin (this method will auto-detect its presence).
 *
 * The options argument for ajaxForm works exactly as it does for ajaxSubmit.  ajaxForm merely
 * passes the options argument along after properly binding events for submit elements and
 * the form itself.  See ajaxSubmit for a full description of the options argument.
 *
 *
 * @example
 * var options = {
 *     target: '#myTargetDiv'
 * };
 * $('#myForm').ajaxSForm(options);
 * @desc Bind form's submit event so that 'myTargetDiv' is updated with the server response
 *       when the form is submitted.
 *
 *
 * @example
 * var options = {
 *     success: function(responseText) {
 *         alert(responseText);
 *     }
 * };
 * $('#myForm').ajaxSubmit(options);
 * @desc Bind form's submit event so that server response is alerted after the form is submitted.
 *
 *
 * @example
 * var options = {
 *     beforeSubmit: function(formArray, jqForm) {
 *         if (formArray.length == 0) {
 *             alert('Please enter data.');
 *             return false;
 *         }
 *     }
 * };
 * $('#myForm').ajaxSubmit(options);
 * @desc Bind form's submit event so that pre-submit callback is invoked before the form
 *       is submitted.
 *
 *
 * @name   ajaxForm
 * @param  options  object literal containing options which control the form submission process
 * @return jQuery
 * @cat    Plugins/Form
 * @type   jQuery
 */
$.fn.ajaxForm = function(options) {
		return this.ajaxFormUnbind().submit(submitHandler).each(function() {
				// store options in hash
				this.formPluginId = $.fn.ajaxForm.counter++;
				$.fn.ajaxForm.optionHash[this.formPluginId] = options;
				$(":submit,input:image", this).click(clickHandler);
		});
};

$.fn.ajaxForm.counter = 1;
$.fn.ajaxForm.optionHash = {};

function clickHandler(e) {
		var $form = this.form;
		$form.clk = this;
		if (this.type == 'image') {
				if (e.offsetX != undefined) {
						$form.clk_x = e.offsetX;
						$form.clk_y = e.offsetY;
				} else if (typeof $.fn.offset == 'function') { // try to use dimensions plugin
						var offset = $(this).offset();
						$form.clk_x = e.pageX - offset.left;
						$form.clk_y = e.pageY - offset.top;
				} else {
						$form.clk_x = e.pageX - this.offsetLeft;
						$form.clk_y = e.pageY - this.offsetTop;
				}
		}
		// clear form vars
		setTimeout(function() { $form.clk = $form.clk_x = $form.clk_y = null; }, 10);
};

function submitHandler() {
		// retrieve options from hash
		var id = this.formPluginId;
		var options = $.fn.ajaxForm.optionHash[id];
		$(this).ajaxSubmit(options);
		return false;
};

/**
 * ajaxFormUnbind unbinds the event handlers that were bound by ajaxForm
 *
 * @name   ajaxFormUnbind
 * @return jQuery
 * @cat    Plugins/Form
 * @type   jQuery
 */
$.fn.ajaxFormUnbind = function() {
		this.unbind('submit', submitHandler);
		return this.each(function() {
				$(":submit,input:image", this).unbind('click', clickHandler);
		});

};

/**
 * formToArray() gathers form element data into an array of objects that can
 * be passed to any of the following ajax functions: $.get, $.post, or load.
 * Each object in the array has both a 'name' and 'value' property.  An example of
 * an array for a simple login form might be:
 *
 * [ { name: 'username', value: 'jresig' }, { name: 'password', value: 'secret' } ]
 *
 * It is this array that is passed to pre-submit callback functions provided to the
 * ajaxSubmit() and ajaxForm() methods.
 *
 * The semantic argument can be used to force form serialization in semantic order.
 * This is normally true anyway, unless the form contains input elements of type='image'.
 * If your form must be submitted with name/value pairs in semantic order and your form
 * contains an input of type='image" then pass true for this arg, otherwise pass false
 * (or nothing) to avoid the overhead for this logic.
 *
 * @example var data = $("#myForm").formToArray();
 * $.post( "myscript.cgi", data );
 * @desc Collect all the data from a form and submit it to the server.
 *
 * @name formToArray
 * @param semantic true if serialization must maintain strict semantic ordering of elements (slower)
 * @type Array<Object>
 * @cat Plugins/Form
 */
$.fn.formToArray = function(semantic) {
		var a = [];
		if (this.length == 0) return a;

		var form = this[0];
		var els = semantic ? form.getElementsByTagName('*') : form.elements;
		if (!els) return a;
		for(var i=0, max=els.length; i < max; i++) {
				var el = els[i];
				var n = el.name;
				if (!n) continue;

				if (semantic && form.clk && el.type == "image") {
						// handle image inputs on the fly when semantic == true
						if(!el.disabled && form.clk == el)
								a.push({name: n+'.x', value: form.clk_x}, {name: n+'.y', value: form.clk_y});
						continue;
				}

				var v = $.fieldValue(el, true);
				if (v && v.constructor == Array) {
						for(var j=0, jmax=v.length; j < jmax; j++)
								a.push({name: n, value: v[j]});
				}
				else if (v !== null && typeof v != 'undefined')
						a.push({name: n, value: v});
		}

		if (!semantic && form.clk) {
				// input type=='image' are not found in elements array! handle them here
				var inputs = form.getElementsByTagName("input");
				for(var i=0, max=inputs.length; i < max; i++) {
						var input = inputs[i];
						var n = input.name;
						if(n && !input.disabled && input.type == "image" && form.clk == input)
								a.push({name: n+'.x', value: form.clk_x}, {name: n+'.y', value: form.clk_y});
				}
		}
		return a;
};


/**
 * Serializes form data into a 'submittable' string. This method will return a string
 * in the format: name1=value1&amp;name2=value2
 *
 * The semantic argument can be used to force form serialization in semantic order.
 * If your form must be submitted with name/value pairs in semantic order then pass
 * true for this arg, otherwise pass false (or nothing) to avoid the overhead for
 * this logic (which can be significant for very large forms).
 *
 * @example var data = $("#myForm").formSerialize();
 * $.ajax('POST', "myscript.cgi", data);
 * @desc Collect all the data from a form into a single string
 *
 * @name formSerialize
 * @param semantic true if serialization must maintain strict semantic ordering of elements (slower)
 * @type String
 * @cat Plugins/Form
 */
$.fn.formSerialize = function(semantic) {
		//hand off to jQuery.param for proper encoding
		return $.param(this.formToArray(semantic));
};


/**
 * Serializes all field elements in the jQuery object into a query string.
 * This method will return a string in the format: name1=value1&amp;name2=value2
 *
 * The successful argument controls whether or not serialization is limited to
 * 'successful' controls (per http://www.w3.org/TR/html4/interact/forms.html#successful-controls).
 * The default value of the successful argument is true.
 *
 * @example var data = $("input").formSerialize();
 * @desc Collect the data from all successful input elements into a query string
 *
 * @example var data = $(":radio").formSerialize();
 * @desc Collect the data from all successful radio input elements into a query string
 *
 * @example var data = $("#myForm :checkbox").formSerialize();
 * @desc Collect the data from all successful checkbox input elements in myForm into a query string
 *
 * @example var data = $("#myForm :checkbox").formSerialize(false);
 * @desc Collect the data from all checkbox elements in myForm (even the unchecked ones) into a query string
 *
 * @example var data = $(":input").formSerialize();
 * @desc Collect the data from all successful input, select, textarea and button elements into a query string
 *
 * @name fieldSerialize
 * @param successful true if only successful controls should be serialized (default is true)
 * @type String
 * @cat Plugins/Form
 */
$.fn.fieldSerialize = function(successful) {
		var a = [];
		this.each(function() {
				var n = this.name;
				if (!n) return;
				var v = $.fieldValue(this, successful);
				if (v && v.constructor == Array) {
						for (var i=0,max=v.length; i < max; i++)
								a.push({name: n, value: v[i]});
				}
				else if (v !== null && typeof v != 'undefined')
						a.push({name: this.name, value: v});
		});
		//hand off to jQuery.param for proper encoding
		return $.param(a);
};


/**
 * Returns the value(s) of the element in the matched set.  For example, consider the following form:
 *
 *  <form><fieldset>
 *      <input name="A" type="text" />
 *      <input name="A" type="text" />
 *      <input name="B" type="checkbox" value="B1" />
 *      <input name="B" type="checkbox" value="B2"/>
 *      <input name="C" type="radio" value="C1" />
 *      <input name="C" type="radio" value="C2" />
 *  </fieldset></form>
 *
 *  var v = $(':text').fieldValue();
 *  // if no values are entered into the text inputs
 *  v == ['','']
 *  // if values entered into the text inputs are 'foo' and 'bar'
 *  v == ['foo','bar']
 *
 *  var v = $(':checkbox').fieldValue();
 *  // if neither checkbox is checked
 *  v === undefined
 *  // if both checkboxes are checked
 *  v == ['B1', 'B2']
 *
 *  var v = $(':radio').fieldValue();
 *  // if neither radio is checked
 *  v === undefined
 *  // if first radio is checked
 *  v == ['C1']
 *
 * The successful argument controls whether or not the field element must be 'successful'
 * (per http://www.w3.org/TR/html4/interact/forms.html#successful-controls).
 * The default value of the successful argument is true.  If this value is false the value(s)
 * for each element is returned.
 *
 * Note: This method *always* returns an array.  If no valid value can be determined the
 *       array will be empty, otherwise it will contain one or more values.
 *
 * @example var data = $("#myPasswordElement").fieldValue();
 * alert(data[0]);
 * @desc Alerts the current value of the myPasswordElement element
 *
 * @example var data = $("#myForm :input").fieldValue();
 * @desc Get the value(s) of the form elements in myForm
 *
 * @example var data = $("#myForm :checkbox").fieldValue();
 * @desc Get the value(s) for the successful checkbox element(s) in the jQuery object.
 *
 * @example var data = $("#mySingleSelect").fieldValue();
 * @desc Get the value(s) of the select control
 *
 * @example var data = $(':text').fieldValue();
 * @desc Get the value(s) of the text input or textarea elements
 *
 * @example var data = $("#myMultiSelect").fieldValue();
 * @desc Get the values for the select-multiple control
 *
 * @name fieldValue
 * @param Boolean successful true if only the values for successful controls should be returned (default is true)
 * @type Array<String>
 * @cat Plugins/Form
 */
$.fn.fieldValue = function(successful) {
		for (var val=[], i=0, max=this.length; i < max; i++) {
				var el = this[i];
				var v = $.fieldValue(el, successful);
				if (v === null || typeof v == 'undefined' || (v.constructor == Array && !v.length))
						continue;
				v.constructor == Array ? $.merge(val, v) : val.push(v);
		}
		return val;
};

/**
 * Returns the value of the field element.
 *
 * The successful argument controls whether or not the field element must be 'successful'
 * (per http://www.w3.org/TR/html4/interact/forms.html#successful-controls).
 * The default value of the successful argument is true.  If the given element is not
 * successful and the successful arg is not false then the returned value will be null.
 *
 * Note: If the successful flag is true (default) but the element is not successful, the return will be null
 * Note: The value returned for a successful select-multiple element will always be an array.
 * Note: If the element has no value the return value will be undefined.
 *
 * @example var data = jQuery.fieldValue($("#myPasswordElement")[0]);
 * @desc Gets the current value of the myPasswordElement element
 *
 * @name fieldValue
 * @param Element el The DOM element for which the value will be returned
 * @param Boolean successful true if value returned must be for a successful controls (default is true)
 * @type String or Array<String> or null or undefined
 * @cat Plugins/Form
 */
$.fieldValue = function(el, successful) {
		var n = el.name, t = el.type, tag = el.tagName.toLowerCase();
		if (typeof successful == 'undefined') successful = true;

		if (successful && (!n || el.disabled || t == 'reset' || t == 'button' ||
				(t == 'checkbox' || t == 'radio') && !el.checked ||
				(t == 'submit' || t == 'image') && el.form && el.form.clk != el ||
				tag == 'select' && el.selectedIndex == -1))
						return null;

		if (tag == 'select') {
				var index = el.selectedIndex;
				if (index < 0) return null;
				var a = [], ops = el.options;
				var one = (t == 'select-one');
				var max = (one ? index+1 : ops.length);
				for(var i=(one ? index : 0); i < max; i++) {
						var op = ops[i];
						if (op.selected) {
								// extra pain for IE...
								var v = $.browser.msie && !(op.attributes['value'].specified) ? op.text : op.value;
								if (one) return v;
								a.push(v);
						}
				}
				return a;
		}
		return el.value;
};


/**
 * Clears the form data.  Takes the following actions on the form's input fields:
 *  - input text fields will have their 'value' property set to the empty string
 *  - select elements will have their 'selectedIndex' property set to -1
 *  - checkbox and radio inputs will have their 'checked' property set to false
 *  - inputs of type submit, button, reset, and hidden will *not* be effected
 *  - button elements will *not* be effected
 *
 * @example $('form').clearForm();
 * @desc Clears all forms on the page.
 *
 * @name clearForm
 * @type jQuery
 * @cat Plugins/Form
 */
$.fn.clearForm = function() {
		return this.each(function() {
				$('input,select,textarea', this).clearFields();
		});
};

/**
 * Clears the selected form elements.  Takes the following actions on the matched elements:
 *  - input text fields will have their 'value' property set to the empty string
 *  - select elements will have their 'selectedIndex' property set to -1
 *  - checkbox and radio inputs will have their 'checked' property set to false
 *  - inputs of type submit, button, reset, and hidden will *not* be effected
 *  - button elements will *not* be effected
 *
 * @example $('.myInputs').clearFields();
 * @desc Clears all inputs with class myInputs
 *
 * @name clearFields
 * @type jQuery
 * @cat Plugins/Form
 */
$.fn.clearFields = $.fn.clearInputs = function() {
		return this.each(function() {
				var t = this.type, tag = this.tagName.toLowerCase();
				if (t == 'text' || t == 'password' || tag == 'textarea')
						this.value = '';
				else if (t == 'checkbox' || t == 'radio')
						this.checked = false;
				else if (tag == 'select')
						this.selectedIndex = -1;
		});
};


/**
 * Resets the form data.  Causes all form elements to be reset to their original value.
 *
 * @example $('form').resetForm();
 * @desc Resets all forms on the page.
 *
 * @name resetForm
 * @type jQuery
 * @cat Plugins/Form
 */
$.fn.resetForm = function() {
		return this.each(function() {
				// guard against an input with the name of 'reset'
				// note that IE reports the reset function as an 'object'
				if (typeof this.reset == 'function' || (typeof this.reset == 'object' && !this.reset.nodeType))
						this.reset();
		});
};


/**
 * Enables or disables any matching elements.
 *
 * @example $(':radio').enabled(false);
 * @desc Disables all radio buttons
 *
 * @name select
 * @type jQuery
 * @cat Plugins/Form
 */
$.fn.enable = function(b) { 
		if (b == undefined) b = true;
		return this.each(function() { 
				this.disabled = !b 
		});
};

/**
 * Checks/unchecks any matching checkboxes or radio buttons and
 * selects/deselects and matching option elements.
 *
 * @example $(':checkbox').selected();
 * @desc Checks all checkboxes
 *
 * @name select
 * @type jQuery
 * @cat Plugins/Form
 */
$.fn.select = function(select) {
		if (select == undefined) select = true;
		return this.each(function() { 
				var t = this.type;
				if (t == 'checkbox' || t == 'radio')
						this.checked = select;
				else if (this.tagName.toLowerCase() == 'option') {
						var $sel = $(this).parent('select');
						if (select && $sel[0] && $sel[0].type == 'select-one') {
								// deselect all other options
								$sel.find('option').select(false);
						}
						this.selected = select;
				}
		});
};

})(jQuery);


//-------- jquery.textcomplete

jQuery.fn.textComplete = function(options){	
	var input = this;
	input.wrapAll("<span></span>"); 	
	var close = function(){		
		jQuery('#' + options.itemContainer.attr.id).remove();
		jQuery('#' + options.itemContainer.attr.id + "_iframe").remove();		
	};
	jQuery(document).bind('mousedown', close);	
	var newSelection = function(item){
		return	jQuery(item)
				.addClass("selected");		
	};	
	var oldSelection = function(item){
		return	jQuery(item || ('#' + options.itemContainer.attr.id + ' .selected'))
				.removeClass("selected");		
	};	
	
	var newItem = function(text){
		return	jQuery("<div></div>")
				.css(options.item.css || {})
				.text(text || "")
				.hover(
					function(){
						oldSelection()		
							.css({color:options.item.hoverColorOff, backgroundColor:options.item.hoverBackgroundOff});
						newSelection(this)
							.css({color:options.item.hoverColorOn || "", backgroundColor:options.item.hoverBackgroundOn || ""});
					},
					function(){
						oldSelection()
							.css({color:options.item.hoverColorOff, backgroundColor:options.item.hoverBackgroundOff});
						newSelection(this)
							.css({color:options.item.hoverColorOff || "", backgroundColor:options.item.hoverBackgroundOff || ""});
					}
				)
				.click(function(){					
					input.val(jQuery(this).text());
					close();
					options.onItemSelect();											
				});			
	}	
	
	var printItems = function(){
		jQuery.get(options.url + input.val(), function(data) {				
			jQuery.each(data.split(options.responseDelimiter[0]), function(i, val){
				if(i == data.split(options.responseDelimiter[0]).length - 1) return;					
				newItem((val.split(options.responseDelimiter[1])[0] || val.split(options.responseDelimiter[0])[0]))						
					.appendTo(jQuery('#' + options.itemContainer.attr.id));							
			});
		});
	}		
	
	input.keyup(function(e){		
		if(input.val().length > (options.minimumKeystrokes || 2)-1){		
			switch(e.keyCode){
				case 37:
				case 39:
					break;							
				case 13:
					e.preventDefault();
					input.val(jQuery('#' + options.itemContainer.attr.id + ' .selected').text());
					close();
					options.onItemSelect();		
					break;
				case 27:
					e.preventDefault();					
					close();		
					break;
				case 38:					
					e.preventDefault();
					if(jQuery('#' + options.itemContainer.attr.id + ' .selected').length > 0 && jQuery('#' + options.itemContainer.attr.id + ' .selected').prev().length == 1){							
						jQuery('#' + options.itemContainer.attr.id + ' .selected').each(function(i, item){							
							oldSelection(item)
								.css({color:options.item.hoverColorOff, backgroundColor:options.item.hoverBackgroundOff})
								.prev()
								.addClass("selected")
								.css({color:options.item.hoverColorOn, backgroundColor:options.item.hoverBackgroundOn});});
					}
					else if(jQuery('#' + options.itemContainer.attr.id + ' .selected').length == 0){
						newSelection('#' + options.itemContainer.attr.id + ' div:first')
							.css({color:options.item.hoverColorOn, backgroundColor:options.item.hoverBackgroundOn});
					}	
					break;
				case 40:
					e.preventDefault();					
					if(jQuery('#' + options.itemContainer.attr.id + ' .selected').length > 0 && jQuery('#' + options.itemContainer.attr.id + ' .selected').next().length == 1){							
						jQuery('#' + options.itemContainer.attr.id + ' .selected').each(function(i, item){							
							oldSelection(item)								
								.css({color:options.item.hoverColorOff, backgroundColor:options.item.hoverBackgroundOff})
								.next()
								.addClass("selected")
								.css({color:options.item.hoverColorOn, backgroundColor:options.item.hoverBackgroundOn});});
					}
					else if(jQuery('#' + options.itemContainer.attr.id + ' .selected').length == 0){
						newSelection('#' + options.itemContainer.attr.id + ' div:first')							
							.css({color:options.item.hoverColorOn, backgroundColor:options.item.hoverBackgroundOn});
					}	
					break;
				default:					
					if(jQuery('#' + options.itemContainer.attr.id).length == 0){	
						jQuery("<div></div>")
							.attr(options.itemContainer.attr)
							.css(options.positioning.css)
							.css(options.itemContainer.css)							
							.mousedown(function(e){
								e.stopPropagation();
							})							
							.prependTo(options.positioning.relativeTo ||input.parent());								
						if(options.useIframe){										
							jQuery("<iframe></iframe>")
								.attr({ id: options.itemContainer.attr.id + "_iframe",	frameBorder: "0" })
								.css(options.positioning.css)
								.css({ background: "Transparent", border: "none", display: "block", zIndex: options.itemContainer.css.zIndex-1	})			
								.prependTo(options.positioning.relativeTo || input.parent());
						}						
						printItems();																				
					}
					else{
						jQuery('#' + options.itemContainer.attr.id).html("");								
						printItems();
					}					
					break;
			}
		}
		else{
			close();
		}
	});
}
// ########################### JQUERY.COMBINED.JS ##### END

// ########################### PROFILE.JS ##### START
// Accepts the URL and size of a swf file and returns the equivalent png information
function avatarSwfToPng(avSize, avUrl) {
	var avWidth = "", avHeight = "", avStyle = "";
	
	switch(avSize.toUpperCase()){		
		case "TINY":
			avWidth = "24";
			avHeight = "19";
			avStyle = "Tiny";
			break;				
		case "SMALL":
			avWidth = "62";
			avHeight = "51";
			avStyle = "Small";
			break;				
		case "MED":
		case "MEDIUM":
			avWidth = "81";
			avHeight = "65";
			avStyle = "Medium";
			break;			
		case "LARGE":
			avWidth = "155";
			avHeight = "125";
			avStyle = "Large";
			break;	
	}

	var lastDefaultPos = avUrl.indexOf('avatar_default');
	var superDir = "/super/";
	var lastSuperPos = avUrl.indexOf(superDir);
	var imgUrlSubStr = "";
	
	// Default avatar
	if(lastDefaultPos > 0) {
		imgUrlSubStr = avUrl.substring(0, lastDefaultPos);
		if(imgUrlSubStr)
			avUrl = imgUrlSubStr + "avatar_default_" + avWidth + "x" + avHeight + ".png"
	// Super User avatar
	} else if(lastSuperPos > 0) {
		lastSuperPos += superDir.length;
		// 4 == length of ".swf"
		var urlLength = avUrl.length - 4;
		superUserName = avUrl.substring(lastSuperPos, urlLength);
		imgUrlSubStr = avUrl.substring(0, lastSuperPos);
		if(imgUrlSubStr)
			avUrl = imgUrlSubStr + "su_" + superUserName + "_" + avWidth + "x" + avHeight + ".png"
	// User avatar
	} else {

		var lastPos = avUrl.lastIndexOf('_');

		imgUrlSubStr = avUrl.substring(0, lastPos);
		var imgSizeExt = "_" + avWidth + "x" + avHeight + ".png";
		
		avUrl = imgUrlSubStr + imgSizeExt;
		
		// Do not return a broken image (Ex: ../_81x65.png)
		if(avUrl == imgSizeExt)
			avUrl = "";
	}
	return { imgUrl: avUrl, imgWidth: avWidth, imgHeight: avHeight, imgStyle: avStyle };
}

jQuery.fn.updateModule = function(options) { 
	return this.each(function() {
		if (this.moduleObject)
			this.moduleObject.update(options);
	}); 
};

var ProfileModuleManager = {
	modules: new Array(),
	initialize: function() {
		jQuery('#ProfilePage .ProfileModule').each(function() { ProfileModuleManager.addModule(this); });
	},
	addModule: function(moduleElement) {
		this.modules.push(new ProfileModule(moduleElement));
	},
	getModuleById: function(id) {
		for (var i=0; i< this.modules.length;i++) {
			if (id == this.modules[i].id) {
				return this.modules[i];
			}
		}
	},
	refreshModuleById: function(id, params) {
		this.getModuleById(id).update(params);
	}
};

function ProfileModule (moduleElement, options) {
	this.moduleElement = moduleElement;
	moduleElement.moduleObject = this;
	this.titleElement = jQuery(moduleElement).children('h1');
	this.bodyElement = jQuery(moduleElement).children('.ModuleBody');
	this.settingsObject = false;
	this.refreshUrl = jQuery(moduleElement).attr('refreshUrl');
	this.id = jQuery(moduleElement).attr('id');
	
	jQuery.extend(this, options);
	
	this.initialize();
}

ProfileModule.prototype = {
	edit: function() { },
	update: function(params) {		
		if (this.refreshUrl) {
			var self = this;
			var refreshUrl = this.refreshUrl;
			if (!typeof(profilePage) != "undefined") {
				var defaultParam = "userNum=" + profilePage.owner().userNum();
				if (params)
					params += "&" + defaultParam;
				else
					params = defaultParam;
			}
			if (params) {
				refreshUrl += "?" + params;
			}
			jQuery.get(refreshUrl, function(response) {
				self.bodyElement.html(response);
				jQuery('#SaveButton').removeClass('LoadingForm');
				onUpdateHTML(self.bodyElement);
			});
		}
	},
	toggleCollapse: function() {	
		if (jQuery(jQuery(this.bodyElement).prev()).hasClass('Collapsed')){
			jQuery('#' + this.moduleElement.id + ' .CollapseToggle').attr("clickPath", "expanded")
			this.show();			
		}
		else{
			jQuery('#' + this.moduleElement.id + ' .CollapseToggle').attr("clickPath", "collapsed")
			this.hide();
		}
	},
	show: function() {		
		jQuery(this.bodyElement).show();
		jQuery(jQuery(this.bodyElement).prev()).removeClass('Collapsed');
		this.setCollapsedCookies(this.id);
		this.update();
	},  /* TODO:  Change 1 back to 'slow' once the IE issue is worked out */
	hide: function() { 
		jQuery(this.bodyElement).hide();
		jQuery(jQuery(this.bodyElement).prev()).addClass('Collapsed');
		this.setCollapsedCookies(this.id);
	},  /* TODO:  Change 1 back to 'slow' once the IE issue is worked out */
	setCollapsedCookies: function(moduleId) {
		var collapsedModules = 'min=[';
		var cDelim = '';
		jQuery('#ProfilePage .ProfileModule').each(function() {
			if (jQuery(this).find('.ModuleHeader').hasClass('Collapsed')) {
				collapsedModules += cDelim + jQuery(this).attr('moduleId');
				cDelim = '.';
			}
		});

		setCookie('module_info', collapsedModules + ']', 'Wed, 1 Jan 2020 23:23:59 GMT', '/', '.iwon.com');
	},
	initialize: function() {
		this.settingsObject = ProfileSettings.addModuleSettings(this.moduleElement, {moduleObject:this});
		var self = this;
		jQuery('#' + this.moduleElement.id + ' .CollapseToggle')
			.click(function() { self.toggleCollapse(); })
			.hover(			
				function(){
					var objSprite = SpriteMap[jQuery(this).attr("spriteKey")] || {left:"0"};
					if (jQuery(this.parentNode).hasClass('Collapsed')){
						jQuery(this).css({backgroundPosition: objSprite.left + ' -60px'});
					}
					else{
						jQuery(this).css({backgroundPosition: objSprite.left + ' -20px'});
					}
				},
				function(){
					var objSprite = SpriteMap[jQuery(this).attr("spriteKey")] || {left:"0"};
					jQuery(this).css({backgroundPosition: objSprite.left + ' 0'});
				}
			);
	},
	loadPage: function() {
		return this.update();
	}
};

function ModuleSettings(module, options, link) {
	if (link != undefined) {
		var jProfileSettingsLink = link;
	}
	else {
		var jProfileSettingsLink = jQuery(module).children('.ProfileSettings');
	}
	this.module = module;
	this.name = jProfileSettingsLink.html();
	this.editURL = jProfileSettingsLink.attr('href');
	this.editURLParams = "";
	this.id = jProfileSettingsLink.attr('id');
	this.moduleObject = false;
	
	jQuery.extend(this, options);
}
ModuleSettings.prototype = {
	getForm: function() {		
		// make the ajax request for the form
		jQuery('#FormContainer').html('').addClass('LoadingForm');
		jQuery('#ModuleList').children('h3').removeClass('SelectedModule');
		jQuery.ajax({
			type: 'get',
			url:this.editURL + '?userNum=' + profilePage.owner().userNum() + this.editURLParams,
			success: this.getFormComplete,
			settingsScope: this
		});
	},
	show: function() {
		this.getForm();
		jQuery('#SectionTitle').html(this.name);
	},
	getFormComplete: function(response) {
		//draw form
		jQuery('#FormContainer').html(response).removeClass('LoadingForm');
		this.settingsScope.listObject.addClass('SelectedModule');
		//Urchin Tracking
		jQuery('#ProfileSettings .TrackClicks[@clickPath]').click(trackClicks);		
		//Urchin Tracking for settings feilds/dropdowns whose values are changed
		var clickPath = "/clicks/profilePage/profileSettings/" + this.settingsScope.name;		
		jQuery('#ProfileSettings input, select').change(function(){
			urchinTracker(clickPath + "/" + this.name + "/valueChanged");
		});
	}
}

var ProfileSettings = {
	isVisible: false,
	width:755,
	height:534,
	modules: new Array(),
	selectedModule: {},
	initialize: function() {
			
	},
	addModuleSettings: function(moduleElement, options) {
		if (typeof(profilePage) != "undefined" && (profilePage.isPrivateView() || profilePage.visitor().bSuper())) {
		jElement = jQuery(moduleElement);
		if (jElement.hasClass('HasEditPane')) {
			//GvH:	Added functionality to support more than one edit link
			aModuleSettings = jElement.children('.ProfileSettings');
			//MJ:	Added logic to visibly separate multiple edit links			
			var sSeparator = (aModuleSettings.length > 1) ? "<div style=\"float:right; color:Gray;\">&nbsp;&nbsp;</div>" : "";			
			var iCnt = 0;			
			aModuleSettings.each(function() {
				if(++iCnt == aModuleSettings.length){
					sSeparator = "";
				}	
				var currentModule = new ModuleSettings(moduleElement, options, jQuery(this));
				ProfileSettings.modules.push(currentModule);				
				sEditLinkName = jQuery(this).attr('linkName');
				if (sEditLinkName == undefined) sEditLinkName = "edit";
				jElement.children('h1.ModuleHeader')					
					.append('<div class="EditModuleSettings Clickable" clickPath="' + sEditLinkName + '"><span>' + sEditLinkName + '</span></div>' + sSeparator)
					.children('.EditModuleSettings:last')
					.hover(
						function(){jQuery(this).css("text-decoration", "underline");},
						function(){jQuery(this).css("text-decoration", "none");}
					)
					.click(function() { ProfileSettings.show(currentModule); })
					.click(trackClicks)
					.addClass('Clickable');							
				
			});
			
			//
				
			return aModuleSettings;
		}
		}
		return false;
	},
	
	refreshCurrentModule: function() { if (ProfileSettings.selectedModule.moduleObject) ProfileSettings.selectedModule.moduleObject.update(); },
	refreshModuleById: function(id) { ProfileSettings.getModuleById(id).update(); },
	getById: function(id) {
		for (var i = 0; i < ProfileSettings.modules.length; i++)
			if (ProfileSettings.modules[i].id == id) 
				return ProfileSettings.modules[i];
	},
	getModuleById: function(id) {
		for (var i = 0; i < ProfileSettings.modules.length; i++) {
			if (ProfileSettings.modules[i].moduleObject.id == id) 
				return ProfileSettings.modules[i].moduleObject;
		}
	},
	showById: function(id) {
		var moduleById = ProfileSettings.getById(id);
		if (ProfileSettings.isVisible) moduleById.show();
		else ProfileSettings.show(moduleById);
	},
	afterSettingsClose: function() {
		ProfileSettings.isVisible = false;
		jQuery('#ProfileSettingsOuter').html(settingsHTML);
		ProfileSettings.additionalAfterSettingsClose();
	},
	afterSettingsOpen: function() {		
		ProfileSettings.isVisible = true;
		var jListContainer = jQuery('#ModuleList');
		for (var i = 0; i < ProfileSettings.modules.length; i++) {
			var shouldPlace = true;
			var currentModule = ProfileSettings.modules[i]; 
			jListContainer.find('h3').each(function() { if (jQuery(this).html() == currentModule.name) shouldPlace = false; });
			if (shouldPlace) {
				if (ProfileSettings.selectedModule === ProfileSettings.modules[i])
					var selected = ' SelectedModule';
				else var selected = '';
				jQuery('#SectionTitle').html(currentModule.name);
				jListContainer.append('<h3 class="Clickable' + selected + '">' + ProfileSettings.modules[i].name + '</h3>');
				// GvH & DB : Why last? In top friends we have two edit links, which calls this function twice, so to prevent the module settings
				// list from doubling, only add a settings field for the last rendered link
				jListContainer.children('h3:last').click(function() { this.moduleObject.show(); }).get(0).moduleObject = currentModule;
				currentModule.listObject = jListContainer.children('h3:last');
			}
		}
		jQuery('#SectionTitle').html(ProfileSettings.selectedModule.name);
		ProfileSettings.selectedModule.getForm();
	},
	additionalAfterSettingsClose: function() {},
	show: function(selectedModule) {		
		ProfileSettings.selectedModule = selectedModule;
		tb_show('', '#TB_inline?height=' + ProfileSettings.height + '&width=' + ProfileSettings.width + '&inlineId=ProfileSettingsOuter&modal=true&onAfterClose=ProfileSettings.afterSettingsClose&&onAfterOpen=ProfileSettings.afterSettingsOpen');
		
						
	},
	close: function() {
		jQuery('#FormContainer').remove();
		tb_remove(null, true);
		ProfileSettings.afterSettingsClose();
	}
};

/*  
	We don't have a true AJAX service for errors, so this will parse error messages
	from HTML, if the HTML is set up to support it 
*/
getErrorMessageFromHTML = function(html, context) {
	context = context || "";
	error = "There was a problem.";
	startError = "<!-- ERROR:";
	endError = ":ERROR -->";
	if (html.indexOf(startError) > -1 && html.indexOf(endError) > -1) {
		error = html.split(startError)[1].split(endError)[0];
	}	
	return getFriendlyErrorMessage(error, context);
};

function getFriendlyErrorMessage(error, context){
	switch(error.toUpperCase()){
		case "ALREADY_FRIENDS":
		case "DEFAULT_FRIEND":
			switch(context.toUpperCase()){
				default:
					error = "You're already friends";
					break;
			}			
			break;
			
		case "ALREADY_INVITED":
			switch(context.toUpperCase()){
				default:
					error = "You have already invited this user to be your friend";
					break;
			}
			break;
						
		case "BLOCKED":
			switch(context.toUpperCase()){	
				default:
					error = "You have blocked this user";
					break;
			}
			break;
			
			
		case "MAX_FRIENDS_REACHED":
			switch(context.toUpperCase()){
				default:
					error = "You have reached the maximum number of friends";
					break;
			}
			break; 
			
		case "AGE_GROUP_DIFFER":
			switch(context.toUpperCase()){
				default:
					error = "This user is not in your age group";
					break;
			}
			break;
			
		case "NO_INVITATION":
			switch(context.toUpperCase()){
				default:
					error = "This invitation no longer exists";
					break;
			}
			break;
	}
	return error;
}

function insertCommas(value, delim){	
	delim = delim || " ";
	value = value + "";
	var retVal = "";
	jQuery.each(value.split(delim), function(i, v){		
		if (!isNaN(v-0)){
			var tmpVal = "";			
			for(var i = v.length-1; i >= 0; i = i-1){				
				if((v.length-i)%3 == 0 && i!=0){
					tmpVal = "," + v.charAt(i) + tmpVal;	
				}
				else{
					tmpVal = v.charAt(i) + tmpVal;
				}
			}
			retVal += " " + tmpVal;
		}
		else{			
			retVal += " " + v;
		}
	});
	return jQuery.trim(retVal);
}


function formError(msg,sourceid, formId) {
	if (formId == null)
		formId = "#FormContainer";

	// The height of the errordiv is determined by available space on #FormContainer, 
	// but always at least one error will be displayed and the height will never exceed 80 pixels.
	
	// get position + height + correction from the last visible element on the form
	lastElementTop = jQuery(formId + ' :last-child:visible:last').position().top + jQuery(formId + ' :last-child:last').outerHeight() + 25;
	if ( (jQuery(formId + " #formErrorMsg div").size() > 1) && (lastElementTop > jQuery(formId).height()) || (jQuery(formId + " #formErrorMsg").height() > 80) ) {
		// keep current height and add scrollbar
		fittingHeight = jQuery(formId + " #formErrorMsg").height();
		jQuery(formId + " #formErrorMsg").css({'overflow':'auto'}).css({'height':fittingHeight+'px'})
	}
	if (jQuery(formId + " #formErrorMsg div").size() == 0) {
		jQuery(formId + " #formErrorMsg").append("<div><span style='font-weight:bold;'>"+"Oops! An error has occurred. Please see areas highlighted in red below."+"</span>").show();
	}	
	jQuery(formId + " #formErrorMsg").append("<div><span style='font-weight:bold;'>&nbsp;&nbsp;"+msg+"</span>").show();
	if (jQuery(formId + ' #SaveButton') != null) {
		jQuery(formId + ' #SaveButton').removeClass('SavingForm');
	}
	//select optional error element
	jQuery(sourceid).addClass('errorElement');
}

function resetFormError(formId){
	if (formId == null) 
		formId = "#FormContainer"
	jQuery(formId + " #formErrorMsg").hide().empty();
	jQuery(formId + " .errorElement").removeClass('errorElement');
}	

function showSavedButton() {
	jQuery('#SaveButton').addClass('SavedForm');
	setTimeout("jQuery('#SaveButton').removeClass('SavedForm')",3000)
}

function profileInitialize() {	
	onUpdateHTML();
	ProfileSettings.initialize();
	ProfileModuleManager.initialize();
	//initializeBadges();
}

function openGameFromAttribute() { openGame(jQuery(this).attr('gameId')); }

// code to make rollover go bye-bye
var cluetipTimeout = null;
var cluetipDelayTimeout = null;

function hideCluetip(){
	cluetipDelayTimeout = clearTimeout(cluetipDelayTimeout);
	cluetipTimeout = setTimeout("jQuery('#cluetip').hide(); cluetipTimeout = clearTimeout(cluetipTimeout);", 1500);
	//jQuery('.RolloverStatz').unbind('mouseout', hideCluetip);	
}

function showCluetip(){
	cluetipDelayTimeout = clearTimeout(cluetipDelayTimeout);
	cluetipTimeout = clearTimeout(cluetipTimeout);
	jQuery('#cluetip').show();
}
//end code to make rollover go bye-bye

function onUpdateHTML(jElement) {
	if (!jElement) var jQueryPrefix = '';
	else var jQueryPrefix = '#' + jElement.get(0).id + ' ';
	
	/* This function is called when a module body is updated (refreshed) 
	-    When adding to the function, be sure to make all the jQuery calls the same way but inside the selector add jQueryPrefix + and then the selector
	-    See the following example:  
	jQuery(jQueryPrefix + '#BlahSelectorEtc .SomeClassNameOrOtherSelector').each(function() {
		...Do stuff...
	});
	*/
	
	//	assign Urchin Tracking handler to all 'TrackClicks' elements within updated area
	jQuery(jQueryPrefix +'.TrackClicks[@clickPath]').click(trackClicks);
	
	jQuery(jQueryPrefix +'.ProfileSettingsStandalone').each(function() {
			var mSettings = new ModuleSettings(this, {
				module: {},
				name: jQuery(this).attr('settingsTitle'),
				editURL: jQuery(this).attr('settingsUrl'),
				editURLParams: j(this).attr('settingsParams'),
				id: jQuery(this).attr('id')
			});
			ProfileSettings.modules.push(mSettings);
			jQuery(this).click(function() { ProfileSettings.show(mSettings); }).addClass('Clickable');
		});

	jQuery(jQueryPrefix + '*.simpleTooltip').cluetip({		
		showTitle: false,
		splitTitle: '|',
		dropShadow: false,
		positionBy: 'bottomTop',		
		topOffset: 15,
		leftOffset: 0,
		renderText: true
	});
	// adds rolloverstatz cluetip currently only to the largeAvatar, 

	//jQuery(jQueryPrefix + '#AvatarSWFClick_largeAvatar, ' + jQueryPrefix + '#MainPiece, ' + jQueryPrefix + '.RolloverStatz').cluetip({

	jQuery(jQueryPrefix + '.BasicHoverSprite').hover(Hover.on, Hover.off);

	jQuery(jQueryPrefix + 'textarea.limited').each(function() {
		jQuery(this).keyup(function() {			
			limitTextFieldEntry(this,jQuery(this).attr("maxsize"));
		})
	});
	
	//initialize challenge launchpoints
	jQuery(jQueryPrefix +'.ChallengeLaunchIcon')
		.attr({
			href: "#",
			title: "|Challenge-a-Player"
		})
		.cluetip({		
			showTitle: false,
			splitTitle: '|',
			dropShadow: false,
			positionBy: 'bottomTop',		
			topOffset: 15,
			leftOffset: 0,
			renderText: true,			
			width: 105
		})
		.click(function(){		
			var element = jQuery(this);
			ChallengePlayer.launchForm(						
				element.attr("challengeeId"),			
				element.attr("gameId")
			);
		});	
	
}
function ProfileUser(userNum, userName, bSuper) {
	this._userNum = userNum;
	this._userName = userName;
	if (bSuper == null) bSuper = false;
	this._bSuper = bSuper;
}

ProfileUser.prototype = {
	userNum: function(num) {
		if (num != null)
			this._userNum = num;
		return this._userNum;
	},
	userName: function(name) {
		if (name != null)
			this._userName = name;
		return this._userName;
	},
	bSuper: function(sup) {
		if (sup != null)
			this._bSuper = sup;
		return this._bSuper;
	} 
}
/* Class for page-level properties/methods */
function ProfilePage(owner, visitor) {
	this._owner = owner;
	this._visitor = visitor;
}

ProfilePage.prototype = {
	isPublicView: function() {
		return this._owner.userNum() != this._visitor.userNum();
	},
	isPrivateView: function() {
		return !this.isPublicView();
	},
	owner: function(user) {
		if (user != null)
			this._owner = user;
		return this._owner;
	},
	visitor: function(user) {
		if (user != null)
			this._visitor = user;
		return this._visitor;
	}
};

// Limit text field size
// Should probably be in more generic form validation section
function limitTextFieldEntry(txtarea,charlimit)
{
	var txt = jQuery(txtarea).val();
	var txtlength = txt.length;
	var line = txt.replace(/\s+$/g,"");
	
	if(txtlength > charlimit)
	{
		jQuery(txtarea).val(txt.substr(0,charlimit));
		return false;
	}
}

// Generic document ready function
jQuery(document).ready(function(){
	// Handles other user's profile page 'Back to My Profile' and 'Add to Friends List' clicks
	jQuery('#backToMyProfile').click(function(){	
		document.location.href = "/profile.jhtml";
	});
	
	jQuery('#addToFriendsList').click(function() {
		var clickRef = this;
		j.ajax({
			type: "POST",
			url: j(this).attr("settingsUrl"),
			data: {newFriend: profilePage.owner().userName()},
			error: function (XMLHttpRequest, textStatus, errorThrown) {
				alert("Sorry, something went wrong.  Please try to add this friend again.");
			},
			success: function(response) {
				if(j(response).filter("success").length==1){
					alert("Your friend request has been sent!");
					if(j(response).find("badges").length==1){
						showBadgeAwardModal(j(response).find("badges").attr("ids"));
					}
				} else if(response.match("ALREADY_INVITED")) {
					alert("You have already invited this user to be your friend.")
				} else if(response.match("ALREADY_FRIENDS")) {
					alert("You are already friends with this user.")
				}
			}
		});
	});
	
	// recruit member
	j('#rightColumn_TwoCol .RecruitButton').click(function() {
		var recruitButton = j(this);
		if (visitorTeamId) {
			j.ajax({
				type: 'POST',
				url: '/teamInvitation.jhtml?teamId=' + visitorTeamId + '&userNames=' + profilePage.owner().userName(),
				success: function() {
					alert('You have invited ' + profilePage.owner().userName() + ' to join your team.');
					recruitButton.addClass('RecruitInviteSent');
				},
				error: function() {
					alert('Sorry, something went wrong.  Please try to recruit this member again.');
				}
			});
		} else {
			alert("Sorry, you can't recruit someone if you aren't on a team.\nYou can find a team to join on the Team Challenge page.");
		}
		return false;
	});
	
	j('#rightColumn_TwoCol .BlockButton').toggle(function() {
		var blockButton = j(this);
		// Block member
		j.ajax({
			type: 'POST',
			url: '/modules/blockFriend.jhtml',
			data: {friend: profilePage.owner().userName(), userNum: profilePage.owner().userNum()},
			success: function() {
				alert('You have blocked ' + profilePage.owner().userName());
				blockButton.addClass('UnblockButton');
			},
			error: function() {
				alert('Sorry, something went wrong.  Please try to block this member again.');
			}
		});
	},function() {
		var blockButton = j(this);
		// Unblock member
		j.ajax({
			type: 'POST',
			url: '/modules/unblockFriend.jhtml',
			data: {friend: profilePage.owner().userName(), userNum: profilePage.owner().userNum()},
			success: function() {
				alert('You have unblocked ' + profilePage.owner().userName());
				blockButton.removeClass('UnblockButton');
			},
			error: function() {
				alert('Sorry, something went wrong.  Please try to unblock this member again.');
			}
		});
	});
});

function setNotificationsBar(val){
	if(!isNaN(val)) {
		val = val-0;		
		var notificationCount = 0;
		if(val-0 < 0){
			notificationCount = (jQuery('#notificationsBar SPAN').text().split(" ")[0].replace("no","")-0)+val;		
		}else{
			notificationCount = val-0;
		}	
		if(notificationCount < 1){
			jQuery("#notificationsBar").css("background", "url(http://ak.imgfarm.com/images/iwon/profile/modules/notifications/bg_no_message.gif) no-repeat");
			jQuery("#notificationsBar SPAN").text("no pending messages").css("font-weight", "normal");
		}
		else{
			jQuery("#notificationsBar").css("background", "url(http://ak.imgfarm.com/images/iwon/profile/modules/notifications/bg_new_message.gif) no-repeat");
			jQuery("#notificationsBar SPAN").text(notificationCount +  " New Message" + ((notificationCount > 1) ? "s" : "") + "!").css("font-weight", "bold");
		}
	}
}

var ChallengePlayer = {		
	challengeeId: null,	
	gameId: null,
	width:542,
	height:323,
	url: "/modules/initiateChallenge.jhtml",
	close: function() {		
		tb_remove(null, true);		
	},
	launchForm: function(challengeeId, gameId){				
		this.challengeeId = challengeeId;		
		this.gameId = gameId;
		this.refresh(true);
	},
	populate: function(response){		
		if(jQuery('#ChallengePlayerForm').length == 1){	
			jQuery('#ChallengePlayerForm').replaceWith(response);
		}
		else{
			jQuery('#ChallengePlayerFormOuter').html(response);
		}		
		jQuery('#ChallengePlayerForm .BasicHoverSprite')
			.hover(Hover.on, Hover.off); 		
		jQuery('#ChallengePlayerForm .Close, #ChallengePlayerForm .Cancel, #ChallengePlayerForm .Ok')
			.click(ChallengePlayer.close);		
		jQuery('#ChallengePlayerForm .SendChallenge')
			.click(function(){
				ChallengePlayer.sendChallenge();
				urchinTracker('/clicks/profilePage/challengeModal/sendChallenge');
			});
		jQuery("#ChallengePlayerGames")
			.change(function(){
				ChallengePlayer.gameId = jQuery(this).val();
				ChallengePlayer.refresh();
				urchinTracker('/clicks/profilePage/challengeModal/chooseGame/' + this.value);
			});
	},
	refresh: function(bLaunch){
		jQuery("#ChallengePlayerForm .ChallengeDetailContainer").html("<div class='LoadingForm LoadingChallenge'></div>");		
		jQuery.get(
			this.url,
			{	
				playerNum: this.challengeeId,
				gameId:	this.gameId
			},
			function(response) {								
				ChallengePlayer.populate(response);
				if(bLaunch){
					tb_show('', '#TB_inline?height=' + ChallengePlayer.height + '&width=' + ChallengePlayer.width + '&inlineId=ChallengePlayerFormOuter&modal=true');
				}
			}
		);	
	},
	sendChallenge: function(){
		if(jQuery("#ChallengePlayerGames").val() == ""){
			alert("Please select a game to challenge");
			return false;
		}	
		jQuery("#initiateChallenge").ajaxSubmit(
			{
				success: function(response){
					if(response == "success:true"){
						jQuery('#ChallengePlayerForm .Cancel, #ChallengePlayerForm .SendChallenge, #ChallengePlayerForm .Headline, #ChallengePlayerForm .ChallengeSummaryContainer, #ChallengePlayerForm .ChallengeDetailContainer').hide(); 			
						jQuery('#ChallengePlayerForm .Ok, #ChallengePlayerForm .Confirmation').show();
					} else {					
						ChallengePlayer.populate(response);					
						if(jQuery("#ChallengePlayerForm .Error").length > 0) {						
							jQuery('#ChallengePlayerForm .Cancel, #ChallengePlayerForm .SendChallenge, #ChallengePlayerForm .Headline, #ChallengePlayerForm .ChallengeSummaryContainer, #ChallengePlayerForm .ChallengeDetailContainer').hide();						
							jQuery('#ChallengePlayerForm .Ok, #ChallengePlayerForm .ErrorMessage').show();
							jQuery('#ChallengePlayerForm .ErrorMessage').html(jQuery("#ChallengePlayerForm .Error:first").html());						
						}						
					}
				}
			}
		);
	}
};

function getUserTier(gameboardLevel) {
	var userTier;
	switch(parseInt(gameboardLevel)) {
		case 1: case 2:
			userTier = "Copper";
			break;
		case 3: case 4:
			userTier = "Bronze";
			break;
		case 5: case 6:
			userTier = "Silver";
			break;
		case 7: case 8:
			userTier = "Gold";
			break;
		case 9: case 10:
			userTier = "Platinum";
			break;
		case 11: case 12:
			userTier = "Jade";
			break;
		case 13: case 14:
			userTier = "Pearl";
			break;
		case 15: case 16:
			userTier = "Ruby";
			break;
		case 17: case 18:
			userTier = "Sapphire";
			break;
		case 19: case 20:
			userTier = "Diamond";
			break;
		default:
			userTier = "Copper";
			break;
	}
	return userTier;
}

// ########################### PROFILE.JS ##### END

// ########################### CHALLENGE.JS ##### START
jQuery(intializeTeamPage);

function intializeTeamPage() {
	jQuery('.SimpleHover').hover( 
		function() { jQuery(this).css({'background-position': '0 -' + jQuery(this).height() + 'px'}); },
		function() { jQuery(this).css({'background-position': '0 0'}); }
	);
	onUpdateHTML();
}
// ########################### CHALLENGE.JS ##### END
