/**
 * Cookie plugin
 *
 * Copyright (c) 2006 Klaus Hartl (stilbuero.de)
 * Dual licensed under the MIT and GPL licenses:
 * http://www.opensource.org/licenses/mit-license.php
 * http://www.gnu.org/licenses/gpl.html
 *
 */

jQuery.cookie = function(name, value, options) {
    if (typeof value != 'undefined') { // name and value given, set cookie
        options = options || {};
        if (value === null) {
            value = '';
            options.expires = -1;
        }
        var expires = '';
        if (options.expires && (typeof options.expires == 'number' || options.expires.toUTCString)) {
            var date;
            if (typeof options.expires == 'number') {
                date = new Date();
                date.setTime(date.getTime() + (options.expires * 24 * 60 * 60 * 1000));
            } else {
                date = options.expires;
            }
            expires = '; expires=' + date.toUTCString(); // use expires attribute, max-age is not supported by IE
        }
        // CAUTION: Needed to parenthesize options.path and options.domain
        // in the following expressions, otherwise they evaluate to undefined
        // in the packed version for some reason...
        var path = options.path ? '; path=' + (options.path) : '';
        var domain = options.domain ? '; domain=' + (options.domain) : '';
        var secure = options.secure ? '; secure' : '';
        document.cookie = [name, '=', encodeURIComponent(value), expires, path, domain, secure].join('');
    } else { // only name given, get cookie
        var cookieValue = null;
        if (document.cookie && document.cookie != '') {
            var cookies = document.cookie.split(';');
            for (var i = 0; i < cookies.length; i++) {
                var cookie = jQuery.trim(cookies[i]);
                // Does this cookie string begin with the name we want?
                if (cookie.substring(0, name.length + 1) == (name + '=')) {
                    cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
                    break;
                }
            }
        }
        return cookieValue;
    }
};

var active_dropdown = null;

;$(document).click(function(){
	if(active_dropdown){
		$(active_dropdown).hide();
	}
});

$.fn.customSelect = function(id) {
		//plugin for custom select boxes

	obj = $(this);  
	obj.after('<div id="' + id + '" class="selectoptions"> </div>');
	
	obj.find('option').each(function(i){ 
		$("#"+ id).append('<div id="' + $(this).attr("value") + '" class="selectitems"><span>' + $(this).html() + '</span></div>');
	});
	
	obj.before('<input type="hidden" value ="" id="' + $(this).attr('name') + '" name="' + $(this).attr('name') + '" class="customselect"/><div id="icon' + id + '" class="iconselect">Please Choose...</div><div id="holder' + id + '" class="iconselectholder"> </div>').remove();

	var obj_id = $(this).attr('name');
	//console.log(obj_id);

	$("#icon" + id).click(function(){
			if($("#holder" + id).is(":hidden")) {
				$("#holder" + id).slideDown("fast");
				
				if(active_dropdown && active_dropdown != $("#holder" + id)){
					$(active_dropdown).hide();
				}
				active_dropdown = $("#holder" + id);
			} else {
			     $("#holder" + id).slideUp("fast");
			}
	});

	$("#holder" + id).append( $("#" + id)[0] );

	$(".selectitems").mouseover(function(){
		$(this).addClass("hoverclass");
	});

	$(".selectitems").mouseout(function(){
		$(this).removeClass("hoverclass");
	});

	$("div#holder" + id + " .selectitems").click(function(){
		$("div#holder" + id + " .selectedclass").removeClass("selectedclass");
		$(this).addClass("selectedclass");
		var thisselection = $(this).html();

		$('label.error[for="' + obj_id + '"]').each(function(){
			$(this).html('');
			$(this).hide();
		});


		$("#" + obj_id).val(this.id);
		$("#icon" + id).html(thisselection);
		$("#holder" + id).slideUp("fast");
	});

};


/* Copyright (c) 2006 Mathias Bank (http://www.mathias-bank.de)
 * Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php) 
 * and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses.
 * 
 * Thanks to Hinnerk Ruemenapf - http://hinnerk.ruemenapf.de/ for bug reporting and fixing.
 */
jQuery.extend({

 getURLParam: function(strParamName){
	  var strReturn = "";
	  var strHref = window.location.href;
	  var bFound=false;
	  
	  var cmpstring = strParamName + "=";
	  var cmplen = cmpstring.length;

	  if ( strHref.indexOf("?") > -1 ){
	    var strQueryString = strHref.substr(strHref.indexOf("?")+1);
	    var aQueryString = strQueryString.split("&");
	    for ( var iParam = 0; iParam < aQueryString.length; iParam++ ){
	      if (aQueryString[iParam].substr(0,cmplen)==cmpstring){
	        var aParam = aQueryString[iParam].split("=");
	        strReturn = aParam[1];
	        bFound=true;
	        break;
	      }
	      
	    }
	  }
	  if (bFound==false) return null;
	  return strReturn;
	}
});



/*
 * jQuery JSON Plugin
 * version: 1.0 (2008-04-17)
 *
 * This document is licensed as free software under the terms of the
 * MIT License: http://www.opensource.org/licenses/mit-license.php
 *
 * Brantley Harris technically wrote this plugin, but it is based somewhat
 * on the JSON.org website's http://www.json.org/json2.js, which proclaims:
 * "NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.", a sentiment that
 * I uphold.  I really just cleaned it up.
 *
 * It is also based heavily on MochiKit's serializeJSON, which is 
 * copywrited 2005 by Bob Ippolito.
 */
 
(function($) {   
    function toIntegersAtLease(n) 
    // Format integers to have at least two digits.
    {    
        return n < 10 ? '0' + n : n;
    }

    Date.prototype.toJSON = function(date)
    // Yes, it polutes the Date namespace, but we'll allow it here, as
    // it's damned usefull.
    {
        return this.getUTCFullYear()   + '-' +
             toIntegersAtLease(this.getUTCMonth()) + '-' +
             toIntegersAtLease(this.getUTCDate());
    };

    var escapeable = /["\\\x00-\x1f\x7f-\x9f]/g;
    var meta = {    // table of character substitutions
            '\b': '\\b',
            '\t': '\\t',
            '\n': '\\n',
            '\f': '\\f',
            '\r': '\\r',
            '"' : '\\"',
            '\\': '\\\\'
        };
        
    $.quoteString = function(string)
    // Places quotes around a string, inteligently.
    // If the string contains no control characters, no quote characters, and no
    // backslash characters, then we can safely slap some quotes around it.
    // Otherwise we must also replace the offending characters with safe escape
    // sequences.
    {
        if (escapeable.test(string))
        {
            return '"' + string.replace(escapeable, function (a) 
            {
                var c = meta[a];
                if (typeof c === 'string') {
                    return c;
                }
                c = a.charCodeAt();
                return '\\u00' + Math.floor(c / 16).toString(16) + (c % 16).toString(16);
            }) + '"';
        }
        return '"' + string + '"';
    };
    
    $.toJSON = function(o, compact)
    {
        var type = typeof(o);
        
        if (type == "undefined")
            return "undefined";
        else if (type == "number" || type == "boolean")
            return o + "";
        else if (o === null)
            return "null";
        
        // Is it a string?
        if (type == "string") 
        {
            return $.quoteString(o);
        }
        
        // Does it have a .toJSON function?
        if (type == "object" && typeof o.toJSON == "function") 
            return o.toJSON(compact);
        
        // Is it an array?
        if (type != "function" && typeof(o.length) == "number") 
        {
            var ret = [];
            for (var i = 0; i < o.length; i++) {
                ret.push( $.toJSON(o[i], compact) );
            }
            if (compact)
                return "[" + ret.join(",") + "]";
            else
                return "[" + ret.join(", ") + "]";
        }
        
        // If it's a function, we have to warn somebody!
        if (type == "function") {
            throw new TypeError("Unable to convert object of type 'function' to json.");
        }
        
        // It's probably an object, then.
        var ret = [];
        for (var k in o) {
            var name;
            type = typeof(k);
            
            if (type == "number")
                name = '"' + k + '"';
            else if (type == "string")
                name = $.quoteString(k);
            else
                continue;  //skip non-string or number keys
            
            var val = $.toJSON(o[k], compact);
            if (typeof(val) != "string") {
                // skip non-serializable values
                continue;
            }
            
            if (compact)
                ret.push(name + ":" + val);
            else
                ret.push(name + ": " + val);
        }
        return "{" + ret.join(", ") + "}";
    };
    
    $.compactJSON = function(o)
    {
        return $.toJSON(o, true);
    };
    
    $.evalJSON = function(src)
    // Evals JSON that we know to be safe.
    {
        return eval("(" + src + ")");
    };
    
    $.secureEvalJSON = function(src)
    // Evals JSON in a way that is *more* secure.
    {
        var filtered = src;
        filtered = filtered.replace(/\\["\\\/bfnrtu]/g, '@');
        filtered = filtered.replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']');
        filtered = filtered.replace(/(?:^|:|,)(?:\s*\[)+/g, '');
        
        if (/^[\],:{}\s]*$/.test(filtered))
            return eval("(" + src + ")");
        else
            throw new SyntaxError("Error parsing JSON, source is not valid.");
    };
})(jQuery);



(function($) {

$.extend({
	metadata : {
		defaults : {
			type: 'class',
			name: 'metadata',
			cre: /({.*})/,
			single: 'metadata'
		},
		setType: function( type, name ){
			this.defaults.type = type;
			this.defaults.name = name;
		},
		get: function( elem, opts ){
			var settings = $.extend({},this.defaults,opts);
			// check for empty string in single property
			if ( !settings.single.length ) settings.single = 'metadata';

			var data = $.data(elem, settings.single);
			// returned cached data if it already exists
			if ( data ) return data;

			data = "{}";

			if ( settings.type == "class" ) {
				var m = settings.cre.exec( elem.className );
				if ( m )
					data = m[1];
			} else if ( settings.type == "elem" ) {
				if( !elem.getElementsByTagName )
					return undefined;
				var e = elem.getElementsByTagName(settings.name);
				if ( e.length )
					data = $.trim(e[0].innerHTML);
			} else if ( elem.getAttribute != undefined ) {
				var attr = elem.getAttribute( settings.name );
				if ( attr )
					data = attr;
			}

			if ( data.indexOf( '{' ) <0 )
			data = "{" + data + "}";

			data = eval("(" + data + ")");

			$.data( elem, settings.single, data );
			return data;
		}
	}
});


$.fn.metadata = function( opts ){
	return $.metadata.get( this[0], opts );
};

})(jQuery);


/*
 *
 * Copyright (c) 2006-2008 Sam Collett (http://www.texotela.co.uk)
 * Licensed under the MIT License:
 * http://www.opensource.org/licenses/mit-license.php
 * 
 * Version 2.0.2
 * Demo: http://www.texotela.co.uk/code/jquery/newsticker/
 *
 * $LastChangedDate$
 * $Rev$
 *
 */
 
(function($) {

$.fn.newsTicker = $.fn.newsticker = function(delay)
{
	delay = delay || 4000;
	initTicker = function(el)
	{
		$.newsticker.clear(el);
		el.items = $("li", el);
		// hide all items (except first one)
		el.items.not(":eq(0)").hide().end();
		// current item
		el.currentitem = 0;
		startTicker(el);
	};
	startTicker = function(el)
	{
		el.tickfn = setInterval(function() { doTick(el) }, delay)
	};
	doTick = function(el)
	{
		// don't run if paused
		if(el.pause) return;
		// pause until animation has finished
		$.newsticker.pause(el);
		// hide current item
		$(el.items[el.currentitem]).fadeOut("slow",
			function()
			{
				$(this).hide();
				// move to next item and show
				el.currentitem = ++el.currentitem % (el.items.size());
				$(el.items[el.currentitem]).fadeIn("slow",
					function()
					{
						$.newsticker.resume(el);
					}
				);
			}
		);
	};
	this.each(
		function()
		{
			if(this.nodeName.toLowerCase()!= "ul") return;
			initTicker(this);
		}
	)
	.addClass("newsticker")
	.hover(
		function()
		{
			// pause if hovered over
			$.newsticker.pause(this);
		},
		function()
		{
			// resume when not hovered over
			$.newsticker.resume(this);
		}
	);
	return this;
};


$.newsticker = $.newsTicker =
{
	pause: function(el)
	{
		(el.jquery ? el[0] : el).pause = true;
	},
	resume: function(el)
	{
		(el.jquery ? el[0] : el).pause = false;
	},
	clear: function(el)
	{
		el = (el.jquery ? el[0] : el);
		clearInterval(el.tickfn);
		el.tickfn = null;
		el.items = null;
		el.currentItem = null;
	}
}

})(jQuery);

$(document).ready(function(){
	
	$('#faqs').newsticker(11000);
	
});


/**
 * jQuery.ScrollTo
 * Copyright (c) 2007-2008 Ariel Flesler - aflesler(at)gmail(dot)com | http://flesler.blogspot.com
 * Dual licensed under MIT and GPL.
 * Date: 9/11/2008
 *
 * @projectDescription Easy element scrolling using jQuery.
 * http://flesler.blogspot.com/2007/10/jqueryscrollto.html
 * Tested with jQuery 1.2.6. On FF 2/3, IE 6/7, Opera 9.2/5 and Safari 3. on Windows.
 *
 * @author Ariel Flesler
 * @version 1.4
 *
 
 */
;(function( $ ){
	
	var $scrollTo = $.scrollTo = function( target, duration, settings ){
		$(window).scrollTo( target, duration, settings );
	};

	$scrollTo.defaults = {
		axis:'y',
		duration:1
	};

	// Returns the element that needs to be animated to scroll the window.
	// Kept for backwards compatibility (specially for localScroll & serialScroll)
	$scrollTo.window = function( scope ){
		return $(window).scrollable();
	};

	// Hack, hack, hack... stay away!
	// Returns the real elements to scroll (supports window/iframes, documents and regular nodes)
	$.fn.scrollable = function(){
		return this.map(function(){
			// Just store it, we might need it
			var win = this.parentWindow || this.defaultView,
				// If it's a document, get its iframe or the window if it's THE document
				elem = this.nodeName == '#document' ? win.frameElement || win : this,
				// Get the corresponding document
				doc = elem.contentDocument || (elem.contentWindow || elem).document,
				isWin = elem.setInterval;

			return elem.nodeName == 'IFRAME' || isWin && $.browser.safari ? doc.body
				: isWin ? doc.documentElement
				: this;
		});
	};

	$.fn.scrollTo = function( target, duration, settings ){
		if( typeof duration == 'object' ){
			settings = duration;
			duration = 0;
		}
		if( typeof settings == 'function' )
			settings = { onAfter:settings };
			
		settings = $.extend( {}, $scrollTo.defaults, settings );
		// Speed is still recognized for backwards compatibility
		duration = duration || settings.speed || settings.duration;
		// Make sure the settings are given right
		settings.queue = settings.queue && settings.axis.length > 1;
		
		if( settings.queue )
			// Let's keep the overall duration
			duration /= 2;
		settings.offset = both( settings.offset );
		settings.over = both( settings.over );

		return this.scrollable().each(function(){
			var elem = this,
				$elem = $(elem),
				targ = target, toff, attr = {},
				win = $elem.is('html,body');

			switch( typeof targ ){
				// A number will pass the regex
				case 'number':
				case 'string':
					if( /^([+-]=)?\d+(px)?$/.test(targ) ){
						targ = both( targ );
						// We are done
						break;
					}
					// Relative selector, no break!
					targ = $(targ,this);
				case 'object':
					// DOMElement / jQuery
					if( targ.is || targ.style )
						// Get the real position of the target 
						toff = (targ = $(targ)).offset();
			}
			$.each( settings.axis.split(''), function( i, axis ){
				var Pos	= axis == 'x' ? 'Left' : 'Top',
					pos = Pos.toLowerCase(),
					key = 'scroll' + Pos,
					old = elem[key],
					Dim = axis == 'x' ? 'Width' : 'Height',
					dim = Dim.toLowerCase();

				if( toff ){// jQuery / DOMElement
					attr[key] = toff[pos] + ( win ? 0 : old - $elem.offset()[pos] );

					// If it's a dom element, reduce the margin
					if( settings.margin ){
						attr[key] -= parseInt(targ.css('margin'+Pos)) || 0;
						attr[key] -= parseInt(targ.css('border'+Pos+'Width')) || 0;
					}
					
					attr[key] += settings.offset[pos] || 0;
					
					if( settings.over[pos] )
						// Scroll to a fraction of its width/height
						attr[key] += targ[dim]() * settings.over[pos];
				}else
					attr[key] = targ[pos];

				// Number or 'number'
				if( /^\d+$/.test(attr[key]) )
					// Check the limits
					attr[key] = attr[key] <= 0 ? 0 : Math.min( attr[key], max(Dim) );

				// Queueing axes
				if( !i && settings.queue ){
					// Don't waste time animating, if there's no need.
					if( old != attr[key] )
						// Intermediate animation
						animate( settings.onAfterFirst );
					// Don't animate this axis again in the next iteration.
					delete attr[key];
				}
			});			
			animate( settings.onAfter );			

			function animate( callback ){
				$elem.animate( attr, duration, settings.easing, callback && function(){
					callback.call(this, target, settings);
				});
			};
			function max( Dim ){
				var attr ='scroll'+Dim,
					doc = elem.ownerDocument;
				
				return win
						? Math.max( doc.documentElement[attr], doc.body[attr]  )
						: elem[attr];
			};
		}).end();
	};

	function both( val ){
		return typeof val == 'object' ? val : { top:val, left:val };
	};

})( jQuery );


/*
 *
 *	jQuery Timer plugin v0.1
 *		Matt Schmidt [http://www.mattptr.net]
 *
 *	Licensed under the BSD License:
 *		http://mattptr.net/license/license.txt
 *
 */
 
; jQuery.timer = function (interval, callback)
 {


	var interval = interval || 100;

	if (!callback)
		return false;
	
	_timer = function (interval, callback) {
		this.stop = function () {
			clearInterval(self.id);
		};
		
		this.internalCallback = function () {
			callback(self);
		};
		
		this.reset = function (val) {
			if (self.id)
				clearInterval(self.id);
			
			var val = val || 100;
			this.id = setInterval(this.internalCallback, val);
		};
		
		this.interval = interval;
		this.id = setInterval(this.internalCallback, this.interval);
		
		var self = this;
	};
	
	return new _timer(interval, callback);
 };


	;$(document).ready(function() {
		var footer_pics = $('#awards img');
		var pic_counter = 0;
		var current_pic = 0;

		function swapImage(){
			$(footer_pics[current_pic]).fadeOut();
			$(footer_pics[pic_counter]).fadeIn();
			current_pic = pic_counter;
			pic_counter = ((pic_counter + 1) >= footer_pics.length) ?  0 : pic_counter + 1;
		}

		/*
		swapImage();

		$.timer(3000, function(){
			swapImage();
		});
		*/
	});
	
	
	/*
	 * jQuery validation plug-in post1.5
	 *
	 * http://bassistance.de/jquery-plugins/jquery-plugin-validation/
	 * http://docs.jquery.com/Plugins/Validation
	 *
	 * Copyright (c) 2006 - 2008 JÃ¶rn Zaefferer
	 *
	 * $Id: jquery.validate.js 6096 2009-01-12 14:12:04Z joern.zaefferer $
	 *
	 * Dual licensed under the MIT and GPL licenses:
	 *   http://www.opensource.org/licenses/mit-license.php
	 *   http://www.gnu.org/licenses/gpl.html
	 */

	;(function($) {

	$.extend($.fn, {
		// http://docs.jquery.com/Plugins/Validation/validate
		validate: function( options ) {

			// if nothing is selected, return nothing; can't chain anyway
			if (!this.length) {
				options && options.debug && window.console && console.warn( "nothing selected, can't validate, returning nothing" );
				return;
			}

			// check if a validator for this form was already created
			var validator = $.data(this[0], 'validator');
			if ( validator ) {
				return validator;
			}

			validator = new $.validator( options, this[0] );
			$.data(this[0], 'validator', validator); 

			if ( validator.settings.onsubmit ) {

				// allow suppresing validation by adding a cancel class to the submit button
				this.find("input, button").filter(".cancel").click(function() {
					validator.cancelSubmit = true;
				});

				// validate the form on submit
				this.submit( function( event ) {
					if ( validator.settings.debug )
						// prevent form submit to be able to see console output
						event.preventDefault();

					function handle() {
						if ( validator.settings.submitHandler ) {
							validator.settings.submitHandler.call( validator, validator.currentForm );
							return false;
						}
						return true;
					}

					// prevent submit for invalid forms or custom submit handlers
					if ( validator.cancelSubmit ) {
						validator.cancelSubmit = false;
						return handle();
					}
					if ( validator.form() ) {
						if ( validator.pendingRequest ) {
							validator.formSubmitted = true;
							return false;
						}
						return handle();
					} else {
						validator.focusInvalid();
						return false;
					}
				});
			}

			return validator;
		},
		// http://docs.jquery.com/Plugins/Validation/valid
		valid: function() {
	        if ( $(this[0]).is('form')) {
	            return this.validate().form();
	        } else {
	            var valid = false;
	            var validator = $(this[0].form).validate();
	            this.each(function() {
					valid |= validator.element(this);
	            });
	            return valid;
	        }
	    },
		// attributes: space seperated list of attributes to retrieve and remove
		removeAttrs: function(attributes) {
			var result = {},
				$element = this;
			$.each(attributes.split(/\s/), function(index, value) {
				result[value] = $element.attr(value);
				$element.removeAttr(value);
			});
			return result;
		},
		// http://docs.jquery.com/Plugins/Validation/rules
		rules: function(command, argument) {
			var element = this[0];

			if (command) {
				var settings = $.data(element.form, 'validator').settings;
				var staticRules = settings.rules;
				var existingRules = $.validator.staticRules(element);
				switch(command) {
				case "add":
					$.extend(existingRules, $.validator.normalizeRule(argument));
					staticRules[element.name] = existingRules;
					if (argument.messages)
						settings.messages[element.name] = $.extend( settings.messages[element.name], argument.messages );
					break;
				case "remove":
					if (!argument) {
						delete staticRules[element.name];
						return existingRules;
					}
					var filtered = {};
					$.each(argument.split(/\s/), function(index, method) {
						filtered[method] = existingRules[method];
						delete existingRules[method];
					});
					return filtered;
				}
			}

			var data = $.validator.normalizeRules(
			$.extend(
				{},
				$.validator.metadataRules(element),
				$.validator.classRules(element),
				$.validator.attributeRules(element),
				$.validator.staticRules(element)
			), element);

			// make sure required is at front
			if (data.required) {
				var param = data.required;
				delete data.required;
				data = $.extend({required: param}, data);
			}

			return data;
		}
	});

	// Custom selectors
	$.extend($.expr[":"], {
		// http://docs.jquery.com/Plugins/Validation/blank
		blank: function(a) {return !$.trim(a.value);},
		// http://docs.jquery.com/Plugins/Validation/filled
		filled: function(a) {return !!$.trim(a.value);},
		// http://docs.jquery.com/Plugins/Validation/unchecked
		unchecked: function(a) {return !a.checked;}
	});


	$.format = function(source, params) {
		if ( arguments.length == 1 ) 
			return function() {
				var args = $.makeArray(arguments);
				args.unshift(source);
				return $.format.apply( this, args );
			};
		if ( arguments.length > 2 && params.constructor != Array  ) {
			params = $.makeArray(arguments).slice(1);
		}
		if ( params.constructor != Array ) {
			params = [ params ];
		}
		$.each(params, function(i, n) {
			source = source.replace(new RegExp("\\{" + i + "\\}", "g"), n);
		});
		return source;
	};

	// constructor for validator
	$.validator = function( options, form ) {
		this.settings = $.extend( {}, $.validator.defaults, options );
		this.currentForm = form;
		this.init();
	};

	$.extend($.validator, {

		defaults: {
			messages: {},
			groups: {},
			rules: {},
			errorClass: "error",
			errorElement: "label",
			focusInvalid: true,
			errorContainer: $( [] ),
			errorLabelContainer: $( [] ),
			onsubmit: true,
			ignore: [],
			ignoreTitle: false,
			onfocusin: function(element) {
				this.lastActive = element;

				// hide error label and remove error class on focus if enabled
				if ( this.settings.focusCleanup && !this.blockFocusCleanup ) {
					this.settings.unhighlight && this.settings.unhighlight.call( this, element, this.settings.errorClass );
					this.errorsFor(element).hide();
				}
			},
			onfocusout: function(element) {
				if ( !this.checkable(element) && (element.name in this.submitted || !this.optional(element)) ) {
					this.element(element);
				}
			},
			onkeyup: function(element) {
				if ( element.name in this.submitted || element == this.lastElement ) {
					this.element(element);
				}
			},
			onclick: function(element) {
				if ( element.name in this.submitted )
					this.element(element);
			},
			highlight: function( element, errorClass ) {
				$( element ).addClass( errorClass );
			},
			unhighlight: function( element, errorClass ) {
				$( element ).removeClass( errorClass );
			}
		},

		// http://docs.jquery.com/Plugins/Validation/Validator/setDefaults
		setDefaults: function(settings) {
			$.extend( $.validator.defaults, settings );
		},

		messages: {
			required: "This field is required.",
			remote: "Please fix this field.",
			email: "Please enter a valid email address.",
			url: "Please enter a valid URL.",
			date: "Please enter a valid date.",
			dateISO: "Please enter a valid date (ISO).",
			dateDE: "Bitte geben Sie ein gÃ¼ltiges Datum ein.",
			number: "Please enter a valid number.",
			numberDE: "Bitte geben Sie eine Nummer ein.",
			digits: "Please enter only digits",
			creditcard: "Please enter a valid credit card number.",
			equalTo: "Please enter the same value again.",
			accept: "Please enter a value with a valid extension.",
			maxlength: $.format("Please enter no more than {0} characters."),
			minlength: $.format("Please enter at least {0} characters."),
			rangelength: $.format("Please enter a value between {0} and {1} characters long."),
			range: $.format("Please enter a value between {0} and {1}."),
			max: $.format("Please enter a value less than or equal to {0}."),
			min: $.format("Please enter a value greater than or equal to {0}.")
		},

		autoCreateRanges: false,

		prototype: {

			init: function() {
				this.labelContainer = $(this.settings.errorLabelContainer);
				this.errorContext = this.labelContainer.length && this.labelContainer || $(this.currentForm);
				this.containers = $(this.settings.errorContainer).add( this.settings.errorLabelContainer );
				this.submitted = {};
				this.valueCache = {};
				this.pendingRequest = 0;
				this.pending = {};
				this.invalid = {};
				this.reset();

				var groups = (this.groups = {});
				$.each(this.settings.groups, function(key, value) {
					$.each(value.split(/\s/), function(index, name) {
						groups[name] = key;
					});
				});
				var rules = this.settings.rules;
				$.each(rules, function(key, value) {
					rules[key] = $.validator.normalizeRule(value);
				});

				function delegate(event) {
					var validator = $.data(this[0].form, "validator");
					validator.settings["on" + event.type] && validator.settings["on" + event.type].call(validator, this[0] );
				}
				$(this.currentForm)
					.delegate("focusin focusout keyup", ":text, :password, :file, select, textarea", delegate)
					.delegate("click", ":radio, :checkbox", delegate);

				if (this.settings.invalidHandler)
					$(this.currentForm).bind("invalid-form.validate", this.settings.invalidHandler);
			},

			// http://docs.jquery.com/Plugins/Validation/Validator/form
			form: function() {
				this.checkForm();
				$.extend(this.submitted, this.errorMap);
				this.invalid = $.extend({}, this.errorMap);
				if (!this.valid())
					$(this.currentForm).triggerHandler("invalid-form", [this]);
				this.showErrors();
				return this.valid();
			},

			checkForm: function() {
				this.prepareForm();
				for ( var i = 0, elements = (this.currentElements = this.elements()); elements[i]; i++ ) {
					this.check( elements[i] );
				}
				return this.valid(); 
			},

			// http://docs.jquery.com/Plugins/Validation/Validator/element
			element: function( element ) {
				element = this.clean( element );
				this.lastElement = element;
				this.prepareElement( element );
				this.currentElements = $(element);
				var result = this.check( element );
				if ( result ) {
					delete this.invalid[element.name];
				} else {
					this.invalid[element.name] = true;
				}
				if ( !this.numberOfInvalids() ) {
					// Hide error containers on last error
					this.toHide = this.toHide.add( this.containers );
				}
				this.showErrors();
				return result;
			},

			// http://docs.jquery.com/Plugins/Validation/Validator/showErrors
			showErrors: function(errors) {
				if(errors) {
					// add items to error list and map
					$.extend( this.errorMap, errors );
					this.errorList = [];
					for ( var name in errors ) {
						this.errorList.push({
							message: errors[name],
							element: this.findByName(name)[0]
						});
					}
					// remove items from success list
					this.successList = $.grep( this.successList, function(element) {
						return !(element.name in errors);
					});
				}
				this.settings.showErrors
					? this.settings.showErrors.call( this, this.errorMap, this.errorList )
					: this.defaultShowErrors();
			},

			// http://docs.jquery.com/Plugins/Validation/Validator/resetForm
			resetForm: function() {
				if ( $.fn.resetForm )
					$( this.currentForm ).resetForm();
				this.submitted = {};
				this.prepareForm();
				this.hideErrors();
				this.elements().removeClass( this.settings.errorClass );
			},

			numberOfInvalids: function() {
				return this.objectLength(this.invalid);
			},

			objectLength: function( obj ) {
				var count = 0;
				for ( var i in obj )
					count++;
				return count;
			},

			hideErrors: function() {
				this.addWrapper( this.toHide ).hide();
			},

			valid: function() {
				return this.size() == 0;
			},

			size: function() {
				return this.errorList.length;
			},

			focusInvalid: function() {
				if( this.settings.focusInvalid ) {
					try {
						$(this.findLastActive() || this.errorList.length && this.errorList[0].element || []).filter(":visible").focus();
					} catch(e) {
						// ignore IE throwing errors when focusing hidden elements
					}
				}
			},

			findLastActive: function() {
				var lastActive = this.lastActive;
				return lastActive && $.grep(this.errorList, function(n) {
					return n.element.name == lastActive.name;
				}).length == 1 && lastActive;
			},

			elements: function() {
				var validator = this,
					rulesCache = {};

				// select all valid inputs inside the form (no submit or reset buttons)
				// workaround $Query([]).add until http://dev.jquery.com/ticket/2114 is solved
				return $([]).add(this.currentForm.elements)
				.filter(":input")
				.not(":submit, :reset, :image, [disabled]")
				.not( this.settings.ignore )
				.filter(function() {
					!this.name && validator.settings.debug && window.console && console.error( "%o has no name assigned", this);

					// select only the first element for each name, and only those with rules specified
					if ( this.name in rulesCache || !validator.objectLength($(this).rules()) )
						return false;

					rulesCache[this.name] = true;
					return true;
				});
			},

			clean: function( selector ) {
				return $( selector )[0];
			},

			errors: function() {
				return $( this.settings.errorElement + "." + this.settings.errorClass, this.errorContext );
			},

			reset: function() {
				this.successList = [];
				this.errorList = [];
				this.errorMap = {};
				this.toShow = $([]);
				this.toHide = $([]);
				this.formSubmitted = false;
				this.currentElements = $([]);
			},

			prepareForm: function() {
				this.reset();
				this.toHide = this.errors().add( this.containers );
			},

			prepareElement: function( element ) {
				this.reset();
				this.toHide = this.errorsFor(element);
			},

			check: function( element ) {
				element = this.clean( element );

				// if radio/checkbox, validate first element in group instead
				if (this.checkable(element)) {
					element = this.findByName( element.name )[0];
				}

				var rules = $(element).rules();
				var dependencyMismatch = false;
				for( method in rules ) {
					var rule = { method: method, parameters: rules[method] };
					try {
						var result = $.validator.methods[method].call( this, element.value, element, rule.parameters );

						// if a method indicates that the field is optional and therefore valid,
						// don't mark it as valid when there are no other rules
						if ( result == "dependency-mismatch" ) {
							dependencyMismatch = true;
							continue;
						}
						dependencyMismatch = false;

						if ( result == "pending" ) {
							this.toHide = this.toHide.not( this.errorsFor(element) );
							return;
						}

						if( !result ) {
							this.formatAndAdd( element, rule );
							return false;
						}
					} catch(e) {
						this.settings.debug && window.console && console.log("exception occured when checking element " + element.id
							 + ", check the '" + rule.method + "' method");
						throw e;
					}
				}
				if (dependencyMismatch)
					return;
				if ( this.objectLength(rules) )
					this.successList.push(element);
				return true;
			},

			// return the custom message for the given element and validation method
			// specified in the element's "messages" metadata
			customMetaMessage: function(element, method) {
				if (!$.metadata)
					return;

				var meta = this.settings.meta
					? $(element).metadata()[this.settings.meta]
					: $(element).metadata();

				return meta && meta.messages && meta.messages[method];
			},

			// return the custom message for the given element name and validation method
			customMessage: function( name, method ) {
				var m = this.settings.messages[name];
				return m && (m.constructor == String
					? m
					: m[method]);
			},

			// return the first defined argument, allowing empty strings
			findDefined: function() {
				for(var i = 0; i < arguments.length; i++) {
					if (arguments[i] !== undefined)
						return arguments[i];
				}
				return undefined;
			},

			defaultMessage: function( element, method) {
				return this.findDefined(
					this.customMessage( element.name, method ),
					this.customMetaMessage( element, method ),
					// title is never undefined, so handle empty string as undefined
					!this.settings.ignoreTitle && element.title || undefined,
					$.validator.messages[method],
					"<strong>Warning: No message defined for " + element.name + "</strong>"
				);
			},

			formatAndAdd: function( element, rule ) {
				var message = this.defaultMessage( element, rule.method );
				if ( typeof message == "function" ) 
					message = message.call(this, rule.parameters, element);
				this.errorList.push({
					message: message,
					element: element
				});
				this.errorMap[element.name] = message;
				this.submitted[element.name] = message;
			},

			addWrapper: function(toToggle) {
				if ( this.settings.wrapper )
					toToggle = toToggle.add( toToggle.parents( this.settings.wrapper ) );
				return toToggle;
			},

			defaultShowErrors: function() {
				for ( var i = 0; this.errorList[i]; i++ ) {
					var error = this.errorList[i];
					this.settings.highlight && this.settings.highlight.call( this, error.element, this.settings.errorClass );
					this.showLabel( error.element, error.message );
				}
				if( this.errorList.length ) {
					this.toShow = this.toShow.add( this.containers );
				}
				if (this.settings.success) {
					for ( var i = 0; this.successList[i]; i++ ) {
						this.showLabel( this.successList[i] );
					}
				}
				if (this.settings.unhighlight) {
					for ( var i = 0, elements = this.validElements(); elements[i]; i++ ) {
						this.settings.unhighlight.call( this, elements[i], this.settings.errorClass );
					}
				}
				this.toHide = this.toHide.not( this.toShow );
				this.hideErrors();
				this.addWrapper( this.toShow ).show();
			},

			validElements: function() {
				return this.currentElements.not(this.invalidElements());
			},

			invalidElements: function() {
				return $(this.errorList).map(function() {
					return this.element;
				});
			},

			showLabel: function(element, message) {
				var label = this.errorsFor( element );
				if ( label.length ) {
					// refresh error/success class
					label.removeClass().addClass( this.settings.errorClass );

					// check if we have a generated label, replace the message then
					label.attr("generated") && label.html(message);
				} else {
					// create label
					label = $("<" + this.settings.errorElement + "/>")
						.attr({"for":  this.idOrName(element), generated: true})
						.addClass(this.settings.errorClass)
						.html(message || "");
					if ( this.settings.wrapper ) {
						// make sure the element is visible, even in IE
						// actually showing the wrapped element is handled elsewhere
						label = label.hide().show().wrap("<" + this.settings.wrapper + "/>").parent();
					}
					if ( !this.labelContainer.append(label).length )
						this.settings.errorPlacement
							? this.settings.errorPlacement(label, $(element) )
							: label.insertAfter(element);
				}
				if ( !message && this.settings.success ) {
					label.text("");
					typeof this.settings.success == "string"
						? label.addClass( this.settings.success )
						: this.settings.success( label );
				}
				this.toShow = this.toShow.add(label);
			},

			errorsFor: function(element) {
				return this.errors().filter("[for='" + this.idOrName(element) + "']");
			},

			idOrName: function(element) {
				return this.groups[element.name] || (this.checkable(element) ? element.name : element.id || element.name);
			},

			checkable: function( element ) {
				return /radio|checkbox/i.test(element.type);
			},

			findByName: function( name ) {
				// select by name and filter by form for performance over form.find("[name=...]")
				var form = this.currentForm;
				return $(document.getElementsByName(name)).map(function(index, element) {
					return element.form == form && element.name == name && element  || null;
				});
			},

			getLength: function(value, element) {
				switch( element.nodeName.toLowerCase() ) {
				case 'select':
					return $("option:selected", element).length;
				case 'input':
					if( this.checkable( element) )
						return this.findByName(element.name).filter(':checked').length;
				}
				return value.length;
			},

			depend: function(param, element) {
				return this.dependTypes[typeof param]
					? this.dependTypes[typeof param](param, element)
					: true;
			},

			dependTypes: {
				"boolean": function(param, element) {
					return param;
				},
				"string": function(param, element) {
					return !!$(param, element.form).length;
				},
				"function": function(param, element) {
					return param(element);
				}
			},

			optional: function(element) {
				return !$.validator.methods.required.call(this, $.trim(element.value), element) && "dependency-mismatch";
			},

			startRequest: function(element) {
				if (!this.pending[element.name]) {
					this.pendingRequest++;
					this.pending[element.name] = true;
				}
			},

			stopRequest: function(element, valid) {
				this.pendingRequest--;
				// sometimes synchronization fails, make sure pendingRequest is never < 0
				if (this.pendingRequest < 0)
					this.pendingRequest = 0;
				delete this.pending[element.name];
				if ( valid && this.pendingRequest == 0 && this.formSubmitted && this.form() ) {
					$(this.currentForm).submit();
				} else if (!valid && this.pendingRequest == 0 && this.formSubmitted) {
					$(this.currentForm).triggerHandler("invalid-form", [this]);
				}
			},

			previousValue: function(element) {
				return $.data(element, "previousValue") || $.data(element, "previousValue", previous = {
					old: null,
					valid: true,
					message: this.defaultMessage( element, "remote" )
				});
			}

		},

		classRuleSettings: {
			required: {required: true},
			email: {email: true},
			url: {url: true},
			date: {date: true},
			dateISO: {dateISO: true},
			dateDE: {dateDE: true},
			number: {number: true},
			numberDE: {numberDE: true},
			digits: {digits: true},
			creditcard: {creditcard: true}
		},

		addClassRules: function(className, rules) {
			className.constructor == String ?
				this.classRuleSettings[className] = rules :
				$.extend(this.classRuleSettings, className);
		},

		classRules: function(element) {
			var rules = {};
			var classes = $(element).attr('class');
			classes && $.each(classes.split(' '), function() {
				if (this in $.validator.classRuleSettings) {
					$.extend(rules, $.validator.classRuleSettings[this]);
				}
			});
			return rules;
		},

		attributeRules: function(element) {
			var rules = {};
			var $element = $(element);

			for (method in $.validator.methods) {
				var value = $element.attr(method);
				if (value) {
					rules[method] = value;
				}
			}

			// maxlength may be returned as -1, 2147483647 (IE) and 524288 (safari) for text inputs
			if (rules.maxlength && /-1|2147483647|524288/.test(rules.maxlength)) {
				delete rules.maxlength;
			}

			return rules;
		},

		metadataRules: function(element) {
			if (!$.metadata) return {};

			var meta = $.data(element.form, 'validator').settings.meta;
			return meta ?
				$(element).metadata()[meta] :
				$(element).metadata();
		},

		staticRules: function(element) {
			var rules = {};
			var validator = $.data(element.form, 'validator');
			if (validator.settings.rules) {
				rules = $.validator.normalizeRule(validator.settings.rules[element.name]) || {};
			}
			return rules;
		},

		normalizeRules: function(rules, element) {
			// handle dependency check
			$.each(rules, function(prop, val) {
				// ignore rule when param is explicitly false, eg. required:false
				if (val === false) {
					delete rules[prop];
					return;
				}
				if (val.param || val.depends) {
					var keepRule = true;
					switch (typeof val.depends) {
						case "string":
							keepRule = !!$(val.depends, element.form).length;
							break;
						case "function":
							keepRule = val.depends.call(element, element);
							break;
					}
					if (keepRule) {
						rules[prop] = val.param !== undefined ? val.param : true;
					} else {
						delete rules[prop];
					}
				}
			});

			// evaluate parameters
			$.each(rules, function(rule, parameter) {
				rules[rule] = $.isFunction(parameter) ? parameter(element) : parameter;
			});

			// clean number parameters
			$.each(['minlength', 'maxlength', 'min', 'max'], function() {
				if (rules[this]) {
					rules[this] = Number(rules[this]);
				}
			});
			$.each(['rangelength', 'range'], function() {
				if (rules[this]) {
					rules[this] = [Number(rules[this][0]), Number(rules[this][1])];
				}
			});

			if ($.validator.autoCreateRanges) {
				// auto-create ranges
				if (rules.min && rules.max) {
					rules.range = [rules.min, rules.max];
					delete rules.min;
					delete rules.max;
				}
				if (rules.minlength && rules.maxlength) {
					rules.rangelength = [rules.minlength, rules.maxlength];
					delete rules.minlength;
					delete rules.maxlength;
				}
			}

			// To support custom messages in metadata ignore rule methods titled "messages"
			if (rules.messages) {
				delete rules.messages
			}

			return rules;
		},

		// Converts a simple string to a {string: true} rule, e.g., "required" to {required:true}
		normalizeRule: function(data) {
			if( typeof data == "string" ) {
				var transformed = {};
				$.each(data.split(/\s/), function() {
					transformed[this] = true;
				});
				data = transformed;
			}
			return data;
		},

		// http://docs.jquery.com/Plugins/Validation/Validator/addMethod
		addMethod: function(name, method, message) {
			$.validator.methods[name] = method;
			$.validator.messages[name] = message;
			if (method.length < 3) {
				$.validator.addClassRules(name, $.validator.normalizeRule(name));
			}
		},

		methods: {

			// http://docs.jquery.com/Plugins/Validation/Methods/required
			required: function(value, element, param) {
				// check if dependency is met
				if ( !this.depend(param, element) )
					return "dependency-mismatch";
				switch( element.nodeName.toLowerCase() ) {
				case 'select':
					var options = $("option:selected", element);
					return options.length > 0 && ( element.type == "select-multiple" || ($.browser.msie && !(options[0].attributes['value'].specified) ? options[0].text : options[0].value).length > 0);
				case 'input':
					if ( this.checkable(element) )
						return this.getLength(value, element) > 0;
				default:
					return $.trim(value).length > 0;
				}
			},

			// http://docs.jquery.com/Plugins/Validation/Methods/remote
			remote: function(value, element, param) {
				if ( this.optional(element) )
					return "dependency-mismatch";

				var previous = this.previousValue(element);

				if (!this.settings.messages[element.name] )
					this.settings.messages[element.name] = {};
				this.settings.messages[element.name].remote = typeof previous.message == "function" ? previous.message(value) : previous.message;

				param = typeof param == "string" && {url:param} || param; 

				if ( previous.old !== value ) {
					previous.old = value;
					var validator = this;
					this.startRequest(element);
					var data = {};
					data[element.name] = value;
					$.ajax($.extend(true, {
						url: param,
						mode: "abort",
						port: "validate" + element.name,
						dataType: "json",
						data: data,
						success: function(response) {
							if ( response ) {
								var submitted = validator.formSubmitted;
								validator.prepareElement(element);
								validator.formSubmitted = submitted;
								validator.successList.push(element);
								validator.showErrors();
							} else {
								var errors = {};
								errors[element.name] =  response || validator.defaultMessage( element, "remote" );
								validator.showErrors(errors);
							}
							previous.valid = response;
							validator.stopRequest(element, response);
						}
					}, param));
					return "pending";
				} else if( this.pending[element.name] ) {
					return "pending";
				}
				return previous.valid;
			},

			// http://docs.jquery.com/Plugins/Validation/Methods/minlength
			minlength: function(value, element, param) {
				return this.optional(element) || this.getLength($.trim(value), element) >= param;
			},

			// http://docs.jquery.com/Plugins/Validation/Methods/maxlength
			maxlength: function(value, element, param) {
				return this.optional(element) || this.getLength($.trim(value), element) <= param;
			},

			// http://docs.jquery.com/Plugins/Validation/Methods/rangelength
			rangelength: function(value, element, param) {
				var length = this.getLength($.trim(value), element);
				return this.optional(element) || ( length >= param[0] && length <= param[1] );
			},

			// http://docs.jquery.com/Plugins/Validation/Methods/min
			min: function( value, element, param ) {
				return this.optional(element) || value >= param;
			},

			// http://docs.jquery.com/Plugins/Validation/Methods/max
			max: function( value, element, param ) {
				return this.optional(element) || value <= param;
			},

			// http://docs.jquery.com/Plugins/Validation/Methods/range
			range: function( value, element, param ) {
				return this.optional(element) || ( value >= param[0] && value <= param[1] );
			},

			// http://docs.jquery.com/Plugins/Validation/Methods/email
			email: function(value, element) {
				// contributed by Scott Gonzalez: http://projects.scottsplayground.com/email_address_validation/
				return this.optional(element) || /^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?$/i.test(value);
			},

			//ben's 
			first_name: function(value, element) {
				return value != 'First Name';
			},

			last_name: function(value, element) {
				return value != 'Last Name';
			},

			// http://docs.jquery.com/Plugins/Validation/Methods/url
			/*
			url: function(value, element) {
				// contributed by Scott Gonzalez: http://projects.scottsplayground.com/iri/
				return this.optional(element) || /^(https?|ftp):\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(\#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i.test(value);
			},
			*/

			// http://docs.jquery.com/Plugins/Validation/Methods/date
			date: function(value, element) {
				return this.optional(element) || !/Invalid|NaN/.test(new Date(value));
			},

			// http://docs.jquery.com/Plugins/Validation/Methods/dateISO
			dateISO: function(value, element) {
				return this.optional(element) || /^\d{4}[\/-]\d{1,2}[\/-]\d{1,2}$/.test(value);
			},

			// http://docs.jquery.com/Plugins/Validation/Methods/dateDE
			dateDE: function(value, element) {
				return this.optional(element) || /^\d\d?\.\d\d?\.\d\d\d?\d?$/.test(value);
			},

			// http://docs.jquery.com/Plugins/Validation/Methods/number
			number: function(value, element) {
				return this.optional(element) || /^-?(?:\d+|\d{1,3}(?:,\d{3})+)(?:\.\d+)?$/.test(value);
			},

			// http://docs.jquery.com/Plugins/Validation/Methods/numberDE
			numberDE: function(value, element) {
				return this.optional(element) || /^-?(?:\d+|\d{1,3}(?:\.\d{3})+)(?:,\d+)?$/.test(value);
			},

			// http://docs.jquery.com/Plugins/Validation/Methods/digits
			digits: function(value, element) {
				return this.optional(element) || /^\d+$/.test(value);
			},

			// http://docs.jquery.com/Plugins/Validation/Methods/creditcard
			// based on http://en.wikipedia.org/wiki/Luhn
			creditcard: function(value, element) {
				if ( this.optional(element) )
					return "dependency-mismatch";
				// accept only digits and dashes
				if (/[^0-9-]+/.test(value))
					return false;
				var nCheck = 0,
					nDigit = 0,
					bEven = false;

				value = value.replace(/\D/g, "");

				for (n = value.length - 1; n >= 0; n--) {
					var cDigit = value.charAt(n);
					var nDigit = parseInt(cDigit, 10);
					if (bEven) {
						if ((nDigit *= 2) > 9)
							nDigit -= 9;
					}
					nCheck += nDigit;
					bEven = !bEven;
				}

				return (nCheck % 10) == 0;
			},

			// http://docs.jquery.com/Plugins/Validation/Methods/accept
			accept: function(value, element, param) {
				param = typeof param == "string" ? param : "png|jpe?g|gif";
				return this.optional(element) || value.match(new RegExp(".(" + param + ")$", "i")); 
			},

			// http://docs.jquery.com/Plugins/Validation/Methods/equalTo
			equalTo: function(value, element, param) {
				return value == $(param).val();
			}

		}

	});

	})(jQuery);

	// ajax mode: abort
	// usage: $.ajax({ mode: "abort"[, port: "uniqueport"]});
	// if mode:"abort" is used, the previous request on that port (port can be undefined) is aborted via XMLHttpRequest.abort() 
	;(function($) {
		var ajax = $.ajax;
		var pendingRequests = {};
		$.ajax = function(settings) {
			// create settings for compatibility with ajaxSetup
			settings = $.extend(settings, $.extend({}, $.ajaxSettings, settings));
			var port = settings.port;
			if (settings.mode == "abort") {
				if ( pendingRequests[port] ) {
					pendingRequests[port].abort();
				}
				return (pendingRequests[port] = ajax.apply(this, arguments));
			}
			return ajax.apply(this, arguments);
		};
	})(jQuery);

	// provides cross-browser focusin and focusout events
	// IE has native support, in other browsers, use event caputuring (neither bubbles)

	// provides delegate(type: String, delegate: Selector, handler: Callback) plugin for easier event delegation
	// handler is only called when $(event.target).is(delegate), in the scope of the jquery-object for event.target 

	// provides triggerEvent(type: String, target: Element) to trigger delegated events
	;(function($) {
		$.each({
			focus: 'focusin',
			blur: 'focusout'	
		}, function( original, fix ){
			$.event.special[fix] = {
				setup:function() {
					if ( $.browser.msie ) return false;
					this.addEventListener( original, $.event.special[fix].handler, true );
				},
				teardown:function() {
					if ( $.browser.msie ) return false;
					this.removeEventListener( original,
					$.event.special[fix].handler, true );
				},
				handler: function(e) {
					arguments[0] = $.event.fix(e);
					arguments[0].type = fix;
					return $.event.handle.apply(this, arguments);
				}
			};
		});
		$.extend($.fn, {
			delegate: function(type, delegate, handler) {
				return this.bind(type, function(event) {
					var target = $(event.target);
					if (target.is(delegate)) {
						return handler.apply(target, arguments);
					}
				});
			},
			triggerEvent: function(type, target) {
				return this.triggerHandler(type, [$.event.fix({ type: type, target: target })]);
			}
		})
	})(jQuery);
	
	
	



	$(document).ready(function(){	
		var links, page, directory, len, loc;

		loc = window.location.pathname.split('/');

		if(loc[2]){
			page 			= loc[2];
			directory = loc[1];
		} else if (loc[1] != '') {
			page 	= 'index.html';
			directory = loc[1];
		} else {
			page 			= 'index.html';
			directory = 'root';
		}

		//console.log('directory: ' + directory + ' page: ' + page);

		links = $('#navigation a');

		jQuery.each(links, function(index, value){
			if (value.href == window.location.toString().replace('#', '')){
				$(value).addClass('active');
				$(value).parents().parents().parents('li').addClass('hover');
			}
		});
	
		//make rel=external target=_blank
		$('a[rel="external"]').click( function(){
			window.open($(this).attr('href'));
			return false;
		});
	
	});
	
	
	/**
	 * Check the existence of the "referrer" URL parameter, if available, sanitize and store in cookie.
	 */
	function check_referrer() {
		var referrer = $.getURLParam('referrer');

		if (referrer) {
			// Remove non digit characters, then trim length to 5
			referrer = referrer.replace(/\D/g, '').substring(0, 5);
			
			// Store the referrer customer number for later use
			$.cookie('referrer', referrer, { expires: 365 });
		}
	}
	
	
	/**
	 * If button(s) with 'referrer' class exist and cookie 'referrer' exist, append customer id to btn URL
	 */
	function handle_referrer() {
		var buttons = $('a.referrer'),
		    i = buttons.length,
			referrer = $.cookie('referrer'),
			paramName = 'referrer';
		
		if (i && referrer && referrer.length === 5) {
			while (i--) {
				var btn = buttons.eq(i),
				    url = btn.attr('href'),
					urlLen = url.length,
					newUrl = '';
				
				// Check to see if URL parameters already exist
				if (url.lastIndexOf('?') > -1 && url.lastIndexOf('=') > -1) {
					
					// Is a & character at the end of the URL string?
					if (url.charAt(urlLen - 1) === '&') {
						newUrl = url + paramName + '=' + referrer;
					}
					else {
						newUrl = url + '&' + paramName + '=' + referrer;
					} 
				}
				else {
					newUrl = url + '?' + paramName + '=' + referrer;
				}
				
				// Assign new url to button
				btn.attr('href', newUrl);
			}
		}
	}
	
	
	$(document).ready(function() {


		var d = new Date();
		$('#datey').html(d.getFullYear());

		if($('#faq' + $.getURLParam("faq")).length){
			var loco = $('#faq' + $.getURLParam("faq"));
			$(document).scrollTo(loco, 500);
			loco.css('color','#FF7802');
		}

		if( $('#extended_info').length ){
			$('#reason_interested').customSelect('1');
			$('#number_of_phones_needed').customSelect('2');
			$('#need_to_transfer').customSelect('3');
			$('#connection_speed').customSelect('4');
			$('#decision_timeframe').customSelect('5');
			$('#current_budget').customSelect('6');
		}

		if($.getURLParam('utm_source')){
			var source = {
				source : $.getURLParam('utm_source')
			}
			$.cookie('source', $.compactJSON(source), { expires: null, path: '/'});
		}else{

			if(!$.cookie('source')){
				var source = {
					source : document.referrer
				}
				$.cookie('source', $.compactJSON(source), { expires: null, path: '/'});

				/*
				//test ajax functionality - having trouble with cross domain nonsense
				$.ajax({
					type: "GET",
					url: "http://www.longjump.com/networking/Service?s=496&amp;a=add&amp;pid=9daf4e9ed6b54d08b948d350fcf5dd2f&amp;cid=819004939&amp;object_id=819004939wxr603814255&amp;lid=", 
					//data: ({ source: source }),
					dataType: "jsonp",
					error: function(XMLHttpRequest, textStatus, errorThrown){
						console.log(XMLHttpRequest + ' ' +  textStatus + ' ' + errorThrown)
					}
				});
				*/

			}
		}
		

		if($('#mini_form').length) {

			//get source from source cookie and set in form
			if($.cookie('source')){
				var cookie_vals = $.evalJSON($.cookie('source'));
				$('input[name=source]').val(cookie_vals.source);
				//alert(cookie_vals.source);
			}

			//$('#field_first_name').focus();
			$('#field_first_name').val("First Name");
			$('#field_last_name').val("Last Name");
			$('#email').val("Email");
			$('#phone_number').val("Phone Number");
		};

		inputs = $('#mini_form input:text');

		jQuery.each(inputs, function(index, value){
			$(value).bind("focus", function(e){
				if($(value).val() == $(value).attr('title')){
					$(value).val("");
				}
			});
		});

		jQuery.each(inputs, function(index, value){
			$(value).bind("blur", function(e){
				if(jQuery.trim($(value).val()).length < 1 ){
					$(value).val($(value).attr('title'));
				}
			});
		});


		if($('#mini_form').length) {

			$('#mini_form').bind('submit', function() {
				 setCookie();
			});

			$('#mini-form-button').bind('click', function(){
				$('#mini_form').submit();
			})

			var validator = $("#mini_form").validate({
				rules: {
					field_first_name: {
						required: true,
						first_name: true
					},
					field_last_name: {
						required: true,
						last_name: true
					},
					email: {
						required: true,
						email: true
					},
					phone_number: {
						required: true,
						minlength: 10
					}
				},
				messages: {
					field_first_name: "Please enter your first name",
					field_last_name: "Please enter your last name",
					email: {
						required: "Please enter a valid email address",
						minlength: "Please enter a valid email address"
					}
				}
			});
		};


			/*===========================
							big form
			===========================*/


		if($('#extended-form').length) {

			if($.cookie('user_info')) {

				var cookie_vals = $.evalJSON($.cookie('user_info'));

				$('#field_first_name').val(cookie_vals.first);
				$('#field_last_name').val(cookie_vals.last);
				$('#email').val(cookie_vals.email);
				$('#phone_number').val(cookie_vals.phone);

			};

			var validator = $("#extended_info").validate({
				rules: {
					field_first_name: {
						required: true,
						first_name: true
					},
					field_last_name: {
						required: true,
						last_name: true
					},
					email: {
						required: true,
						email: true
					},
					phone_number: {
						required: true,
						minlength: 10
					},
					company_name_1: "required",
					positiontitle: "required",
					industry: "required",
					city: "required",
					state: "required",
					zip: "required",
					reason_interested: "required",
					number_of_phones_needed: "required",
					need_to_transfer: "required",
					connection_speed: "required",
					decision_timeframe: "required"
				},
				messages: {
					field_first_name: "Please enter first name",
					field_last_name: "Please enter your last name",
					email: {
						required: "Please enter a valid email address",
						minlength: "Please enter a valid email address"
					},
					phone_number: "Please enter a valid phone number",
					company_name_1: "Please enter a valid company name",
					positiontitle: "Please enter a valid position title",
					industry: "Please enter a valid industry",
					city: "Please enter a valid city",
					state: "Please enter a valid state",
					zip: "Please enter a valid ZIP code",
					reason_interested: "Please choose a valid reason for purchasing a new phone service",
					number_of_phones_needed: "Please choose the number of phones needed",
					need_to_transfer: "Please choose whether you need to transfer lines or not",
					connection_speed: "Please choose a valid connection speed",
					decision_timeframe: "Please choose a valid decision timeframe"
				}
			});

			$('#free-consult-button').bind('click', function(e){
				e.preventDefault();
				$('#extended_info').submit();
			})

		};


		if($('#extended_info_reseller').length){

			var validator = $("#extended_info_reseller").validate({
				rules: {
					field_first_name: {
						required: true,
						first_name: true
					},
					field_last_name: {
						required: true,
						last_name: true
					},
					email: {
						required: true,
						email: true
					},
					phone_number: {
						required: true,
						minlength: 10
					},
					company_name: "required",
					street: "required",
					city: "required",
					state: "required",
					zip: "required"
				},
				messages: {
					field_first_name: "Please enter your First Name",
					field_last_name: "Please enter your Last Name",
					street: "Enter Address",
					email: {
						required: "Please enter a valid email address",
						minlength: "Please enter a valid email address"
					},
					phone_number: "Please enter a valid phone number",
					company_name: "Please enter a valid company name",
					city: "Please enter a valid city",
					state: "Please enter a valid state",
					zip: "Please enter a valid ZIP"
				}
			});

			$('#partner-consult-button').bind('click', function(e){
				e.preventDefault();
				setCookie();
				$('#extended_info_reseller').submit();
			})


		}


		if($('#register-webinarski').length) {

			$('#register-webinarski').bind('submit', function(e) {
				setCookie(true);
			});

			//set webinar date
			var finalDate;
			var current_date = new Date();
			
			//move 2 days ahead
			current_date.setDate(current_date.getDate() + 2); 

			var dates = Array (
				'March 6, 2009',
				'March 20, 2009',
				'April 3, 2009',
				'April 17, 2009',
				'May 1, 2009',
				'May 15, 2009',
				'May 29, 2009',
				'June 12, 2009',
				'June 26, 2009',
				'July 10, 2009',
				'July 24, 2009',
				'August 10, 2009',
				'August 21, 2009', 
				'September 4, 2009',
				'September 18, 2009',
				'October 2, 2009',
				'October 16, 2009',
				'October 30, 2009',
				'November 13, 2009',
				'November 27, 2009',
				'December 11, 2009'
			)

			function datify(el){
				return new Date(el);
			}

			$(dates).each(function(idx, el){
				if(finalDate === undefined){
					if(datify(el) > current_date){
						finalDate = el;
					}
				}
			})

			$('#date').html(finalDate + " 1PM PST");
			$('input[name=nextWebinar]').val(finalDate);


			//get cookie vals
			var cookie_vals = $.evalJSON($.cookie('user_info'));

			//set hidden field values to values from cookie
			//these are passed to longjump as form continuation variables and make able to send the info to Joe
			$('input[name=field_first_name]').val(cookie_vals.first);
			$('input[name=field_last_name]').val(cookie_vals.last);
			$('input[name=email]').val(cookie_vals.email);
			$('input[name=phone_number]').val(cookie_vals.phone);


			//if registered for webinar show the Registered div
			if(cookie_vals){
				if(cookie_vals.webinar){
					$('#status').html('Registered');
					$('#status').css('color','#96D41C')
				}
			}


		}


	}); 

	function setCookie(webinarski) {

		var cookie_vals = {
			first		: '',
			last		: '',
			email		: '',
			phone		: '',
			mini		: false,
			ext			: false,
			webinar : webinarski
		};

		cookie_vals.first = $('input[name=field_first_name]').val();
		cookie_vals.last	= $('input[name=field_last_name]').val();
		cookie_vals.email	= $('input[name=email]').val();
		cookie_vals.phone	= $('input[name=phone_number]').val();
		$.cookie('user_info', $.compactJSON(cookie_vals), { expires: 7, path: '/'});
	};

	function alertCookie() {
		var cookie_vals = $.evalJSON($.cookie('user_info'));
		alert(cookie_vals);
	};




	function writePlayer(file){

		$('#player').html('<img src="/img/ajaxloader.gif" alt="" />');
	 	setTimeout(function(){startPlay(file)}, 3000);
	}


	function startPlay(file){
		$('#player').html(' \
				<object classid="CLSID:22d6f312-b0f6-11d0-94ab-0080c74c7e95" codebase="https://activex.microsoft.com/activex/controls/mplayer/en/nsmp2inf.cab#Version=6,4,7,1112" height="60" id="wmp" type="application/x-oleobject" width="145" standby="Loading Microsoft Windows Media Player components..."> \
					<param name="src" value="http://static.ivrweblink.com/freedomvoice/audio/' + file + '"> \
					<embed type="audio/wav" pluginspage="http://www.apple.com/quicktime/download/" src="http://static.ivrweblink.com/freedomvoice/audio/' + file + '" name="wmp" SHOWCONTROLS="1" SHOWDISPLAY="0" SHOWSTATUSBAR="1" autosize="1" autostart="true" width="145" height="60" displaybackcolor="black" mastersound> \
					<noembed> \
						<param name="filename" value="http://static.ivrweblink.com/freedomvoice/audio/' + file + '"> \
						<param name="AnimationAtStart" value="0"> \
						<param name="videoborderwidth" value="20"> \
						<param name="volume" value="0"> \
						<a href="http://static.ivrweblink.com/freedomvoice/audio/' + file + '">Your web browser does not support embeded audio. Click here to listen to your message.</a> \
					</noembed> \
				</object> \
		');
	}

(function() {

var spoof = $('#spoof');
window.loadOnce = true;

if (spoof.length) {

	if ($.getURLParam("play") === 'trudat') {
		spoof.html('<iframe width="710" height="455" frameborder="0" src="/inc/flash/intro.html" style="overflow: hidden" >you are using a browser without support for frames</iframe>');
	
		loadOnce = false;
	}
	else {
		spoof.click(function() {
			if (loadOnce) {
				$(this).html('<iframe width="710" height="455" frameborder="0" src="/inc/flash/intro.html" style="overflow: hidden" >you are using a browser without support for frames</iframe>');
			
				loadOnce = false;
			}
	
		});
	}
}

})();

//stripe internation rates table

$(document).ready(function() {
	if($('#zebra').length){
		$('#zebra tr:even').css({'background':'#ccc'});
	}
})

// =================
// = GET BLOG NEWS =
// =================

$(function() {
	
if ($('#blog-news').length) {
	
	var blognews = $.cookie('blognews');
	
	if ( ! blognews) {
		$.getJSON('/inc/presentation/get-blog-news.php?feed=http://www.freedomvoice.com/blog/feed/&amount=3', function(data) {
			var data = data.join('');
			$('#blog-news').html(data);
			$.cookie('blognews', data, {path: '/', expires: 2});
		});
	}
	else {
		$('#blog-news').html(blognews);
	}
}

if ($('#get-free-trial').length) {
	switch(location.href) {
		case 'http://www.freedomvoice.com/plans-and-pricing/freedomstart.shtml':
			$('#get-free-trial').attr('href', 'https://orders.freedomvoice.com/secure-order/toll-free?utm_term=fvs&plan=FST15Q');
			break;
		case 'http://www.freedomvoice.com/plans-and-pricing/freedomedge.shtml':
			$('#get-free-trial').attr('href', 'https://orders.freedomvoice.com/secure-order/toll-free?utm_term=fvs&plan=FE15Q');
			break;
		case 'http://www.freedomvoice.com/plans-and-pricing/freedomsuite.shtml':
			$('#get-free-trial').attr('href', 'https://orders.freedomvoice.com/secure-order/toll-free?utm_term=fvs&plan=FSU15Q');
			break;
		case 'http://www.freedomvoice.com':
			$('#get-free-trial').attr('href', 'https://orders.freedomvoice.com/secure-order/toll-free?utm_term=fvs&plan=FST15Q');
			break;
		case 'http://www.freedomvoice.com/toll-free-numbers/800-numbers.shtml':
			$('#get-free-trial').attr('href', 'https://orders.freedomvoice.com/secure-order?utm_term=800-numbers');
			break;
		case 'http://www.freedomvoice.com/toll-free-numbers/vanity-numbers.shtml':
			$('#get-free-trial').attr('href', 'https://orders.freedomvoice.com/secure-order?utm_term=vanity-numbers');
			break;
		case 'http://www.freedomvoice.com/toll-free-numbers/':
		case 'http://www.freedomvoice.com/toll-free-numbers/transfer-numbers.shtml':
			$('#get-free-trial').attr('href', 'https://orders.freedomvoice.com/secure-order?utm_term=toll-free-numbers');
			break;
		case 'http://www.freedomvoice.com/virtual-office-features/':
		default:
			$('#get-free-trial').attr('href', 'https://orders.freedomvoice.com/secure-order?utm_term=virtual-phone-systems');
			break;
	}	
}

// Comments open in a new window
if ($('#comments').length) {
	$('#comments').find('a').attr('target', '_blank');
}

check_referrer();

handle_referrer();

});




