/* =========================================================

// jquery.innerfade.js

// Datum: 2007-01-29
// Firma: Medienfreunde Hofmann & Baldes GbR
// Autor: Torsten Baldes
// Mail: t.baldes@medienfreunde.com
// Web: http://medienfreunde.com

// based on the work of Matt Oakes http://portfolio.gizone.co.uk/applications/slideshow/

// ========================================================= */


(function($) {

$.fn.innerfade = function(options) {

	this.each(function(){ 	
		
		var settings = {
			animationtype: 'fade',
			speed: 'fast',
			timeout: 2000,
			type: 'sequence',
			containerheight: 'auto',
			runningclass: 'innerfade'
		};
		
		if(options)
			$.extend(settings, options);
		
		var elements = $(this).children();
	
		if (elements.length > 1) {
		
			$(this).css('position', 'relative');
	
			$(this).css('height', settings.containerheight);
			$(this).addClass(settings.runningclass);
			
			for ( var i = 0; i < elements.length; i++ ) {
				$(elements[i]).css('z-index', String(elements.length-i)).css('position', 'absolute');
				$(elements[i]).hide();
			};
		
			if ( settings.type == 'sequence' ) {
				setTimeout(function(){
					$.innerfade.next(elements, settings, 1, 0);
				}, settings.timeout);
				$(elements[0]).show();
			} else if ( settings.type == 'random' ) {
				setTimeout(function(){
					do { current = Math.floor ( Math.random ( ) * ( elements.length ) ); } while ( current == 0 )
					$.innerfade.next(elements, settings, current, 0);
				}, settings.timeout);
				$(elements[0]).show();
			}	else {
				alert('type must either be \'sequence\' or \'random\'');
			}
			
		}
		
	});
};


$.innerfade = function() {}
$.innerfade.next = function (elements, settings, current, last) {

	if ( settings.animationtype == 'slide' ) {
		$(elements[last]).slideUp(settings.speed, $(elements[current]).slideDown(settings.speed));
	} else if ( settings.animationtype == 'fade' ) {
		$(elements[last]).fadeOut(settings.speed);
		$(elements[current]).fadeIn(settings.speed);
	} else {
		alert('animationtype must either be \'slide\' or \'fade\'');
	};
	
	if ( settings.type == 'sequence' ) {
		if ( ( current + 1 ) < elements.length ) {
			current = current + 1;
			last = current - 1;
		} else {
			current = 0;
			last = elements.length - 1;
		};
	}	else if ( settings.type == 'random' ) {
		last = current;
		while (	current == last ) {
			current = Math.floor ( Math.random ( ) * ( elements.length ) );
		};
	}	else {
		alert('type must either be \'sequence\' or \'random\'');
	};
	setTimeout((function(){$.innerfade.next(elements, settings, current, last);}), settings.timeout);
};
})(jQuery);


/* JQuery Innerfade Init */
$(document).ready(
	function() {
		$('#branding').innerfade({
		speed: 'slow',
		timeout: 6000,
		type: 'sequence',
		containerheight: '0'
	});
});

$(document).ready(
	function() {
		$('#news').innerfade({
		animationtype: 'fade',
		speed: 'slow',
		timeout: 4500,
		type: 'sequence',
		containerheight: '70px'
	});
});


/* HTML5
For discussion and comments, see: http://remysharp.com/2009/01/07/html5-enabling-script */
(function(){if(!/*@cc_on!@*/0)return;var e = "abbr,article,aside,audio,canvas,datalist,details,eventsource,figure,footer,header,hgroup,mark,menu,meter,nav,output,progress,section,time,video".split(','),i=e.length;while(i--){document.createElement(e[i])}})()

/**********************************************************
Author:
Adam Barry
eBOUND
www.ebound.dk

Date: December 8 2008

� 2007 Adam Barry, all rights reserved

Inspiration: http://simonwillison.net/2004/May/26/addLoadEvent/
-----------------------------------------------------------

Name:
windowOnLoad script

-----------------------------------------------------------
Description:
Function that enables loading of multiple functions during
window.onload

-----------------------------------------------------------
Usage:
Simply place a link to the this script in the top of the
<head>-section of the XHTML page - before including
additional JavaScript files. The script will then
automatically execute on page load.

Include the addLoadEvent code in the scripts that you wish to have
loaded at the time of page-load according to the example below.

<script type="text/javascript" src="windowOnLoad.js"></script>

-----------------------------------------------------------
Example:
<script type="text/javascript" src="windowOnLoad.js"></script>

function functionToLoad() {
	alert("Execute me on page-load, please");
}

addLoadEvent(function(){functionToLoad();});

-----------------------------------------------------------
Dependencies:
None

**********************************************************/
var onLoadScripts = new Array();

function addLoadEvent(func) {
    var oldonload = window.onload;
    if (typeof window.onload != 'function') {
        window.onload = func;
    } else {
        window.onload = function() {
            if (oldonload) {
                oldonload();
            }
            func();
            onLoadScripts.push(func);
        }
    }
}


/*********************************************************
Name:
reloadOnLoadScripts script

-----------------------------------------------------------
Description:
Function that enables reloading of the functions loaded
onpageload for AJAX environments

-----------------------------------------------------------
Usage:
Execute reloadOnLoadScripts() after a part of the website
that is dependent on the windowOnLoad-scripts has been
refreshed.

reloadOnLoadScripts()

-----------------------------------------------------------
Dependencies:
This script depends on the windowOnLoad-script to execute

**********************************************************/

function reloadOnLoadScripts () {

	for (var i = 0; i < onLoadScripts.length; i++) {
		onLoadScripts[i]();
	}
}


/**********************************************************
Author:
Adam Barry
eBOUND
www.ebound.dk

Date: June 12 2007

� 2007 Adam Barry, all rights reserved
-----------------------------------------------------------

Name:
dropDownNav script

-----------------------------------------------------------
Description:
Function that enables drop-down navigation functionality by
the use of a standard compliant list-based navigation
structure with drop-down functionality in IE, Firefox,
Opera, Safari etc.

-----------------------------------------------------------
Usage:
Simply place a link to the this script in the head-section
of the XHTML page. The script will then automatically
execute on page load.

<script type="text/javascript" src="dropDownNav.js"></script>

Make sure that your list structure has "navigation" as
classname, according to the example below.

-----------------------------------------------------------
Example:
<script type="text/javascript" src="dropDownNav.js"></script>

<ul class="navigation">
	<li class='first'><a class='selected' href='default.htm'>Home</a></li>
	<li><a href='default.htm'>Page 2</a>
		<ul>
			<li><a class='first' href='default.htm'>Subpage 2.1</a></li>
			<li><a href='default.htm'>Subpage 2.2</a></li>
		</ul>
	</li>
	<li><a href='default.htm'>Page 3</a>
		<ul>
			<li><a class='first' href='default.htm'>Subpage 3.1</a></li>
			<li><a href='default.htm'>Subpage 3.2</a></li>
		</ul>
	</li>
</ul>

-----------------------------------------------------------
Dependencies:
This script depends on the windowOnLoad-script to execute

**********************************************************/

function dropDownNav () {
	if (!document.getElementsByTagName) return;

	var navs = new Array();
	var lists = document.getElementsByTagName("ul");

	for (var i = 0; i < lists.length; i++) {
		if (lists[i].className.indexOf('navigation') == 0) {
			navs.push(lists[i]);
		}
	}

	for (var t = 0; t < navs.length; t++) {

		var togglers = navs[t].getElementsByTagName("LI");
		for (var i=0; i < togglers.length; i++) {
			togglers[i].onmouseover = function() {
				this.className += " stretch";
			}
			togglers[i].onmouseout = function() {
				this.className = this.className.replace(new RegExp("stretch\\b"), "");
			}
			togglers[i].onclick = function() {
				this.className = this.className.replace(new RegExp("stretch\\b"), "");
			}
		}
	}
}
addLoadEvent(function(){dropDownNav();});


/**********************************************************
Author:
Adam Barry
Klestrup partners
www.klestrup-partners.dk

Date: April 21 2009

� 2009 Adam Barry, all rights reserved
-----------------------------------------------------------

Name:
tabs script

-----------------------------------------------------------
Description:
Function that enables run-time switching between tabs in
multiple tab-structures.

-----------------------------------------------------------
Usage:
Simply place a link to the this script in the head-section
of the XHTML page. The script will then automatically
execute on page load.

<script type="text/javascript" src="tabs.js"></script>

-----------------------------------------------------------
Example:
<script type="text/javascript" src="tabs.js"></script>

<div class="tabs">
	<ul class="tabsHeader">
		<li class="first selected"><span><span>Tab 1</span></span></li>
		<li><span><span>Tab 2</span></span></li>
	</ul>

	<div class="body">
		<div class="tabsContainer selected">
			<h2>Contents of container 1</h2>
		</div>

		<div class="tabsContainer">
			<h2>Contents of the second container</h2>
		</div>
	</div>
</div>

-----------------------------------------------------------
Dependencies:
This script depends on the windowOnLoad-script to execute

**********************************************************/

var tabDivs = new Array();
function tabSection (element,elements,currentTab) {
	this.element = element;
	this.elements = new Array();
	this.currentTab = currentTab;
}

var tabs = new Array();
function tab (headerElement,tabContainer) {
/*Array-element for the tabs array */
	this.headerElement = headerElement;
	this.tabContainer = tabContainer;
}


function initTabs (openTab) {
	if (!document.getElementsByTagName) return;

	/* Reset arrays */
	tabDivs = new Array();
	tabs = new Array();

	var divs = document.getElementsByTagName("div");

	for (var i = 0; i < divs.length; i++) {

		if (divs[i].className == "tabs") {
			tabDivs.push(new tabSection(divs[i],'',''));
		}
	}
	if (!tabDivs[0]) return;

	for (var x = 0; x < tabDivs.length; x++) {
		var tabDiv = tabDivs[x].element;

		/* Identify tab containers */
		tabContainers = tabDiv.getElementsByTagName("div");

		for (var p = 0; p < tabContainers.length; p++) {
			if (tabContainers[p].className.indexOf('tabsContainer') == 0) {
				tabDivs[x].elements.push(new tab('',tabContainers[p]));
			}
		}

		/* Identify tab togglers */
		var tabHeader;
		tabLists = tabDiv.getElementsByTagName("ul");

		for (var i = 0; i < tabLists.length; i++) {

			if (tabLists[i].className.indexOf('tabsHeader') == 0) {
				tabHeader = tabLists[i];
			}
		}

		if (!tabHeader) return;

		var togglers = tabHeader.getElementsByTagName("li");

		for (var t = 0; t < togglers.length; t++) {

			if (!tabDivs[x].elements[t]) {
				togglers[t].parentNode.removeChild(togglers[t]);
			}

			else {

				tabDivs[x].elements[t].headerElement = togglers[t];

				togglers[t].onclick = function() {
					displayTab(this.parentNode.parentNode, this);
				}
			}
		}
	}
}addLoadEvent(function(){initTabs(1);});


function displayTab (tabDiv,tabHeader) {
	clearTabs(tabDiv);
	var currentTabSection;

	for (var i = 0; i < tabDivs.length; i++) {

		if (tabDivs[i].element == tabDiv) {
			currentTabSection = tabDivs[i];
			break;
		}
	}

	for (var i = 0; i < currentTabSection.elements.length; i++) {
		if (currentTabSection.elements[i].headerElement == tabHeader) {
			currentTabSection.elements[i].headerElement.className += " selected";
			currentTabSection.elements[i].tabContainer.className += " selected";
			currentTabSection.currentTab = i;
		}
	}
}

function clearTabs (tabDiv) {
	var currentTabSection;

	for (var i = 0; i < tabDivs.length; i++) {

		if (tabDivs[i].element == tabDiv) {
			currentTabSection = tabDivs[i];
		}
	}

	for (var i = 0; i < currentTabSection.elements.length; i++) {
		currentTabSection.elements[i].headerElement.className = currentTabSection.elements[i].headerElement.className.replace(new RegExp("selected\\b"), "");
		currentTabSection.elements[i].tabContainer.className = currentTabSection.elements[i].tabContainer.className.replace(new RegExp("selected\\b"), "");
	}
}


/**********************************************************
Author:
Adam Barry
www.ebound.dk

Date: June 11 2008

� 2008 Adam Barry, all rights reserved
-----------------------------------------------------------

Name:
xmlhttp script

-----------------------------------------------------------
Description:
Function that enables dynamic loading of dynamic content

-----------------------------------------------------------
Usage:
Simply place a link to the this script in the head-section
of the XHTML page.

<script type="text/javascript" src="xmlhttp.js"></script>

-----------------------------------------------------------
Example:

<script type="text/javascript" src="xmlhttp.js"></script>

<script>
	callServer(myFunction,"result.html");	//executes the request and passes the result to a callback function
	callServer(false,"result.html");		//executes the request and then does nothing

	function myFunction(response) {
		alert(response);
	}
</script>


**********************************************************/

function callServer(callbackFunction,url) {
	try {
		var xmlhttp;

		/* Initialize the xmlhttp object */
		if (window.XMLHttpRequest) { xmlhttp = new XMLHttpRequest();}
		else if (window.ActiveXObject) { xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");}
		if (!xmlhttp) return false;

		xmlhttp.onreadystatechange = function() {
			if (xmlhttp.readyState == 4) {
				response = xmlhttp.responseText;
				if (!callbackFunction == false) {
					callbackFunction(response);
				}
			}
		}

		xmlhttp.open("GET",url,true);
		xmlhttp.send('');
	}

	/* �f xmlhttp throws an exception */
	catch (exception) {

		var name = exception.name;
		var message = exception.message;
		var fileName = exception.fileName;
		var lineNumber = exception.lineNumber;
		var stack = exception.stack;
		var tip = "Please make sure that the website executing the\ncallServer function is running on a webserver, and\nnot as a folder on a local hard drive";

		callbackFunction("XMLHTTP error: "+ name +"\nDescription: " +message + "\nFile name: "+ fileName + "\nLine number: "+ lineNumber +"\nStack: "+stack + "\n\nTip:\n"+ tip);
	}
}


/**********************************************************
Author:
Adam Barry
Klestrup partners
www.klestrup-partners.dk

Date: March 9 2009

� 2009 Adam Barry, all rights reserved

-----------------------------------------------------------

Name:
textFieldHandler script

-----------------------------------------------------------
Description:
Functions that enables dynamic style-switching when input
fields are filled.

-----------------------------------------------------------
Usage:
Simply place a link to the this script in the head-section
of the XHTML page. The script will then automatically
execute on page load.

<script type="text/javascript" src="textFieldHandler.js"></script>

<fieldset>
	<input type="text" class="text" />
</fieldset>

-----------------------------------------------------------
Dependencies:
This script depends on the windowOnLoad-script to execute

-----------------------------------------------------------
Revision history:

2009-05-18: Maxlength-functionality for input and password
fields added

**********************************************************/

function controlInputFields() {
	if (!document.getElementsByTagName) return;

	var inputs = document.getElementsByTagName('input');

	if (!inputs) return;

	for (var i = 0; i < inputs.length; i++) {
		if (inputs[i].type == "text" || inputs[i].type == "password") {
			var me = inputs[i];
			me.onkeydown = function(event) {
				var evt = event || window.event;

				toggleInputClass(this);

				if (this.getAttribute("maxlength")) {
					var maxlength = this.getAttribute("maxlength");

					if (evt.keyCode >= 48 && this.value.length >= maxlength) {
						focusOnNextElement(this);
					}
				}
			}

			me.onblur = function() {
				toggleInputClass(this);
			}

			/* If the page is refreshed, make sure that filled fields have a correponding classname */
			if (me.value !="") {
				me.className += " filled";
			}
		}
	}

}addLoadEvent(function(){controlInputFields();});


function toggleInputClass(element) {

	if (element.value.length > 0) {

		/* If the element contains text, but does not yet have its classname set to 'filled' */
		if (element.className.indexOf("filled") < 0) {
			element.className += " filled";
		}

		/* If an error class is set on the current element then remove it when typing occurs */
		if (element.className.indexOf("error") > -1) {
			element.className = element.className.replace(new RegExp("error\\b"), "");
		}
	}

	/* If the element does not contain any text then remove the 'filled' class */
	else {
		element.className = element.className.replace(new RegExp("filled\\b"), "");
	}

	if (element.className.indexOf("error") > -1) {
		element.className = element.className.replace(new RegExp("error\\b"), "");
	}
}


function focusOnNextElement(element) {

	if (!element.form) return;

	var elements = element.form.elements;

	if (!elements) return;

	for (var i = 0; i < elements.length; i++) {
		if (elements[i] == element && elements[i+1]) {
			elements[i+1].focus();
		}
	}
}


/**********************************************************
Author:
Adam Barry
Klestrup partners
www.klestrup-partners.dk

Date: April 30 2009

� 2009 Adam Barry, all rights reserved

Based on script from http://homepage.ntlworld.com/bobosola
-----------------------------------------------------------

Name:
pngfix script

-----------------------------------------------------------
Description:
Function that enables PNG-transparency in IE 5.5 & 6

-----------------------------------------------------------
Usage:
Simply place a link to the this script in the head-section
of the XHTML page. The script will then automatically
execute on page load.

<script type="text/javascript" src="pngfix.js"></script>

-----------------------------------------------------------
Dependencies:
This script depends on the windowOnLoad-script to execute

**********************************************************/

function fixSpecificPNG() {

	var arVersion = navigator.appVersion.split("MSIE")
	var version = parseFloat(arVersion[1])

	if ((version < 7) && (version >= 5.5) && (document.body.filters)) {

		/* Specify specific global elements  that should be handled */

		/* Search */
		var elements = document.getElementsByTagName('div');
		for (var i = 0; i < elements.length; i++) {
			if (elements[i].className.indexOf('logo') > -1) {
				fixPngImage(elements[i],'/graphics/logo.png','crop');
			}
		}

		var elements = document.getElementsByTagName('a');
		for (var i = 0; i < elements.length; i++) {
			if (elements[i].className.indexOf('internal') > -1) {
				fixPngImage(elements[i],'/graphics/linkInternal.png','crop');
			}
		}

		var elements = document.getElementsByTagName('a');
		for (var i = 0; i < elements.length; i++) {
			if (elements[i].className.indexOf('external') > -1) {
				fixPngImage(elements[i],'/graphics/linkExternal.png','crop');
			}
		}

		var elements = document.getElementsByTagName('a');
		for (var i = 0; i < elements.length; i++) {
			if (elements[i].className.indexOf('download') > -1) {
				fixPngImage(elements[i],'/graphics/linkDownload.png','crop');
			}
		}

		fixPNGimages();
	}
}
addLoadEvent(function(){fixSpecificPNG();});


function fixPngImage(element,backgroundImage,sizingMethod) {
	/* sizingMethod options: scale, crop, image */
	element.style.backgroundImage = "none";
	element.style.filter  = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='"+ backgroundImage +"', sizingMethod='"+sizingMethod+"')";
}

function fixPNGimages() {
	var pngImages = new Array();
	var images = document.getElementsByTagName('img');

	if (!images.length > 0) return;

	for (var i = 0; i < images.length; i++) {

		if (images[i].src.indexOf('.png') > -1) {

			pngImages.push(images[i]);
		}
	}

	if (pngImages.length < 0) return;

	/*for (var i = 0; i < pngImages.length; i++) {
		if (pngImages[i].parentNode.className.indexOf('imageGallery') <= -1) {

			var width = pngImages[i].width;
			var height = pngImages[i].height;
			var fileName = pngImages[i].src;


			var newHTML = "<span style=\"width:"+width+"px;height:"+height+"px;float:left;display:block;position:relative;filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='"+fileName+"', sizingMethod='scale')\"></span>";

			if (pngImages[i].parentNode) {
				pngImages[i].parentNode.innerHTML = newHTML;
			}
		}
	}*/
}


/**********************************************************
Author:
Adam Barry
Klestrup partners
www.klestrup-partners.dk

Date: December 8 2008

� 2008 Adam Barry, all rights reserved
-----------------------------------------------------------

Name:
formValidation script (Microsoft .NET compatible)

-----------------------------------------------------------
Description:
Function that enable runs validation on userinputs on
various forms conforming to Microsoft.Net built pages.

-----------------------------------------------------------
Usage:
Simply place a link to the this script in the head-section
of the XHTML page. The script will then automatically
execute on page load.

<script type="text/javascript" src="formValidation.Net.js"></script>

<form method="get" action="">


	<div class="form">
		<fieldset>
			<legend>Form framework</legend>
			<ul>
				<li><label for="name">Name</label><input name="name" id="name" class="text required" type="text" /></li>
				<li><label for="address">Address</label><input name="address" id="address" class="text" type="text" /></li>
				<li><label for="email">E-mail</label><input name="email" id="email" class="text email" type="text" /></li>
				<li><label for="number">Number</label><input name="number" id="number" class="text number required" type="text" /></li>
			</ul>
			<button type="button" class="submit"><span><span><span>Submit</span></span></span></button>
			<button type="reset"><span><span><span>Reset</span></span></span></button>
		</fieldset>
	</div>

	<div class="form">
		<fieldset>
			<legend>Form framework</legend>
			<ul>
				<li><label for="name">Name</label><input name="name" id="name" class="text required" type="text" /></li>
				<li><label for="address">Address</label><input name="address" id="address" class="text" type="text" /></li>
				<li><label for="email">E-mail</label><input name="email" id="email" class="text email" type="text" /></li>
			</ul>
			<button type="button" class="submit"><span><span><span>Submit</span></span></span></button>
			<button type="reset"><span><span><span>Reset</span></span></span></button>
		</fieldset>
	</div>


</form>

Please note that the class attribute "required" and "email"
determins whether the specific form element is required.

-----------------------------------------------------------
Dependencies:
This script depends on the windowOnLoad-script to execute

-----------------------------------------------------------
Revision history:

2009-05-15: Submit-on-enter functionality added

2009-05-18: Script refactored with emphasis on submit-on-
enter functionality

2009-06-27: Added additional check to test whether buttons onchange property has already been set
This allows script to be run multiple times on page

**********************************************************/

function initSubmitButtons () {
	if (!document.getElementsByTagName) return false;

	var buttons = document.getElementsByTagName("button");
	for (var i = 0; i < buttons.length; i++) {
		if (buttons[i].className.indexOf("submit") > -1) {

			var button = buttons[i];

			if (button.onclick != null && button.onchange == null) {

				/* store the onclick command in onchange attribute */
				button.onchange = button.onclick;

				button.onclick = function() {

					var me = this;

					if (findDivForm(me) == true) {
						me.onchange();
					}

					else {
						return false;
					}
				}

			}
		}
	}
}addLoadEvent(function(){initSubmitButtons();});


function initInputs () {

	/* Overcome stupid Firefox-error */
	var browser = navigator.userAgent;

	if (browser.indexOf('Firefox') > -1) {

		if (!document.getElementsByTagName) return false;

		var elements = document.getElementsByTagName("input");
		for (var i = 0; i < elements.length; i++) {
			elements[i].setAttribute("autocomplete","off");
		}
	}
}addLoadEvent(function(){initInputs();});


function findDivForm (button) {

	var formDivClassName = "form";
	var formDiv = button.parentNode;

	/* Loop throug the parentNodes of the cl�cked button until a div.form is found */
	while (formDiv.className.indexOf("form") == -1) {
		formDiv = formDiv.parentNode;
	}

	/* Validate the field elements in div.form */
	return validateForm(formDiv);
}


function submitButtonExecute (vThisform) {
	if (!vThisform) {return false;}

	buttons = vThisform.getElementsByTagName('button');
	if (!buttons) {return false;}

	for (var i = 0; i < buttons.length; i++) {
		if (buttons[i].className.indexOf('submit') > -1 && 	buttons[i].onchange != null) {
			buttons[i].onchange();
		}
	}
}


function submitPseudoForm(vThisform) {
	submitButtonExecute(vThisform);
	return false;
}


function validateCustomForm (button) {

    var formDivClassName = "form";
	var formDiv = button.parentNode;

	/* Loop throug the parentNodes of the cl�cked button until a div.form is found */
	while (formDiv.className.indexOf("form") == -1) {
		formDiv = formDiv.parentNode;
	}

	/* Validate the field elements in div.form */
	submitPseudoForm(formDiv);
}


/**********************************************************
Validators
**********************************************************/

function validate_required(field) {

	with (field) {

		if (type == "checkbox") {
			if (checked == "") {
				field.className+=" error";
				field.focus();
				return false;
			}
		}

		if (value==null || value.length <= 0 || value==" ") {
			field.className+=" error";
			field.focus();
			return false;
		}

		else {
			field.className = field.className.replace(new RegExp("error\\b"), "");
			return true;
		}
	}
}


function validate_email(field) {

	with (field) {

		if (field.value.indexOf(".") > 2 && field.value.indexOf("@") > 0) {
			field.className = field.className.replace(new RegExp("error\\b"), "");
			return true;
		}
		else {
			field.className+=" error";
			field.focus();
			return false;
		}
	}
}


function validate_number(field) {

	with (field) {

		if (field.value.match(/^\d+$/)) {
			field.className = field.className.replace(new RegExp("error\\b"), "");
			return true;
		}
		else {
			field.className+=" error";
			field.focus();
			return false;
		}
	}
}


function validate_select(element) {

    if (element.selectedIndex == 0) {
        element.focus();
        element.className += " error";
        return false;
    }
}


function validate_textarea(field) {

	if (field.value.length <= 0) {
		field.focus();
		field.className += " error";
		return false;
	}
}


/**********************************************************
Form validation
**********************************************************/

function validateForm(vThisform) {

	if (!vThisform) {return false;}

	var thisform = vThisform.getElementsByTagName("*");

	 /*	Loop through all form elements of 'thisform' and determine
		which of them have 'required' or 'email' classes and are not children of a
		noValidation fieldset */

	for (var i = 0; i < thisform.length; i++) {
		var me = thisform[i];

		/* Loop through the form's required fields */
		if (me.className.indexOf('required') > -1 && me.parentNode.parentNode.parentNode.className.indexOf('noValidation') == -1) {

			if (me.tagName.toLowerCase() == "input" || me.tagName.toLowerCase == "password") {

				if (validate_required(me) == false) {
					return false;
				}
			}

			if (me.tagName.toLowerCase() == "select") {

				if (validate_select(me) == false) {
					return false;
				}
			}

			if (me.tagName.toLowerCase() == "textarea") {

				if (validate_textarea(me) == false) {
					return false
				}
			}
		}

		/* Loop through the form's fields that have been filled out, although they are not required */
		if (me.className.indexOf('email') > -1 && me.value.length > 0) {

			if (validate_email(me) == false) {
				return false;
			}
		}

		if (me.className.indexOf('number') > -1 && me.value.length > 0) {

			if (validate_number(me) == false) {
				return false;
			}
		}
	}

	return true; /* Form is valid */
}



/**********************************************************
No validation pseudo-forms
**********************************************************/

function noValidationCheckboxes () {
	if (!document.getElementsByTagName) return false;

	var inputs = document.getElementsByTagName('input');

	for (var i = 0; i < inputs.length; i++) {

		if (inputs[i].className.indexOf('noValidation') > -1) {
			var me = inputs[i];

			me.onclick = function () {

				/* if the page is reloaded and the checkbox is unchecked */
				if (me.checked == true && me.parentNode.className.indexOf('noValidation') > -1) {
					me.parentNode.className = me.parentNode.className.replace(new RegExp("noValidation\\b"), "");
				}

				if (me.checked == false) {
					me.parentNode.className = me.parentNode.className.replace(new RegExp("noValidation\\b"), "");
				}
				else {
					me.parentNode.className += " noValidation";
				}
			}
		}
	}

}addLoadEvent(function(){noValidationCheckboxes();});


/**********************************************************
Eventhandlers
**********************************************************/

function checkFormsOnEnter() {
	if (!document.getElementsByTagName) return false;

	var forms = new Array();
	var elements = document.getElementsByTagName("div");

	for (var i = 0; i < elements.length; i++) {
		if (elements[i].className.indexOf("form") > -1) {
			forms.push(elements[i]);
		}
	}

	for (var i = 0; i < forms.length; i++) {
		forms[i].onkeydown = function(event) {

			var evt = event || window.event;

			if (evt) {
				var target = evt.target || evt.srcElement;

				switch (evt.keyCode) {
					case 13:	/* Enter/return key */
						if (target.tagName.toLowerCase() == "textarea") {
							return true;
						}

						else {
							if (validateForm(this) == true) {
								submitPseudoForm(this);
							}
							return false;
							break;
						}
				}
			}
		}
	}
}addLoadEvent(function(){checkFormsOnEnter();});

/**********************************************************
Author:
Adam Barry
Klestrup partners
www.klestrup-partners.dk

Date: August 8 2009

© 2009 Adam Barry, all rights reserved
-----------------------------------------------------------

Name:
popupWindow script

-----------------------------------------------------------
Description:
Functions that enable an integrated popup-window which
sits in front of the normal page content.

-----------------------------------------------------------
Usage:
Simply place a link to the this script in the head-section
of the XHTML page. The script will then automatically
execute on page load.

<script type="text/javascript" src="popupWindow.js"></script>

-----------------------------------------------------------
Example:
<script type="text/javascript" src="popupWindow.js"></script>


<a href="javascript:popup(false,false,false)">Open popup window</a>
<a href="javascript:popup('<h2>New HTML</h2><p>This text has been injected into the popup-window.</p>',false,2500)">Open time-limited popup window</a>


<div class="popupWindow">
	<div class="popupContainer">

		<div class="popup">
			<a class="close"><span>Close</span></a>

			<div class="popupContent">
				<h2>User notification</h2>
			</div>

		</div>

	</div>
</div>	

-----------------------------------------------------------
Dependencies:
windowOnLoad.js

Optional:
keyHandler.js

**********************************************************/

var popupWindow;
var popupContent;

function initPopup() {
	if (!document.getElementsByTagName) return;

	var divs = document.getElementsByTagName("div");

	for (var i = 0; i < divs.length; i++) {
		if (divs[i].className.indexOf('popupWindow') > -1) {
			var me = divs[i];
			popupWindow = me;
			if(typeof addKeyAction == 'function') {	
				addKeyAction(me,function(){hidePopup();},13);
				addKeyAction(me,function(){hidePopup();},27);
				addKeyAction(me,function(){hidePopup();},32);
			}
			break;
		}
	}


	if (!popupWindow) addPopupWindow();

	var anchors = popupWindow.getElementsByTagName("a");

	for (var i = 0; i < anchors.length; i++) {

		if (anchors[i].className.indexOf('close') > -1) {
			var me = anchors[i];
			me.onclick = function() {
				hidePopup();
			}
				break;
		}
	}

	var divs = popupWindow.getElementsByTagName("div");

	for (var i = 0; i < divs.length; i++) {
		if (divs[i].className.indexOf('popupContent') > -1) {
			popupContent = divs[i];
			break;
		}
	}

}addLoadEvent(function(){initPopup();});


function addPopupWindow() {
	popupStructure = document.createElement('div');

	popupStructure.innerHTML = "<div class=\"popupContainer\"><div class=\"popup\"><a class=\"close\"><span>Close</span></a><div class=\"popupContent\"><h2>User notification</h2></div></div></div>";

	document.body.appendChild(popupStructure);
	popupStructure.className = "popupWindow";

	popupWindow = popupStructure;
}



function hidePopup() {
	popupWindow.className = popupWindow.className.replace(new RegExp("active\\b"), "");

	if(typeof removeActiveElement == 'function') {
		removeActiveElement();
	}
}


function popupTimer(time) {
	window.setTimeout(hidePopup,time);
}


function popup(message,classInformation,keepVisibleTime) {
	if (!popupWindow) return;
	if (!popupContent) return;

	if (message) {
		popupContent.innerHTML = message;
	}
	else {
		popupContent.innerHTML = "";
	}

	if (classInformation) {
		popupWindow.className += classInformation;
	}

	popupWindow.className += " active";

	if (keepVisibleTime) {
		popupTimer(keepVisibleTime);
	}

	if(typeof setActiveElement == 'function') {
		setActiveElement(popupWindow);
	}
}
/**********************************************************
Author:
Adam Barry
Klestrup partners
www.klestrup-partners.dk

Date: August 9 2009

© 2009 Adam Barry, all rights reserved
-----------------------------------------------------------

Name:
keyHandler script

-----------------------------------------------------------
Description:
Functions that enables various actions to keyboard events
to various elements, thus making it possible to have
various actions to key events depending on which element
is currently active.

-----------------------------------------------------------
Usage:
Identify the element which you wish to assign a function to.
Create the function that is to be executed.
Assign the function to a specific key.

<script type="text/javascript" src="keyHandler.js"></script>

-----------------------------------------------------------
Example:
<script type="text/javascript" src="keyHandler.js"></script>

Initialize:
	if(typeof addKeyAction == 'function') {	
		addKeyAction(elementToHaveKeyHandlerAttached,function(){functionToLoad();},27);
	}
	
	if(typeof setActiveElement == 'function') {
		setActiveElement(elementToHaveKeyHandlerAttached);
	}

	if(typeof removeActiveElement == 'function') {
		removeActiveElement();
	}
	

Quick key-code reference:
13: Enter/return key
27: Escape key
32: Space bar key

-----------------------------------------------------------
Dependencies:
None

**********************************************************/

var keyActions = new Array();	/* Array holding all elements and associated key-actions */
function keyAction(element,func,keycode) {
	this.element = element;		/* The element invoking a key event */
	this.func = func;			/* The function that is to be executed */
	this.keycode = keycode;		/* The keycode that will initiate the function */
}

var currentActiveKeyElement = "";

var activeKeyElements = new Array();	/* Array-stack holding the active element in last position */
function activeKeyElement(element) {
	this.element = element;
}


function addKeyAction(element,func,keycode) {
	
	keyActions.push(new keyAction(element,func,keycode));
}


function setActiveElement(element) {
	activeKeyElements.push(new activeKeyElement(element));
	currentActiveKeyElement = element;
	
	
	/* identify the keyactions for the current active element */
	for (var i = 0; i < keyActions.length; i++) {
		if (keyActions[i].element == element) {
			var me = keyActions[i];
		}
	}
}


function removeActiveElement() {
	activeKeyElements.pop();
	
	/* If more elements are currently in the stack, activate the next element */
	var length = activeKeyElements.length;
	if (length > 0) {
		setActiveElement(activeKeyElements[length-1].element);	
	}
	else {
		currentActiveKeyElement = "";	
	}
}


function keyListener(event) {
	
	var evt = event || window.event;

	if (evt) {
	
		/* document.getElementById("notify").innerHTML = evt.keyCode; */
		
		for (var i = 0; i < keyActions.length; i++) {
			if (keyActions[i].element == currentActiveKeyElement && keyActions[i].keycode == evt.keyCode) {
				keyActions[i].func();
			}
		}
	}
} document.onkeydown = keyListener;

/**********************************************************
Author:
Adam Barry
Klestrup partners
www.klestrup-partners.dk

Date: February 20 2008

� 2008 Adam Barry, all rights reserved
-----------------------------------------------------------

Name:
Google Analytics track links script

-----------------------------------------------------------
Inspiration
http://www.terenzani.it/54/urchintrack-utility-tracciare-link-esterni-e-download-con-google-analytics
GA urchin.trackLinks 0.2

-----------------------------------------------------------
Description:
Function that enables Google Analytics tracking of
downloaded files - when placed in an <a> structure.

NB. This version is not compatible with the old Google
Analytics/Urchin tracking code.

-----------------------------------------------------------
Usage:
Simply place a link to the this script in the head-section
of the XHTML page. The script will then automatically
execute on page load.

<script type="text/javascript" src="GA.trackLinks.js"></script>

-----------------------------------------------------------
Example:
<script type="text/javascript" src="GA.trackLinks.js"></script>

<a href="filename.pdf">Download tracked PDF file</a>

-----------------------------------------------------------
Dependencies:
This script depends on the windowOnLoad-script to execute

**********************************************************/

function urchin() {
 /* It contains the download extension separated by a "|" */
	this.trackDownload = '';

 	this.trackLinks = function() {
  		var a = document.getElementsByTagName('a');

	 /* Extract the domain from the location (the domain is in domain[2]) */
		var domain = /^(http|https):\/\/([a-z-.0-9]+)[\/]{0,1}/i.exec(window.location);
	 	if (!domain) return;

	 /* Expression that checks for internal links */
		var internalLink = new RegExp("^(http|https):\/\/"+domain[2], "i");

	 /* Expression that checks for downloads */
		var isDownload = new RegExp("("+this.trackDownload+")$", "i");

	  /* For each anchor */
		for(var i = 0; i < a.length; i++) {
		/* If href points to an internal resource */
			if(internalLink.test(a[i].href)) {
		/* ... and if the file extension is in this.trackDownload ... */
				if(this.trackDownload && isDownload.test(a[i].href))
				a[i].onclick = function() {
		  /* Clean and track the URL */
				pageTracker._trackPageview('/download/'+this.href.replace(/^(http|https):\/\/([a-z-.0-9]+)\//i, '').split('/').join('--'));
				}
			}

			else
				/* is external */
				a[i].onclick = function() {
				/* Clean and track the URL*/
				pageTracker._trackPageview('/outgoing/'+this.href.replace(/^http:\/\/|https:\/\//i, '').split('/').join('--'));
			}
		}
 	}
}

function initDownloadTracker () {
  	urchin = new urchin();
  	urchin.trackDownload = "zip|rar|pdf|exe|gz|dmg|avi|jpg|gif|png|doc|dot|ashx";
  	urchin.trackLinks();
}addLoadEvent(function(){initDownloadTracker();});


/**********************************************************
Author:
Adam Barry
Klestrup partners
www.klestrup-partners.dk

Date: November 11 2007

� 2007 Adam Barry, all rights reserved
-----------------------------------------------------------

Name:
thumbnails script

-----------------------------------------------------------
Description:
A script that enables thumbnail/preview functionality to
multiple thumbnail structures. The construction of the
thumbnail list means that browsers that do not support
document.getElementsByTagName will still be able to view
the standard-images, although in new windows.

-----------------------------------------------------------
Usage:
Simply place a link to the this script in the head-section
of the XHTML page. The script will then automatically
execute on page load.

<script type="text/javascript" src="thumbnails.js"></script>

Make sure that your list structure has (1) an image element
where the class-name is "previewImage" and (2) a unordered
list with "thumbnails" as class-name according to the
example below.

-----------------------------------------------------------
Example:
<script type="text/javascript" src="thumbnails.js"></script>

<img class="previewImage" src="books/bookname/standard/image1.png" alt=""/>

<ul class="thumbnails">
	<li>
		<a href="components/imagegallery/standard/image1.png" class="selected">
			<img src="components/imagegallery/thumbs/image1.png" alt=""/>
			<span>1</span>
		</a>
	</li>
	<li>
		<a href="components/imagegallery/standard/image2.png">
			<img src="components/imagegallery/thumbs/image2.png" alt=""/>
			<span>2</span>
		</a>
	</li>
	<li>
</ul>

-----------------------------------------------------------
Dependencies:
This script depends on the windowOnLoad-script to execute

**********************************************************/

var imageGalleries = new Array();
function imageGallery (element,previewImage,thumbnails,currentPosition) {
	this.element = element;
	this.previewImage = previewImage;
	this.thumbnails = new Array();
	this.currentPosition = currentPosition;
}


function initImageGalleries () {
	if (!document.getElementsByTagName) return;

	var elements = document.getElementsByTagName("div");

	/* When an element with the classname 'imageGallery' is found
	   create a new entry in the imageGalleries array */
	for (var i = 0; i < elements.length; i++) {
		if (elements[i].className == "imageGallery") {
			imageGalleries.push(new imageGallery(elements[i],'','',''))
		}
	}

	/* If the imageGalleries array is empty do not proceed  */
	if (!imageGalleries[0]) return;

	/* Run through each imageGallery in the imageGalleries array */
	for (var x = 0; x < imageGalleries.length; x++) {
		/* alert("Debug: Now processing imageGallery No. #"+x); */
		var gallery = imageGalleries[x].element;

		/* Identify the previewImage of the current imageGallery
		   and store it in the imageGalleries array */
		var images = gallery.getElementsByTagName("img");

		for (var i = 0; i < images.length; i++) {
			if (images[i].className.indexOf('previewImage') == 0) {
				imageGalleries[x].previewImage = images[i];
			}
		}

		if (!imageGalleries[x].previewImage) return;
		var previewImage = imageGalleries[x].previewImage;

		/* Now that we have identified the previewImage let's
		   identify the thumbnail images and add them the the
		   imageGalleries array */
		var thumbnailList;
		var lists = gallery.getElementsByTagName("ul");

		for (var i = 0; i < lists.length; i++) {
			if (lists[i].className == 'thumbnails') {
				thumbnailList = lists[i];
			}
		}

		/* Identify the child items of the thumbnailList */
		var thumbnails = thumbnailList.getElementsByTagName("a");

		/* When a thumbnail element is found add it to thumbnails array in
		   the current imageGallery object */
		for (var i = 0; i < thumbnails.length; i++) {
			imageGalleries[x].thumbnails.push(thumbnails[i]);
		}

		/* Quit the function if no thumbnails have been found */
		if (!imageGalleries[x].thumbnails[0]) return;

		/* To keep track of which thumbnail is currently selected
		   find it an store it in the current imageGallery object */
		for (var i = 0; i < thumbnails.length; i++) {
			if (thumbnails[i].className == 'selected') {
				imageGalleries[x].currentPosition = i;
			}
		}

		/* The thumbnails have now been stored in the imageGallery object
		   so now add some functionality to them */
		for (var i = 0; i < thumbnails.length; i++) {
			thumbnails[i].onclick = function() {
				var parentNode = this.parentNode.parentNode.parentNode.parentNode;

				thumbnailHandler(parentNode,this);
				return false;	/* make sure the link is not actually followed */
			}
		}

		/* Make it possible to proceed to the next image by clicking the previewImage */
		previewImage.onclick = function() {
				var currentImageGallery;

			/* identify the image currently shown */
			for (var i = 0; i < imageGalleries.length; i++) {
				if (imageGalleries[i].previewImage == this) {
					currentImageGallery = imageGalleries[i].element;
				}
			}
			showNextImage(currentImageGallery);
		}

		/* Make it possible to navigate through the images by mouse scroll */
		initMouseScroll(previewImage);


		/* Make it possible to navigate through the images by using the arrow-keys */
		/*handleArrowKeys(previewImage); */
	}

	/* Preload the images to make viewing faster */
	for (var i = 0; i < imageGalleries.length; i++) {
		preloadImages(imageGalleries[i].element);
	}
}
addLoadEvent(function(){initImageGalleries();});


function identifyImageGallery(imageGallery) {
	var currentImageGallery;

	/* Identify the position of the current imageGallery
	   in the imageGalleries array */
	for (var i = 0; i < imageGalleries.length; i++) {

		if (imageGalleries[i].element == imageGallery) {
			currentImageGallery = imageGalleries[i];
		}
	}

	return currentImageGallery;
}

function thumbnailHandler (imageGallery,thumbnail) {
	clearThumbnails(imageGallery);
	thumbnail.className+="selected";
	thumbnail.blur();
	showImage(imageGallery,thumbnail);
	setDisplayedThumbnail(imageGallery,thumbnail);
}

function clearThumbnails (imageGallery) {
	var currentImageGallery = identifyImageGallery(imageGallery);

	/* Loop through the thumbnails and make sure none of them
	   are selected */
	for (var i = 0; i < currentImageGallery.thumbnails.length; i++) {
		currentImageGallery.thumbnails[i].className = "";
	}
}

function showImage (imageGallery,thumbnail) {
	var currentImageGallery = identifyImageGallery(imageGallery);
	var path = thumbnail.href;

	currentImageGallery.previewImage.src = path;
}

function setDisplayedThumbnail(imageGallery,thumbnail) {
	var currentImageGallery = identifyImageGallery(imageGallery);

	for (var i = 0; i < currentImageGallery.thumbnails.length; i++) {
		if (currentImageGallery.thumbnails[i] == thumbnail) {
			currentImageGallery.currentPosition = i;
		}
	}
}

function showNextImage (imageGallery) {
	var currentImageGallery = identifyImageGallery(imageGallery);
	var noOfThumbnails = currentImageGallery.thumbnails.length-1;
	var nextImage;

	if (currentImageGallery.currentPosition < noOfThumbnails) {
		nextPosition = currentImageGallery.currentPosition + 1;
		nextImage = currentImageGallery.thumbnails[nextPosition];
	}
	else {
		nextImage = currentImageGallery.thumbnails[0];
	}

	thumbnailHandler(imageGallery,nextImage);
}

function showPreviousImage (imageGallery) {
	var currentImageGallery = identifyImageGallery(imageGallery);
	var noOfThumbnails = currentImageGallery.thumbnails.length-1;
	var previousImage;

	if (currentImageGallery.currentPosition > 0) {
		previousPosition = currentImageGallery.currentPosition - 1;
		previousImage = currentImageGallery.thumbnails[previousPosition];
	}
	else {
		previousImage = currentImageGallery.thumbnails[noOfThumbnails];
	}

	thumbnailHandler(imageGallery,previousImage);
}

function setDisplayedThumbnail(imageGallery,thumbnail) {
	var currentImageGallery = identifyImageGallery(imageGallery);

	for (var i = 0; i < currentImageGallery.thumbnails.length; i++) {
		if (currentImageGallery.thumbnails[i] == thumbnail) {
			currentImageGallery.currentPosition = i;
		}
	}
}


/*: Mouse scroll navigation
Functions relevant
----------------------------------------------------------*/

function initMouseScroll (previewImage) {
	if (previewImage.addEventListener) {
		previewImage.addEventListener ("DOMMouseScroll",wheelGallery,false); /* Firefox */
		previewImage.addEventListener ("mousewheel",wheelGallery,false); /* Safari  & Opera */
	} else if (previewImage.attachEvent) {
		previewImage.attachEvent ("onmousewheel",wheelGallery); /* Internet Explorer */
	} else {
		previewImage.DOMMouseScroll = wheelGallery;
	}
}

function eventTrigger (e) {
    if (! e) {
        e = event;
	}

    return e.target || e.srcElement;
}

function handleWheelGallery (delta,event) {

	/* Identify which object triggered the mouse scroll event */
	var obj = eventTrigger (event);
	var currentImageGallery;

	for (var i = 0; i < imageGalleries.length; i++) {
		if (imageGalleries[i].previewImage == obj) {
			currentImageGallery = imageGalleries[i].element;
		}
	}

	/* Mouse scroll down */
	if (delta < 0) {
		showNextImage(currentImageGallery);
	}
	/* Mouse scroll up */
	else {
		showPreviousImage(currentImageGallery);
	}
}

function wheelGallery (event) {
	var delta = 0;

	if (!event) { /* For IE. */
		event = window.event;
	}

	if (event.wheelDelta) { /* IE/Opera. */
		delta = event.wheelDelta/120;
		if (window.opera) {
			delta = -delta;
		}
	}

	else if (event.detail) { /** Mozilla case. */
			delta = -event.detail/3;
	}

	if (delta) {
		handleWheelGallery(delta,event);
	}

	if (event.preventDefault) {
		event.preventDefault();
	}

	event.returnValue = false;
}


/*: Pre-load thumbnail images
Functions relevant
----------------------------------------------------------*/

String.prototype.reverse = function () {
	var s = "";
	var i = this.length;

	while (i>0) {
		s += this.substring(i-1,i);
		i--;
	}
    return s;
}

function getFileName (string) {
	var reversePath = string.reverse();
	var splitPath = reversePath.split("/");
	var fileName = splitPath[0].reverse();
	return fileName;
}

function preloadImages (imageGallery) {
	var currentImageGallery;

	/* Identify the position of the current imageGallery
	   in the imageGalleries array */
	for (var i = 0; i < imageGalleries.length; i++) {

		if (imageGalleries[i].element == imageGallery) {
			currentImageGallery = imageGalleries[i];
		}
	}

	for (var i = 0; i < currentImageGallery.thumbnails.length; i++) {
		var path = currentImageGallery.thumbnails[i].href;
		var fileName = getFileName(path);

		fileName = new Image();
		fileName.src = path;
	}
}

/*: jCap */

/*
 * A JavaScript implementation of the RSA Data Security, Inc. MD5 Message
 * Digest Algorithm, as defined in RFC 1321.
 * Version 2.1 Copyright (C) Paul Johnston 1999 - 2002.
 * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
 * Distributed under the BSD License
 * See http://pajhome.org.uk/crypt/md5 for more info.
 */

/*
 * Configurable variables. You may need to tweak these to be compatible with
 * the server-side, but the defaults work in most cases.
 */
var hexcase = 0;  /* hex output format. 0 - lowercase; 1 - uppercase        */
var b64pad  = ""; /* base-64 pad character. "=" for strict RFC compliance   */
var chrsz   = 8;  /* bits per input character. 8 - ASCII; 16 - Unicode      */

/*
 * These are the functions you'll usually want to call
 * They take string arguments and return either hex or base-64 encoded strings
 */
function hex_md5(s){ return binl2hex(core_md5(str2binl(s), s.length * chrsz));}
function b64_md5(s){ return binl2b64(core_md5(str2binl(s), s.length * chrsz));}
function str_md5(s){ return binl2str(core_md5(str2binl(s), s.length * chrsz));}
function hex_hmac_md5(key, data) { return binl2hex(core_hmac_md5(key, data)); }
function b64_hmac_md5(key, data) { return binl2b64(core_hmac_md5(key, data)); }
function str_hmac_md5(key, data) { return binl2str(core_hmac_md5(key, data)); }

/*
 * Perform a simple self-test to see if the VM is working
 */
function md5_vm_test()
{
  return hex_md5("abc") == "900150983cd24fb0d6963f7d28e17f72";
}

/*
 * Calculate the MD5 of an array of little-endian words, and a bit length
 */
function core_md5(x, len)
{
  /* append padding */
  x[len >> 5] |= 0x80 << ((len) % 32);
  x[(((len + 64) >>> 9) << 4) + 14] = len;

  var a =  1732584193;
  var b = -271733879;
  var c = -1732584194;
  var d =  271733878;

  for(var i = 0; i < x.length; i += 16)
  {
    var olda = a;
    var oldb = b;
    var oldc = c;
    var oldd = d;

    a = md5_ff(a, b, c, d, x[i+ 0], 7 , -680876936);
    d = md5_ff(d, a, b, c, x[i+ 1], 12, -389564586);
    c = md5_ff(c, d, a, b, x[i+ 2], 17,  606105819);
    b = md5_ff(b, c, d, a, x[i+ 3], 22, -1044525330);
    a = md5_ff(a, b, c, d, x[i+ 4], 7 , -176418897);
    d = md5_ff(d, a, b, c, x[i+ 5], 12,  1200080426);
    c = md5_ff(c, d, a, b, x[i+ 6], 17, -1473231341);
    b = md5_ff(b, c, d, a, x[i+ 7], 22, -45705983);
    a = md5_ff(a, b, c, d, x[i+ 8], 7 ,  1770035416);
    d = md5_ff(d, a, b, c, x[i+ 9], 12, -1958414417);
    c = md5_ff(c, d, a, b, x[i+10], 17, -42063);
    b = md5_ff(b, c, d, a, x[i+11], 22, -1990404162);
    a = md5_ff(a, b, c, d, x[i+12], 7 ,  1804603682);
    d = md5_ff(d, a, b, c, x[i+13], 12, -40341101);
    c = md5_ff(c, d, a, b, x[i+14], 17, -1502002290);
    b = md5_ff(b, c, d, a, x[i+15], 22,  1236535329);

    a = md5_gg(a, b, c, d, x[i+ 1], 5 , -165796510);
    d = md5_gg(d, a, b, c, x[i+ 6], 9 , -1069501632);
    c = md5_gg(c, d, a, b, x[i+11], 14,  643717713);
    b = md5_gg(b, c, d, a, x[i+ 0], 20, -373897302);
    a = md5_gg(a, b, c, d, x[i+ 5], 5 , -701558691);
    d = md5_gg(d, a, b, c, x[i+10], 9 ,  38016083);
    c = md5_gg(c, d, a, b, x[i+15], 14, -660478335);
    b = md5_gg(b, c, d, a, x[i+ 4], 20, -405537848);
    a = md5_gg(a, b, c, d, x[i+ 9], 5 ,  568446438);
    d = md5_gg(d, a, b, c, x[i+14], 9 , -1019803690);
    c = md5_gg(c, d, a, b, x[i+ 3], 14, -187363961);
    b = md5_gg(b, c, d, a, x[i+ 8], 20,  1163531501);
    a = md5_gg(a, b, c, d, x[i+13], 5 , -1444681467);
    d = md5_gg(d, a, b, c, x[i+ 2], 9 , -51403784);
    c = md5_gg(c, d, a, b, x[i+ 7], 14,  1735328473);
    b = md5_gg(b, c, d, a, x[i+12], 20, -1926607734);

    a = md5_hh(a, b, c, d, x[i+ 5], 4 , -378558);
    d = md5_hh(d, a, b, c, x[i+ 8], 11, -2022574463);
    c = md5_hh(c, d, a, b, x[i+11], 16,  1839030562);
    b = md5_hh(b, c, d, a, x[i+14], 23, -35309556);
    a = md5_hh(a, b, c, d, x[i+ 1], 4 , -1530992060);
    d = md5_hh(d, a, b, c, x[i+ 4], 11,  1272893353);
    c = md5_hh(c, d, a, b, x[i+ 7], 16, -155497632);
    b = md5_hh(b, c, d, a, x[i+10], 23, -1094730640);
    a = md5_hh(a, b, c, d, x[i+13], 4 ,  681279174);
    d = md5_hh(d, a, b, c, x[i+ 0], 11, -358537222);
    c = md5_hh(c, d, a, b, x[i+ 3], 16, -722521979);
    b = md5_hh(b, c, d, a, x[i+ 6], 23,  76029189);
    a = md5_hh(a, b, c, d, x[i+ 9], 4 , -640364487);
    d = md5_hh(d, a, b, c, x[i+12], 11, -421815835);
    c = md5_hh(c, d, a, b, x[i+15], 16,  530742520);
    b = md5_hh(b, c, d, a, x[i+ 2], 23, -995338651);

    a = md5_ii(a, b, c, d, x[i+ 0], 6 , -198630844);
    d = md5_ii(d, a, b, c, x[i+ 7], 10,  1126891415);
    c = md5_ii(c, d, a, b, x[i+14], 15, -1416354905);
    b = md5_ii(b, c, d, a, x[i+ 5], 21, -57434055);
    a = md5_ii(a, b, c, d, x[i+12], 6 ,  1700485571);
    d = md5_ii(d, a, b, c, x[i+ 3], 10, -1894986606);
    c = md5_ii(c, d, a, b, x[i+10], 15, -1051523);
    b = md5_ii(b, c, d, a, x[i+ 1], 21, -2054922799);
    a = md5_ii(a, b, c, d, x[i+ 8], 6 ,  1873313359);
    d = md5_ii(d, a, b, c, x[i+15], 10, -30611744);
    c = md5_ii(c, d, a, b, x[i+ 6], 15, -1560198380);
    b = md5_ii(b, c, d, a, x[i+13], 21,  1309151649);
    a = md5_ii(a, b, c, d, x[i+ 4], 6 , -145523070);
    d = md5_ii(d, a, b, c, x[i+11], 10, -1120210379);
    c = md5_ii(c, d, a, b, x[i+ 2], 15,  718787259);
    b = md5_ii(b, c, d, a, x[i+ 9], 21, -343485551);

    a = safe_add(a, olda);
    b = safe_add(b, oldb);
    c = safe_add(c, oldc);
    d = safe_add(d, oldd);
  }
  return Array(a, b, c, d);

}

/*
 * These functions implement the four basic operations the algorithm uses.
 */
function md5_cmn(q, a, b, x, s, t)
{
  return safe_add(bit_rol(safe_add(safe_add(a, q), safe_add(x, t)), s),b);
}
function md5_ff(a, b, c, d, x, s, t)
{
  return md5_cmn((b & c) | ((~b) & d), a, b, x, s, t);
}
function md5_gg(a, b, c, d, x, s, t)
{
  return md5_cmn((b & d) | (c & (~d)), a, b, x, s, t);
}
function md5_hh(a, b, c, d, x, s, t)
{
  return md5_cmn(b ^ c ^ d, a, b, x, s, t);
}
function md5_ii(a, b, c, d, x, s, t)
{
  return md5_cmn(c ^ (b | (~d)), a, b, x, s, t);
}

/*
 * Calculate the HMAC-MD5, of a key and some data
 */
function core_hmac_md5(key, data)
{
  var bkey = str2binl(key);
  if(bkey.length > 16) bkey = core_md5(bkey, key.length * chrsz);

  var ipad = Array(16), opad = Array(16);
  for(var i = 0; i < 16; i++)
  {
    ipad[i] = bkey[i] ^ 0x36363636;
    opad[i] = bkey[i] ^ 0x5C5C5C5C;
  }

  var hash = core_md5(ipad.concat(str2binl(data)), 512 + data.length * chrsz);
  return core_md5(opad.concat(hash), 512 + 128);
}

/*
 * Add integers, wrapping at 2^32. This uses 16-bit operations internally
 * to work around bugs in some JS interpreters.
 */
function safe_add(x, y)
{
  var lsw = (x & 0xFFFF) + (y & 0xFFFF);
  var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
  return (msw << 16) | (lsw & 0xFFFF);
}

/*
 * Bitwise rotate a 32-bit number to the left.
 */
function bit_rol(num, cnt)
{
  return (num << cnt) | (num >>> (32 - cnt));
}

/*
 * Convert a string to an array of little-endian words
 * If chrsz is ASCII, characters >255 have their hi-byte silently ignored.
 */
function str2binl(str)
{
  var bin = Array();
  var mask = (1 << chrsz) - 1;
  for(var i = 0; i < str.length * chrsz; i += chrsz)
    bin[i>>5] |= (str.charCodeAt(i / chrsz) & mask) << (i%32);
  return bin;
}

/*
 * Convert an array of little-endian words to a string
 */
function binl2str(bin)
{
  var str = "";
  var mask = (1 << chrsz) - 1;
  for(var i = 0; i < bin.length * 32; i += chrsz)
    str += String.fromCharCode((bin[i>>5] >>> (i % 32)) & mask);
  return str;
}

/*
 * Convert an array of little-endian words to a hex string.
 */
function binl2hex(binarray)
{
  var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef";
  var str = "";
  for(var i = 0; i < binarray.length * 4; i++)
  {
    str += hex_tab.charAt((binarray[i>>2] >> ((i%4)*8+4)) & 0xF) +
           hex_tab.charAt((binarray[i>>2] >> ((i%4)*8  )) & 0xF);
  }
  return str;
}

/*
 * Convert an array of little-endian words to a base-64 string
 */
function binl2b64(binarray)
{
  var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
  var str = "";
  for(var i = 0; i < binarray.length * 4; i += 3)
  {
    var triplet = (((binarray[i   >> 2] >> 8 * ( i   %4)) & 0xFF) << 16)
                | (((binarray[i+1 >> 2] >> 8 * ((i+1)%4)) & 0xFF) << 8 )
                |  ((binarray[i+2 >> 2] >> 8 * ((i+2)%4)) & 0xFF);
    for(var j = 0; j < 4; j++)
    {
      if(i * 8 + j * 6 > binarray.length * 32) str += b64pad;
      else str += tab.charAt((triplet >> 6*(3-j)) & 0x3F);
    }
  }
  return str;
}

/*: Original:  Jonathan Feaster (http://www.archreality.com/)
Web Site:  http://www.archreality.com/jcap/
Version: 2.0
Based on: Gimpy CAPTCHA Project at Carnegie Mellon University (http://www.captcha.net/) */

var imgdir = "/graphics/cimg/"; /* identify directory where captcha images are located */
var jfldid = "uword"; /* identify word field id name */
var jfldsz = ''; /* identify word field size */

function sjcap(jfldcls){
imgdir = encodeURIComponent(imgdir);
if (jfldcls == null){
jfldcls = "";
}
anum = (Math.floor(Math.random()*191))+1;
imgid = parseInt(anum);
cword = 
["60ee0bc62638fccf2d37ac27a634a9e9", "68e2d83709f317938b51e53f7552ed04", "f4c9385f1902f7334b00b9b4ecd164de",
 "df491a4de50739fa9cffdbd4e3f4b4bb", "ef56b0b0ddb93c2885892c06be830c68", "fe4c0f30aa359c41d9f9a5f69c8c4192",
 "cbf4e0b7971051760907c327e975f4e5", "ea9e801b0d806f2398bd0c7fe3f3f0cd", "609a8f6f218fdfe6f955e19f818ec050",
 "cbf4e0b7971051760907c327e975f4e5", "8cb554127837a4002338c10a299289fb", "28f9b1cae5ae23caa8471696342f6f0c",
 "74e04ddb55ce3825f65ebec374ef8f0d", "567904efe9e64d9faf3e41ef402cb568", "7edabf994b76a00cbc60c95af337db8f",
 "639849f6b368019778991b32434354fc", "7edabf994b76a00cbc60c95af337db8f", "dd8fc45d87f91c6f9a9f43a3f355a94a",
 "eb5c1399a871211c7e7ed732d15e3a8b", "8cb554127837a4002338c10a299289fb", "0b8263d341de01f741e4deadfb18f9eb",
 "87fa4eaaf3698e1b1e2caadabbc8ca60", "327a6c4304ad5938eaf0efb6cc3e53dc", "841a2d689ad86bd1611447453c22c6fc",
 "ceb20772e0c9d240c75eb26b0e37abee", "a3e2a6cbf4437e50816a60a64375490e", "bc8fba5b68a7babc05ec51771bf6be21",
 "68934a3e9455fa72420237eb05902327", "c9fab33e9458412c527c3fe8a13ee37d", "2fc01ec765ec0cb3dcc559126de20b30",
 "fcc790c72a86190de1b549d0ddc6f55c", "918b81db5e91d031548b963c93845e5b", "9dfc8dce7280fd49fc6e7bf0436ed325",
 "ea82410c7a9991816b5eeeebe195e20a", "fb81c91eb92d6cb64aeb64c3f37ef2c4", "8d45c85b51b27a04ad7fdfc3f126f9f8",
 "70dda5dfb8053dc6d1c492574bce9bfd", "b9b83bad6bd2b4f7c40109304cf580e1", "981c1e7b3795da18687613fbd66d4954",
 "e170e3a15923188224c1c2bd1477d451", "fb81c91eb92d6cb64aeb64c3f37ef2c4", "cb15e32f389b7af9b285a63ca1044651",
 "632a2406bbcbcd553eec45ac14b40a0a", "e7b95b49658278100801c88833a52522", "6d4db5ff0c117864a02827bad3c361b9",
 "8b373710bcf876edd91f281e50ed58ab", "508c75c8507a2ae5223dfd2faeb98122", "97f014516561ef487ec368d6158eb3f4",
 "23678db5efde9ab46bce8c23a6d91b50", "2d6b0cefb06fd579a62bf56f02b6c2b3", "f1bdf5ed1d7ad7ede4e3809bd35644b0",
 "3ddaeb82fbba964fb3461d4e4f1342eb", "c9507f538a6e79c9bd6229981d6e05a3", "9e925e9341b490bfd3b4c4ca3b0c1ef2",
 "125097a929a62998c06340ea9ef43d77", "a557264a7d6c783f6fb57fb7d0b9d6b0", "eba478647c77836e50de44b323564bdb",
 "45fe7e5529d283851d93b74536e095a0", "56609ab6ba04048adc2cbfafbe745e10", "d938ad5cbe68bec494fbbf4463ad031d",
 "9bbd993d9da7df60b3fd4a4ed721b082", "a6ab62e9da89b20d720c70602624bfc2", "51037a4a37730f52c8732586d3aaa316",
 "7c4f29407893c334a6cb7a87bf045c0d", "3b7770f7743e8f01f0fd807f304a21d0", "29d233ae0b83eff6e5fbd67134b88717",
 "8d45c85b51b27a04ad7fdfc3f126f9f8", "9aa91f81de7610b371dd0e6fe4168b01", "9f27410725ab8cc8854a2769c7a516b8",
 "6ee6a213cb02554a63b1867143572e70", "918b81db5e91d031548b963c93845e5b", "3767b450824877f2b8f284f7a5625440",
 "81513effdf5790b79549208838404407", "7aea2552dfe7eb84b9443b6fc9ba6e01", "d8735f7489c94f42f508d7eb1c249584",
 "fde27e470207e146b29b8906826589cb", "2a2d595e6ed9a0b24f027f2b63b134d6", "99e0d947e01bbc0a507a1127dc2135b1",
 "6758fcdc0da017540d11889c22bb5a6e", "ab1991b4286f7e79720fe0d4011789c8", "28f9b1cae5ae23caa8471696342f6f0c",
 "f5b75010ea8a54b96f8fe7dafac65c18", "2570c919f5ef1d7091f0f66d54dac974", "ada15bd1a5ddf0b790ae1dcfd05a1e70",
 "eb88d7636980738cd0522ea69e212905", "83ab982dd08483187289a75163dc50fe", "8ac20bf5803e6067a65165d9df51a8e7",
 "7c4f29407893c334a6cb7a87bf045c0d", "67942503875c1ae74e4b5b80a0dade01", "d74fdde2944f475adc4a85e349d4ee7b",
 "163ccb6353c3b5f4f03cda0f1c5225ba", "6b1628b016dff46e6fa35684be6acc96", "de1b2a7baf7850243db71c4abd4e5a39",
 "5eda0ea98768e91b815fa6667e4f0178", "23ec24c5ca59000543cee1dfded0cbea", "ea9e801b0d806f2398bd0c7fe3f3f0cd",
 "35393c24384b8862798716628f7bc6f4", "28b26be59c986170c572133aaace31c2", "c2bfd01762cfbe4e34cc97b9769b4238",
 "22811dd94d65037ef86535740b98dec8", "acaa16770db76c1ffb9cee51c3cabfcf", "7516c3b35580b3490248629cff5e498c",
 "b04ab37e571600800864f7a311e2a386", "7e25b972e192b01004b62346ee9975a5", "2764ca9d34e90313978d044f27ae433b",
 "660cb6fe7437d4b40e4a04b706b93f70", "87a429872c7faee7e8bc9268d5bf548e", "31c13f47ad87dd7baa2d558a91e0fbb9",
 "e6ec529ba185279aa0adcf93e645c7cd", "21a361d96e3e13f5f109748c2a9d2434", "85814ce7d88361ec8eb8e07294043bc3",
 "a5fdad9de7faf3a0492812b9cb818d85", "0b8263d341de01f741e4deadfb18f9eb", "0cb47aeb6e5f9323f0969e628c4e59f5",
 "23a58bf9274bedb19375e527a0744fa9", "7e25b972e192b01004b62346ee9975a5", "b9d27d6b3d1915aacd5226b9d702bdbb",
 "6758fcdc0da017540d11889c22bb5a6e", "e2704f30f596dbe4e22d1d443b10e004", "da4f0053a5c13882268852ae2da2e466",
 "1562eb3f6d9c5ac7e159c04a96ff4dfe", "a94aa000f9a94cc51775bd5eac97c926", "1e4483e833025ac10e6184e75cb2d19d",
 "a957a3153eb7126b1c5f8b6aac35de53", "731b886d80d2ea138da54d30f43b2005", "a850c17cba5eb16b0d3d40a106333bd5",
 "7516c3b35580b3490248629cff5e498c", "d508fe45cecaf653904a0e774084bb5c", "18ccf61d533b600bbf5a963359223fe4",
 "f4d3b5a1116ded3facefb8353d0bd5ba", "28b26be59c986170c572133aaace31c2", "d5ca322453f2986b752e58b11af83d96",
 "37b19816109a32106d109e83bbb3c97d", "0423fa423baf1ea8139f6662869faf2f", "8ab8a4dfab57b4618331ffc958ebb4ec",
 "85814ce7d88361ec8eb8e07294043bc3", "273b9ae535de53399c86a9b83148a8ed", "4c9184f37cff01bcdc32dc486ec36961",
 "8ee2027983915ec78acc45027d874316", "1cba77c39b4d0a81024a7aada3655a28", "de1b2a7baf7850243db71c4abd4e5a39",
 "608f0b988db4a96066af7dd8870de96c", "06a224da9e61bee19ec9eef88b95f934", "df55340f75b5da454e1c189d56d7f31b",
 "8c728e685ddde9f7fbbc452155e29639", "2570c919f5ef1d7091f0f66d54dac974", "dce7c4174ce9323904a934a486c41288",
 "573ce5969e9884d49d4fab77b09a306a", "d5ca322453f2986b752e58b11af83d96", "eb88d7636980738cd0522ea69e212905",
 "e7e94d9ef1edaf2c6c55e9966b551295", "762f8817ab6af0971fe330dbf46a359a", "d8a48e3f0e1322d53d401e3dcb3360db",
 "c1940aeeb9693a02e28c52eb85ce261c", "d74fdde2944f475adc4a85e349d4ee7b", "b6a5d96a4e99b63723ab54ddb471baad",
 "6b157916b43b09df5a22f658ccb92b64", "bec670e5a55424d840db8636ecc28828", "4a6cbcd66d270792b89f50771604d093",
 "07202a7e6cbfbabe27abba87989f807e", "d60db28d94d538bbb249dcc7f2273ab1", "123402c04dcfb6625f688f771a5fc05d",
 "cd69b4957f06cd818d7bf3d61980e291", "be1ab1632e4285edc3733b142935c60b", "2bda2998d9b0ee197da142a0447f6725",
 "ba535ef5a9f7b8bc875812bb081286bb", "e9f40e1f1d1658681dad2dac4ae0971e", "eabe04e738cfb621f819e4e8f9489234",
 "aa2d6e4f578eb0cfaba23beef76c2194", "126ac4b07f93bc4f7bed426f5e978c16", "f43dff9a0dc54f0643d0c6d7971635f0",
 "ccaaac957ec37bde4c9993a26a064730", "2feaaf89c21770ea5c21196bc33848dd", "07cf4f8f5d8b76282917320715dda2ad",
 "1ffd9e753c8054cc61456ac7fac1ac89", "6050ce63e4bce6764cb34cac51fb44d1", "327a6c4304ad5938eaf0efb6cc3e53dc",
 "b82c91e2103d0a495c099f0a12f66363", "41d1de28e96dc1cde568d3b068fa17bb", "cad1c068cb62b0681fe4c33d1db1bad6",
 "de1b2a7baf7850243db71c4abd4e5a39", "75e52a0ecfafeda17a34fc60111c1f0b", "fc7e987f23de5bd6562b7c0063cad659",
 "126ac4b07f93bc4f7bed426f5e978c16", "fcc790c72a86190de1b549d0ddc6f55c", "72792fa10d4ca61295194377da0bcc05",
 "821f03288846297c2cf43c34766a38f7", "faec47e96bfb066b7c4b8c502dc3f649", "78b6367af86e03f19809449e2c365ff5",
 "015f28b9df1bdd36427dd976fb73b29d", "755f85c2723bb39381c7379a604160d8"];

document.write("<input type=\"text\" id=\"" + jfldid + "\" name=\"" + jfldid + "\" class=\"" + jfldcls + "\" size=\"" +  jfldsz + "\">");
document.write("<span class=\"image\"><img src=\"" + decodeURIComponent(imgdir) + imgid + ".jpg\" width=\"290\" height=\"80\" alt=\"\"><\/span>");
}

function jcap(){

var uword = hex_md5(document.getElementById(jfldid).value);

if (uword==cword[anum-1]) {
return true;
}

else {
popup('<h2>Fejl</h2><p>Du har tastet forkert i bekræftelsesfeltet, prøv venligst igen.</p>', false, 2000);
document.getElementById(jfldid).focus();
return false;
}
}

/*: Utilities */

function siteSearch() {
	var queryString = document.getElementById('query').value;

	location = "/search?search="+queryString;
}

function inquire() {
	var name = document.getElementById("name").value;
	var email = document.getElementById("email").value;
	var phone = document.getElementById("phone").value;
	var message = document.getElementById("message").value;

	alert("Name: "+name+", E-mail: "+email+", Phone: "+phone+"\nMessage: "+message);
}

function initTogglers() {
	if (!document.getElementsByTagName) return false;

	var togglers = document.getElementsByTagName("a");

	for (var i = 0; i < togglers.length; i++) {
		if (togglers[i].className.indexOf('toggler') > -1) {
			togglers[i].onclick = function() {
				toggle(this);
				this.blur();
			}
		}
	}
}addLoadEvent(function() { initTogglers(); });


function toggle(element) {
	var parent = element.parentNode;

	if (parent.className.indexOf('active') > -1) {
		parent.className = parent.className.replace(new RegExp("active\\b"), "");
		pageTracker._trackEvent('Kundeportal', 'Hide login-form');
	}
	else {
		parent.className += " active";
		document.getElementById("username").focus();
		pageTracker._trackEvent('Kundeportal', 'Show login-form');
	}
}


function remoteAssistance() {
	Portal = document.forms[0].Portal.value;
	Target = document.forms[0].Target.value;
	Template = document.forms[0].Template.value;
	JavaScript = document.forms[0].JavaScript.value;
	Form = document.forms[0].Form.value;
	Question = document.forms[0].Question.value;

	location = "https://broker.gotoassist.com/h/klestrup?Portal="+Portal+"&amp;Target="+Target+"&amp;Template="+Template+"&amp;JavaScript="+JavaScript+"&amp;Form="+Form+"&amp;Question="+Question;
}

function LoginPortal() {
	pageTracker._trackEvent('Kundeportal', 'Login');
    	document.forms[0].action = 'https://portal.klestrup-partners.dk/login.aspx';
	document.forms[0].method = 'post';
	document.forms[0].submit();
}