/*  Prototype JavaScript framework, version 1.4.0
 *  (c) 2005 Sam Stephenson <sam@conio.net>
 *
 *  Prototype is freely distributable under the terms of an MIT-style license.
 *  For details, see the Prototype web site: http://prototype.conio.net/
 *
/*--------------------------------------------------------------------------*/

//note: stripped down version of prototype, to be used with moo.fx by mad4milk (http://moofx.mad4milk.net).

var Class = {
	create: function() {
		return function() {
			this.initialize.apply(this, arguments);
		}
	}
};

Object.extend = function(destination, source) {
	for (var property in source) destination[property] = source[property];
	return destination;
};

Function.prototype.bind = function(object) {
	var __method = this;
	return function() {
		return __method.apply(object, arguments);
	}
};

if (!Array.prototype.forEach){
	Array.prototype.forEach = function(fn, bind){
		for(var i = 0; i < this.length ; i++) fn.call(bind, this[i], i);
	};
}

Array.prototype.each = Array.prototype.forEach;

String.prototype.camelize = function(){
	return this.replace(/-\D/gi, function(match){
		return match.charAt(match.length - 1).toUpperCase();
	});
};

var $A = function(iterable) {
	var nArray = [];
	for (var i = 0; i < iterable.length; i++) nArray.push(iterable[i]);
	return nArray;
};

function $() {
	if (arguments.length == 1) return get$(arguments[0]);
	var elements = [];
	$c(arguments).each(function(el){
		elements.push(get$(el));
	});
	return elements;

	function get$(el){
		if (typeof el == 'string') el = document.getElementById(el);
		return el;
	}
};

if (!window.Element) var Element = {};

Object.extend(Element, {

	remove: function(element) {
		element = $(element);
		element.parentNode.removeChild(element);
	},

	hasClassName: function(element, className) {
		element = $(element);
		return !!element.className.match(new RegExp("\\b"+className+"\\b"));
	},

	addClassName: function(element, className) {
		element = $(element);
		if (!Element.hasClassName(element, className)) element.className = (element.className+' '+className);
	},

	removeClassName: function(element, className) {
		element = $(element);
		if (Element.hasClassName(element, className)) element.className = element.className.replace(className, '');
	}

});

document.getElementsByClassName = function(className){
	var elements = [];
	var all = document.getElementsByTagName('*');
	$A(all).each(function(el){
		if (Element.hasClassName(el, className)) elements.push(el);
	});
	return elements;
};
//(c) 2006 Valerio Proietti (http://mad4milk.net). MIT-style license.
//moo.fx.js - depends on prototype.js OR prototype.lite.js
//version 2.0

// import prototype.lite.js

var Fx = fx = {};

Fx.Base = function(){};
Fx.Base.prototype = {

	setOptions: function(options){
		this.options = Object.extend({
			onStart: function(){},
			onComplete: function(){},
			transition: Fx.Transitions.sineInOut,
			duration: 500,
			unit: 'px',
			wait: true,
			fps: 50
		}, options || {});
	},

	step: function(){
		var time = new Date().getTime();
		if (time < this.time + this.options.duration){
			this.cTime = time - this.time;
			this.setNow();
		} else {
			setTimeout(this.options.onComplete.bind(this, this.element), 10);
			this.clearTimer();
			this.now = this.to;
		}
		this.increase();
	},

	setNow: function(){
		this.now = this.compute(this.from, this.to);
	},

	compute: function(from, to){
		var change = to - from;
		return this.options.transition(this.cTime, from, change, this.options.duration);
	},

	clearTimer: function(){
		clearInterval(this.timer);
		this.timer = null;
		return this;
	},

	_start: function(from, to){
		if (!this.options.wait) this.clearTimer();
		if (this.timer) return;
		setTimeout(this.options.onStart.bind(this, this.element), 10);
		this.from = from;
		this.to = to;
		this.time = new Date().getTime();
		this.timer = setInterval(this.step.bind(this), Math.round(1000/this.options.fps));
		return this;
	},

	custom: function(from, to){
		return this._start(from, to);
	},

	set: function(to){
		this.now = to;
		this.increase();
		return this;
	},

	hide: function(){
		return this.set(0);
	},

	setStyle: function(e, p, v){
		if (p == 'opacity'){
			if (v == 0 && e.style.visibility != "hidden") e.style.visibility = "hidden";
			else if (e.style.visibility != "visible") e.style.visibility = "visible";
			if (window.ActiveXObject) e.style.filter = "alpha(opacity=" + v*100 + ")";
			e.style.opacity = v;
		} else e.style[p] = v+this.options.unit;
	}

};

Fx.Style = Class.create();
Fx.Style.prototype = Object.extend(new Fx.Base(), {

	initialize: function(el, property, options){
		this.element = $(el);
		this.setOptions(options);
		this.property = property.camelize();
	},

	increase: function(){
		this.setStyle(this.element, this.property, this.now);
	}

});

Fx.Styles = Class.create();
Fx.Styles.prototype = Object.extend(new Fx.Base(), {

	initialize: function(el, options){
		this.element = $(el);
		this.setOptions(options);
		this.now = {};
	},

	setNow: function(){
		for (p in this.from) this.now[p] = this.compute(this.from[p], this.to[p]);
	},

	custom: function(obj){
		if (this.timer && this.options.wait) return;
		var from = {};
		var to = {};
		for (p in obj){
			from[p] = obj[p][0];
			to[p] = obj[p][1];
		}
		return this._start(from, to);
	},

	increase: function(){
		for (var p in this.now) this.setStyle(this.element, p, this.now[p]);
	}

});

//Transitions (c) 2003 Robert Penner (http://www.robertpenner.com/easing/), BSD License.

Fx.Transitions = {
	linear: function(t, b, c, d) { return c*t/d + b; },
	sineInOut: function(t, b, c, d) { return -c/2 * (Math.cos(Math.PI*t/d) - 1) + b; }
};
//by Valerio Proietti (http://mad4milk.net). MIT-style license.
//moo.fx.utils.js - depends on prototype.js OR prototype.lite.js + moo.fx.js
//version 2.0

// import moo.fx.js

Fx.Height = Class.create();
Fx.Height.prototype = Object.extend(new Fx.Base(), {

	initialize: function(el, options){
		this.element = $(el);
		this.setOptions(options);
		this.element.style.overflow = 'hidden';
	},

	toggle: function(){
		if (this.element.offsetHeight > 0) return this.custom(this.element.offsetHeight, 0);
		else return this.custom(0, this.element.scrollHeight);
	},

	show: function(){
		return this.set(this.element.scrollHeight);
	},

	increase: function(){
		this.setStyle(this.element, 'height', this.now);
	}

});

Fx.Width = Class.create();
Fx.Width.prototype = Object.extend(new Fx.Base(), {

	initialize: function(el, options){
		this.element = $(el);
		this.setOptions(options);
		this.element.style.overflow = 'hidden';
		this.iniWidth = this.element.offsetWidth;
	},

	toggle: function(){
		if (this.element.offsetWidth > 0) return this.custom(this.element.offsetWidth, 0);
		else return this.custom(0, this.iniWidth);
	},

	show: function(){
		return this.set(this.iniWidth);
	},

	increase: function(){
		this.setStyle(this.element, 'width', this.now);
	}

});

Fx.Opacity = Class.create();
Fx.Opacity.prototype = Object.extend(new Fx.Base(), {

	initialize: function(el, options){
		this.element = $(el);
		this.setOptions(options);
		this.now = 1;
	},

	toggle: function(){
		if (this.now > 0) return this.custom(1, 0);
		else return this.custom(0, 1);
	},

	show: function(){
		return this.set(1);
	},

	increase: function(){
		this.setStyle(this.element, 'opacity', this.now);
	}

});
//by Valerio Proietti (http://mad4milk.net). MIT-style license.
//moo.fx.pack.js - depends on prototype.js or prototype.lite.js + moo.fx.js
//version 2.0

// import moo.fx.js

Fx.Scroll = Class.create();
Fx.Scroll.prototype = Object.extend(new Fx.Base(), {

	initialize: function(el, options) {
		this.element = $(el);
		this.setOptions(options);
		this.element.style.overflow = 'hidden';
	},

	down: function(){
		return this.custom(this.element.scrollTop, this.element.scrollHeight-this.element.offsetHeight);
	},

	up: function(){
		return this.custom(this.element.scrollTop, 0);
	},

	increase: function(){
		this.element.scrollTop = this.now;
	}

});

//fx.Color, originally by Tom Jensen (http://neuemusic.com) MIT-style LICENSE.

Fx.Color = Class.create();
Fx.Color.prototype = Object.extend(new Fx.Base(), {

	initialize: function(el, property, options){
		this.element = $(el);
		this.setOptions(options);
		this.property = property.camelize();
		this.now = [];
	},

	custom: function(from, to){
		return this._start(from.hexToRgb(true), to.hexToRgb(true));
	},

	setNow: function(){
		[0,1,2].each(function(i){
			this.now[i] = Math.round(this.compute(this.from[i], this.to[i]));
		}.bind(this));
	},

	increase: function(){
		this.element.style[this.property] = "rgb("+this.now[0]+","+this.now[1]+","+this.now[2]+")";
	}

});

Object.extend(String.prototype, {

	rgbToHex: function(array){
		var rgb = this.match(new RegExp('([\\d]{1,3})', 'g'));
		if (rgb[3] == 0) return 'transparent';
		var hex = [];
		for (var i = 0; i < 3; i++){
			var bit = (rgb[i]-0).toString(16);
			hex.push(bit.length == 1 ? '0'+bit : bit);
		}
		var hexText = '#'+hex.join('');
		if (array) return hex;
		else return hexText;
	},

	hexToRgb: function(array){
		var hex = this.match(new RegExp('^[#]{0,1}([\\w]{1,2})([\\w]{1,2})([\\w]{1,2})$'));
		var rgb = [];
		for (var i = 1; i < hex.length; i++){
			if (hex[i].length == 1) hex[i] += hex[i];
			rgb.push(parseInt(hex[i], 16));
		}
		var rgbText = 'rgb('+rgb.join(',')+')';
		if (array) return rgb;
		else return rgbText;
	}

});
/*
	Lightbox JS: Fullsize Image Overlays by Lokesh Dhakar - http://www.huddletogether.com
	For more information on this script, visit: http://huddletogether.com/projects/lightbox/
	Licensed under the Creative Commons Attribution 2.5 License - http://creativecommons.org/licenses/by/2.5/
	(basically, do anything you want, just leave my name and link)
*/

// If you would like to use a custom loading image or close button reference them in the next two lines.
var loadingImage = '/wiki/nn/img/progress.gif';
var closeButton  = '/wiki/nn/img/lightbox-close.gif';

// getPageScroll()
// Returns array with x,y page scroll values.
// Core code from - quirksmode.org
function getPageScroll(){
	var yScroll;
	if (self.pageYOffset) {
		yScroll = self.pageYOffset;
	} else if (document.documentElement && document.documentElement.scrollTop){	 // Explorer 6 Strict
		yScroll = document.documentElement.scrollTop;
	} else if (document.body) {// all other Explorers
		yScroll = document.body.scrollTop;
	}
	arrayPageScroll = new Array('',yScroll)
	return arrayPageScroll;
}

// getPageSize()
// Returns array with page width, height and window width, height
// Core code from - quirksmode.org
// Edit for Firefox by pHaez
function getPageSize(){
	var xScroll, yScroll;
	if (window.innerHeight && window.scrollMaxY) {
		xScroll = document.body.scrollWidth;
		yScroll = window.innerHeight + window.scrollMaxY;
	} else if (document.body.scrollHeight > document.body.offsetHeight){ // all but Explorer Mac
		xScroll = document.body.scrollWidth;
		yScroll = document.body.scrollHeight;
	} else { // Explorer Mac...would also work in Explorer 6 Strict, Mozilla and Safari
		xScroll = document.body.offsetWidth;
		yScroll = document.body.offsetHeight;
	}
	var windowWidth, windowHeight;
	if (self.innerHeight) {	// all except Explorer
		windowWidth = self.innerWidth;
		windowHeight = self.innerHeight;
	} else if (document.documentElement && document.documentElement.clientHeight) { // Explorer 6 Strict Mode
		windowWidth = document.documentElement.clientWidth;
		windowHeight = document.documentElement.clientHeight;
	} else if (document.body) { // other Explorers
		windowWidth = document.body.clientWidth;
		windowHeight = document.body.clientHeight;
	}
	// for small pages with total height less then height of the viewport
	if(yScroll < windowHeight){
		pageHeight = windowHeight;
	} else {
		pageHeight = yScroll;
	}
	// for small pages with total width less then width of the viewport
	if(xScroll < windowWidth){
		pageWidth = windowWidth;
	} else {
		pageWidth = xScroll;
	}
	arrayPageSize = new Array(pageWidth,pageHeight,windowWidth,windowHeight)
	return arrayPageSize;
}

// pause(numberMillis)
// Pauses code execution for specified time. Uses busy code, not good.
// Code from http://www.faqts.com/knowledge_base/view.phtml/aid/1602
function pause(numberMillis) {
	var now = new Date();
	var exitTime = now.getTime() + numberMillis;
	while (true) {
		now = new Date();
		if (now.getTime() > exitTime)
			return;
	}
}

// getKey(key)
// Gets keycode. If 'x' is pressed then it hides the lightbox.
function getKey(e){
	if (e == null) { // ie
		keycode = event.keyCode;
	} else { // mozilla
		keycode = e.which;
	}
	key = String.fromCharCode(keycode).toLowerCase();
	if(key == 'x'){ hideLightbox(); }
}

// listenKey()
function listenKey () {	document.onkeypress = getKey; }

// showLightbox()
// Preloads images. Pleaces new image in lightbox then centers and displays.
function showLightbox(objLink)
{
	var objOverlay = document.getElementById('overlay');
	var objLightbox = document.getElementById('lightbox');
	var objCaption = document.getElementById('lightboxCaption');
	var objImage = document.getElementById('lightboxImage');
	var objLoadingImage = document.getElementById('loadingImage');
	var objLightboxDetails = document.getElementById('lightboxDetails');
	var arrayPageSize = getPageSize();
	var arrayPageScroll = getPageScroll();
	if (objLoadingImage) {
		objLoadingImage.style.top = (arrayPageScroll[1] + ((arrayPageSize[3] - 35 - objLoadingImage.height) / 2) + 'px');
		objLoadingImage.style.left = (((arrayPageSize[0] - 20 - objLoadingImage.width) / 2) + 'px');
		objLoadingImage.style.display = 'block';
	}
	objOverlay.style.height = (arrayPageSize[1] + 'px');
	objOverlay.style.display = 'block';
	imgPreload = new Image();
	imgPreload.onload=function(){
		objImage.src = objLink.href;
		var lightboxTop = arrayPageScroll[1] + ((arrayPageSize[3] - 35 - imgPreload.height) / 2);
		var lightboxLeft = ((arrayPageSize[0] - 20 - imgPreload.width) / 2);
		objLightbox.style.top = (lightboxTop < 0) ? "0px" : lightboxTop + "px";
		objLightbox.style.left = (lightboxLeft < 0) ? "0px" : lightboxLeft + "px";
		objLightboxDetails.style.width = imgPreload.width + 'px';
		if(objLink.getAttribute('title')){
			objCaption.style.display = 'block';
			//objCaption.style.width = imgPreload.width + 'px';
			objCaption.innerHTML = objLink.getAttribute('title');
		} else {
			objCaption.style.display = 'none';
		}
		if (navigator.appVersion.indexOf("MSIE")!=-1){
			pause(250);
		}
		if (objLoadingImage) {	objLoadingImage.style.display = 'none'; }
		selects = document.getElementsByTagName("select");
		for (i = 0; i != selects.length; i++) {
			selects[i].style.visibility = "hidden";
		}
		objLightbox.style.display = 'block';
		arrayPageSize = getPageSize();
		objOverlay.style.height = (arrayPageSize[1] + 'px');
		listenKey();
		return false;
	}
	imgPreload.src = objLink.href;
}

// hideLightbox()
function hideLightbox()
{
	objOverlay = document.getElementById('overlay');
	objLightbox = document.getElementById('lightbox');
	objOverlay.style.display = 'none';
	objLightbox.style.display = 'none';
	selects = document.getElementsByTagName("select");
		for (i = 0; i != selects.length; i++) {
		selects[i].style.visibility = "visible";
	}
	document.onkeypress = '';
}

// initLightbox()
// Function runs on window load, going through link tags looking for rel="lightbox".
// These links receive onclick events that enable the lightbox display for their targets.
// The function also inserts html markup at the top of the page which will be used as a
// container for the overlay pattern and the inline image.
function initLightbox()
{
	if (!document.getElementsByTagName){ return; }
	var anchors = document.getElementsByTagName("a");
	// loop through all anchor tags
	for (var i=0; i<anchors.length; i++) {
		var anchor = anchors[i];
		var href = anchor.getAttribute("href");
		if (!href) continue;
		if ((anchor.className.indexOf("lightbox") != -1) ||
				((anchor.className.indexOf("image-reference") != -1) &&
					href.match(/\.(png|jpg|jpeg|gif)$/i))) {
			anchor.onclick = function () { showLightbox(this); return false; }
		}
	}

	// the rest of this code inserts html at the top of the page that looks like this:
	//
	// <div id="overlay">
	//		<a href="#" onclick="hideLightbox(); return false;"><img id="loadingImage" /></a>
	//	</div>
	// <div id="lightbox">
	//		<a href="#" onclick="hideLightbox(); return false;" title="Click anywhere to close image">
	//			<img id="closeButton" />
	//			<img id="lightboxImage" />
	//		</a>
	//		<div id="lightboxDetails">
	//			<div id="lightboxCaption"></div>
	//			<div id="keyboardMsg"></div>
	//		</div>
	// </div>
	var objBody = document.getElementsByTagName("body").item(0);
	var objOverlay = document.createElement("div");
	objOverlay.setAttribute('id','overlay');
	objOverlay.onclick = function () {hideLightbox(); return false;}
	objOverlay.style.display = 'none';
	objOverlay.style.position = 'absolute';
	objOverlay.style.top = '0';
	objOverlay.style.left = '0';
	objOverlay.style.zIndex = '90';
	objOverlay.style.width = '100%';
	objBody.insertBefore(objOverlay, objBody.firstChild);
	var arrayPageSize = getPageSize();
	var arrayPageScroll = getPageScroll();
	var imgPreloader = new Image();
	imgPreloader.onload=function(){
		var objLoadingImageLink = document.createElement("a");
		objLoadingImageLink.setAttribute('href','#');
		objLoadingImageLink.onclick = function () {hideLightbox(); return false;}
		objOverlay.appendChild(objLoadingImageLink);
		var objLoadingImage = document.createElement("img");
		objLoadingImage.src = loadingImage;
		objLoadingImage.setAttribute('id','loadingImage');
		objLoadingImage.style.position = 'absolute';
		objLoadingImage.style.zIndex = '150';
		objLoadingImageLink.appendChild(objLoadingImage);
		imgPreloader.onload=function(){};	//	clear onLoad, as IE will flip out w/animated gifs
		return false;
	}
	imgPreloader.src = loadingImage;
	var objLightbox = document.createElement("div");
	objLightbox.setAttribute('id','lightbox');
	objLightbox.style.display = 'none';
	objLightbox.style.position = 'absolute';
	objLightbox.style.zIndex = '100';
	objBody.insertBefore(objLightbox, objOverlay.nextSibling);
	var objLink = document.createElement("a");
	objLink.setAttribute('href','#');
	objLink.setAttribute('title','Click to close');
	objLink.onclick = function () {hideLightbox(); return false;}
	objLightbox.appendChild(objLink);
	var imgPreloadCloseButton = new Image();
	imgPreloadCloseButton.onload=function(){
		var objCloseButton = document.createElement("img");
		objCloseButton.src = closeButton;
		objCloseButton.setAttribute('id','closeButton');
		objCloseButton.style.position = 'absolute';
		objCloseButton.style.zIndex = '200';
		objLink.appendChild(objCloseButton);
		return false;
	}
	imgPreloadCloseButton.src = closeButton;
	var objImage = document.createElement("img");
	objImage.setAttribute('id','lightboxImage');
	objLink.appendChild(objImage);
	var objLightboxDetails = document.createElement("div");
	objLightboxDetails.setAttribute('id','lightboxDetails');
	objLightbox.appendChild(objLightboxDetails);
	var objCaption = document.createElement("div");
	objCaption.setAttribute('id','lightboxCaption');
	objCaption.style.display = 'none';
	objLightboxDetails.appendChild(objCaption);
	var objKeyboardMsg = document.createElement("div");
	objKeyboardMsg.setAttribute('id','keyboardMsg');
	objKeyboardMsg.innerHTML = 'press <a href="#" onclick="hideLightbox(); return false;"><kbd>x</kbd></a> to close';
	objLightboxDetails.appendChild(objKeyboardMsg);
}

// addLoadEvent()
// Adds event to window.onload without overwriting currently assigned onload functions.
// Function found at Simon Willison's weblog - http://simon.incutio.com/
function addLoadEvent(func)
{
	var oldonload = window.onload;
	if (typeof window.onload != 'function'){
    	window.onload = func;
	} else {
		window.onload = function(){
		oldonload();
		func();
		}
	}
}

//addLoadEvent(initLightbox);	// run initLightbox onLoad
// import prototype.lite.js
/*
 * site.js
 * Copyright (C) 2008 Adrián Pérez <acastro@connectical.com>
 *
 * Distributed under terms of the MIT license.
 */

if (typeof FancySearch == "undefined") FancySearch = {};


Element.ComputedStyle = function (elt, item)
{
	if (elt.currentStyle)
		return elt.currentStyle[item];
	if (document.defaultView && document.defaultView.getComputedStyle)
		return document.defaultView.getComputedStyle(elt, null).getPropertyValue(item);
	return null;
}


FancySearch.GetLabelText = function ()
{
	var searchform = $('quick-search');
	if (searchform) {
		var labels = searchform.getElementsByTagName('label');

		if (labels) {
			var labelFor = labels[0].getAttribute('for');
			var labelText = labels[0].firstChild.nodeValue;
		}
		else {
			var labelText = 'Search:';
		}
	}
	else {
		var labelText = 'Search';
	}
	return labelText;
}


FancySearch._HandleChange = function (fieldId, buttonId, spinner)
{
	var button = $(buttonId);
	var field  = $(fieldId);

	if ((field.value.length > 0) && (field.value != labelText) && !this.clearButton) {
		button._fieldId = fieldId;
		button.style.display = 'block';
		this.clearButton = true;
	}
	else if ((field.value.length == 0) && this.clearButton) {
		Element.removeClassName(button, 'spinner');
		button.style.display = 'none';
		this.clearButton = false;
		if (!field._focused) {
			field.value = labelText;
			field.style.color = labelColor;
		}
	}
	if (spinner) {
		Element.addClassName(button, 'spinner');
	}
}


FancySearch._HandleClear = function ()
{
	var field = $(this._fieldId);
	field.value = '';
	FancySearch._HandleChange(this._fieldId, this.id);
	field.focus();
}


FancySearch.Init = function ()
{
	var searchform  = $('quick-search');
	var searchinput = $('q');

	if (!searchform || !searchinput) return;

	labelText = FancySearch.GetLabelText();

	if (navigator.userAgent.toLowerCase().indexOf('safari') < 0 /*||
			navigator.userAgent.toLowerCase().indexOf('macos') < 0*/) {
		this.clearButton = false;
		Element.addClassName(searchinput, 'fancysearch');

		var rcorner = document.createElement('span');
		var lcorner = document.createElement('span');
		rcorner.className = 'search-r';
		lcorner.className = 'search-l';

		var cbutton = document.createElement('div');
		cbutton.id = 'search-clearbutton';
		cbutton.className = 'clearbutton';
		rcorner.appendChild(cbutton);
		nnAddEvent(cbutton, 'click', FancySearch._HandleClear);

		var fieldset = searchform.getElementsByTagName('fieldset')[0];
		fieldset.insertBefore(lcorner, searchinput);
		fieldset.appendChild(rcorner);

		/* Keeps Opera happy */
		var divclear = document.createElement('div');
		Element.addClassName(divclear, 'clear');
		searchform.appendChild(divclear);

		var labels = searchform.getElementsByTagName('label');
		if (labels) {
			labelColor = Element.ComputedStyle(labels[0], 'color');
			inputColor = Element.ComputedStyle(searchinput, 'color');
		}

		searchinput._focused = false;
		searchinput.value = labelText;
		searchinput.style.color = labelColor;
		nnAddEvent(searchinput, 'keyup', function () {
				FancySearch._HandleChange('q', 'search-clearbutton');
		});
		nnAddEvent(searchinput, 'focus', function () {
				if (this.value == labelText) {
					this.value = '';
					this.style.color = inputColor;
					searchinput._focused = true;
				}
		});
		nnAddEvent(searchinput, 'blur', function () {
				if (this.value == '') {
					this.value = labelText;
					this.style.color = labelColor;
					searchinput._focused = false;
				}
		});
		nnAddEvent(searchform, 'submit', function () {
				return (searchinput && searchinput.value != labelText);
		});
	}
	else {
		searchinput.type = 'search';
		searchinput.setAttribute('placeholder', labelText);
		searchinput.setAttribute('autosave', 'NN_FSearch');
		searchinput.setAttribute('results', '5');
	}
}


/*
 * Sortable Table 1.12 -- For WebFX (http://webfx.eae.net/)
 * Copyright (c) 1998 - 2004 Erik Arvidsson
 *
 * Distributed under terms of the GNU General Public License
 * (http://www.gnu.org/licenses/gpl.txt)
 */

function SortableTable(oTable, oSortTypes)
{
	this.sortTypes = oSortTypes || [];

	this.sortColumn = null;
	this.descending = null;

	var oThis = this;
	this._headerOnclick = function (e) {
		oThis.headerOnclick(e);
	};

	if (oTable) {
		this.setTable( oTable );
		this.document = oTable.ownerDocument || oTable.document;
	}
	else {
		this.document = document;
	}


	// only IE needs this
	var win = this.document.defaultView || this.document.parentWindow;
	this._onunload = function () {
		oThis.destroy();
	};
	if (win && typeof win.attachEvent != "undefined") {
		win.attachEvent("onunload", this._onunload);
	}
}

SortableTable.gecko = navigator.product == "Gecko";
SortableTable.msie = /msie/i.test(navigator.userAgent);
// Mozilla is faster when doing the DOM manipulations on
// an orphaned element. MSIE is not
SortableTable.removeBeforeSort = SortableTable.gecko;

SortableTable.prototype.onsort = function () {};

// default sort order. true -> descending, false -> ascending
SortableTable.prototype.defaultDescending = false;

// shared between all instances. This is intentional to allow external files
// to modify the prototype
SortableTable.prototype._sortTypeInfo = {};

SortableTable.prototype.setTable = function (oTable) {
	if ( this.tHead )
		this.uninitHeader();
	this.element = oTable;
	this.setTHead( oTable.tHead );
	this.setTBody( oTable.tBodies[0] );
};

SortableTable.prototype.setTHead = function (oTHead) {
	if (this.tHead && this.tHead != oTHead )
		this.uninitHeader();
	this.tHead = oTHead;
	this.initHeader( this.sortTypes );
};

SortableTable.prototype.setTBody = function (oTBody) {
	this.tBody = oTBody;
};

SortableTable.prototype.setSortTypes = function ( oSortTypes ) {
	if ( this.tHead )
		this.uninitHeader();
	this.sortTypes = oSortTypes || [];
	if ( this.tHead )
		this.initHeader( this.sortTypes );
};

// adds arrow containers and events
// also binds sort type to the header cells so that reordering columns does
// not break the sort types
SortableTable.prototype.initHeader = function (oSortTypes) {
	if (!this.tHead) return;
	var cells = this.tHead.rows[0].cells;
	var doc = this.tHead.ownerDocument || this.tHead.document;
	this.sortTypes = oSortTypes || [];
	var l = cells.length;
	var c;
	for (var i = 0; i < l; i++) {
		c = cells[i];
		if (this.sortTypes[i] != null && this.sortTypes[i] != "None") {
			if (this.sortTypes[i] != null)
				c._sortType = this.sortTypes[i];
			if (typeof c.addEventListener != "undefined")
				c.addEventListener("click", this._headerOnclick, false);
			else if (typeof c.attachEvent != "undefined")
				c.attachEvent("onclick", this._headerOnclick);
			else
				c.onclick = this._headerOnclick;
		}
		else
		{
			c.setAttribute( "_sortType", oSortTypes[i] );
			c._sortType = "None";
		}
	}
	this.updateHeaderArrows();
};

// remove arrows and events
SortableTable.prototype.uninitHeader = function () {
	if (!this.tHead) return;
	var cells = this.tHead.rows[0].cells;
	var l = cells.length;
	var c;
	for (var i = 0; i < l; i++) {
		c = cells[i];
		if (c._sortType != null && c._sortType != "None") {
			c.removeChild(c.lastChild);
			if (typeof c.removeEventListener != "undefined")
				c.removeEventListener("click", this._headerOnclick, false);
			else if (typeof c.detachEvent != "undefined")
				c.detachEvent("onclick", this._headerOnclick);
			c._sortType = null;
			c.removeAttribute( "_sortType" );
		}
	}
};

SortableTable.prototype.updateHeaderArrows = function () {
	if (!this.tHead) return;
	var cells = this.tHead.rows[0].cells;
	var l = cells.length;
	for (var i = 0; i < l; i++) {
		if (cells[i]._sortType != null && cells[i]._sortType != "None") {
			if (i == this.sortColumn)
				cells[i].className = "sort-arrow " + (this.descending ? "descending" : "ascending");
			else
				cells[i].className = "sort-arrow";
		}
	}
};

SortableTable.prototype.headerOnclick = function (e) {
	// find TD *or* TH element
	var el = e.target || e.srcElement;
	while ((el.tagName != "TD") && (el.tagName != "TH"))
		el = el.parentNode;

	this.sort(SortableTable.msie ? SortableTable.getCellIndex(el) : el.cellIndex);
};

// IE returns wrong cellIndex when columns are hidden
SortableTable.getCellIndex = function (oTd) {
	var cells = oTd.parentNode.childNodes
	var l = cells.length;
	var i;
	for (i = 0; cells[i] != oTd && i < l; i++)
		;
	return i;
};

SortableTable.prototype.getSortType = function (nColumn) {
	return this.sortTypes[nColumn] || "String";
};

// only nColumn is required
// if bDescending is left out the old value is taken into account
// if sSortType is left out the sort type is found from the sortTypes array

SortableTable.prototype.sort = function (nColumn, bDescending, sSortType) {
	if (!this.tBody) return;
	if (sSortType == null)
		sSortType = this.getSortType(nColumn);

	// exit if None
	if (sSortType == "None")
		return;

	if (bDescending == null) {
		if (this.sortColumn != nColumn)
			this.descending = this.defaultDescending;
		else
			this.descending = !this.descending;
	}
	else
		this.descending = bDescending;

	this.sortColumn = nColumn;

	if (typeof this.onbeforesort == "function")
		this.onbeforesort();

	var f = this.getSortFunction(sSortType, nColumn);
	var a = this.getCache(sSortType, nColumn);
	var tBody = this.tBody;

	a.sort(f);

	if (this.descending)
		a.reverse();

	if (SortableTable.removeBeforeSort) {
		// remove from doc
		var nextSibling = tBody.nextSibling;
		var p = tBody.parentNode;
		p.removeChild(tBody);
	}

	// insert in the new order
	var l = a.length;
	for (var i = 0; i < l; i++)
		tBody.appendChild(a[i].element);

	if (SortableTable.removeBeforeSort) {
		// insert into doc
		p.insertBefore(tBody, nextSibling);
	}

	this.updateHeaderArrows();

	this.destroyCache(a);

	if (typeof this.onsort == "function")
		this.onsort();
};

SortableTable.prototype.asyncSort = function (nColumn, bDescending, sSortType) {
	var oThis = this;
	this._asyncsort = function () {
		oThis.sort(nColumn, bDescending, sSortType);
	};
	window.setTimeout(this._asyncsort, 1);
};

SortableTable.prototype.getCache = function (sType, nColumn) {
	if (!this.tBody) return [];
	var rows = this.tBody.rows;
	var l = rows.length;
	var a = new Array(l);
	var r;
	for (var i = 0; i < l; i++) {
		r = rows[i];
		a[i] = {
			value:		this.getRowValue(r, sType, nColumn),
			element:	r
		};
	};
	return a;
};

SortableTable.prototype.destroyCache = function (oArray) {
	var l = oArray.length;
	for (var i = 0; i < l; i++) {
		oArray[i].value = null;
		oArray[i].element = null;
		oArray[i] = null;
	}
};

SortableTable.prototype.getRowValue = function (oRow, sType, nColumn) {
	// if we have defined a custom getRowValue use that
	if (this._sortTypeInfo[sType] && this._sortTypeInfo[sType].getRowValue)
		return this._sortTypeInfo[sType].getRowValue(oRow, nColumn);

	var s;
	var c = oRow.cells[nColumn];
	if (typeof c.innerText != "undefined")
		s = c.innerText;
	else
		s = SortableTable.getInnerText(c);
	return this.getValueFromString(s, sType);
};

SortableTable.getInnerText = function (oNode) {
	var s = "";
	var cs = oNode.childNodes;
	var l = cs.length;
	for (var i = 0; i < l; i++) {
		switch (cs[i].nodeType) {
			case 1: //ELEMENT_NODE
				s += SortableTable.getInnerText(cs[i]);
				break;
			case 3:	//TEXT_NODE
				s += cs[i].nodeValue;
				break;
		}
	}
	return s;
};

SortableTable.prototype.getValueFromString = function (sText, sType) {
	if (this._sortTypeInfo[sType])
		return this._sortTypeInfo[sType].getValueFromString( sText );
	return sText;
	/*
	switch (sType) {
		case "Number":
			return Number(sText);
		case "CaseInsensitiveString":
			return sText.toUpperCase();
		case "Date":
			var parts = sText.split("-");
			var d = new Date(0);
			d.setFullYear(parts[0]);
			d.setDate(parts[2]);
			d.setMonth(parts[1] - 1);
			return d.valueOf();
	}
	return sText;
	*/
	};

SortableTable.prototype.getSortFunction = function (sType, nColumn) {
	if (this._sortTypeInfo[sType])
		return this._sortTypeInfo[sType].compare;
	return SortableTable.basicCompare;
};

SortableTable.prototype.destroy = function () {
	this.uninitHeader();
	var win = this.document.parentWindow;
	if (win && typeof win.detachEvent != "undefined") {	// only IE needs this
		win.detachEvent("onunload", this._onunload);
	}
	this._onunload = null;
	this.element = null;
	this.tHead = null;
	this.tBody = null;
	this.document = null;
	this._headerOnclick = null;
	this.sortTypes = null;
	this._asyncsort = null;
	this.onsort = null;
};

// Adds a sort type to all instance of SortableTable
// sType : String - the identifier of the sort type
// fGetValueFromString : function ( s : string ) : T - A function that takes a
//    string and casts it to a desired format. If left out the string is just
//    returned
// fCompareFunction : function ( n1 : T, n2 : T ) : Number - A normal JS sort
//    compare function. Takes two values and compares them. If left out less than,
//    <, compare is used
// fGetRowValue : function( oRow : HTMLTRElement, nColumn : int ) : T - A function
//    that takes the row and the column index and returns the value used to compare.
//    If left out then the innerText is first taken for the cell and then the
//    fGetValueFromString is used to convert that string the desired value and type

SortableTable.prototype.addSortType = function (sType, fGetValueFromString, fCompareFunction, fGetRowValue) {
	this._sortTypeInfo[sType] = {
		type:				sType,
		getValueFromString:	fGetValueFromString || SortableTable.idFunction,
		compare:			fCompareFunction || SortableTable.basicCompare,
		getRowValue:		fGetRowValue
	};
};

// this removes the sort type from all instances of SortableTable
SortableTable.prototype.removeSortType = function (sType) {
	delete this._sortTypeInfo[sType];
};

SortableTable.basicCompare = function compare(n1, n2) {
	if (n1.value < n2.value)
		return -1;
	if (n2.value < n1.value)
		return 1;
	return 0;
};

SortableTable.idFunction = function (x) {
	return x;
};

SortableTable.toUpperCase = function (s) {
	return s.toUpperCase();
};

SortableTable.toDate = function (s) {
	var parts = s.split("-");
	var d = new Date(0);
	d.setFullYear(parts[0]);
	d.setDate(parts[2]);
	d.setMonth(parts[1] - 1);
	return d.valueOf();
};


// add sort types
SortableTable.prototype.addSortType("Number", Number);
SortableTable.prototype.addSortType("CaseInsensitiveString", SortableTable.toUpperCase);
SortableTable.prototype.addSortType("Date", SortableTable.toDate);
SortableTable.prototype.addSortType("String");
// None is a special case
/*
 * nn.js -- Site JavaScript for http://connectical.com
 *
 * Copyright © 2008 Adrian Perez <acastro at connectical.com>
 * Copyright © 2007 Adrian Perez <acastro at connectical.com>
 *
 * Distributed under terms of the MIT license.
 */

// import sortabletable.js
// import search.js
// import lightbox.js
// import prototype.lite.js
// import moo.fx.pack.js
// import moo.fx.utils.js

var nnUsingIE = (navigator.appVersion.indexOf("MSIE") != -1);


/*
 * Cookie functions. Blindy stolen from
 * http://www.quirksmode.org/js/cookies.html
 */
function nnSetCookie(name, value, days)
{
	if (days) {
		var d = new Date();
		d.setTime(d.getTime() + (days * 24 * 60 * 60 * 1000));
		var expires = "; expires=" + d.toGMTString();
	}
	else var expires = "";
	document.cookie = name + "=" + value + expires + "; path=/";
}


function nnGetCookie(name)
{
	var nameEq = name + "=";
	var ca = document.cookie.split(";");
	for (var i = 0; i < ca.length; i++) {
		var c = ca[i];
		while (c.charAt(0) == ' ') c = c.substring(1, c.length);
		if (c.indexOf(nameEq) == 0)
			return c.substring(nameEq.length, c.length);
	}
	return null;
}


function nnDelCookie(name) {
	nnSetCookie(name, "", -1);
}


function nnSetLanguage(language) {
	if (language != null)
		nnSetCookie("MMPP_LANGUAGE", language);
	else
		nnDelCookie("MMPP_LANGUAGE");
	window.location.reload();
}


function nnManipulateChildren(element, condition, manipulate)
{
	if (condition == null) condition = function () { return true };
	for (var e = element.firstChild; e != null; e = e.nextSibling)
		if (condition(e)) manipulate(e);
}


function nnFindChild(element, condition)
{
	for (var e = element.firstChild; e != null; e = e.nextSibling)
		if (condition(e)) return e;
	return null;
}


function nnAddEvent(element, eventType, lamdaFunction)
{
  if (element.addEventListener) {
    element.addEventListener(eventType, lamdaFunction, false);
    return true;
  } else if (element.attachEvent) {
    return element.attachEvent('on' + eventType, lamdaFunction);
  } else {
    return false;
  }
}


function nnFixMoinSidemenu()
{
	if (!document.getElementById) return;
	var menu = $('menu-side');
	var cont = $('content');

	if (cont && (cont.scrollHeight < 300))
		cont.style.height = '300px';

	if (menu) {
		if (cont.scrollHeight < menu.scrollHeight)
			cont.style.height = menu.scrollHeight + 'px';
	}
	else {
		var p = $('page');
		if (p) p.style.marginLeft = '0';
	}
}



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

	var elem = document.getElementsByTagName('img');
	for (var i = 0; i < elem.length; i++) {
		if (!elem[i].getAttribute || !elem[i].setAttribute);
			continue;

		var tit = elem[i].getAttribute('title');
		var alt = elem[i].getAttribute('alt');
		if (alt && (!tit || tit == "")) elem[i].setAttribute('title', alt);
	}
}


function nnColorizeTableRows(elem, color) {
	if (!elem.getElementsByTagName) return;
	if (color == null) color = "#f2f2fa";
	var rows = elem.getElementsByTagName("tr");
	for (var i = 1; i < rows.length; i++)
		rows[i].style.background = (i % 2 == 0) ? color : '';
}



function nnMakeTableAdditions()
{
	if (!document.getElementsByTagName || typeof SortableTable == "undefined")
		return;

	var elem = document.getElementsByTagName('table');
	for (var i = 0; i < elem.length; i++) {
		if (Element.hasClassName(elem[i], "sort-table")) {
			// FIXME This sorts columns only by string value!
			var cols = [];
			for (var j = 0; j < elem[i].getElementsByTagName("col").length; j++)
				cols[j] = "CaseInsensitiveString";

			if (Element.hasClassName(elem[i], "directory-listing"))
				cols[0] = null;

			var table = new SortableTable(elem[i], cols);
			if (Element.hasClassName(elem[i], "colorize-rows") || cols[0] == null)
				table.onsort = function () { nnColorizeTableRows(this.element) };

			table.sort((cols[0] == null) ? 1 : 0);
		}
		else if (element.hasClassName(elem[i], "colorize-rows")) {
			nnColorizeTableRows(elem[i]);
		}
	}
}


function nnTag(tagName) {
	return function (e) { return e.tagName == tagName };
}


function nnSidebarEffect(level)
{
	return function (element) {
		var fgFx = new Fx.Color(element, "color", {
			duration: 300,
			wait    : false
		});
		var bgFx = new Fx.Color(element, "background-color", {
			duration: 300,
			wait    : false
		});

		var fgColorA = "#888";
		var fgColorB = "#eee";
		var bgColorA = "#555";
		var bgColorB = "#888";

		if (level > 0) {
			bgColorA = "5e5e5e";
			bgColorB = "8a8a8a";
		}

		nnAddEvent(element, "mouseover", function () {
			fgFx.custom(fgColorA, fgColorB);
			bgFx.custom(bgColorA, bgColorB);
		});
		nnAddEvent(element, "mouseout", function () {
			fgFx.custom(fgColorB, fgColorA);
			bgFx.custom(bgColorB, bgColorA);
		});
	};
}


function nnWireSidebarEffects()
{
	var element = $((arguments.length > 0) ? arguments[0] : "menu-side");
	if (!element) return;

	nnManipulateChildren(element, nnTag("UL"), function (ulist) {
		nnManipulateChildren(ulist, nnTag("LI"), function (litem) {
			nnManipulateChildren(litem, nnTag("A"), nnSidebarEffect(0))

			nnManipulateChildren(litem, nnTag("UL"), function (ulist) {
				nnManipulateChildren(ulist, nnTag("LI"), function (litem) {
					nnManipulateChildren(litem, nnTag("A"), nnSidebarEffect(1));
				});
			});
		});
	});
}


function nnWireRestTocEffect()
{
	if (!document.getElementsByClassName) return;

	var elem = document.getElementsByClassName("contents");
	for (var i = 0; i < elem.length; i++) {
		var listIndex = nnFindChild(elem[i], nnTag("UL"));
		var titlePara = nnFindChild(elem[i], nnTag("P"));
		if (!titlePara || !listIndex) continue; // Something is missing!
		var fx = new Fx.Height(listIndex, { wait: false, duration: 1000 });
		nnAddEvent(titlePara, "click", function () { fx.toggle(); });
	}
}


var nnClipoHTML =
	'It looks like you are trying to <span class="strike">write a letter' +
	'</span> surf the net. If you want me to, I could help you <a href=' +
	'"http://mozilla.com">choose a web browser...</a>';

function nnCreateAnnoyingClip() {
	// We definitely need those!
	if (!nnUsingIE || !document.createElement) return;

	var whole = $("wholepage");
	if (!whole) return;

	var div = document.createElement("div");
	div.id = "clipo"; // We need this so CSS rules get applied.
	div.innerHTML = nnClipoHTML;
	whole.insertBefore(div, whole.firstChild);
}


function nnMarkCurrent(element)
{
	if (!element) return;
	element = $(element);
	if (!element) return;

	var e = element.getElementsByTagName('a');
	var h = window.location.protocol + '//' + window.location.host + '/';
	var l = window.location + ''; // Convert to string.
	for (var i = 0; i < e.length; i++) {
		if ((l.indexOf(e[i].href) == 0 && l.length >= e[i].href.length && e[i].href != h)
				|| (window.location.pathname == '/' && h == e[i].href))
			Element.addClassName(e[i].parentNode, 'current');
	}
}


function nnMapMarker(loc, titleText, htmlText) {
	var marker = new GMarker(loc, titleText);
	GEvent.addListener(marker, 'click', function () {
		marker.openInfoWindowHtml(htmlText);
	});
	return marker;
}


var nnMap_Title =
	'Connectical, Inc.' ;
var nnMap_Text =
	'<img src="/wiki/nn/img/esxai.jpeg"' +
	'   alt="Edificio de Investigación" width="250" height="188">' +
	'<p><strong>Oficina Principal</strong><br>' +
	'Servicios Generales de Apoyo a la Investigación<br>' +
	'<em>Campus de Elviña, s/n</em><br>' +
	'<em>15071 A Coruña, España</em></p>' ;


function nnMapLoad() {
	var mapDiv = $("map");
	if (!mapDiv) return;
	if (!GBrowserIsCompatible()) return;

	var map = new GMap2(mapDiv);
	mapTypes = map.getMapTypes();
	map.addControl(new GSmallMapControl());
	map.addControl(new GMapTypeControl());
	var loc = new GLatLng(43.331, -8.41211);
	map.setCenter(loc, 16);
	map.setMapType(mapTypes[2]);

	map.addOverlay(
		nnMapMarker(loc,
			nnMap_Title, nnMap_Text));
}


nnAddEvent(window, 'load', function () {
	// nnCreateAnnoyingClip();
	// nnWireSidebarEffects();
	// nnMakeTableAdditions();
	// nnWireRestTocEffect();
	// nnFillImageTitles();
	// nnFixMoinSidemenu();
	// nnMarkCurrent('menu-top');
	// nnMarkCurrent('menu-side');
	// initLightbox();
	// nnMapLoad();
	// Safely inject CSS3 and give the search results a shadow

	FancySearch.Init();
	// Safely inject CSS3 and give the search results a shadow
	var cssObj = { 'box-shadow' : '#888 5px 10px 10px', // Added when CSS3 is standard
		'-webkit-box-shadow' : '#888 5px 10px 10px', // Safari
		'-moz-box-shadow' : '#888 5px 10px 10px', // Firefox 3.5+
		'display' : 'none' };

	$("suggestions").setStyle(cssObj);
	
	// Fade out the suggestions box when not active
	$("q").observe('blur',function(){
	  $('suggestions').fade({ duration: 0.5, from: 1, to: 0 });
	});

})

if (typeof GUnload == "function") {
	nnAddEvent(window, 'unload', GUnload);
}

