/**
 * Webstores.js - Webstores javascript library
 * 
 * @author  Webstores <info at webstores dot nl>
 *           Copyright (c) Webstores internet totaalbureau <http://www.webstores.nl/>
 */
var WS = {
	version: 1.5,
	
	browser: {
		IE: /msie/i.test(navigator.userAgent),
		IE6: /msie 6/i.test(navigator.userAgent),
		IE7: /msie 7/i.test(navigator.userAgent),
		Gecko: /gecko/i.test(navigator.userAgent),
		Webkit: /webkit/i.test(navigator.userAgent)
	},
	
	/**
	 * Returns an element
	 * 
	 * @param {Mixed} el The ID of or reference to an element
	 * @return The reference to the element
	 */
	get: function(el) {
		return (typeof el == 'string') ?
			document.getElementById(el) : el;
	},
	
	/**
	 * Logs to console if present
	 * 
	 * @param {Mixed} obj Anything you want to log to console
	 */
	log: function(obj) {
		if(console)
			console.log(obj);
	},
	
	/**
	 * Hides an element
	 * 
	 * @param {Mixed} el The ID of or reference to an element
	 * @return {Object} The hidden element
	 */
	hide: function(el) {
		el = get(el);
		el.style.display = 'none';
		return el;
	},
	
	/**
	 * Shows a hidden element
	 * 
	 * @param {Mixed} el The ID of or reference to an element
	 * @return {Object} The visible element
	 */
	show: function(el) {
		el = get(el);
		el.style.display = '';
		return el;
	},
	
	/**
	 * Toggles an element's display property
	 * 
	 * @param {Mixed} el The ID of or reference to an element
	 */
	toggle: function(el) {
		el = get(el);
		el.style.display == '' ?
			this.hide(el) : this.show(el);
	},
	
	/**
	 * Add a class name to an element
	 * 
	 * @param {Mixed} el The ID of or reference to an element
	 * @param {String} cls The class name to add
	 */
	addClass: function(el, cls) {
		el = get(el);
		if(!this.hasClass(el, cls))
			el.className += (' ' + cls);
	},
	
	/**
	 * Remove a class name from an element
	 * 
	 * @param {Mixed} el The ID of or reference to an element
	 * @param {String} cls The class name to remove
	 */
	removeClass: function(el, cls) {
		el = get(el);
		if(this.hasClass(el, cls)) {
			var regex = new RegExp('(\\s|^)' + cls + '(\\s|$)');
			el.className = el.className.replace(regex, ' ');
		}
	},
	
	/**
	 * Toggle between a class name
	 * 
	 * @param {Mixed} el The ID of or reference to an element
	 * @param {String} cls The class name to toggle
	 */
	toggleClass: function(el, cls) {
		if(this.hasClass(el, cls))
			this.removeClass(el, cls);
		else
			this.addClass(el, cls);
	},
	
	/**
	 * Check if an element has a class name
	 * 
	 * @param {Mixed} el The ID of or reference to an element
	 * @param {String} cls The class name to check
	 * @param {Boolean} greedy If true, matches any characters in className
	 * @return {Boolean} True if the element has the className, false otherwise
	 */
	hasClass: function(el, cls, greedy) {
		el = get(el);
		
		if(!el.className) {
			return false;
		}
		else if(greedy) {
			var regex = new RegExp(cls);
			return regex.test(el.className);
		}
		else {
			return el.className.match(new RegExp('(\\s|^)' + cls + '(\\s|$)'));
		}
	},
	
	/**
	 * Gets the opacity of an element
	 * 
	 * @param {Mixed} el The ID of or reference to an element
	 * @return {Number} The element's opacity
	 */
	getOpacity: function(el) {
		el = get(el);
		if(WS.browser.IE) {
			return el.style.filter ? (parseFloat(el.style.filter.replace('alpha(opacity=', '')) / 100) : 1.0;
		}
		return el.style.opacity || 1.0;
	},
	
	/**
	 * Sets the opacity of an element
	 * 
	 * @param {Mixed} el The ID of or reference to an element
	 * @param {Number} op The opacity value (0-10)
	 */
	setOpacity: function(el, op) {
		el = get(el);
		if(WS.browser.IE) {
			var ieOp = (op * 100);
			if(ieOp < 100)
				el.style.filter = 'alpha(opacity=' + ieOp + ')';
			else
				el.style.filter = '';
		}
		else {
			el.style.opacity = op;
		}
	},
	
	/**
	 * Set the text of an element
	 * 
	 * @param {Mixed} el The ID of or reference to an element
	 * @param {String} text The element's new text
	 */
	setText: function(el, text) {
		el = get(el);
		el.innerHTML = text;
	}
}

if(typeof get != 'function') {
	get = WS.get;
}


/**
 * WS.DOM - Webstores DOM traversing
 * 
 * @author  Webstores <info at webstores dot nl>
 *           Copyright (c) Webstores internet totaalbureau <http://www.webstores.nl/>
 */
WS.DOM = {
	/**
	 * Dustin Diaz's implementation of getElementsByClass
	 * 
	 * @param {String} searchClass Class name as a string
	 * @param {Object} node (optional) Supply a node (default: document)
	 * @param {Object} tag (optional) Limit the results by adding a tagName (default: *)
	 * @return {Array} An array containing the elements found
	 * 
	 * @see http://www.dustindiaz.com/getelementsbyclass/
	 */
	getElementsByClass: function(searchClass, node, tag) {
		var classElements = new Array();
		if(node == null)
			node = document;
		if(tag == null)
			tag = '*';
		var els = node.getElementsByTagName(tag);
		var elsLen = els.length;
		var pattern = new RegExp("(^|\\s)"+searchClass+"(\\s|$)");
		for(i = 0, j = 0; i < elsLen; i++) {
			if(pattern.test(els[i].className)) {
				classElements[j] = els[i];
				j++;
			}
		}
		return classElements;
	},
	
	/**
	 * Returns a parent node at an arbitary height
	 * 
	 * @param {Mixed} el The ID of or reference to an element
	 * @param {Number} depth The height of the parent node to retrieve
	 * @return {Object} The parent node of arbitary height
	 */
	getParent: function(el, depth) {
		depth = depth || 1;
		var parent = get(el).parentNode;
		for(var i = 1; i < depth; i++)
			parent = parent.parentNode;
		return parent;
	},
	
	/**
	 * Returns a child node at an arbitary depth
	 * 
	 * @param {Mixed} el The ID of or reference to an element
	 * @param {Number} depth The depth of the child node to retrieve
	 * @return {Object} The child node of arbitary depth
	 */
	getChild: function(el, depth) {
		var child = get(el).childNodes[depth-1];
		while(child.nodeType != 1)
			child = child.nextSibling;
		return child;
	},
	
	/**
	 * Returns all child nodes of nodeType ELEMENT_NODE
	 * 
	 * @param {Mixed} el The ID of or reference to an element
	 * @return {Array} The child nodes array
	 */
	getChildren: function(el) {
		var arr = [];
		var children = get(el).childNodes;
		for(var i = 0; i < children.length; i++)
			if(children[i].nodeType == 1)
				arr.push(children[i]);
		return arr;
	},
	
	/**
	 * Returns a sibling node
	 * 
	 * @param {Mixed} el The ID of or reference to an element
	 * @return {Object} The element's sibling node
	 */
	next: function(el) {
		var next = el.nextSibling;
		while(next.nodeType != 1)
			next = next.nextSibling;
		return next;
	},
	
	/**
	 * Inserts a node after the reference node
	 * 
	 * @param {Object} node The node to insert
	 * @param {Object} referenceNode The node to insert after
	 */
	insertAfter: function(node, referenceNode) {
		referenceNode.parentNode.insertBefore(node, referenceNode.nextSibling);
	}
}


/**
 * WS.Util - Webstores utility
 * 
 * @author  Webstores <info at webstores dot nl>
 *           Copyright (c) Webstores internet totaalbureau <http://www.webstores.nl/>
 */
WS.Util = {
	/**
	 * Hides and reveals default input value
	 * 
	 * @param {String} id The ID of the search input
	 * @param {String} fCls The input focus class
	 */
	toggleValue: function(id, fCls) {
		var el = document.getElementById(id);
		var v = el.value;
		
		el.onfocus = function() {
			if(this.value == v)
				this.value = '';
			WS.addClass(this, fCls);
		}
		el.onblur = function() {
			if(this.value == '') {
				this.value = v;
				WS.removeClass(this, fCls);
			}
		}
	},
	
	/**
	 * Creates a toggler/container pair
	 * 
	 * @param {String} id The ID of the elements
	 */
	createToggle: function(id) {
		var t = get(id + '-toggle');
		var c = get(id + '-container');
		WS.hide(c);
		
		WS.Event.addEvent(t, 'click', function(e) {
			WS.Event.stopEvent(e);
			WS.toggle(c);
		});
	},
	
	/**
	 * Quick and dirty fix for PNG transparency in IE6
	 * 
	 * @param {Mixed} el The ID of or reference to the element
	 * @param {String} src The image's path to the PNG file
	 * @param {String} sizingMethod The AlphaImageLoader's sizingMethod (scale or crop)
	 */
	fixPngBackground: function(el, src, sizingMethod) {
		sizingMethod = sizingMethod || 'scale'; // There's also sizingMethod 'crop'
		
		if(WS.browser.IE6) {
			el = get(el);
			el.style.filter = 'progid:DXImageTransform.Microsoft.AlphaImageLoader(src=\'' + src + '\', sizingMethod=\'' + sizingMethod + '\')';
			el.style.background = 'none';
		}
	},
	
	/**
	 * Parses a JSON string to a JSON object
	 * 
	 * @param {String} json The JSON string to parse
	 * @return {Object} The JSON object
	 */
	parseJSON: function(json) {
		try {
			if(/^("(\\.|[^"\\\n\r])*?"|[,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t])+?$/.test(json)) {
				var j = eval('(' + json + ')');
				return j;
			}
		}
		catch(e) {}
		throw new SyntaxError('Can\'t parse JSON string');
	},
	
	/**
	 * PHP's number_format function rewritten for Javascript
	 * 
	 * @param {Number} a The number to format
	 * @param {Number} b The number of decimal points
	 * @param {String} c The separator for the decimal point
	 * @param {String} d The thousands separator
	 * 
	 * @see http://mathiasbynens.be/archive/2006/01/js-number-format
	 */
	number_format: function(a, b, c, d) {
		a = Math.round(a * Math.pow(10, b)) / Math.pow(10, b);
		e = a + '';
		f = e.split('.');
		if (!f[0]) {
			f[0] = '0';
		}
		if (!f[1]) {
			f[1] = '';
		}
		if (f[1].length < b) {
			g = f[1];
			for (i=f[1].length + 1; i <= b; i++) {
				g += '0';
			}
			f[1] = g;
		}
		if(d != '' && f[0].length > 3) {
			h = f[0];
			f[0] = '';
			for(j = 3; j < h.length; j+=3) {
				i = h.slice(h.length - j, h.length - j + 3);
				f[0] = d + i +  f[0] + '';
			}
			j = h.substr(0, (h.length % 3 == 0) ? 3 : (h.length % 3));
			f[0] = j + f[0];
		}
		c = (b <= 0) ? '' : c;
		return f[0] + c + f[1];
	},
	
	/**
	 * Converts a HTMLCollection to an Array. For example, the function
	 * getElementsByTagName returns an HTMLCollection, where in 80% of the time
	 * you want to execute Array operations on that object.
	 * 
	 * @param {HTMLCollection} c The HTMLCollection to convert to Array
	 * @return {Array} The HTMLCollection converted to Array
	 */
	collectionToArray: function(c) {
		var a = [];
		for(var i = 0; i < c.length; i++)
			a.push(c.item(i));
		return a;
	},
	
	/**
	 * Converts a number of seconds to a string of minutes:seconds (e.g. 4:25)
	 * 
	 * @param {Number} sec The seconds to convert to minutes
	 */
	secondsToMinutes: function(sec) {
		var minutes = Math.floor(sec / 60);
		var seconds = sec % 60;
		if(seconds < 10) { seconds = '0' + seconds; }
		return minutes + ':' + seconds;
	}
}


/**
 * WS.Event - Webstores event handling
 * 
 * @author  Webstores <info at webstores dot nl>
 *           Copyright (c) Webstores internet totaalbureau <http://www.webstores.nl/>
 */
WS.Event = {
	/**
	 * Cross browser function to ADD an event listener to an element
	 * 
	 * @param {Mixed} el The ID of or reference to an element to add the event to
	 * @param {String} type The event type, eg. 'click' or 'focus'
	 * @param {Function} listener The function to execute when the event fires
	 * @param {Boolean} useCapture (optional) Whether to use event capturing, or event bubbling (default).
	 */
	addEvent: function(el, type, listener, useCapture) {
		var el = get(el);
		useCapture = useCapture || false;
		
		if(WS.browser.Gecko) {
			el.addEventListener(type, listener, useCapture);
		}
		else if(WS.browser.IE) {
			var r = el.attachEvent('on' + type, function() {
				listener.call(el, window.event);
			});
			return r;
		}
	},
	
	/**
	 * Cross browser function to REMOVE an event listener from an element
	 * 
	 * @param {Mixed} el The ID of or reference to an element to remove the event from
	 * @param {String} type The event type being removed, eg. 'click' or 'focus'
	 * @param {Function} listener The EventListener function to be removed
	 * @param {Boolean} useCapture (optional)
	 */
	removeEvent: function(el, type, listener, useCapture) {
		useCapture = useCapture || false;
		
		if(WS.browser.Gecko) {
			el.removeEventListener(type, listener, useCapture);
		}
		else if(WS.browser.IE) {
			var r = el.detachEvent('on' + type, listener);
		}
	},
	
	/**
	 * Cross browser function to stop the default event behavior
	 * 
	 * @param {Object} e The event object to stop
	 */
	stopEvent: function(e) {
		e = e || window.event;
		
		if(WS.browser.Gecko)
			e.preventDefault();
		else
			e.returnValue = false;
		
		return false;
	},
	
	/**
	 * Retrieves the target element that fired the event
	 * 
	 * @param {Object} e The event being fired
	 * @return {Object} The target element
	 */
	getTarget: function(e) {
		if(e.target)
			return e.target;
		else if(e.srcElement)
			return e.srcElement;
		else
			return false;
	}
}


/**
 * WS.Ajax - Webstores AJAX
 * 
 * @author  Webstores <info at webstores dot nl>
 *           Copyright (c) Webstores internet totaalbureau <http://www.webstores.nl/>
 */
WS.Ajax = {
	/**
	 * Empty callback function
	 */
	callback: function() {},
	
	/**
	 * Returns a new XMLHttp object
	 * 
	 * @return The XMLHttp object
	 */
	getXMLHttpObject: function() {
		return window.ActiveXObject ?
		       new ActiveXObject('Microsoft.XMLHTTP') :
			   new XMLHttpRequest();
	},
	
	/**
	 * Gets called after each readyState change, calls callback function after the request completes
	 * 
	 * @param {Object} xhr The XMLHttp object firing readystatechanged
	 */
	stateChanged: function(xhr) {
		if(xhr.readyState == 4) {
			this.callback(xhr.responseText);
		}
	},
	
	/**
	 * Perform the request
	 * 
	 * @param {String} url The URL to request to
	 * @param {Function} callback The function to call after the request completes (readyState 4)
	 */
	request: function(url, fn) {
		var self = this;
		var post = arguments[2] || '';
		var xhr = this.getXMLHttpObject();
		
		this.callback = fn;
		
		if(xhr) {
			xhr.onreadystatechange = function() {
				self.stateChanged(xhr); // 'this' doesn't refer to the xhr object, so we use xhr
			}
			
			if(post) {
				xhr.open('POST', url, true);
				xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
				xhr.setRequestHeader('Content-length', post.length);
				xhr.setRequestHeader('Connection', 'close');
			}
			else {
				xhr.open('GET', url, true);
			}
			
			xhr.send(post);
		}
	}
}


/**
 * WS.Fx - Webstores effects
 * 
 * @author  Webstores <info at webstores dot nl>
 *           Copyright (c) Webstores internet totaalbureau <http://www.webstores.nl/>
 */
WS.Fx = {
	duration: 50,
		
	/*FadeOut: function(el) {
		el = get(el);
		var oldOpacity = el.getInlineOpacity();
		var options = Object.extend({
			from: el.getOpacity() || 1.0,
			to: 0.0,
			afterFinishInternal: function(effect) {
				if (effect.options.to!=0) return;
				effect.el.hide().setStyle({opacity: oldOpacity});
			}
		}, arguments[1] || { });
		return new Effect.Opacity(el, options);
	},
	
	FadeIn: function(el) {
		el = get(el);
		var options = Object.extend({
			from: (el.getStyle('display') == 'none' ? 0.0 : el.getOpacity() || 0.0),
			to: 1.0,
			afterFinishInternal: function(effect) {
				effect.el.forceRerendering();
			},
			beforeSetup: function(effect) {
				effect.el.setOpacity(effect.options.from).show();
			}
		}, arguments[1] || { });
		return new Effect.Opacity(el, options);
	}*/
	
	Fade: function(el, opacity, effectFn) {
		el = get(el);
		effectFn = effectFn || WS.Fx.Transitions.Linear;
		
		console.log(WS.getOpacity(el));
		//if(opacity !== 0)
		//	opacity = opacity || 10;
		setOpacity(el, effectFn.call(opacity, WS.getOpacity(el), 0, this.duration));
		var self = this;
		
		if(opacity > 0) {
			setTimeout(function() {
				console.log(WS.getOpacity(el));
				self.Fade(el);
			}, 1000 / this.duration);
		}
	}
}


/**
 * WS.Transitions - Webstores effect transitions
 * 
 * @author  Webstores <info at webstores dot nl>
 *           Copyright (c) Webstores internet totaalbureau <http://www.webstores.nl/>
 */
WS.Fx.Transitions = {
	/**
	 * Linear transition
	 * 
	 * @param {Number} t Time
	 * @param {Number} b Begin
	 * @param {Number} c Change
	 * @param {Number} d Duration
	 */
	Linear: function(t, b, c, d) {
		return c * t / d + b;
	},
	
	/**
	 * Quint out transition
	 * 
	 * @param {Number} t Time
	 * @param {Number} b Begin
	 * @param {Number} c Change
	 * @param {Number} d Duration
	 */
	QuintOut: function(t, b, c, d) {
		return c * ((t = t / d - 1) * t * t * t * t + 1) + b;
	}
}


/**
 * Javascript extensions
 * ------------------------------------------------------------
 */

/**
 * Binds a function call to a specific scope
 */
Function.prototype.bind = function() {
	var handler = this, args = [].slice.call(arguments, 0), obj = args.shift();
	
	return function()
	{
		return handler.apply(obj, args.concat([].slice.call(arguments, 0)));
	}
}

/**
 * Internet Explorer does not have Array.indexOf implemented
 * 
 * @param {Mixed} obj The object to find
 * @return {Number} The index of obj or -1
 */
if(!Array.indexOf) {
	Array.prototype.indexOf = function(obj) {
		for(var i = 0; i < this.length; i++) {
			if(this[i] == obj) {
				return i;
			}
		}
		return -1;
	}
}

/**
 * Returns the first element of the array
 * 
 * @return The first element of the array
 */
Array.prototype.first = function() {
	return this[0];
}

/**
 * Returns the last element of the array
 * 
 * @return The last element of the array
 */
Array.prototype.last = function() {
	return this[this.length - 1];
}

var YouTubePlayer=function(pId,options){if(typeof swfobject.embedSWF=='undefined'){throw'YouTubePlayer requires SWFObject 2.0 or higher to work!';}if(!/^[A-Za-z0-9\_]+$/.test(pId)){throw'The YouTube Player ID can only contain A-Z a-z 0-9 and _ (underscores). The ID being used: '+pId;}var self=this;this.pId=pId;this.player=false;if(typeof options!='undefined'){for(prop in options){this[prop]=options[prop];}}this.playerReady=function(playerId){if(self.pId==playerId){self.player=document.getElementById(playerId);self.addEventListener('onStateChange',self.pId+'onStateChange');if(self.onReady){self.onReady(self.player);}if(self.videoId&&self.autoPlay){self.loadVideoById(self.videoId);}else if(self.videoId){self.cueVideoById(self.videoId);}if(self.muted){self.mute();}else{self.unMute();self.setVolume(100);}}};this.stateChange=function(state){if(state===0&&self.onEnd){self.onEnd(self.player);}else if(state===1&&self.onPlay){self.onPlay(self.player);}else if(state===2&&self.onPause){self.onPause(self.player);}else if(state===3&&self.onBuffering){self.onBuffering(self.player);}else if(state===5&&self.onCue){self.onCue(self.player);}};this.error=function(error){if(error===100&&self.onNotFoundError){self.onNotFoundError(self.player);}else if((error===101||error===150)&&self.onNoEmbedError){self.onNoEmbedError(self.player);}};var oldOnYouTubePlayerReady=window.onYouTubePlayerReady||false;if(typeof oldOnYouTubePlayerReady=='function'){window.onYouTubePlayerReady=function(playerId){oldOnYouTubePlayerReady(playerId);self.playerReady(playerId);};}else{window.onYouTubePlayerReady=this.playerReady;}window[this.pId+'onStateChange']=this.stateChange;window[this.pId+'onError']=this.error;swfobject.embedSWF('http://www.youtube.com/apiplayer?enablejsapi=1&playerapiid='+pId,pId,(this.width||320),(this.height||240),'8',null,null,{allowScriptAccess:'always',bgcolor:'#000000',wmode:'transparent'},{id:pId});};YouTubePlayer.prototype={cueVideoById:function(videoId,startSeconds,suggestedQuality){this.player.cueVideoById(videoId,startSeconds,suggestedQuality);},loadVideoById:function(videoId,startSeconds,suggestedQuality){this.player.loadVideoById(videoId,startSeconds,suggestedQuality);},playVideo:function(){this.player.playVideo();},pauseVideo:function(){this.player.pauseVideo();},togglePlay:function(){this.getPlayerState()===1?this.pauseVideo():this.playVideo();},stopVideo:function(){this.player.stopVideo();},seekTo:function(seconds,allowSeekAhead){this.player.seekTo(seconds,allowSeekAhead);},clearVideo:function(){this.player.clearVideo();},mute:function(){this.player.mute();},unMute:function(){this.player.unMute();},isMuted:function(){return this.player.isMuted();},toggleMute:function(){this.isMuted()?this.unMute():this.mute();},setVolume:function(v){this.player.setVolume(v);},getVolume:function(){return this.player.getVolume();},setSize:function(width,height){this.player.setSize(width,height);},getVideoBytesLoaded:function(){return this.player.getVideoBytesLoaded();},getVideoBytesTotal:function(){return this.player.getVideoBytesTotal();},getVideoStartBytes:function(){return this.player.getVideoStartBytes();},getPlayerState:function(){return this.player.getPlayerState();},getCurrentTime:function(){return this.player.getCurrentTime();},getDuration:function(){return this.player.getDuration();},getVideoUrl:function(){return this.player.getVideoUrl();},getVideoEmbedCode:function(){return this.player.getVideoEmbedCode();},addEventListener:function(event,listener){this.player.addEventListener(event,listener);}};

WS.Validation=function(form){var form=get(form),formElements=[],errorClass='wsv-error';var validations={required:{errorMessage:'Dit veld is verplicht',regex:/\S+/},email:{errorMessage:'U dient een geldig e-mailadres in te vullen',regex:/^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}$/},zip:{errorMessage:'U dient een geldige postcode in te vullen (1234AB)',regex:/^[0-9]{4}[\ ]?[a-zA-Z]{2}$/},numeric:{errorMessage:'Dit veld mag alleen numerieke tekens bevatten',regex:/^[0-9]*$/},phone:{errorMessage:'U dient een geldig telefoonnummer in te vullen',regex:/^[0-9 +-]{10,16}$/}};return{initialize:function(){if(!form){return false;}for(var i=0;i<form.elements.length;i++){if(WS.hasClass(form.elements[i],'wsv-',true)){formElements.push(form.elements[i]);}}if(WS.browser.Webkit){var fieldsets=form.getElementsByTagName('fieldset');for(var i=0;i<fieldsets.length;i++){if(WS.hasClass(fieldsets[i],'wsv-',true)){formElements.push(fieldsets[i]);}}}this.initEvents();},initEvents:function(){var self=this;form.onsubmit=function(){return self.validateForm();};},enableElement:function(el){el=get(el);el.disabled=false;},disableElement:function(el){el=get(el);el.disabled=true;},addValidation:function(name,properties){if(!validations[name]){validations[name]=properties;}},validateElement:function(el){var valid=true;var vArr=el.className.match(/wsv-\w+/g);for(var i=0;i<vArr.length;i++){if(vArr[i]!=errorClass){if(el.nodeName=='INPUT'){if(el.type=='text'||el.type=='password'){if(vArr[i]=='wsv-required'||el.value!==''){valid=validations[vArr[i].split('wsv-')[1]].regex.test(el.value);}}else if(el.type=='checkbox'){valid=el.checked;}else if(el.type=='radio'){var nextElement=formElements[formElements.indexOf(el)+1];do{if(!el.checked){valid=false;}nextElement=formElements[formElements.indexOf(nextElement)+1];}while(nextElement.type=='radio'&&nextElement.name==el.name);}}else if(el.nodeName=='SELECT'){valid=el.value!=-1;}else if(el.nodeName=='TEXTAREA'){valid=el.value;}else if(el.nodeName=='FIELDSET'){valid=0;var inputs=el.getElementsByTagName('input');for(var i=0;i<inputs.length;i++){valid+=inputs[i].checked;}}}if(!valid){WS.addClass(el,errorClass);}else if(valid&&WS.hasClass(el,errorClass)){WS.removeClass(el,errorClass);}}return valid;},validateForm:function(){var submit=true;for(var i=0;i<formElements.length;i++){if(!this.validateElement(formElements[i])){submit=false;}}return submit;}};};