if (document.getElementById && document.createTextNode) {
	var puna = {
		options : {
			get : function(e, n) {
				for (var p=e; p.getAttribute; p = p.parentNode) {	
					if (p.getAttribute(n)) {return p.getAttribute(n)}
				}
				return puna.options[n];
			},
			focus	: true,
			sticky	: false,
			cookies	: true,
			shade	: false,
			drag	: true,
			delay	: 200,
			delimit	: ',',
			regexp	: true
		},

		browser : {
			agent : navigator.userAgent.toLowerCase(),
			isIE : ((document.all) && (navigator.userAgent.toLowerCase().indexOf('opera')==-1)),
			sniff : function() {document.write('<script language="javascript" src="punaSniff.js"></script>')}
		},

		cookie : {
			remove : function(name, path, domain) {
				puna.cookie.set(name, '', new Date(0), path, domain);
			},

			set : function(name, value, expires, path, domain, secure) {
				document.cookie = name + "=" + escape (value) +
				((expires) ? "; expires=" + expires.toGMTString() : "") +
				((path) ? "; path=" + path : "") +
				((domain) ? "; domain=" + domain : "") +
				((secure) ? "; secure" : "");	
			},

			value : function(name, defaults) {	
				var prefix = name + "=";	
				var cookie = document.cookie;
				var begin = cookie.indexOf('; ' + prefix);
				if (begin == -1) {
				    begin = cookie.indexOf(prefix);
				    if (begin != 0) {return defaults};
				} else {begin += 2}
				var end = cookie.indexOf(";", begin);
				if (end == -1) {end = cookie.length}
				var value = unescape(cookie.substring(begin + prefix.length, end));
				return value;
			}
		},

		css : {
			add : function(e, n) {
				if (e) {
					if(!puna.css.includes(e,n)){e.className+=(' '+n)}
				}
			},

			change : function(n, p, v, ds) {	
				if (ds!=window.undefined) {
					if (typeof(ds) != 'object') {ds = document.styleSheets[ds]}
					for (var r = puna.css.selector(n, ds);r;r = puna.css.selector(n, ds, r)) {
						r.style[p] = v;
					}
				} else {
					for(var j=0; j<document.styleSheets.length; j++) {
						puna.css.change(n, p, v, document.styleSheets[j]);
					}
				}
			},

			enabled : function (t, i) {
				var s = puna.css.styleSheets();
				if (s) {
					if (i != window.undefined && i != null) {
						i = (i < 0) ? s.length - 1 : i;
						i = (i >= s.length) ? 0 : i;
						s[i].disabled = !t;
					} else {				
						for (var j = 0; j < s.length; j++) {
							s[j].disabled = !t;							
						}					
					}
				}
			},

			includes : function(e, name) {
				if (e) {
					return (e.className.search(new RegExp('(^| )'+name+'($| )'))>=0);
				}
				return false;
			},
			
			index : function (i) {
				var s = puna.css.styleSheets();
				if (s) {					
					i = (i != window.undefined) ? i++ : 0;
					for (var j = 0; j < s.length; j++) {
						if(!s[j].disabled){return j}
					}
				}
				return null;
			},			

			remove : function(e, name) {
				if (e) {
					e.className=e.className.replace(new RegExp('(^| +)'+name+'($| +)'),' ');
					e.className.replace(/ +/g,' ');
				}
			},

			selector : function(n, ds, prev) {
				if (ds != window.undefined) {
					if (typeof(ds) != 'object') {ds = document.styleSheets[ds]}		
					var r = (ds.rules != window.undefined) ? ds.rules : ds.cssRules;
					for (var k = 0; k < r.length; k++) {
						if (prev) {
							if (prev == r[k]) {
								prev = null;
								puna.css.selector.prev = null;
							}
						} else {
							if (r[k].selectorText != window.undefined) {
								if (r[k].selectorText.toLowerCase() == n) {return r[k]}
							}
						}
					}
				} else {
					puna.css.selector.prev = prev; //required to keep state across stylesheets
					for(var j = 0; j < document.styleSheets.length; j++) {
						var s = puna.css.selector(n, document.styleSheets[j], puna.css.selector.prev);
						if (s) {return s}
					}					
				}
				return null;
			},
			
			styleSheets : function() {return (document.styleSheets) ? document.styleSheets : document.getElementsByTagName('link')}
		},

		document : {
			add : function(tag, id, css, shaded) {			
				return document.body.appendChild(puna.document.createElement(tag, id, css, shaded));
			},

			anchors : {
				untab : function(p) {
					if (p == window.undefined) {p = document}
					var e = p.getElementsByTagName('a');
					for (var i=0;i<e.length;i++){
						if (e[i].tabIndex) {
							e[i].wasTabIndex = e[i].tabIndex;
							e[i].tabIndex *= -1;
						} else {						
							e[i].wasTabIndex = 0;
							e[i].tabIndex = -1;
						}
					}		
				},

				retab : function(p) {
					if (p == window.undefined) {p = document}
					var e = p.getElementsByTagName('a');
					for (var i=0;i<e.length;i++){
						if (e[i].wasTabIndex != window.undefined) {e[i].tabIndex = e[i].wasTabIndex}
					}
				}	
			},			
			
			createElement : function(tag, id, css, shaded) {
				var child = document.createElement(tag)
				if (id) {
					child.setAttribute('name', id);
					child.setAttribute('id', id);
				}
				if (tag == 'iframe') {
					child.frameBorder = "0";
					child.scrolling = "no";
					child.allowtransparency="true";
				}
				if (css) {puna.css.add(child, css)}
				if (shaded) {
					if (puna.browser.isIE) {puna.document.mask(child)}
					puna.document.shade(child);
				}
				return child;
			},

			fontsize : function(e) {
				if(document.defaultView && document.defaultView.getComputedStyle){
					return parseInt(document.defaultView.getComputedStyle(e,'').getPropertyValue('font-size'));
				} else if(document.all && e.currentStyle){
					return parseInt(e.currentStyle.fontSize);
				}
			},

			hide : function(e) {
				e.style.display = 'none';
				if (e.shadow) {e.shadow.style.display = 'none'}
				if (e.mask) {e.mask.style.display = 'none'}
				puna.css.remove(e.raisedby, 'infoActive');
				puna.css.remove(e.raisedby, 'active');
			},			
			
			isInput : function(e) {
				if (e) {return ((e.type == "reset") || (e.type == "hidden") || (e.type == "file") || (e.type == "radio") ||( e.type == "checkbox") || (e.type == "text") || (e.type == "textarea") || (e.type == "button") || (e.type == "submit")|| (e.type == "select-multiple") || (e.type == "select-one"))}
				return false;
			},

			map : function(d, s) {
				d.metrics = new puna.metrics(s);
				d.style.left = d.metrics.x + 'px';
				d.style.top = d.metrics.y + 'px';
				d.style.width = d.metrics.w + 'px';
				d.style.height = d.metrics.h + 'px';
				return d;
			},
			
			mask : function(e) {
				if (!e.mask) {
					if (document.all) {
						e.mask = puna.document.add('iframe','','mask');
					} else {
						e.mask = puna.document.add('div','','mask');
					}
				}
			},

			shade : function(e) {	
				if (!e.shadow) {e.shadow = puna.document.add('div','','shadow')}
			},

			reveal : function(e, t) {
				if (!t) {
					t = e.raisedby;
				} else {
					e.raisedby = t;
				}

				if (puna.css.includes(t, 'infoTrigger')) {
					puna.css.add(t, 'infoActive');
				} else {
					puna.css.add(t, 'active');
				}				
				t.metrics = new puna.metrics(t);

				window.metrics = new puna.metrics(window);
				if (e.parentMenu) {
					e.style.left = t.metrics.r + 'px';
					e.style.top = t.metrics.y + 'px';
				} else {
					e.style.left = t.metrics.x + 'px';
					e.style.top = t.metrics.b + 'px';
				}	

				e.style.display = 'block';
				e.metrics = new puna.metrics(e);	
						
				if ((e.metrics.r + 5) > window.metrics.r) {
					if (e.parentMenu) {
						e.metrics.x = t.metrics.x - e.metrics.w;
					} else {
						e.metrics.x = t.metrics.x - e.metrics.w + t.metrics.w;
					}
					if (e.metrics.x > 0) {e.style.left = e.metrics.x + 'px'}
				}
				if ((e.metrics.b + 5) > window.metrics.b) {					
					if (e.parentMenu) {
						e.metrics.y = t.metrics.y + t.metrics.h - e.metrics.h;
					} else {
						e.metrics.y = t.metrics.y - e.metrics.h;
					}
					if (e.metrics.y > 0) {e.style.top = e.metrics.y + 'px'}
				}
				e.metrics = new puna.metrics(e);
			
				if (e.mask) {
					e.mask.style.width = e.metrics.w + 5 + 'px';
					e.mask.style.height = e.metrics.h + 5 + 'px';
					e.mask.style.left = e.metrics.x + 'px';
					e.mask.style.top = e.metrics.y + 'px';					
					e.mask.style.display = 'block';
				}
				if (e.shadow) {
					e.shadow.style.width = e.metrics.w + 'px';
					e.shadow.style.height = e.metrics.h + 'px';
					e.shadow.style.left = e.metrics.x + 5 + 'px';
					e.shadow.style.top = e.metrics.y + 5 + 'px';
					e.shadow.style.display='block';
				}
			}
		},

		event : {
			add : function(e, event, handler) {
				if(e.attachEvent) {
					e.attachEvent('on' + event, handler);
				} else if(e.addEventListener) {
					e.addEventListener(event, handler, false);
				}
			},

			element : function(ev) {
				ev = puna.event.object(ev);
				var e = (ev.target) ? ev.target : ev.srcElement;
				while (e.nodeType != 1) {e = e.parentNode}
				return e;
			},

			isInput : function(ev) {
				return puna.document.isInput(puna.event.element(ev));
			},
			
			keypressed : function(ev) {
				ev = puna.event.object(ev);
				if (ev) {
					return (ev.charCode) ? ev.charCode : (ev.keyCode) ? ev.keyCode : (ev.which) ? ev.which : null;
				}
				return null;
			},
			
			object : function(ev) {
				return (ev) ? ev : (window.event) ? window.event : null;
			},
			
			remove : function(e, event, handler) {
				if (e.detachEvent) {
					e.detachEvent('on' + event, handler);
				} else if (e.removeEventListener) {
					e.removeEventListener(event, handler, false);
				}
			},

			stop : function(ev) {
				ev = puna.event.object(ev);
				if (ev) {
					ev.cancelBubble = true;
					if (ev.stopPropagation) {ev.stopPropagation()}
				}
			}
		},
		
		form : {
			asArray : function(e) {
				if (puna.form.isArray(e)) {return e}
				return [e];
			},

			disable : function(d, p) {	
				var set = function(t, d, p) {
					if (d == window.undefined) {d = true}
					if (p == window.undefined) {p = document}
					var a = p.getElementsByTagName(t);
					var processed = new Array();

					
					for (var i in a) {
						if (typeof(a[i]) == 'object') {

							if (t == 'input') {
								if (a[i].length) {
									if (!processed[a[i][0].name]) {
										for (var j=0; j<a[i].length; j++) {
											if (d) {
												a[i][j].wasDisabled = (a[i][j].disabled) ? true : false;
												a[i][j].disabled = d;
											} else {
												a[i][j].disabled = (a[i][j].wasDisabled) ? true : false;
											}
										}
										processed[a[i][0].name] = true;
									}
									continue;									
								}
							}
									
							if (t == 'select') {	
								if (a[i].length > 1) {
									if (a[i][0].length) {	
										if (!processed[a[i][0].name]) {
											for (var j=0; j<a[i].length; j++) {				
												if (d) {
													a[i][j].wasDisabled = (a[i][j].disabled) ? true : false;
													a[i][j].disabled = d;
												} else {
													a[i][j].disabled = (a[i][j].wasDisabled) ? true : false;;
												}
											}
											processed[a[i][0].name] = true;
										}
										continue;	
									}
								}
							}


							if (d) {							
								a[i].wasDisabled = (a[i].disabled) ? true : false;
								a[i].disabled = d;
							} else {							
								a[i].disabled = (a[i].wasDisabled) ? true : false;
							}
						}
					}
				}
				set('input', d, p);
				set('select', d, p);
				set('textarea', d, p);			
			},
			
			isArray : function(e) {
				if (e.type == window.undefined) {return (puna.document.isInput(e[0]) && puna.document.isInput(e[1]))}
				return false;	
			},

			select : {
				copy : function(source, dest) {	
					dest.length = 0;
					for (var i=0; i<source.length; i++) {puna.form.select.option.copy(source[i], dest)}
				},
				
				option : {
					copy : function(source, toSelect) {
						var newOption = new Option(source.text, source.value);
						newOption.selected = source.selected;
						toSelect[toSelect.length] = newOption;
						for (var i=0; i<source.attributes.length; i++) {
							var attr = source.attributes[i];
							newOption.setAttribute(attr.name, attr.value);
						}
					}
				},
				
				remove : function(select, value) {
					for (var i=select.options.length -1; i >= 0; i--) {
						if (select.options[i].value == value) {select.options[i] = null}
					}
				}
			},

			values : function(e) {
				var r = new Array();
				var a = puna.form.asArray(e);
				for (var i=0; i<a.length; i++) {
					e = a[i];
					if ((e.type == 'reset') || (e.type == 'hidden') || (e.type == 'file') || (e.type == 'text') || (e.type == 'textarea') || (e.type == 'button') || (e.type == 'submit')) {
						r[r.length] = e.value;
					} else if ((e.type == 'radio') || (e.type == 'checkbox')) {
						if (e.checked) {r[r.length] = e.value}
					} else if ((e.type == 'select-one') || (e.type == 'select-multiple')) {
						for (var j=0; j<e.options.length; j++) {
							if (e.options[j].selected) {r[r.length] = (e.options[j].value) ? e.options[j].value : e.options[j].text}
						}
					}
				}
				return r;
			}
		},		

		menu : {
			add : function(id, data) {//[[label|token, uri, target, submenuID, anchorID, confirmText], [...]]	
				if (!puna.menu.menus) {puna.menu.menus = new Array()}
				if (!puna.menu.menus[id]) {
					puna.menu.menus[id] = data;
				} else {
					puna.menu.menus[id].push(data);
				}
			},
			
			onContext : function(e) {
				return true;
			},
			
			onLoad : function(e) {
				if (puna.menu.menus) {
					for (var id in puna.menu.menus) {
						var menu = puna.document.add('ul', id, 'menu');
						var data = puna.menu.menus[id];
						for (var i=0;i<data.length;i++) {
							var li = menu.appendChild(document.createElement('li'));					
							if (data[i].length > 1) {
								if (data[i][1]) {
									var e = li.appendChild(document.createElement('a'));	
									//Treat URLs formatted 'javascript:...' specially				
									if (data[i][1].toLowerCase().substring(0, 11) == 'javascript:') {
										e.setAttribute('href', '#');
										e.onclick = new Function(data[i][1] + ';return false;');
									} else {
										e.setAttribute('href', data[i][1]);
									}
								} else {
									var e = li.appendChild(document.createElement('span'));
								}
								if (data[i].length > 2) {
									//Target
									if (data[i][2]) {e.setAttribute('target', data[i][2])}
									//subMenu ID									
									if (data[i][3]) {e.setAttribute('menu', data[i][3])}
									//Anchor ID
									if (data[i][4]) {e.setAttribute('id', data[i][4])}
									//Confirm text
									if (data[i][5]) {e.onclick=new Function("return confirm('" + data[i][5] + "')")}
									//expand options here
								}
								e.innerHTML = data[i][0];
							} else {
								switch (data[i][0]) {
									case ('hr') : {
										li.appendChild(document.createElement('hr'));
										break;
									}
								}
							}
						}
					} 
				}
				puna.menu.afterLoad();
			},
			
			onMenu : function(e) {	
				return true;
			},

			afterLoad : function() {}			
		},
		
		metrics : function(e) {
	
			if (e == window) {
				this.x = (window.pageXOffset) ? (window.pageXOffset) : (document.documentElement) ? document.documentElement.scrollLeft : document.body.scrollLeft;
				this.y = (window.pageYOffset) ? (window.pageYOffset) : (document.documentElement) ? document.documentElement.scrollTop : document.body.scrollTop;
					
				if (window.innerHeight != window.undefined) {
					this.h = window.innerHeight;
				} else if (document.compatMode=='CSS1Compat') {
					this.h = document.documentElement.clientHeight;
				} else if (document.body) {
					this.h =  document.body.clientHeight;
				}

				if (window.innerWidth != window.undefined) {
					this.w = window.innerWidth;
				} else if (document.compatMode=='CSS1Compat') {
					this.w = document.documentElement.clientWidth;
				} else if (document.body) {
					this.w = document.body.clientWidth;
				}
			} else {
				this.x = parseInt(e.offsetLeft);
				this.y = parseInt(e.offsetTop);
				var o=e;
				while (o.offsetParent!=null){
					o=o.offsetParent;
					if(o.block){return true}
					this.x+=parseInt(o.offsetLeft);
					this.y+=parseInt(o.offsetTop);
					
					if (o.offsetParent) {
						if (o.scrollLeft) {this.x-=parseInt(o.scrollLeft)}
						if (o.scrollTop) {this.y-=parseInt(o.scrollTop)}
					}
				}
				this.h = parseInt(e.offsetHeight);
				this.w = parseInt(e.offsetWidth);
			}
			this.r=this.x+this.w;
			this.b=this.y+this.h;
		},

		modal : {
			center : function(w, h, metrics) {
				if (puna.modal.dialog.open) {
					with (puna.modal.dialog) {
						style.display = 'block';
						if (w==null || isNaN(w)) {w = offsetWidth - 4}
						if (h==null || isNaN(h)) {h = offsetHeight - 4}
					}
					window.metrics = (metrics) ? metrics : new puna.metrics(window);
					with (puna.modal.dialog.style) {				
						top = (window.metrics.y + ((window.metrics.h - h) / 2)) + 'px';
						left =  (window.metrics.x + ((window.metrics.w - w) / 2)) + 'px';
						width = w + 'px';
						height = h + 'px';							
					}
					if (puna.modal.dialog.iframe) {
						puna.modal.dialog.iframe.style.height = h - puna.modal.dialog.caption.offsetHeight + 'px';
					}
					with (puna.modal.dialog.block.style) {						
						display = 'block';
						height = document.body.clientHeight + 'px';
						width = document.body.clientWidth + 'px';						
						top = '0px';
						left = '0px';
					}	
					with (puna.modal.dialog.mask.style) {					
						display = 'block';
						top = (window.metrics.y + ((window.metrics.h - h) / 2)) + 'px';
						left =  (window.metrics.x + ((window.metrics.w - w) / 2)) + 'px';
						width = w + 8 + 'px';
						height = h + 8 + 'px';
					}
				}
			},
					
			document : document,

			hide : function () {
				if (puna.modal.dialog) {
					if (puna.modal.dialog.open) {					
						puna.document.anchors.retab();
						puna.form.disable(false);
						puna.modal.dialog.style.display = "none";
						puna.modal.dialog.block.style.display = "none";
						puna.modal.dialog.mask.style.display = "none";
						if (puna.modal.dialog.iframe) {puna.modal.dialog.iframe.src = ''}
						puna.modal.dialog.open = false;
					}
				}		
			},
			
			show : function(caption, uri, width, height) {
				puna.modal.hide();
				var metrics = new puna.metrics(window);
				
				var dialog = (typeof(uri) == 'object') ? uri : document.getElementById(uri);
				if (!dialog) {
					dialog = puna.modal.div;
					if (!dialog) {
						dialog = puna.modal.div = puna.document.add('div', '', 'modal');
						dialog.caption = dialog.appendChild(puna.document.createElement('h4', '', 'caption'));
						dialog.iframe = dialog.appendChild(puna.document.createElement('iframe', '', 'modal'));
					}
					dialog.iframe.src = uri;
				} else if (!dialog.caption) {
					dialog.caption = dialog.insertBefore(puna.document.createElement('h4', '', 'caption'), dialog.firstChild);
				}
	
				if (!dialog.caption.span) {dialog.caption.span = dialog.caption.appendChild(puna.document.createElement('span', '', 'text'))}
				if (!dialog.caption.control) {
					dialog.caption.control = dialog.caption.appendChild(puna.document.createElement('span', '', 'control'));
					dialog.caption.control.innerHTML = "<input type='button' value='X' onclick='puna.modal.hide()'/>";
				}
				dialog.caption.span.innerHTML = caption;
				puna.css.add(dialog.caption, 'grip');

				if (!dialog.mask) {puna.document.mask(dialog, 'shaded')}
				dialog.block = (dialog.block) ? dialog.block : puna.document.add('div', '', 'mask');
				
				puna.form.disable();
				puna.form.disable(false, dialog);
				puna.document.anchors.untab();
				puna.document.anchors.retab(dialog);
				puna.modal.dialog = dialog;					
				dialog.open = true;
				puna.modal.center(width, height, metrics);
				
				if (!puna.modal.handlers) {
					puna.event.add(window, "resize", puna.modal.center);
					puna.event.add(window, "scroll", puna.modal.center);
					puna.modal.handlers = true;
				}
				if (eval(puna.options.get(dialog, 'drag'))) {
					dialog.caption.drags = dialog;
					dialog.caption.onmousedown = punaAPI.drag.start;
				}
			},

			window : window
		},

		walktree : function(e, callback) {
			if(e){
				if(e.nodeType==1){
					if (e.getAttribute('puna')=='stop'){return}
					callback(e);
				}
				for(var n=e.firstChild;n;n=n.nextSibling){puna.walktree(n,callback)}
			}
		}
	}
	
	function punaAPI() {
		if (puna.beforeLoad) {puna.beforeLoad()}
		puna.menu.onLoad();
		puna.walktree(document.documentElement, punaAPI.setup);
		punaAPI.mask.setup();
		
		//improve this - ought be run on each tab click and modal open	
	
		if (puna.options.focus && (document.forms.length > 0)) {
			var fs = document.forms;

			for (var f in fs) {
				for (var e in fs[f].elements) {
					if (puna.document.isInput(fs[f].elements[e])) {
						if (fs[f].elements[e].type != 'hidden') {
							if (fs[f].elements[e].focus) {
								try {
									fs[f].elements[e].focus();
									break;
								} catch(ex) {}
							}	
						}
					}
				}
			}
		}			
		if (puna.onLoad) {puna.onLoad(punaAPI.tabSets.array)}
	}

	//add allowance for pasting!
	punaAPI.mask = {
		keypress : function(ev) {
			var c = puna.event.keypressed(ev);
			if (c > 45 || c == 32) {
				var k = String.fromCharCode(c);
				var e = puna.event.element(ev);
				var a = e.getAttribute('mask');
				if ((a.search(/unsigned/)==0) && (k.search(/[\+-]/) != -1)) {return false}
				switch (a.toLowerCase()) {
					case 'integer' : {
						if (k.search(/[\+-]/) != -1) {return (e.value.length == 0)}
						return (k.search(/[0-9]/) != -1) ? true : false;
					}
									
					case 'float' : {
						if (k.search(/[\+-]/) != -1) {return (e.value.length == 0)}
						if (k=='.') {return (e.value.indexOf('.') == -1)}
						return (k.search(/[0-9]/) != -1) ? true : false;
					}
				
					default : {
						return (k.search(a) != -1) ? true : false;
					}
				}
			}
			return true;
		},
		
		setup : function() {
			var e = document.getElementsByTagName('input');
			for (var i=0; i<e.length; i++) {
				if ((e[i].type=='text') && (e[i].getAttribute('mask'))) {
					e[i].onkeypress = punaAPI.mask.keypress;
				}
			}
		}		
	}
	
	punaAPI.handler = {
		info : {
			add : function(e) {
				var info = punaAPI.handler.info.div;
				if (!info) {
					info = punaAPI.handler.info.div = puna.document.add('div', 'puna.info', 'info', true);						
					info.onmouseover = function(e) {punaAPI.handler.info.stoptimer()}
					info.onmouseout = function(e) {punaAPI.handler.info.starttimer()}
					punaAPI.handler.info.raised = false;
				} else {
					info.raisedby = null;
				}
				puna.event.add(e, 'mouseover', punaAPI.handler.info.mouseover);
				puna.event.add(e, 'mouseout', punaAPI.handler.info.mouseout);
				puna.css.add(e, 'infoTrigger');			
			},
			
			hide : function(e) {
				punaAPI.handler.info.stoptimer();
				puna.document.hide(punaAPI.handler.info.div);
				punaAPI.handler.info.raised = false;
			},

			mouseout : function(e) {
				clearTimeout(punaAPI.handler.info.div.reveal);
				punaAPI.handler.info.starttimer()
			},	
			
			mouseover : function(ev) {
				punaAPI.handler.info.stoptimer();
				var e = puna.event.element(ev);
				var info = punaAPI.handler.info.div;
				if (info.raisedby != e) {
					punaAPI.handler.info.hide()
					info.raisedby = e;
					var t = e.getAttribute('info');
					var p = document.getElementById(t);
					if (p) {
						info.innerHTML = p.innerHTML;
					} else {
						info.innerHTML = t.replace('\n', '<br/>');
					}
				}
				if (!punaAPI.handler.info.raised) {
					punaAPI.handler.info.div.reveal = setTimeout('punaAPI.handler.info.reveal()', puna.options.delay * 2);
				}
			},
			
			reveal : function() {
				puna.document.reveal(punaAPI.handler.info.div);
				punaAPI.handler.info.raised = true;
			},

			remove : function(e) {
				punaAPI.handler.info.hide(e);
				e.onmouseover = function(ev) {return true};
				e.onmouseout = function(ev) {return true};
				puna.css.remove(e, 'infoTrigger');	
			},

			starttimer : function() {punaAPI.handler.info.div.timer = setTimeout('punaAPI.handler.info.hide()', puna.options.delay)},
			stoptimer : function() {clearTimeout(punaAPI.handler.info.div.timer)}
		},
			
		menu : {
			add : function(e, menu, blnContext) {
				e.menu = menu;
				for(var p = menu.raisedby = e;p;p=p.parentNode) {
					if (p.raisedby) {menu.parentMenu = p}
				}
				menu.starttimer = punaAPI.handler.menu.starttimer;
				menu.stoptimer = punaAPI.handler.menu.stoptimer;
				menu.onmouseover = function(e) {this.stoptimer()}
				menu.onmouseout = function(e) {this.starttimer()}

				puna.document.mask(menu);
				puna.document.shade(menu);
				
				if (blnContext) {
					puna.css.add(e, 'contextMenu');
					e.oncontextmenu = function(e) {if (puna.menu.onContext(this)) {this.menu.stoptimer(this)}; return false};
				} else {
					puna.css.add(e, 'menuTrigger');
					e.onmouseover = function(e) {if (puna.menu.onMenu(this)) {this.menu.stoptimer()}};				
				}
				e.onmouseout = function (e) {this.menu.starttimer()};			
			},
			
			starttimer : function() {
				if (this.parentMenu) {this.parentMenu.starttimer()}					
				clearTimeout(this.timer);
				this.timer = setTimeout("puna.document.hide(document.getElementById('" + this.getAttribute('id') + "'))", puna.options.delay);
			},

			stoptimer : function(raisedBy) {				
				if (this.parentMenu) {this.parentMenu.stoptimer()}				
				clearTimeout(this.timer);
				if (this.style.display != 'block'){puna.document.reveal(this, raisedBy)}
			}
		}
	}

	punaAPI.ruler = {
		add : function(e) {
			var sticky = eval(puna.options.get(e, 'sticky'));
			var trs = e.getElementsByTagName('tr');
			for(var i=0;i<trs.length;i++){
				trs[i].onmouseover = function(e) {puna.css.add(this, 'ruled')};
				trs[i].onmouseout = function(e) {puna.css.remove(this, 'ruled')};
				if (sticky) {trs[i].onclick = function(e) {if (!puna.event.isInput(e)) {punaAPI.ruler.swap(this)}}}
				var inputs = trs[i].getElementsByTagName('input');
				for (var j=0;j<inputs.length;j++) {
					if ((inputs[j].type == 'checkbox') && (inputs[j].getAttribute('ruler')=='sync')) {
						inputs[j].tr = trs[i];
						inputs[j].onclick = function (e) {punaAPI.ruler.sync(this.tr)}
					}
				}				
			}
		},

		stick : function(tr) {
			puna.css.add(tr,'stickyRow');	
			tr.stuck = true;		
		},

		swap : function(tr) {
			if (tr.stuck) {
				punaAPI.ruler.unstick(tr);						
			} else {
				punaAPI.ruler.stick(tr);
			}
			var nodes = tr.getElementsByTagName('input');
			for (var i=0;i<nodes.length;i++) {
				var n = nodes[i];
				if (n.tr == tr) {n.checked = tr.stuck}
			}
		},
		
		sync : function(tr) {
			var update = false;
			var stick = false;
			var nodes = tr.getElementsByTagName('input');
			for (var i=0;i<nodes.length;i++) {
				var n = nodes[i];
				if (n.tr == tr) {
					update = true;
					if (n.getAttribute('ruler')=='sync') {stick = (stick || n.checked)}
				}
			}
			if (update) {punaAPI.ruler.update(tr, stick)}
		},

		unstick : function(tr) {
			puna.css.remove(tr,'stickyRow');	
			tr.stuck = false;		
		},

		update : function(tr, stick) {
			if (stick) {
				punaAPI.ruler.stick(tr);
			} else {
				punaAPI.ruler.unstick(tr);
			}
		}
	}
	
	punaAPI.drag = {
		on : false,
		
		move : function(e) {
			if (punaAPI.drag.on) {	
				if (!e) {e = event}
				punaAPI.drag.object.style.left = e.clientX + punaAPI.drag.object.metrics.offset.x + 'px';
				punaAPI.drag.object.style.top = e.clientY + punaAPI.drag.object.metrics.offset.y + 'px';
				if (punaAPI.drag.object.mask) {
					punaAPI.drag.object.mask.style.left = punaAPI.drag.object.style.left;
					punaAPI.drag.object.mask.style.top = punaAPI.drag.object.style.top;
				}
			}
			return true;
		},
		
		start : function(e) {	
			punaAPI.drag.stop();
			if (!e) {e = event}
			var drags = this.drags;
			if (!drags) {drags = this}
			drags.metrics = new puna.metrics(drags);
			drags.metrics.offset = new Object();
			drags.metrics.offset.x = drags.metrics.x - e.clientX;
			drags.metrics.offset.y = drags.metrics.y - e.clientY;			
			punaAPI.drag.object = drags;
			document.onmouseup = punaAPI.drag.stop;
			document.onmousemove = punaAPI.drag.move;
			punaAPI.drag.on = true;				
			return true;
		},
		
		stop : function(e) {
			if (punaAPI.drag.on) {		
				document.onmousemove = function(e) {return false}			
				document.onmouseup = function(e) {return false}
				punaAPI.drag.on = false;
			}
		}     
	}
	
	punaAPI.setup = function(e) {
		var tag = e.nodeName.toLowerCase();

		switch (tag) {
			case 'img' : {
				var r = e.getAttribute('rollover');
				if (r) {
					e.rollover = new Image;
					e.rollover.src = r;
					e.rollover.old = e.src;	
					puna.event.add(e,'mouseover',function(e){var n=puna.event.element(e);if(eval(n.src==n.rollover.old)){n.src=n.rollover.src}});
					puna.event.add(e,'mouseout',function(e){var n=puna.event.element(e);if(eval(n.src!=n.rollover.old)){n.src=n.rollover.old}});
				}
			} break;
		
			case 'table' : {
				if (puna.css.includes(e,'ruler')) {punaAPI.ruler.add(e)}			
				break;
			} break;

			default : {
				var a = e.getAttribute('context');
				if (a) {
					var menu = document.getElementById(a);			
					if (menu) {punaAPI.handler.menu.add(e, menu, true)}		
				}
				
				a = e.getAttribute('drag');				
				if (a) {
					switch (a) {
						case 'parent' : {
							e.drags = e.parentNode;
							break;
						}
					}
					puna.css.add(e, 'grip');
					e.onmousedown = punaAPI.drag.start;
				}
							
				if (e.getAttribute('info')) {punaAPI.handler.info.add(e)}

				a = e.getAttribute('menu');
				if (a) {				
					var menu = document.getElementById(a);			
					if (menu) {punaAPI.handler.menu.add(e, menu)}
				}
			}
		}
		if (puna.css.includes(e,'tabset')) {punaAPI.tabSets.add(e)}		
	}

	punaAPI.tabSets = {
		add : function (e) {
			if (!punaAPI.tabSets.array) {punaAPI.tabSets.array = new Array()}
			punaAPI.tabSets.array[punaAPI.tabSets.array.length] = new punaAPI.tabSet(e);
		},
		select : function(tabpane) {tabpane.tabSet.select(tabpane.index)},
		mouseout : function (tabpane) {puna.css.remove(tabpane.tab, 'hover')},
		mouseover : function (tabpane) {puna.css.add(tabpane.tab, 'hover')}
	}	

	punaAPI.tabSet = function(e) {
		e.tabSet = this;	
		this.index = punaAPI.tabSets.array.length;
		this.tabPanes = new Array();

		this.tabDiv = puna.document.add('div', 'q', 'tabs');
		e.insertBefore(this.tabDiv, e.firstChild);

		if (eval(puna.options.get(e, 'cookies'))) {this.selected = puna.cookie.value('punaTabSet_' + this.index)}
		if (!this.selected) {this.selected = 0}

		this.add = function(e) {
			var i = this.tabPanes.length;
			var newTabPane = this.tabPanes[i] = new punaAPI.tabPane(e, this, i);
			this.tabDiv.appendChild(newTabPane.tab);
			if (i == this.selected) {newTabPane.show()} else {newTabPane.hide()}
			return newTabPane;
		}

		this.select = function(i) {
			if (this.selected != i) {
				if (this.tabPanes[i].onSelect()) {
					if (!isNaN(this.selected)) {this.tabPanes[this.selected].hide()}
					this.selected = i;
					this.tabPanes[this.selected].show();
					if (eval(puna.options.get(e, 'cookies'))) {puna.cookie.set('punaTabSet_' + this.index, i)}
				}
			}		
		}

		var panes = e.getElementsByTagName('div');
		for (var i=1; i<panes.length; i++) {
			if (panes[i].parentNode==e) {
				if (panes[i]!=this.tabDiv){this.add(panes[i])}
			}
		}
	}

	punaAPI.tabPane = function (e, tabSet, i) {	
		puna.css.add(e, 'tabpane');
		e.tabpane = this;
		this.element = e;
		this.tabSet = tabSet;		
		this.index = i;
		this.onSelect = function(){return true};		
		var n = e.getElementsByTagName('h2');
		if (n.length) {
			this.tab = n[0];
		} else {	
			this.tab = e.insertBefore(puna.document.createElement('h2'), e.firstChild);
			this.tab.innerHTML = 'Tab ' + (this.index + 1);
		}
		puna.css.add(this.tab, 'tab');
		this.tab.tabpane = this;
		var a = puna.document.add("a");
		this.anchor = a;
		a.href = "#";
		a.onclick = function () {return false};
		while (this.tab.hasChildNodes()) {a.appendChild(this.tab.firstChild)}
		this.tab.appendChild(a);
		var t = this;
		puna.event.add(this.tab,'mouseover', function () {punaAPI.tabSets.mouseover(t)});
		puna.event.add(this.tab,'mouseout', function () {punaAPI.tabSets.mouseout(t)});
		puna.event.add(this.tab,'click', function() {punaAPI.tabSets.select(t)});

		this.show = function () {
			puna.css.add(this.tab, 'selected');
			this.element.style.display = "block";
		}

		this.hide = function () {
			puna.css.remove(this.tab, 'selected');
			this.element.style.display = "none";
		}
	}
}

if (puna) {
	document.write('<link id="punaCSS" rel="stylesheet" href="/punaAPI/punaAPI.css"/>');
	puna.event.add(window, 'load', punaAPI);
} else {
	var puna = new Object();
}

