String.extend( {
	deCamelize : function() {
		return this.replace(/([a-z])([A-Z])/g, "$1 $2")
	},
	trunc : function(B, A) {
		if (!A) {
			A = "..."
		}
		return (this.length < B) ? this : this.substring(0, B) + A
	},
	stripScripts : function() {
		var A = this.replace(/<script[^>]*>([\s\S]*?)<\/script>/gi, function() {
			return ""
		});
		return A
	}
});
function $getText(A) {
	return A.innerText || A.textContent || ""
}
Element.extend( {
	wrapChildren : function(A) {
		while (A.firstChild) {
			this.appendChild(A.firstChild)
		}
		A.appendChild(this);
		return this
	},
	visible : function() {
		var A = this;
		while ($type(A) == "element") {
			if (A.getStyle("visibility") == "hidden") {
				return false
			}
			if (A.getStyle("display") == "none") {
				return false
			}
			A = A.getParent()
		}
		return true
	},
	hide : function() {
		return this.setStyle("display", "none")
	},
	show : function() {
		return this.setStyle("display", "")
	},
	toggle : function() {
		return this.visible() ? this.hide() : this.show()
	},
	scrollTo : function(A, B) {
		this.scrollLeft = A;
		this.scrollTop = B
	},
	getPosition : function(A) {
		A = A || [];
		var B = this, D = 0, C = 0;
		do {
			D += B.offsetLeft || 0;
			C += B.offsetTop || 0;
			B = B.offsetParent
		} while (B);
		A.each(function(E) {
			D -= E.scrollLeft || 0;
			C -= E.scrollTop || 0
		});
		return {
			x : D,
			y : C
		}
	},
	getDefaultValue : function() {
		switch (this.getTag()) {
		case "select":
			var A = [];
			$each(this.options, function(B) {
				if (B.defaultSelected) {
					A.push($pick(B.value, B.text))
				}
			});
			return (this.multiple) ? A : A[0];
		case "input":
			if (!(this.defaultChecked && [ "checkbox", "radio" ]
					.contains(this.type))
					&& ! [ "hidden", "text", "password" ].contains(this.type)) {
				break
			}
		case "textarea":
			return this.defaultValue
		}
		return false
	}
});
var Observer = new Class( {
	initialize : function(C, B, A) {
		this.options = Object.extend( {
			event : "keyup",
			delay : 300
		}, A || {});
		this.element = $(C);
		this.callback = B;
		this.timeout = null;
		this.listener = this.fired.bind(this);
		this.value = this.element.getValue();
		this.element.setProperty("autocomplete", "off").addEvent(
				this.options.event, this.listener)
	},
	fired : function() {
		if (this.value == this.element.value) {
			return
		}
		this.clear();
		this.value = this.element.value;
		this.timeout = this.callback.delay(this.options.delay, null,
				[ this.element ])
	},
	clear : function() {
		this.timeout = $clear(this.timeout)
	},
	stop : function() {
		this.element.removeEvent(this.options.event, this.listener);
		this.clear()
	}
});
Element.extend( {
	observe : function(B, A) {
		return new Observer(this, B, A)
	}
});
var LocalizedStrings = LocalizedStrings || [];
String.extend( {
	localize : function() {
		var B = LocalizedStrings["javascript." + this], A = arguments;
		if (!B) {
			return ("???" + this + "???")
		}
		return B.replace(/\{(\d)\}/g, function(C) {
			return A[C.charAt(1)] || "???" + C.charAt(1) + "???"
		})
	}
});
Number.REparsefloat = new RegExp("([+-]?\\d+(:?\\.\\d+)?(:?e[-+]?\\d+)?)", "i");
function $T(B) {
	var A = $(B);
	return (A && A.tBodies[0]) ? $(A.tBodies[0]) : A
}
function getAncestorByTagName(B, A) {
	if (!B) {
		return null
	}
	if (B.nodeType == 1 && (B.tagName.toLowerCase() == A.toLowerCase())) {
		return B
	} else {
		return getAncestorByTagName(B.parentNode, A)
	}
}
var Wiki = {
	onPageLoad : function() {
		if (this.prefs) {
			return
		}
		$$("meta").each(function(D) {
			var E = D.getProperty("name") || "";
			if (E.indexOf("wiki") == 0) {
				this[E.substr(4)] = D.getProperty("content")
			}
		}, this);
		var A = location.host;
		this.BasePath = this.BaseUrl.slice(this.BaseUrl.indexOf(A) + A.length,
				-1);
		if (this.BasePath == "") {
			this.BasePath = "/"
		}
		this.prefs = new Hash.Cookie("JSPWikiUserPrefs", {
			path : Wiki.BasePath,
			duration : 20
		});
		this.PermissionEdit = !!$$("a.edit")[0];
		this.url = null;
		this.parseLocationHash.periodical(500);
		this.makeMenuFx("morebutton", "morepopup");
		this.addEditLinks();
		var C = $("page");
		if (C) {
			this.renderPage(C, Wiki.PageName)
		}
		var B = $("favorites");
		if (B) {
			this.renderPage(B, "Favorites")
		}
	},
	alert : function(A) {
		return alert(A)
	},
	prompt : function(B, A, C) {
		return C(prompt(B, A))
	},
	renderPage : function(B, A) {
		this.$pageHandlers.each(function(C) {
			C.render(B, A)
		})
	},
	addPageRender : function(A) {
		if (!this.$pageHandlers) {
			this.$pageHandlers = []
		}
		this.$pageHandlers.push(A)
	},
	setFocus : function() {
		[ "editorarea", "j_username", "loginname", "assertedName", "query2" ]
				.some(function(A) {
					A = $(A);
					if (A && A.visible()) {
						A.focus();
						return true
					}
					return false
				})
	},
	getUrl : function(A) {
		return this.PageUrl.replace(/%23%24%25/, A)
	},
	getPageName : function(A) {
		var C = this.PageUrl.escapeRegExp().replace(/%23%24%25/, "(.+)"), B = A
				.match(new RegExp(C));
		return (B ? B[1] : false)
	},
	cleanLink : function(A) {
		return A.trim().replace(/\s+/g, " ").replace(
				/[^A-Za-z0-9()&+,-=._$ ]/g, "")
	},
	changeOrientation : function() {
		var A = $("prefOrientation").getValue();
		$("wikibody").removeClass("fav-left").removeClass("fav-right")
				.addClass(A)
	},
	makeMenuFx : function(A, C) {
		var A = $(A), C = $(C);
		if (!A || !C) {
			return
		}
		var B = C.effect("opacity", {
			wait : false
		}).set(0);
		A.adopt(C).set( {
			href : "#",
			events : {
				mouseout : function() {
					B.start(0)
				},
				mouseover : function() {
					Wiki.locatemenu(A, C);
					B.start(0.9)
				}
			}
		})
	},
	locatemenu : function(C, D) {
		var F = {
			x : window.getWidth(),
			y : window.getHeight()
		}, I = {
			x : window.getScrollLeft(),
			y : window.getScrollTop()
		}, J = C.getPosition(), E = {
			x : C.offsetWidth - D.offsetWidth,
			y : C.offsetHeight
		}, B = {
			x : D.offsetWidth,
			y : D.offsetHeight
		}, A = {
			x : "left",
			y : "top"
		};
		for ( var G in A) {
			var H = J[G] + E[G];
			if ((H + B[G] - I[G]) > F[G]) {
				H = F[G] - B[G] + I[G]
			}
			D.setStyle(A[G], H)
		}
	},
	parseLocationHash : function() {
		if (this.url && this.url == location.href) {
			return
		}
		this.url = location.href;
		var B = location.hash;
		if (B == "") {
			return
		}
		B = B.replace(/^#/, "");
		var A = $(B);
		while ($type(A) == "element") {
			if (A.hasClass("hidetab")) {
				TabbedSection.click.apply($("menu-" + A.id))
			} else {
				if (A.hasClass("tab")) {
				} else {
					if (A.hasClass("collapsebody")) {
					} else {
						if (!A.visible()) {
						}
					}
				}
			}
			A = A.getParent()
		}
		location = location.href
	},
	submitOnce : function(A) {
		window.onbeforeunload = null;
		(function() {
			$A(A.elements).each(function(B) {
				if ((/submit|button/i).test(B.type)) {
					B.disabled = true
				}
			})
		}).delay(10);
		return true
	},
	submitUpload : function(B, A) {
		$("progressbar").setStyle("visibility", "visible");
		this.progressbar = Wiki.jsonrpc.periodical(1000, this, [
				"progressTracker.getProgress",
				[ A ],
				function(C) {
					C = C.stripScripts();
					if (!C.code) {
						$("progressbar").getFirst().setStyle("width", C + "%")
								.setHTML(C + "%")
					}
				} ]);
		return Wiki.submitOnce(B)
	},
	addEditLinks : function() {
		if ($("previewcontent") || !this.PermissionEdit
				|| this.prefs.get("SectionEditing") != "on") {
			return
		}
		var B = this.EditUrl;
		B = B + (B.contains("?") ? "&" : "?") + "section=";
		var D = new Element("a").setHTML("quick.edit".localize()), A = new Element(
				"span", {
					"class" : "editsection"
				}).adopt(D), C = 0;
		$$("#pagecontent *[id^=section]").each(function(E) {
			if (E.id == "section-TOC") {
				return
			}
			D.set( {
				href : B + C++
			});
			E.adopt(A.clone())
		})
	},
	$jsonid : 10000,
	jsonrpc : function(C, B, A) {
		new Ajax(Wiki.JsonUrl, {
			postBody : Json.toString( {
				id : Wiki.$jsonid++,
				method : C,
				params : B
			}),
			method : "post",
			onComplete : function(D) {
				var E = Json.evaluate(D, true);
				if (E) {
					if (E.result) {
						A(E.result)
					} else {
						if (E.error) {
							A(E.error)
						}
					}
				}
			}
		}).request()
	}
};
var WikiSlimbox = {
	render : function(C, A) {
		var B = 0, D = new Element("a", {
			"class" : "slimbox"
		}).setHTML("&raquo;");
		$ES("*[class^=slimbox]", C)
				.each(
						function(F) {
							var G = "lightbox" + B++, H = F.className
									.split("-")[1]
									|| "img ajax", E = [];
							if (H.test("img")) {
								E.extend( [ "img.inline", "a.attachment" ])
							}
							if (H.test("ajax")) {
								E.extend( [ "a.wikipage", "a.external" ])
							}
							$ES(E.join(","), F)
									.each(
											function(K) {
												var J = K.src || K.href, I = (K.className
														.test("inline|attachment")) ? "img"
														: "ajax";
												if ((I == "img")
														&& !J
																.test(
																		"(.bmp|.gif|.png|.jpg|.jpeg)(\\?.*)?$",
																		"i")) {
													return
												}
												D
														.clone()
														.setProperties(
																{
																	href : J,
																	rel : G
																			+ " "
																			+ I,
																	title : K.alt
																			|| K
																					.getText()
																})
														.injectBefore(K);
												if (K.src) {
													K
															.replaceWith(new Element(
																	"a",
																	{
																		"class" : "attachment",
																		href : K.src
																	})
																	.setHTML(K.alt
																			|| K
																					.getText()))
												}
											})
						});
		if (B) {
			Lightbox.init()
		}
	}
};
Wiki.addPageRender(WikiSlimbox);
var Lightbox = {
	init : function(A) {
		this.options = $extend( {
			resizeDuration : 400,
			resizeTransition : false,
			initialWidth : 250,
			initialHeight : 250,
			animateCaption : true,
			errorMessage : "slimbox.error".localize()
		}, A || {});
		this.anchors = [];
		$each(document.links, function(D) {
			if (D.rel && D.rel.test(/^lightbox/i)) {
				D.onclick = this.click.pass(D, this);
				this.anchors.push(D)
			}
		}, this);
		this.eventKeyDown = this.keyboardListener.bindAsEventListener(this);
		this.eventPosition = this.position.bind(this);
		this.overlay = new Element("div", {
			id : "lbOverlay"
		}).inject(document.body);
		this.center = new Element("div", {
			id : "lbCenter",
			styles : {
				width : this.options.initialWidth,
				height : this.options.initialHeight,
				marginLeft : -(this.options.initialWidth / 2),
				display : "none"
			}
		}).inject(document.body);
		new Element("a", {
			id : "lbCloseLink",
			href : "#",
			title : "slimbox.close.title".localize()
		}).inject(this.center).onclick = this.overlay.onclick = this.close
				.bind(this);
		this.image = new Element("div", {
			id : "lbImage"
		}).inject(this.center);
		this.bottomContainer = new Element("div", {
			id : "lbBottomContainer",
			styles : {
				display : "none"
			}
		}).inject(document.body);
		this.bottom = new Element("div", {
			id : "lbBottom"
		}).inject(this.bottomContainer);
		this.caption = new Element("div", {
			id : "lbCaption"
		}).inject(this.bottom);
		var B = new Element("div").inject(this.bottom);
		this.prevLink = new Element("a", {
			id : "lbPrevLink",
			href : "#",
			styles : {
				display : "none"
			}
		}).setHTML("slimbox.previous".localize()).inject(B);
		this.number = new Element("span", {
			id : "lbNumber"
		}).inject(B);
		this.nextLink = this.prevLink.clone().setProperties( {
			id : "lbNextLink"
		}).setHTML("slimbox.next".localize()).inject(B);
		this.prevLink.onclick = this.previous.bind(this);
		this.nextLink.onclick = this.next.bind(this);
		this.error = new Element("div").setProperty("id", "lbError").setHTML(
				this.options.errorMessage);
		new Element("div", {
			styles : {
				clear : "both"
			}
		}).inject(this.bottom);
		var C = this.nextEffect.bind(this);
		this.fx = {
			overlay : this.overlay.effect("opacity", {
				duration : 500
			}).hide(),
			resize : this.center.effects($extend( {
				duration : this.options.resizeDuration,
				onComplete : C
			}, this.options.resizeTransition ? {
				transition : this.options.resizeTransition
			} : {})),
			image : this.image.effect("opacity", {
				duration : 500,
				onComplete : C
			}),
			bottom : this.bottom.effect("margin-top", {
				duration : 400,
				onComplete : C
			})
		};
		this.fxs = new Fx.Elements( [ this.center, this.image ], $extend( {
			duration : this.options.resizeDuration,
			onComplete : C
		}, this.options.resizeTransition ? {
			transition : this.options.resizeTransition
		} : {}));
		this.preloadPrev = new Image();
		this.preloadNext = new Image()
	},
	click : function(D) {
		var B = D.rel.split(" ");
		if (B[0].length == 8) {
			return this.open( [ [ url, title, B[1] ] ], 0)
		}
		var C = 0, A = [];
		this.anchors.each(function(F) {
			var E = F.rel.split(" ");
			if (E[0] != B[0]) {
				return
			}
			if ((F.href == D.href) && (F.title == D.title)) {
				C = A.length
			}
			A.push( [ F.href, F.title, E[1] ])
		});
		return this.open(A, C)
	},
	open : function(A, B) {
		this.images = A;
		this.position();
		this.setup(true);
		this.top = window.getScrollTop() + (window.getHeight() / 15);
		this.center.setStyles( {
			top : this.top,
			display : ""
		});
		this.fx.overlay.start(0.7);
		return this.changeImage(B)
	},
	position : function() {
		this.overlay.setStyles( {
			top : window.getScrollTop(),
			height : window.getHeight()
		})
	},
	setup : function(A) {
		var C = $A(document.getElementsByTagName("object"));
		C.extend(document.getElementsByTagName(window.ie ? "select" : "embed"));
		C.each(function(D) {
			if (A) {
				D.lbBackupStyle = D.style.visibility
			}
			D.style.visibility = A ? "hidden" : D.lbBackupStyle
		});
		var B = A ? "addEvent" : "removeEvent";
		window[B]("scroll", this.eventPosition)[B]
				("resize", this.eventPosition);
		document[B]("keydown", this.eventKeyDown);
		this.step = 0
	},
	keyboardListener : function(A) {
		switch (A.keyCode) {
		case 27:
		case 88:
		case 67:
			this.close();
			break;
		case 37:
		case 38:
		case 80:
			this.previous();
			break;
		case 13:
		case 32:
		case 39:
		case 40:
		case 78:
			this.next();
			break;
		default:
			return
		}
		new Event(A).stop()
	},
	previous : function() {
		return this.changeImage(this.activeImage - 1)
	},
	next : function() {
		return this.changeImage(this.activeImage + 1)
	},
	changeImage : function(A) {
		if (this.step || (A < 0) || (A >= this.images.length)) {
			return false
		}
		this.step = 1;
		this.activeImage = A;
		this.center.style.backgroundColor = "";
		this.bottomContainer.style.display = this.prevLink.style.display = this.nextLink.style.display = "none";
		this.fx.image.hide();
		this.center.className = "lbLoading";
		this.preload = new Image();
		this.image.empty().setStyle("overflow", "hidden");
		if (this.images[A][2] == "img") {
			this.preload.onload = this.nextEffect.bind(this);
			this.preload.src = this.images[A][0]
		} else {
			this.iframeId = "lbFrame_" + new Date().getTime();
			this.so = new Element("iframe").setProperties( {
				id : this.iframeId,
				frameBorder : 0,
				scrolling : "auto",
				src : this.images[A][0]
			}).inject(this.image);
			this.nextEffect()
		}
		return false
	},
	ajaxFailure : function() {
		this.ajaxFailed = true;
		this.image.setHTML("").adopt(this.error.clone());
		this.nextEffect()
	},
	nextEffect : function() {
		switch (this.step++) {
		case 1:
			this.center.className = "";
			this.caption.empty().adopt(new Element("a", {
				href : this.images[this.activeImage][0],
				title : "slimbox.directLink".localize()
			}).setHTML(this.images[this.activeImage][1] || ""));
			var D = (this.images[this.activeImage][2] == "img") ? "slimbox.info"
					: "slimbox.remoteRequest";
			this.number.setHTML((this.images.length == 1) ? "" : D.localize(
					this.activeImage + 1, this.images.length));
			this.image.style.backgroundImage = "none";
			var B = Math.max(this.options.initialWidth, this.preload.width), C = Math
					.max(this.options.initialHeight, this.preload.height), E = Window
					.getWidth() - 10, A = Window.getHeight() - 120;
			if (this.images[this.activeImage][2] != "img" && !this.ajaxFailed) {
				B = 6000;
				C = 3000
			}
			if (B > E) {
				C = Math.round(C * E / B);
				B = E
			}
			if (C > A) {
				B = Math.round(B * A / C);
				C = A
			}
			this.image.style.width = this.bottom.style.width = B + "px";
			this.image.style.height = C + "px";
			if (this.images[this.activeImage][2] == "img") {
				this.image.style.backgroundImage = "url("
						+ this.images[this.activeImage][0] + ")";
				if (this.activeImage) {
					this.preloadPrev.src = this.images[this.activeImage - 1][0]
				}
				if (this.activeImage != (this.images.length - 1)) {
					this.preloadNext.src = this.images[this.activeImage + 1][0]
				}
				this.number.setHTML(this.number.innerHTML + "&nbsp;&nbsp;["
						+ this.preload.width + "&#215;" + this.preload.height
						+ "]")
			} else {
				this.so.style.width = B + "px";
				this.so.style.height = C + "px"
			}
			if (this.options.animateCaption) {
				this.bottomContainer.setStyles( {
					height : "0px",
					display : ""
				})
			}
			this.fxs.start( {
				"0" : {
					height : [ this.image.offsetHeight ],
					width : [ this.image.offsetWidth ],
					marginLeft : [ -this.image.offsetWidth / 2 ]
				},
				"1" : {
					opacity : [ 1 ]
				}
			});
			break;
		case 2:
			this.image.setStyle("overflow", "auto");
			this.bottomContainer.setStyles( {
				top : (this.top + this.center.clientHeight) + "px",
				marginLeft : this.center.style.marginLeft
			});
			if (this.options.animateCaption) {
				this.fx.bottom.set(-this.bottom.offsetHeight);
				this.bottomContainer.style.height = "";
				this.fx.bottom.start(0);
				break
			}
			this.bottomContainer.style.height = "";
		case 3:
			if (this.activeImage) {
				this.prevLink.style.display = ""
			}
			if (this.activeImage != (this.images.length - 1)) {
				this.nextLink.style.display = ""
			}
			this.step = 0
		}
	},
	close : function() {
		if (this.step < 0) {
			return
		}
		this.step = -1;
		if (this.preload) {
			this.preload.onload = Class.empty;
			this.preload = null
		}
		for ( var A in this.fx) {
			this.fx[A].stop()
		}
		this.center.style.display = this.bottomContainer.style.display = "none";
		this.fx.overlay.chain(this.setup.pass(false, this)).start(0);
		this.image.empty();
		return false
	}
};
var TabbedSection = {
	render : function(B, A) {
		$ES(".tabmenu a", B).each(function(C) {
			if (!C.href) {
				C.addEvent("click", this.click)
			}
		}, this);
		$ES(".tabbedSection", B).each(function(C) {
			if (C.hasClass("tabs")) {
				return
			}
			C.addClass("tabs");
			var D = new Element("div", {
				"class" : "tabmenu"
			}).injectBefore(C);
			C.getChildren().each(function(G, F) {
				var E = G.className;
				if (!E.test("^tab-")) {
					return
				}
				if (!G.id || (G.id == "")) {
					G.id = E
				}
				(F == 0) ? G.removeClass("hidetab") : G.addClass("hidetab");
				new Element("div", {
					"class" : "clearbox"
				}).inject(G);
				var H = E.substr(4).deCamelize();
				new Element("a", {
					id : "menu-" + G.id,
					"class" : (F == 0) ? "activetab" : "",
					events : {
						click : this.click
					}
				}).appendText(H).inject(D)
			}, this)
		}, this)
	},
	click : function() {
		var B = $(this).getParent(), A = B.getNext();
		B.getChildren().removeClass("activetab");
		this.addClass("activetab");
		A.getChildren().addClass("hidetab");
		A.getElementById(this.id.substr(5)).removeClass("hidetab")
	}
};
Wiki.addPageRender(TabbedSection);
var SearchBox = {
	onPageLoad : function() {
		this.onPageLoadQuickSearch();
		this.onPageLoadFullSearch()
	},
	onPageLoadQuickSearch : function() {
		var B = $("query");
		if (!B) {
			return
		}
		this.query = B;
		B.observe(this.ajaxQuickSearch.bind(this));
		this.hover = $("searchboxMenu").setProperty("visibility", "visible")
				.effect("opacity", {
					wait : false
				}).set(0);
		$(B.form).addEvent("submit", this.submit.bind(this)).addEvent(
				"mouseout", function() {
					this.hover.start(0)
				}.bind(this)).addEvent("mouseover", function() {
			Wiki.locatemenu(this.query, $("searchboxMenu"));
			this.hover.start(0.9)
		}.bind(this));
		$("recentClear").addEvent("click", this.clear.bind(this));
		this.recent = Wiki.prefs.get("RecentSearch");
		if (!this.recent) {
			return
		}
		var A = new Element("ul", {
			id : "recentItems"
		}).inject($("recentSearches").show());
		this.recent.each(function(C) {
			C = C.stripScripts();
			new Element("a", {
				href : "#",
				events : {
					click : function() {
						B.value = C;
						B.form.submit()
					}
				}
			}).setHTML(C).inject(new Element("li").inject(A))
		})
	},
	onPageLoadFullSearch : function() {
		var C = $("query2");
		if (!C) {
			return
		}
		this.query2 = C;
		var B = function() {
			var D = this.query2.value.replace(
					/^(?:author:|name:|contents:|attachment:)/, "");
			this.query2.value = $("scope").getValue() + D;
			this.runfullsearch()
		}.bind(this);
		C.observe(this.runfullsearch0.bind(this));
		$("scope").addEvent("change", B);
		$("details").addEvent("click", this.runfullsearch.bind(this));
		if (location.hash) {
			var A = decodeURIComponent(location.hash.substr(1)).match(
					/(.*):(-?\d+)$/);
			if (A && A.length == 3) {
				C.value = A[1];
				$("start").value = A[2];
				B()
			}
		}
	},
	runfullsearch0 : function() {
		$("start").value = "0";
		this.runfullsearch()
	},
	runfullsearch : function(C) {
		var D = this.query2.value;
		if (!D || (D.trim() == "")) {
			$("searchResult2").empty();
			return
		}
		$("spin").show();
		var B = $("scope"), A = D
				.match(/^(?:author:|name:|contents:|attachment:)/)
				|| "";
		$each(B.options, function(E) {
			if (E.value == A) {
				E.selected = true
			}
		});
		new Ajax(Wiki.TemplateUrl + "AJAXSearch.jsp", {
			postBody : $("searchform2").toQueryString(),
			update : "searchResult2",
			method : "post",
			onComplete : function() {
				$("spin").hide();
				GraphBar.render($("searchResult2"));
				Wiki.prefs.set("PrevQuery", D)
			}
		}).request();
		location.hash = "#" + D + ":" + $("start").value
	},
	submit : function() {
		var A = this.query.value.stripScripts();
		if (A == this.query.defaultValue) {
			this.query.value = ""
		}
		if (!this.recent) {
			this.recent = []
		}
		if (!this.recent.test(A)) {
			if (this.recent.length > 9) {
				this.recent.pop()
			}
			this.recent.unshift(A);
			Wiki.prefs.set("RecentSearch", this.recent)
		}
	},
	clear : function() {
		this.recent = [];
		Wiki.prefs.remove("RecentSearch");
		$("recentSearches", "recentClear").hide()
	},
	ajaxQuickSearch : function() {
		var A = this.query.value.stripScripts();
		if ((A == null) || (A.trim() == "") || (A == this.query.defaultValue)) {
			$("searchOutput").empty();
			return
		}
		$("searchTarget").setHTML("(" + A + ") :");
		$("searchSpin").show();
		Wiki.jsonrpc("search.findPages", [ A, 20 ], function(B) {
			$("searchSpin").hide();
			if (!B.list) {
				return
			}
			var C = new Element("ul");
			B.list.each(function(D) {
				new Element("li").adopt(new Element("a", {
					href : Wiki.getUrl(D.map.page)
				}).setHTML(D.map.page), new Element("span", {
					"class" : "small"
				}).setHTML(" (" + D.map.score + ")")).inject(C)
			});
			$("searchOutput").empty().adopt(C);
			Wiki.locatemenu($("query"), $("searchboxMenu"))
		})
	},
	navigate : function(B, A, H, D) {
		var G = Wiki.PageName, F = (H) ? G + "sbox.clone.suffix".localize() : G, E = this.query.value;
		if (E == this.query.defaultValue) {
			E = ""
		}
		var C = function(I) {
			if (I == "") {
				return
			}
			if (!D) {
				I = Wiki.cleanLink(I)
			}
			G = encodeURIComponent(G);
			I = encodeURIComponent(I);
			if (H && (I != G)) {
				I += "&clone=" + G
			}
			location.href = B.replace("__PAGEHERE__", I)
		};
		if (E != "") {
			C(E)
		} else {
			Wiki.prompt(A, F, C.bind(this))
		}
	}
};
var Color = new Class(
		{
			_HTMLColors : {
				black : "000000",
				green : "008000",
				silver : "c0c0c0",
				lime : "00ff00",
				gray : "808080",
				olive : "808000",
				white : "ffffff",
				yellow : "ffff00",
				maroon : "800000",
				navy : "000080",
				red : "ff0000",
				blue : "0000ff",
				purple : "800080",
				teal : "008080",
				fuchsia : "ff00ff",
				aqua : "00ffff"
			},
			initialize : function(A, C) {
				if (!A) {
					return false
				}
				C = C || (A.push ? "rgb" : "hex");
				if (this._HTMLColors[A]) {
					A = this._HTMLColors[A]
				}
				var B = (C == "rgb") ? A : A.toString().hexToRgb(true);
				if (!B) {
					return false
				}
				B.hex = B.rgbToHex();
				return $extend(B, Color.prototype)
			},
			mix : function() {
				var A = $A(arguments), B = this.copy(), C = (($type(A[A.length - 1]) == "number") ? A
						.pop()
						: 50) / 100, D = 1 - C;
				A.each(function(E) {
					E = new Color(E);
					for ( var F = 0; F < 3; F++) {
						B[F] = Math.round((B[F] * D) + (E[F] * C))
					}
				});
				return new Color(B, "rgb")
			},
			invert : function() {
				return new Color(this.map(function(A) {
					return 255 - A
				}))
			}
		});
var GraphBar = {
	render : function(B, A) {
		$ES("*[class^=graphBars]", B)
				.each(
						function(I) {
							var H = 20, C = 320, E = 20, Q = null, P = null, O = false, L = false, K = true, M = I.className
									.substr(9).split("-"), G = M.shift();
							M
									.each(function(S) {
										S = S.toLowerCase();
										if (S == "vertical") {
											K = false
										} else {
											if (S == "progress") {
												L = true
											} else {
												if (S == "gauge") {
													O = true
												} else {
													if (S.indexOf("min") == 0) {
														H = S.substr(3).toInt()
													} else {
														if (S.indexOf("max") == 0) {
															C = S.substr(3)
																	.toInt()
														} else {
															if (S != "") {
																S = new Color(
																		S,
																		"hex");
																if (!S.hex) {
																	return
																}
																if (!Q) {
																	Q = S
																} else {
																	if (!P) {
																		P = S
																	}
																}
															}
														}
													}
												}
											}
										}
									});
							if (!P && Q) {
								P = (O || L) ? Q.invert() : Q
							}
							if (H > C) {
								var D = C;
								C = H;
								C = D
							}
							var R = C - H;
							var N = $ES(".gBar" + G, I);
							if ((N.length == 0) && G && (G != "")) {
								N = this.getTableValues(I, G)
							}
							if (!N) {
								return
							}
							var J = this.parseBarData(N, H, R), F = (K ? "borderLeft"
									: "borderBottom");
							N
									.each(
											function(S, W) {
												var V = $H().set(F + "Width",
														J[W]), U = $H(), T = new Element(
														"span",
														{
															"class" : "graphBar"
														}), X = S.getParent();
												if (K) {
													T.setHTML("x");
													if (L) {
														U.extend(V.obj);
														V.set(F + "Width",
																C - J[W]).set(
																"marginLeft",
																"-1ex")
													}
												} else {
													if (X.getTag() == "td") {
														X = new Element("div")
																.wrapChildren(X)
													}
													X
															.setStyles( {
																height : C
																		+ S
																				.getStyle(
																						"lineHeight")
																				.toInt(),
																position : "relative"
															});
													S.setStyle("position",
															"relative");
													if (!L) {
														S.setStyle("top",
																(C - J[W]))
													}
													V.extend( {
														position : "absolute",
														width : E,
														bottom : "0"
													});
													if (L) {
														U.extend(V.obj).set(
																F + "Width", C)
													}
												}
												if (L) {
													if (Q) {
														V.set("borderColor",
																Q.hex)
													}
													if (P) {
														U.set("borderColor",
																P.hex)
													} else {
														V.set("borderColor",
																"transparent")
													}
												} else {
													if (Q) {
														var Y = O ? (J[W] - H)
																/ R
																: W
																		/ (N.length - 1);
														V
																.set(
																		"borderColor",
																		Q
																				.mix(
																						P,
																						100 * Y).hex)
													}
												}
												if (U.length > 0) {
													T.clone().setStyles(U.obj)
															.injectBefore(S)
												}
												if (V.length > 0) {
													T.setStyles(V.obj)
															.injectBefore(S)
												}
											}, this)
						}, this)
	},
	parseBarData : function(B, G, D) {
		var A = [], F = Number.MIN_VALUE, E = Number.MAX_VALUE, C = date = true;
		B.each(function(J, H) {
			var I = J.getText();
			A.push(I);
			if (C) {
				C = !isNaN(parseFloat(I.match(Number.REparsefloat)))
			}
			if (date) {
				date = !isNaN(Date.parse(I))
			}
		});
		A = A.map(function(H) {
			if (date) {
				H = new Date(Date.parse(H)).valueOf()
			} else {
				if (C) {
					H = parseFloat(H.match(Number.REparsefloat))
				}
			}
			F = Math.max(F, H);
			E = Math.min(E, H);
			return H
		});
		if (F == E) {
			F = E + 1
		}
		D = D / (F - E);
		return A.map(function(H) {
			return ((D * (H - E)) + G).toInt()
		})
	},
	getTableValues : function(G, H) {
		var F = $E("table", G);
		if (!F) {
			return false
		}
		var C = F.rows.length;
		if (C > 1) {
			var E = F.rows[0];
			for ( var D = 0; D < E.cells.length; D++) {
				if ($getText(E.cells[D]).trim() == H) {
					var A = [];
					for ( var B = 1; B < C; B++) {
						A.push(new Element("span")
								.wrapChildren(F.rows[B].cells[D]))
					}
					return A
				}
			}
		}
		for ( var D = 0; D < C; D++) {
			var E = F.rows[D];
			if ($getText(E.cells[0]).trim() == H) {
				var A = [];
				for ( var B = 1; B < E.cells.length; B++) {
					A.push(new Element("span").wrapChildren(E.cells[B]))
				}
				return A
			}
		}
		return false
	}
};
Wiki.addPageRender(GraphBar);
var Collapsible = {
	pims : [],
	render : function(C, A) {
		C = $(C);
		if (!C) {
			return
		}
		var B = Wiki.Context.test(/view|edit|comment/) ? "JSPWikiCollapse" + A
				: "";
		if (!this.bullet) {
			this.bullet = new Element("div", {
				"class" : "collapseBullet"
			}).setHTML("&bull;")
		}
		this.pims.push( {
			name : B,
			value : "",
			initial : (B ? Cookie.get(B) : "")
		});
		$ES(".collapse", C).each(function(D) {
			if (!$E(".collapseBullet", D)) {
				this.collapseNode(D)
			}
		}, this);
		$ES(".collapsebox,.collapsebox-closed", C).each(function(D) {
			this.collapseBox(D)
		}, this)
	},
	collapseBox : function(D) {
		if ($E(".collapsetitle", D)) {
			return
		}
		var E = D.getFirst();
		if (!E) {
			return
		}
		var A = new Element("div", {
			"class" : "collapsebody"
		}), B = this.bullet.clone(), C = D.hasClass("collapsebox-closed");
		while (E.nextSibling) {
			A.appendChild(E.nextSibling)
		}
		D.appendChild(A);
		if (C) {
			D.removeClass("collapsebox-closed").addClass("collapsebox")
		}
		B.injectTop(E.addClass("collapsetitle"));
		this.newBullet(B, A, !C, E)
	},
	collapseNode : function(A) {
		$ES("li", A).each(function(B) {
			var D = $E("ul", B) || $E("ol", B);
			var E = true;
			for ( var F = B.firstChild; F; F = F.nextSibling) {
				if ((F.nodeType == 3) && (F.nodeValue.trim() == "")) {
					continue
				}
				if ((F.nodeName == "UL") || (F.nodeName == "OL")) {
					break
				}
				E = false;
				break
			}
			if (E) {
				return
			}
			new Element("div", {
				"class" : "collapsebody"
			}).wrapChildren(B);
			var C = this.bullet.clone().injectTop(B);
			if (D) {
				this.newBullet(C, D, (D.getTag() == "ul"))
			}
		}, this)
	},
	newBullet : function(C, A, F, E) {
		var D = this.pims.getLast();
		F = this.parseCookie(F);
		if (!E) {
			E = C
		}
		var B = A.setStyle("overflow", "hidden").effect("height", {
			wait : false,
			onStart : this.renderBullet.bind(C),
			onComplete : function() {
				if (C.hasClass("collapseOpen")) {
					A.setStyle("height", "auto")
				}
			}
		});
		C.className = (F ? "collapseClose" : "collapseOpen");
		E.addEvent("click",
				this.clickBullet.bind(C, [ D, D.value.length - 1, B ]))
				.addEvent("mouseenter", function() {
					E.addClass("hover")
				}).addEvent("mouseleave", function() {
					E.removeClass("hover")
				});
		B.fireEvent("onStart");
		if (!F) {
			B.set(0)
		}
	},
	renderBullet : function() {
		if (this.hasClass("collapseClose")) {
			this.setProperties( {
				title : "collapse".localize(),
				"class" : "collapseOpen"
			}).setHTML("-")
		} else {
			this.setProperties( {
				title : "expand".localize(),
				"class" : "collapseClose"
			}).setHTML("+")
		}
	},
	clickBullet : function(B, C, A) {
		// protective Google Chrome and FF4 fix		
		if($type(B) == 'array'){
			C = B[1];
			A = B[2];
			B = B[0];		
		}
		
		var E = this.hasClass("collapseOpen"), D = A.element.scrollHeight;
		if (E) {
			A.start(D, 0)
		} else {
			A.start(D)
		}
		B.value = B.value.substring(0, C) + (E ? "c" : "o")
				+ B.value.substring(C + 1);
		if (B.name) {
			Cookie.set(B.name, B.value, {
				path : Wiki.BasePath,
				duration : 20
			})
		}
	},
	parseCookie : function(D) {
		var A = this.pims.getLast(), E = A.value.length, B = (D ? "o" : "c");
		if (A.initial && (A.initial.length > E)) {
			var C = A.initial.charAt(E);
			if ((D && (C == "c")) || (!D && (C == "o"))) {
				B = C
			}
			if (B != C) {
				A.initial = null
			}
		}
		A.value += B;
		return (B == "o")
	}
};
Wiki.addPageRender(Collapsible);
var Sortable = {
	render : function(B, A) {
		this.DefaultTitle = "sort.click".localize();
		this.AscendingTitle = "sort.ascending".localize();
		this.DescendingTitle = "sort.descending".localize();
		$ES(".sortable table", B)
				.each(
						function(C) {
							if (C.rows.length < 2) {
								return
							}
							$A(C.rows[0].cells)
									.each(
											function(D) {
												D = $(D);
												if (D.getTag() == "th") {
													D
															.addEvent(
																	"click",
																	this.sort
																			.bind(
																					this,
																					[ D ]))
															.addClass("sort").title = this.DefaultTitle
												}
											}, this)
						}, this)
	},
	sort : function(A) {
		var H = getAncestorByTagName(A, "table"), B = (H.filterStack), I = (H.sortCache || []), C = 0, E = $T(H);
		A = $(A);
		$A(E.rows[0].cells)
				.each(
						function(J, K) {
							if (J.getTag() != "th") {
								return
							}
							if (A == J) {
								C = K;
								return
							}
							J.removeClass("sortAscending").removeClass(
									"sortDescending").addClass("sort").title = Sortable.DefaultTitle
						});
		if (I.length == 0) {
			$A(E.rows).each(function(K, J) {
				if ((J == 0) || ((J == 1) && (B))) {
					return
				}
				I.push(K)
			})
		}
		var D = Sortable.guessDataType(I, C);
		if (A.hasClass("sort")) {
			I.sort(Sortable.createCompare(C, D))
		} else {
			I.reverse()
		}
		var F = A.hasClass("sortDescending");
		A.removeClass("sort").removeClass("sortAscending").removeClass(
				"sortDescending");
		A.addClass(F ? "sortAscending" : "sortDescending").title = F ? Sortable.DescendingTitle
				: Sortable.AscendingTitle;
		var G = document.createDocumentFragment();
		I.each(function(K, J) {
			G.appendChild(K)
		});
		E.appendChild(G);
		H.sortCache = I;
		if (H.zebra) {
			H.zebra()
		}
	},
	guessDataType : function(C, B) {
		var A = date = ip4 = euro = kmgt = true;
		C.each(function(F, E) {
			var D = $getText(F.cells[B]).clean().toLowerCase();
			if (A) {
				A = !isNaN(parseFloat(D))
			}
			if (date) {
				date = !isNaN(Date.parse(D))
			}
			if (ip4) {
				ip4 = D.test(/(?:\\d{1,3}\\.){3}\\d{1,3}/)
			}
			if (euro) {
				euro = D.test(/^[£$€][0-9.,]+/)
			}
			if (kmgt) {
				kmgt = D.test(/(?:[0-9.,]+)\s*(?:[kmgt])b/)
			}
		});
		return (kmgt) ? "kmgt" : (euro) ? "euro" : (ip4) ? "ip4"
				: (date) ? "date" : (A) ? "num" : "string"
	},
	convert : function(E, C) {
		switch (C) {
		case "num":
			return parseFloat(E.match(Number.REparsefloat));
		case "euro":
			return parseFloat(E.replace(/[^0-9.,]/g, ""));
		case "date":
			return new Date(Date.parse(E));
		case "ip4":
			var A = E.split(".");
			return parseInt(A[0]) * 1000000000 + parseInt(A[1]) * 1000000
					+ parseInt(A[2]) * 1000 + parseInt(A[3]);
		case "kmgt":
			var B = E.toString().toLowerCase().match(/([0-9.,]+)\s*([kmgt])b/);
			if (!B) {
				return 0
			}
			var D = B[2];
			D = (D == "m") ? 3 : (D == "g") ? 6 : (D == "t") ? 9 : 0;
			return B[1].toFloat() * Math.pow(10, D);
		default:
			return E.toString().toLowerCase()
		}
	},
	createCompare : function(A, B) {
		return function(F, D) {
			var E = Sortable.convert($getText(F.cells[A]), B);
			var C = Sortable.convert($getText(D.cells[A]), B);
			if (E < C) {
				return -1
			} else {
				if (E > C) {
					return 1
				} else {
					return 0
				}
			}
		}
	}
};
Wiki.addPageRender(Sortable);
var TableFilter = {
	render : function(B, A) {
		this.All = "filter.all".localize();
		this.FilterRow = 1;
		$ES(".table-filter table", B).each(
				function(F) {
					if (F.rows.length < 2) {
						return
					}
					var E = $(F.insertRow(TableFilter.FilterRow)).addClass(
							"filterrow");
					for ( var C = 0; C < F.rows[0].cells.length; C++) {
						var D = new Element("select", {
							events : {
								change : TableFilter.filter
							}
						});
						D.fcol = C;
						new Element("th").adopt(D).inject(E)
					}
					F.filterStack = [];
					TableFilter.buildEmptyFilters(F)
				})
	},
	buildEmptyFilters : function(C) {
		for ( var B = 0; B < C.rows[0].cells.length; B++) {
			var A = C.filterStack.some(function(D) {
				return D.fcol == B
			});
			if (!A) {
				TableFilter.buildFilter(C, B)
			}
		}
		if (C.zebra) {
			C.zebra()
		}
	},
	buildFilter : function(D, B, C) {
		var A = D.rows[TableFilter.FilterRow].cells[B].firstChild;
		if (!A) {
			return
		}
		A.options.length = 0;
		var F = [];
		$A(D.rows).each(function(H, G) {
			if ((G == 0) || (G == TableFilter.FilterRow)) {
				return
			}
			if (H.style.display == "none") {
				return
			}
			F.push(H)
		});
		F.sort(Sortable.createCompare(B, Sortable.guessDataType(F, B)));
		A.options[0] = new Option(this.All, this.All);
		var E;
		F.each(function(I, H) {
			var G = $getText(I.cells[B]).clean().toLowerCase();
			if (G == E) {
				return
			}
			E = G;
			A.options[A.options.length] = new Option(G.trunc(32), E)
		});
		(A.options.length <= 2) ? A.hide() : A.show();
		if (C != undefined) {
			A.value = C
		} else {
			A.options[0].selected = true
		}
	},
	filter : function() {
		var A = this.fcol, C = this.value, B = getAncestorByTagName(this,
				"table");
		if (!B || B.style.display == "none") {
			return
		}
		if (B.filterStack.every(function(E, D) {
			if (E.fcol != A) {
				return true
			}
			if (C == TableFilter.All) {
				B.filterStack.splice(D, 1)
			} else {
				E.fValue = C
			}
			return false
		})) {
			B.filterStack.push( {
				fValue : C,
				fcol : A
			})
		}
		$A(B.rows).each(function(E, D) {
			E.style.display = ""
		});
		B.filterStack.each(function(F) {
			var D = F.fValue, G = F.fcol;
			TableFilter.buildFilter(B, G, D);
			var E = 0;
			$A(B.rows).each(function(I, H) {
				if ((H == 0) || (H == TableFilter.FilterRow)) {
					return
				}
				if (D != $getText(I.cells[G]).clean().toLowerCase()) {
					I.style.display = "none"
				}
			})
		});
		TableFilter.buildEmptyFilters(B)
	}
};
Wiki.addPageRender(TableFilter);
var Categories = {
	render : function(B, A) {
		$ES(".category a.wikipage", B)
				.each(
						function(E) {
							var G = Wiki.getPageName(E.href);
							if (!G) {
								return
							}
							var D = new Element("span").injectBefore(E)
									.adopt(E), C = new Element("div", {
								"class" : "categoryPopup"
							}).inject(D), F = C.effect("opacity", {
								wait : false
							}).set(0);
							E
									.addClass("categoryLink")
									.setProperties( {
										href : "#",
										title : "category.title".localize(G)
									})
									.addEvent(
											"click",
											function(H) {
												new Event(H).stop();
												new Ajax(
														Wiki.TemplateUrl
																+ "AJAXCategories.jsp",
														{
															postBody : "&page="
																	+ G,
															update : C,
															onComplete : function() {
																E
																		.setProperty(
																				"title",
																				"")
																		.removeEvent(
																				"click");
																D
																		.addEvent(
																				"mouseover",
																				function(
																						I) {
																					F
																							.start(0.9)
																				})
																		.addEvent(
																				"mouseout",
																				function(
																						I) {
																					F
																							.start(0)
																				});
																C
																		.setStyle(
																				"left",
																				E
																						.getPosition().x);
																C
																		.setStyle(
																				"top",
																				E
																						.getPosition().y + 16);
																F.start(0.9);
																$ES(
																		"li,div.categoryTitle",
																		C)
																		.each(
																				function(
																						I) {
																					I
																							.addEvent(
																									"mouseout",
																									function() {
																										this
																												.removeClass("hover")
																									})
																							.addEvent(
																									"mouseover",
																									function() {
																										this
																												.addClass("hover")
																									})
																				})
															}
														}).request()
											})
						})
	}
};
Wiki.addPageRender(Categories);
var ZebraTable = {
	render : function(B, A) {
		$ES("*[class^=zebra]", B)
				.each(
						function(G) {
							var E = G.className.split("-"), F = E[1]
									.test("table"), D = "", C = "";
							if (E[1]) {
								D = new Color(E[1], "hex")
							}
							if (E[2]) {
								C = new Color(E[2], "hex")
							}
							$ES("table", G).each(function(H) {
								H.zebra = this.zebrafy.pass( [ F, D, C ], H);
								H.zebra()
							}, this)
						}, this)
	},
	zebrafy : function(D, C, B) {
		var A = 0;
		$A($T(this).rows).each(function(F, E) {
			if (E == 0 || (F.style.display == "none")) {
				return
			}
			if (D) {
				(A++ % 2) ? $(F).addClass("odd") : $(F).removeClass("odd")
			} else {
				$(F).setStyle("background-color", (A++ % 2) ? C : B)
			}
		})
	}
};
Wiki.addPageRender(ZebraTable);
var HighlightWord = {
	onPageLoad : function() {
		var A = Wiki.prefs.get("PrevQuery");
		Wiki.prefs.set("PrevQuery", "");
		if (!A && document.referrer.test("(?:\\?|&)(?:q|query)=([^&]*)", "g")) {
			A = RegExp.$1
		}
		if (!A) {
			return
		}
		var B = decodeURIComponent(A).stripScripts();
		B = B.replace(/\+/g, " ");
		B = B.replace(/\s+-\S+/g, "");
		B = B.replace(/([\(\[\{\\\^\$\|\)\?\*\.\+])/g, "\\$1");
		B = B.trim().split(/\s+/).join("|");
		this.reMatch = new RegExp("(" + B + ")", "gi");
		this.walkDomTree($("pagecontent"))
	},
	walkDomTree : function(C) {
		if (!C) {
			return
		}
		for ( var F = null, E = C.firstChild; E; E = F) {
			F = E.nextSibling;
			this.walkDomTree(E)
		}
		if (C.nodeType != 3) {
			return
		}
		if (C.parentNode.className == "searchword") {
			return
		}
		var B = C.innerText || C.textContent || "";
		B = B.replace(/</g, "&lt;");
		if (!this.reMatch.test(B)) {
			return
		}
		var A = new Element("span").setHTML(B.replace(this.reMatch,
				"<span class='searchword'>$1</span>"));
		var D = document.createDocumentFragment();
		while (A.firstChild) {
			D.appendChild(A.firstChild)
		}
		C.parentNode.replaceChild(D, C)
	}
};
window.addEvent("load", function() {
	Wiki.onPageLoad();
	SearchBox.onPageLoad();
	HighlightWord.onPageLoad();
	Wiki.setFocus()
});
