Index: ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/LICENSE
===================================================================
--- ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/LICENSE	(revision 14969)
+++ ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/LICENSE	(revision 14969)
@@ -0,0 +1,12 @@
+All Files of this Software are licensed under the Creative Commons 
+Attribution-NonCommercial-ShareAlike 3.0 Unported 
+License if not stated otherwise in a files head. To view a copy of this license, visit
+http://creativecommons.org/licenses/by-nc-sa/3.0/ or send a letter to Creative
+Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
+
+Alternatively, this plugin may be distributed and executed on hardware which
+is licensed by Dream Multimedia GmbH.
+
+This plugin is NOT free software. It is open source, you are allowed to
+modify it (if you keep the license), but it may not be commercially 
+distributed other than under the conditions noted above.
Index: ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/WebChilds/External/AutoTimer.py
===================================================================
--- ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/WebChilds/External/AutoTimer.py	(revision 14969)
+++ ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/WebChilds/External/AutoTimer.py	(revision 14969)
@@ -0,0 +1,8 @@
+from Plugins.Extensions.WebInterface.WebChilds.Toplevel import addExternalChild
+from Plugins.Extensions.AutoTimer.AutoTimerResource import AutoTimerDoParseResource, \
+	AutoTimerListAutoTimerResource
+
+root = AutoTimerListAutoTimerResource()
+root.putChild('parse', AutoTimerDoParseResource())
+addExternalChild( ("autotimer", root ) )
+
Index: ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/WebChilds/External/EPGRefresh.py
===================================================================
--- ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/WebChilds/External/EPGRefresh.py	(revision 14969)
+++ ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/WebChilds/External/EPGRefresh.py	(revision 14969)
@@ -0,0 +1,16 @@
+from Plugins.Extensions.WebInterface.WebChilds.Toplevel import addExternalChild
+from Plugins.Extensions.EPGRefresh.EPGRefreshResource import \
+		EPGRefreshStartRefreshResource, \
+		EPGRefreshAddRemoveServiceResource, \
+		EPGRefreshListServicesResource, \
+		EPGRefreshChangeSettingsResource, \
+		EPGRefreshSettingsResource
+
+root = EPGRefreshListServicesResource()
+root.putChild("refresh", EPGRefreshStartRefreshResource())
+root.putChild("add", EPGRefreshAddRemoveServiceResource(EPGRefreshAddRemoveServiceResource.TYPE_ADD))
+root.putChild("del", EPGRefreshAddRemoveServiceResource(EPGRefreshAddRemoveServiceResource.TYPE_DEL))
+root.putChild("set", EPGRefreshChangeSettingsResource())
+root.putChild("get", EPGRefreshSettingsResource())
+addExternalChild( ("epgrefresh", root) )
+
Index: ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/WebChilds/External/Example.py
===================================================================
--- ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/WebChilds/External/Example.py	(revision 14969)
+++ ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/WebChilds/External/Example.py	(revision 14969)
@@ -0,0 +1,1714 @@
+# AAF-Panel by Bonkel
+from Components.config import config
+import sys, os, struct, stat
+from twisted.web import resource, http
+from Plugins.Extensions.WebInterface.WebChilds.Toplevel import addExternalChild
+import commands
+from os import path as os_path, symlink, listdir, unlink, readlink, remove, system
+from commands import getoutput
+from enigma import eConsoleAppContainer, gMainDC
+from Screens.Standby import TryQuitMainloop
+
+header_string=""
+header_string +="<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\""
+header_string +="\"http://www.w3.org/TR/html4/loose.dtd\">"
+header_string +="<head>"
+header_string +="<meta content=\"text/html; charset=UTF-8\" http-equiv=\"content-type\"><META HTTP-EQUIV=\"CACHE-CONTROL\" CONTENT=\"NO-CACHE\">"
+header_string +="</head><body><font color=\"#485052\" >"
+tself="target=\"_self\""
+cammessage="<center>Bitte erst die Aktive SoftCam beenden! <a href=\"SoftCamPanel\" target=\"_self\"><input type=\"submit\" value=\"Zur&uuml;ck\"></a></center>"
+camdkil="<a href=\"camdkill\""
+#ipk
+kplugins="<center>Sry keine Plugins gefunden!</center>"
+#flashen
+receiver = commands.getoutput('cat /etc/model')
+meldungbegin="<center>Bitte jetzt das Image per FTP in /tmp kopieren ,danach auf \"Best&auml;tigen\" klicken<br><b>!!!WICHTIG!!! die Datei muss die Endung img haben !!!WICHTIG!!!</b><br>"
+meldungend="<a href=\"UpdatePanel\" target=\"_self\"><input type=\"submit\" value=\"Abbrechen\"></a></center>"
+flashmeldung="<center>Bitte kopier auch die md5 datei nach /tmp und dann probier es"
+jalert="onclick=\"alert('Willst du wirklich flashen???');\""
+backstart="erfolgreich gestartet! <a href=\"SoftCamPanel\" %s><input type=\"submit\" value=\"Zur&uuml;ck\"></a></center>" % (tself)
+backend="erfolgreich beendet! <a href=\"SoftCamPanel\" %s><input type=\"submit\" value=\"Zur&uuml;ck\"></a></center>" % (tself)
+#overclock
+pllone="/proc/cpu_frequ/pll0_ndiv_mdiv"
+backzu="<a href=\"overclock\" target=\"_self\"><input type=\"submit\" value=\"Zur&uuml;ck\"></a>"
+wahl="<select name=\"wahl\" size=\"1\" onChange=\"self.location.href=this.options[this.selectedIndex].value;\">"
+conf="/var/etc/autostart/start-config"
+#video
+port = config.av.videoport.value
+mode = config.av.videomode[port].value
+vmode = "/proc/stb/video/videomode"
+vmodee = "/etc/videomode"
+colormode = "/proc/stb/avs/0/colorformat"
+amode = "/proc/stb/hdmi/audio_source"
+tmode = "/proc/stb/video/3d_mode"
+#start softcam
+def checkCams(objelt):
+	emuDir = "/var/etc/"
+	emuDirlist = []
+	infoList = []
+	emuDirlist = listdir(emuDir)
+
+	for x in emuDirlist:
+		list = []
+		if x.find("emu") > -1:
+			if os_path.islink(emuDir + x):
+				linkemudir = readlink(emuDir + x)
+				print "[Softcam] linkemudir", linkemudir
+				em = open(linkemudir)
+			else:
+				em = open(emuDir + x)
+
+			for line in em.readlines():
+				line1 = line
+				if line.find("emuname") > -1:
+					line = line.split("=")
+					list.append(line[1].strip())
+				line = line1
+				if line.find("binname") > -1:
+					line = line.split("=")
+					list.append(line[1].strip())
+					p = getoutput('pidof %s |wc -w' % line[1].strip())
+					if int(p) > 0:
+						list.append("yes")
+					else:
+						list.append("no")
+
+				line = line1
+				if line.find("startcam") > -1:
+					line = line.split("=")
+					list.append(line[1].strip())
+
+				line = line1
+				if line.find("stopcam") > -1:
+					line = line.split("=")
+					list.append(line[1].strip())
+
+			if len(list) >0:
+				infoList.append(list)
+	if os.path.exists("/var/swap/etc") is True:
+		emuDir1 = "/var/swap/etc/"
+		emuDirlist1 = listdir(emuDir1)
+		for x in emuDirlist1:
+			list = []
+			if x.find("emu") > -1:
+				if os_path.islink(emuDir1 + x):
+					linkemudir = readlink(emuDir1 + x)
+					print "[Softcam] linkemudir", linkemudir
+					em = open(linkemudir)
+				else:
+					em = open(emuDir1 + x)
+
+				for line in em.readlines():
+					line1 = line
+					if line.find("emuname") > -1:
+						line = line.split("=")
+						list.append(line[1].strip())
+					line = line1
+					if line.find("binname") > -1:
+						line = line.split("=")
+						list.append(line[1].strip())
+						p = getoutput('pidof %s |wc -w' % line[1].strip())
+						if int(p) > 0:
+							list.append("yes")
+						else:
+							list.append("no")
+
+					line = line1
+					if line.find("startcam") > -1:
+						line = line.split("=")
+						list.append(line[1].strip())
+
+					line = line1
+					if line.find("stopcam") > -1:
+						line = line.split("=")
+						list.append(line[1].strip())
+
+				if len(list) >0:
+					infoList.append(list)
+	print infoList
+	return infoList
+class SoftCamPanel(resource.Resource):
+	def render_GET(self, req):
+		global infoList
+		output = commands.getoutput('ps -A')
+		aktiv="<input style=\"background-color&#58;#00b000;\" type=\"button\" value=\"Aktiviert\">"
+		aktivieren="<input style=\"color&#58;#00b000;\" type=\"submit\" value=\"Aktivieren\">"
+		deaktivieren="<input style=\"color&#58;#FF0000;\" type=\"submit\" value=\"Deaktivieren\">"
+		deaktiviert="<input style=\"background-color&#58;#FF0000;\" type=\"button\" value=\"Deaktiviert\">"
+		req.setResponseCode(http.OK)
+		req.setHeader('Content-type', 'text/html')
+		req.setHeader('charset', 'UTF-8')
+		infoList = checkCams(None)
+		camdinfo = ""
+		html=header_string
+		for info in infoList:
+			addExternalChild( ("%sstart" % (info[0]), CamdStart(info[0])) )
+			addExternalChild( ("%skill" % (info[0]), CamdKill(info[0])) )
+			if info[2] == "yes":
+				camd = '%s<a href=\"%skill\" target=\"_self\">%s</a>' % (aktiv,info[0],deaktivieren)
+			else:
+				camd = '<a href=\"%sstart\" target=\"_self\">%s</a>%s</form>' % (info[0],aktivieren,deaktiviert)
+			html +="<center><table style=\"width: 80%%;table-layout: fixed;\" border=\"1\" cellspacing=\"0\"><tr><td align=\"left\">%s:</td><td align=\"right\">%s</td></tr></center>" % (info[0],camd)
+		active = commands.getoutput('emu.sh active')
+		ipaddrr = commands.getoutput('ifconfig | grep addr: | cut -d ":" -f2 | sed s/Bcast//')
+		if 'oscam' in active:
+			webch = commands.getoutput('cat /var/keys/oscam.conf | grep webif')
+			if 'webif' in webch:
+				port = commands.getoutput('cat /var/keys/oscam.conf | grep httpport | cut -d "=" -f2 | sed "s/ \+//g"')
+				html +="<center><a href=\"http://%s:%s\"><input type=\"button\" value=\"Oscam WebIF\"></a></center>" % (ipaddrr, port)
+		elif 'vizcam' in active:
+			webch = commands.getoutput('cat /var/keys/vizcam.conf | grep webif')
+			if 'webif' in webch:
+				port = commands.getoutput('cat /var/keys/vizcam.conf | grep httpport | cut -d "=" -f2 | sed "s/ \+//g"')
+				html +="<center><a href=\"http://%s:%s\"><input type=\"button\" value=\"Vizcam WebIF\"></a></center>" % (ipaddrr, port)
+		else:
+			html +=""
+		if os.path.isfile("/tmp/ecm.info"):
+			fd=open("/tmp/ecm.info")
+			for line in fd:
+				print line
+				html +="<center><table align=\"center\" style=\"width: 50%%;table-layout: fixed;\" border=\"1\" cellspacing=\"0\"><tr><td>%s</font></td></tr></table></center>" % (line)
+		else:
+			html +="<center><table style=\"width: 50%%;table-layout: fixed;\" border=\"1\" cellspacing=\"0\"><tr><td><font color=\"#a1a1a1\">ECM Info N/A</font></td></tr></table></center>"
+		return  html
+class CamdStart(resource.Resource):
+	def __init__(self,input):
+		self.container=eConsoleAppContainer()
+		self.container.appClosed.append(self.finished)
+		self.input = input
+		print "self.input", self.input
+	def render_GET(self, req):
+		global infoList
+		req.setResponseCode(http.OK)
+		req.setHeader('Content-type', 'text/html')
+		req.setHeader('charset', 'UTF-8')
+		html=header_string
+		for info in infoList:
+			if info[0] == self.input:
+				self.container.execute(info[3])
+				config.softcam.actCam.value = "%s" % (self.input)
+				config.softcam.actCam.save()
+				html +="<center>%s erfolgreich Gestartet!  <a href=\"SoftCamPanel\" target=\"_self\"><input type=\"submit\" value=\"Zur&uuml;ck\"></a></center>" % (self.input)
+			else:
+				html +="<p></p>"
+		return  html
+	def finished(self,retval):
+		print "finished", retval
+class CamdKill(resource.Resource):
+	def __init__(self,input):
+		self.container=eConsoleAppContainer()
+		self.container.appClosed.append(self.finished)
+		self.input = input
+	def render_GET(self, req):
+		global infoList
+		req.setResponseCode(http.OK)
+		req.setHeader('Content-type', 'text/html')
+		req.setHeader('charset', 'UTF-8')
+		html=header_string
+		for info in infoList:
+			if info[0] == self.input:
+				self.container.execute(info[4])
+				config.softcam.actCam.value = "no cam active"
+				config.softcam.actCam.save()
+				html +="<center>%s erfolgreich beendet!  <a href=\"SoftCamPanel\" target=\"_self\"><input type=\"submit\" value=\"Zur&uuml;ck\"></a></center>" % (self.input)
+			else:
+				html +="<p></p>"
+		return  html
+	def finished(self,retval):
+		print "finished", retval
+addExternalChild( ("SoftCamPanel", SoftCamPanel()) )
+infoList = checkCams(None)
+for info in infoList:
+	addExternalChild( ("%sstart" % (info[0]), CamdStart(info[0])) )
+	addExternalChild( ("%skill" % (info[0]), CamdKill(info[0])) )
+#start update
+class UpdatePanel(resource.Resource):
+	def render_GET(self, req):
+		kernelflash="<a href=\"kernelmeldung\" %s %s><input type=\"submit\" value=\"Kernel Flashen\">" % (jalert,tself)
+		varflash="<a href=\"varmeldung\" %s %s><input type=\"submit\" value=\"Var Flashen\">" % (jalert,tself)
+		rootflash="<a href=\"rootmeldung\" %s %s><input type=\"submit\" value=\"Root Flashen\">" % (jalert,tself)
+		fullflash="<a href=\"fullmeldung\" %s %s><input type=\"submit\" value=\"FullImage Flashen\">" % (jalert,tself)
+		anfang="<center>"
+		message="<font color=\"#a1a1a1\">Sry diese funktion ist f&uuml;r deinen Receiver nicht Verf&uuml;gbar.</font>"
+		ende="</center>"
+		req.setResponseCode(http.OK)
+		req.setHeader('Content-type', 'text/html')
+		req.setHeader('charset', 'UTF-8')
+		html=header_string
+		if os.path.exists("/etc/.usbimage") is True:
+			html +="%s Sry nur f&uuml;r FlashImages %s" % (anfang,ende)
+		elif receiver.upper() == 'UFS910':
+			html +="%s%s<br>%s<br>%s<br>%s%s" % (anfang,kernelflash,varflash,rootflash,fullflash,ende)
+		elif receiver.upper() == 'UFS922':
+			html +="%s%s<br>%s<br>%s<br>%s%s" % (anfang,kernelflash,varflash,rootflash,fullflash,ende)
+		elif receiver.upper() == 'UFS912':
+			html +="%s%s<br>%s%s" % (anfang,kernelflash,rootflash,ende)
+		elif receiver.upper() == 'IPBOX91':
+			html +="%s%s<br>%s<br>%s<br>%s%s" % (anfang,kernelflash,varflash,rootflash,fullflash,ende)
+		elif receiver.upper() == 'IPBOX910':
+			html +="%s%s<br>%s<br>%s<br>%s%s" % (anfang,kernelflash,varflash,rootflash,fullflash,ende)
+		elif receiver.upper() == 'IPBOX900':
+			html +="%s%s<br>%s<br>%s<br>%s%s" % (anfang,kernelflash,varflash,rootflash,fullflash,ende)
+		elif receiver.upper() == 'IPBOX9000':
+			html +="%s%s<br>%s<br>%s<br>%s%s" % (anfang,kernelflash,varflash,rootflash,fullflash,ende)
+		elif receiver.upper() == 'AT7000':
+			html +="%s%s<br>%s<br>%s<br>%s%s" % (anfang,kernelflash,varflash,rootflash,fullflash,ende)
+		elif receiver.upper() == 'AT700':
+			html +="%s%s<br>%s<br>%s<br>%s%s" % (anfang,kernelflash,varflash,rootflash,fullflash,ende)
+		elif receiver.upper() == 'AT7500':
+			html +="Sry nicht f&uuml;r Atevio7500 verf&uuml;gbar!"
+		else:
+			html +="%s%s%s" % (anfang,message,ende)
+		return  html
+addExternalChild( ("UpdatePanel", UpdatePanel()) )
+class KernelMeldung(resource.Resource):
+	def render_GET(self, req):
+		req.setResponseCode(http.OK)
+		req.setHeader('Content-type', 'text/html')
+		req.setHeader('charset', 'UTF-8')
+		html=header_string
+		html +="%s<a href=\"kernelflashen\" target=\"_self\"><input type=\"submit\" value=\"Best&auml;tigen\"></a>%s" % (meldungbegin, meldungend)
+		return  html
+addExternalChild( ("kernelmeldung", KernelMeldung()) )
+class VarMeldung(resource.Resource):
+	def render_GET(self, req):
+		req.setResponseCode(http.OK)
+		req.setHeader('Content-type', 'text/html')
+		req.setHeader('charset', 'UTF-8')
+		html=header_string
+		html +="%s<a href=\"varflashen\" target=\"_self\"><input type=\"submit\" value=\"Best&auml;tigen\"></a>%s" % (meldungbegin, meldungend)
+		return  html
+addExternalChild( ("varmeldung", VarMeldung()) )
+class RootMeldung(resource.Resource):
+	def render_GET(self, req):
+		req.setResponseCode(http.OK)
+		req.setHeader('Content-type', 'text/html')
+		req.setHeader('charset', 'UTF-8')
+		html=header_string
+		html +="%s<a href=\"rootflashen\" target=\"_self\"><input type=\"submit\" value=\"Best&auml;tigen\"></a>%s" % (meldungbegin, meldungend)
+		return  html
+addExternalChild( ("rootmeldung", RootMeldung()) )
+class FullMeldung(resource.Resource):
+	def render_GET(self, req):
+		req.setResponseCode(http.OK)
+		req.setHeader('Content-type', 'text/html')
+		req.setHeader('charset', 'UTF-8')
+		html=header_string
+		html +="%s<a href=\"fullflashen\" target=\"_self\"><input type=\"submit\" value=\"Best&auml;tigen\"></a>%s" % (meldungbegin, meldungend)
+		return  html
+addExternalChild( ("fullmeldung", FullMeldung()) )
+class KernelFlashen(resource.Resource):
+	def __init__(self):
+		self.container=eConsoleAppContainer()
+		self.container.appClosed.append(self.finished)
+	def render_GET(self, req):
+		req.setResponseCode(http.OK)
+		req.setHeader('Content-type', 'text/html')
+		md5check = commands.getoutput('ls /tmp | grep md5')
+		imgcheck = commands.getoutput('ls /tmp | grep img')
+		img="/tmp/%s" % (imgcheck)
+		md5="/tmp/%s" % (md5check)
+		req.setHeader('charset', 'UTF-8')
+		html=header_string
+		if 'md5' in md5check:
+			html +="<center>%s wird in ca.5 sekunden geflashed</center>" % (img)
+			self.container.execute('sleep 5 && /sbin/update.sh tmp kernel ' + str(img) + ' > /var/swap/update_debug.log 2>&1')
+		else:
+			html +="%s <a href=\"kernelflashen\" target=\"_self\"><input type=\"submit\" value=\"Nochmal\"></a></center>" % (flashmeldung)
+		return  html
+	def finished(self,retval):
+		print "finished", retval
+addExternalChild( ("kernelflashen", KernelFlashen()) )
+class VarFlashen(resource.Resource):
+	def __init__(self):
+		self.container=eConsoleAppContainer()
+		self.container.appClosed.append(self.finished)
+	def render_GET(self, req):
+		req.setResponseCode(http.OK)
+		req.setHeader('Content-type', 'text/html')
+		md5check = commands.getoutput('ls /tmp | grep md5')
+		imgcheck = commands.getoutput('ls /tmp | grep img')
+		img="/tmp/%s" % (imgcheck)
+		md5="/tmp/%s" % (md5check)
+		req.setHeader('charset', 'UTF-8')
+		html=header_string
+		if 'md5' in md5check:
+			html +="<center>%s in ca.5 sekunden wird geflashed</center>" % (img)
+			self.container.execute('sleep 5 && /sbin/update.sh tmp var ' + str(img) + ' > /var/swap/update_debug.log 2>&1')
+		else:
+			html +="%s <a href=\"varflashen\" target=\"_self\"><input type=\"submit\" value=\"Nochmal\"></a></center>" % (flashmeldung)
+		return  html
+	def finished(self,retval):
+		print "finished", retval
+addExternalChild( ("varflashen", VarFlashen()) )
+class RootFlashen(resource.Resource):
+	def __init__(self):
+		self.container=eConsoleAppContainer()
+		self.container.appClosed.append(self.finished)
+	def render_GET(self, req):
+		req.setResponseCode(http.OK)
+		req.setHeader('Content-type', 'text/html')
+		md5check = commands.getoutput('ls /tmp | grep md5')
+		imgcheck = commands.getoutput('ls /tmp | grep img')
+		img="/tmp/%s" % (imgcheck)
+		md5="/tmp/%s" % (md5check)
+		req.setHeader('charset', 'UTF-8')
+		html=header_string
+		if 'md5' in md5check:
+			html +="<center>%s wird in ca.5 sekunden geflashed</center>" % (img)
+			self.container.execute('sleep 5 && /sbin/update.sh tmp root ' + str(img) + ' > /var/swap/update_debug.log 2>&1')
+		else:
+			html +="%s <a href=\"rootflashen\" target=\"_self\"><input type=\"submit\" value=\"Nochmal\"></a></center>" % (flashmeldung)
+		return  html
+	def finished(self,retval):
+		print "finished", retval
+addExternalChild( ("rootflashen", RootFlashen()) )
+class FullFlashen(resource.Resource):
+	def __init__(self):
+		self.container=eConsoleAppContainer()
+		self.container.appClosed.append(self.finished)
+	def render_GET(self, req):
+		req.setResponseCode(http.OK)
+		req.setHeader('Content-type', 'text/html')
+		md5check = commands.getoutput('ls /tmp | grep md5')
+		imgcheck = commands.getoutput('ls /tmp | grep img')
+		img="/tmp/%s" % (imgcheck)
+		md5="/tmp/%s" % (md5check)
+		req.setHeader('charset', 'UTF-8')
+		html=header_string
+		if 'md5' in md5check:
+			html +="<center>%s wird in ca.5 sekunden geflashed</center>" % (img)
+			self.container.execute('sleep 5 && /sbin/update.sh tmp full ' + str(img) + ' > /var/swap/update_debug.log 2>&1')
+		else:
+			html +="%s <a href=\"fullflashen\" target=\"_self\"><input type=\"submit\" value=\"Nochmal\"></a></center>" % (flashmeldung)
+		return  html
+	def finished(self,retval):
+		print "finished", retval
+addExternalChild( ("fullflashen", FullFlashen()) )
+#backup&restore
+class SettingBackupRestore(resource.Resource):
+	def render_GET(self, req):
+		output = commands.getoutput('ps -A')
+		req.setResponseCode(http.OK)
+		req.setHeader('Content-type', 'text/html')
+		req.setHeader('charset', 'UTF-8')
+		html=header_string
+		html +="<center><b>Backup&Restore RecordFestplatte oder Swapstick:</b><br><a href=\"settingbackup\" target=\"_self\"><input type=\"button\" value=\"Backup erstellen\"></a><br><a href=\"settingrestore\" target=\"_self\"><input type=\"button\" value=\"Backup einspielen\"></a><br><br><br><b>Restore mit heruntergeladenem backup:</b><br><a href=\"settingrestorepc\" target=\"_self\"><input type=\"button\" value=\"Backup von PC einspielen\"></a>"
+		return  html
+addExternalChild( ("settingbackuprestore", SettingBackupRestore()) )
+class SettingBackup(resource.Resource):
+	def __init__(self):
+		self.container=eConsoleAppContainer()
+		self.container.appClosed.append(self.finished)
+	def render_GET(self, req):
+		req.setResponseCode(http.OK)
+		req.setHeader('Content-type', 'text/html')
+		backupa = commands.getoutput('/sbin/settings enigma2 backup')
+		req.setHeader('charset', 'UTF-8')
+		html=header_string
+		if os.path.ismount("/var/swap/") or os.path.ismount("/media/hdd/"):
+			if 'successfully done to /media/hdd' in backupa:
+				self.container.execute('sleep 1 && tar -czvf /tmp/backup.tar.gz /media/hdd/backup/.actbackup /media/hdd/backup/*')
+				html +="<center>Backup erfolgreich nach /media/hdd erstellt!<br><br>Um es auch auf den Computer zu speichern, klicke nach 20 sekunden auf:<br><a href=\"file?file=/tmp/backup.tar.gz\" target=\"_self\"><input type=\"button\" value=\"Download\"></a></center>"
+			elif 'successfully done to /var/swap' in backupa:
+				self.container.execute('sleep 1 && tar -czvf /tmp/backup.tar.gz /var/swap/backup/.actbackup /var/swap/backup/*')
+				html +="<center>Backup erfolgreich nach /var/swap erstellt!<br><br>Um es auch auf den Computer zu speichern, klicke nach 20 sekunden auf:<br><a href=\"file?file=/tmp/backup.tar.gz\" target=\"_self\"><input type=\"button\" value=\"Download\"></a></center>"
+		else:
+			html +="<center>Backup fehlgeschlagen, da kein Swapstick oder die RecordFestplatte gemountet ist!</center>"
+		return  html
+	def finished(self,retval):
+		print "finished", retval
+addExternalChild( ("settingbackup", SettingBackup()) )
+class SettingRestore(resource.Resource):
+	def __init__(self):
+		self.container=eConsoleAppContainer()
+		self.container.appClosed.append(self.finished)
+	def render_GET(self, req):
+		req.setResponseCode(http.OK)
+		req.setHeader('Content-type', 'text/html')
+		message="<center>Receiver startet in ca. 15 sekunden neu und spielt das Backup ein!</center>"
+		req.setHeader('charset', 'UTF-8')
+		html=header_string
+		if os.path.isfile("/media/hdd/backup/.actbackup"):
+			f=open("/media/hdd/backup/.firstrun", "w"); f.close()
+			self.session.open(TryQuitMainloop, 2)
+			html +="%s" % (message)
+		elif os.path.isfile("/var/swap/backup/.actbackup"):
+			f=open("/var/swap/backup/.firstrun", "w"); f.close()
+			self.session.open(TryQuitMainloop, 2)
+			html +="%s" % (message)
+		else:
+			if os.path.exists("/media/hdd/backup"):
+				f=open("/media/hdd/backup/.firstrun", "w"); f.close()
+				self.session.open(TryQuitMainloop, 2)
+				html +="%s" % (message)
+			elif os.path.exists("/var/swap/backup"):
+				f=open("/var/swap/backup/.firstrun", "w"); f.close()
+				self.session.open(TryQuitMainloop, 2)
+				html +="%s" % (message)
+			else:
+				html +="<center>Backup einspielen fehlgeschlagen! Bitte nachschauen ob der Swapstick oder die RecordFestplatte gemountet ist!funden!</center>"
+		return  html
+	def finished(self,retval):
+		print "finished", retval
+addExternalChild( ("settingrestore", SettingRestore()) )
+class SettingRestorePC(resource.Resource):
+	def __init__(self):
+		self.container=eConsoleAppContainer()
+		self.container.appClosed.append(self.finished)
+	def render_GET(self, req):
+		req.setResponseCode(http.OK)
+		req.setHeader('Content-type', 'text/html')
+		message="<center>Receiver startet in ca. 20 sekunden neu und spielt das Backup ein!</center>"
+		req.setHeader('charset', 'UTF-8')
+		html=header_string
+		if os.path.isfile("/tmp/file.tar.gz"):
+			self.container.execute('cd / && tar -xzvf /tmp/file.tar.gz && sleep 20 && touch /media/hdd/backup/.firstrun; sync; reboot & sleep 20; reboot -f')
+			html +="%s" % (message)
+		else:
+			html +="<center>Bitte die Datei file.tar.gz die beim backup heruntergeladen wurde nach /tmp kopieren und:<br><a href=\"settingrestorepc\" target=\"_self\"><input type=\"button\" value=\"Nochmal Probieren\"></a></center>"
+		return  html
+	def finished(self,retval):
+		print "finished", retval
+addExternalChild( ("settingrestorepc", SettingRestorePC()) )
+#start ipk
+class IPK(resource.Resource):
+	def __init__(self):
+		self.container=eConsoleAppContainer()
+		self.container.appClosed.append(self.finished)
+	def render_GET(self, req):
+		req.setResponseCode(http.OK)
+		req.setHeader('Content-type', 'text/html')
+		self.container.execute('ipkg update & rm -r /tmp/.ipkremove')
+		req.setHeader('charset', 'UTF-8')
+		html=header_string
+		html +="<center><a href=\"IPKonline\" %s><input type=\"submit\" value=\"Plugins Online\"></a><br><a href=\"IPKtmpinstall\" %s><input type=\"submit\" value=\"Plugin aus dem /tmp Installieren\"></a><br><br><br><a href=\"IPKrm\" %s><input type=\"submit\" value=\"Installierte Plugins entfernen\"></a></center>" % (tself,tself,tself)
+		return  html
+	def finished(self,retval):
+		print "finished", retval
+addExternalChild( ("IPK", IPK()) )
+class IPKtmpinstall(resource.Resource):
+	def __init__(self):
+		self.container=eConsoleAppContainer()
+		self.container.appClosed.append(self.finished)
+	def render_GET(self, req):
+		req.setResponseCode(http.OK)
+		ipkcheck = commands.getoutput('ls /tmp | grep .ipk')
+		req.setHeader('Content-type', 'text/html')
+		req.setHeader('charset', 'UTF-8')
+		html=header_string
+		self.container.execute('ipkg install /tmp/' + str(ipkcheck) )
+		if '.ipk' in ipkcheck:	
+			html +="<center>" + str(ipkcheck) + "<br>erfolgreich installiert!<a href=\"IPK\" %s><input type=\"submit\" value=\"Zur&uuml;ck\"></a></center>" % (tself)
+		else:
+			html +="<center>Kein IPK gefunden, bitte IPK per FTP in den /tmp Ordner kopieren und <a href=\"IPKtmpinstall\" %s><input type=\"submit\" value=\"Neu Laden\"></a></center>" % (tself)
+		return  html
+	def finished(self,retval):
+		print "finished", retval
+addExternalChild( ("IPKtmpinstall", IPKtmpinstall()) )
+class IPKrm(resource.Resource):
+	def render_GET(self, req):
+		req.setResponseCode(http.OK)
+		commands.getoutput('rm -r /tmp/.installedipk')
+		req.setHeader('Content-type', 'text/html')
+		req.setHeader('charset', 'UTF-8')
+		lis = commands.getoutput('ipkg list_installed | cut -d " " -f1 | sed "s/Successfully//" >> /tmp/.installedipk')
+		html=header_string
+		fd=open("/tmp/.installedipk")
+		for b in fd:
+			print b
+			if 'enigma2' in b:
+				html +="<center>" + str(b) + "<a href=\"ipkg?command=remove&package=" + str(b) + "\" %s><input type=\"submit\" value=\"DeInstallieren\"></a></center>" % (tself)
+		return  html
+addExternalChild( ("IPKrm", IPKrm()) )
+class IPKonline(resource.Resource):
+	def __init__(self):
+		self.container=eConsoleAppContainer()
+		self.container.appClosed.append(self.finished)
+	def render_GET(self, req):
+		req.setResponseCode(http.OK)
+		self.container.execute('ipkg update')
+		req.setHeader('Content-type', 'text/html')
+		req.setHeader('charset', 'UTF-8')
+		html=header_string
+		html +="<center><div style=\"position: absolute; top: 40px; height: 60px; width: 300px;\"><select name=\"wahl\" size=\"1\" onChange=\"self.location.href=this.options[this.selectedIndex].value;\">"
+		html +="<option selected>Bitte Kategorie ausw&auml;hlen</option><option></option><option value=\"BootLogos\">BootLogos</option><option value=\"Browsers\">Browsers</option><option value=\"Editors\">Editors</option><option value=\"Emus\">Emus</option><option value=\"EPG\">EPG</option><option value=\"Fonts\">Fonts</option><option value=\"Games\">Games</option><option value=\"Infos\">Infos</option><option value=\"Keymaps\">Keymaps</option><option value=\"MediaCenter\">MediaCenter</option><option value=\"Picons\">Picons</option><option value=\"Players\">Players</option><option value=\"RadioLogos\">RadioLogos</option><option value=\"Sprachen\">Sprachen</option><option value=\"Settings\">Settings</option><option value=\"Skins\">Skins</option><option value=\"Spinner\">Spinner</option><option value=\"System\">System</option>"
+		html +="</select></div></center>"
+		return  html
+	def finished(self,retval):
+		print "finished", retval
+addExternalChild( ("IPKonline", IPKonline()) )
+class BootLogos(resource.Resource):
+	def render_GET(self, req):
+		req.setResponseCode(http.OK)
+		req.setHeader('Content-type', 'text/html')
+		req.setHeader('charset', 'UTF-8')
+		html=header_string
+		if os.path.isfile("/tmp/.bootlogob"):
+			fd=open("/tmp/.bootlogob")
+			for b in fd:
+				print b
+				if 'bootlogos' in b:
+					html +="<center>" + str(b) + "<a href=\"ipkg?command=install&package=" + str(b) + "\" %s><input type=\"submit\" value=\"Installieren\"></a></center>" % (tself)
+				else:
+					html +="%s" % (kplugins)
+		elif os.path.isfile("/tmp/.bootlogob") is False:
+			commands.getoutput('cat /usr/lib/ipkg/cross | grep Package | sed "s/Package: //g" | grep bootlogos >> /tmp/.bootlogob')
+			fd=open("/tmp/.bootlogob")
+			for b in fd:
+				print b
+				if 'bootlogos' in b:
+					html +="<center>" + str(b) + "<a href=\"ipkg?command=install&package=" + str(b) + "\" %s><input type=\"submit\" value=\"Installieren\"></a></center>" % (tself)
+				else:
+					html +="%s" % (kplugins)
+		return  html
+addExternalChild( ("BootLogos", BootLogos()) )
+class Browsers(resource.Resource):
+	def render_GET(self, req):
+		req.setResponseCode(http.OK)
+		req.setHeader('Content-type', 'text/html')
+		req.setHeader('charset', 'UTF-8')
+		html=header_string
+		if os.path.isfile("/tmp/.browserb"):
+			fd=open("/tmp/.browserb")
+			for b in fd:
+				print b
+				if 'browsers' in b:
+					html +="<center>" + str(b) + "<a href=\"ipkg?command=install&package=" + str(b) + "\" %s><input type=\"submit\" value=\"Installieren\"></a></center>" % (tself)
+				else:
+					html +="%s" % (kplugins)
+		elif os.path.isfile("/tmp/.browserb") is False:
+			commands.getoutput('cat /usr/lib/ipkg/cross | grep Package | sed "s/Package: //g" | grep browsers >> /tmp/.browserb')
+			fd=open("/tmp/.browserb")
+			for b in fd:
+				print b
+				if 'browsers' in b:
+					html +="<center>" + str(b) + "<a href=\"ipkg?command=install&package=" + str(b) + "\" %s><input type=\"submit\" value=\"Installieren\"></a></center>" % (tself)
+				else:
+					html +="%s" % (kplugins)
+		return  html
+addExternalChild( ("Browsers", Browsers()) )
+class Editors(resource.Resource):
+	def render_GET(self, req):
+		req.setResponseCode(http.OK)
+		req.setHeader('Content-type', 'text/html')
+		req.setHeader('charset', 'UTF-8')
+		html=header_string
+		if os.path.isfile("/tmp/.editorb"):
+			fd=open("/tmp/.editorb")
+			for b in fd:
+				print b
+				if 'editors' in b:
+					html +="<center>" + str(b) + "<a href=\"ipkg?command=install&package=" + str(b) + "\" %s><input type=\"submit\" value=\"Installieren\"></a></center>" % (tself)
+				else:
+					html +="%s" % (kplugins)
+		elif os.path.isfile("/tmp/.editorb") is False:
+			commands.getoutput('cat /usr/lib/ipkg/cross | grep Package | sed "s/Package: //g" | grep editors >> /tmp/.editorb')
+			fd=open("/tmp/.editorb")
+			for b in fd:
+				print b
+				if 'editors' in b:
+					html +="<center>" + str(b) + "<a href=\"ipkg?command=install&package=" + str(b) + "\" %s><input type=\"submit\" value=\"Installieren\"></a></center>" % (tself)
+				else:
+					html +="%s" % (kplugins)
+		return  html
+addExternalChild( ("Editors", Editors()) )
+class Emus(resource.Resource):
+	def render_GET(self, req):
+		req.setResponseCode(http.OK)
+		req.setHeader('Content-type', 'text/html')
+		req.setHeader('charset', 'UTF-8')
+		html=header_string
+		if os.path.isfile("/tmp/.emub"):
+			fd=open("/tmp/.emub")
+			for b in fd:
+				print b
+				if 'emus' in b:
+					html +="<center>" + str(b) + "<a href=\"ipkg?command=install&package=" + str(b) + "\" %s><input type=\"submit\" value=\"Installieren\"></a></center>" % (tself)
+				else:
+					html +="%s" % (kplugins)
+		elif os.path.isfile("/tmp/.emub") is False:
+			commands.getoutput('cat /usr/lib/ipkg/cross | grep Package | sed "s/Package: //g" | grep emus >> /tmp/.emub')
+			fd=open("/tmp/.emub")
+			for b in fd:
+				print b
+				if 'emus' in b:
+					html +="<center>" + str(b) + "<a href=\"ipkg?command=install&package=" + str(b) + "\" %s><input type=\"submit\" value=\"Installieren\"></a></center>" % (tself)
+				else:
+					html +="%s" % (kplugins)
+		return  html
+addExternalChild( ("Emus", Emus()) )
+class EPG(resource.Resource):
+	def render_GET(self, req):
+		req.setResponseCode(http.OK)
+		req.setHeader('Content-type', 'text/html')
+		req.setHeader('charset', 'UTF-8')
+		html=header_string
+		if os.path.isfile("/tmp/.epgb"):
+			fd=open("/tmp/.epgb")
+			for b in fd:
+				print b
+				if 'epg' in b:
+					html +="<center>" + str(b) + "<a href=\"ipkg?command=install&package=" + str(b) + "\" %s><input type=\"submit\" value=\"Installieren\"></a></center>" % (tself)
+				else:
+					html +="%s" % (kplugins)
+		elif os.path.isfile("/tmp/.epgb") is False:
+			commands.getoutput('cat /usr/lib/ipkg/cross | grep Package | sed "s/Package: //g" | grep epg >> /tmp/.epgb')
+			fd=open("/tmp/.epgb")
+			for b in fd:
+				print b
+				if 'epg' in b:
+					html +="<center>" + str(b) + "<a href=\"ipkg?command=install&package=" + str(b) + "\" %s><input type=\"submit\" value=\"Installieren\"></a></center>" % (tself)
+				else:
+					html +="%s" % (kplugins)
+		return  html
+addExternalChild( ("EPG", EPG()) )
+class Fonts(resource.Resource):
+	def render_GET(self, req):
+		req.setResponseCode(http.OK)
+		req.setHeader('Content-type', 'text/html')
+		req.setHeader('charset', 'UTF-8')
+		html=header_string
+		if os.path.isfile("/tmp/.fontsb"):
+			fd=open("/tmp/.fontsb")
+			for b in fd:
+				print b
+				if 'fonts' in b:
+					html +="<center>" + str(b) + "<a href=\"ipkg?command=install&package=" + str(b) + "\" %s><input type=\"submit\" value=\"Installieren\"></a></center>" % (tself)
+				else:
+					html +="%s" % (kplugins)				
+		elif os.path.isfile("/tmp/.fontsb") is False:
+			commands.getoutput('cat /usr/lib/ipkg/cross | grep Package | sed "s/Package: //g" | grep fonts >> /tmp/.fontsb')
+			fd=open("/tmp/.fontsb")
+			for b in fd:
+				print b
+				if 'fonts' in b:
+					html +="<center>" + str(b) + "<a href=\"ipkg?command=install&package=" + str(b) + "\" %s><input type=\"submit\" value=\"Installieren\"></a></center>" % (tself)
+				else:
+					html +="%s" % (kplugins)
+		return  html
+addExternalChild( ("Fonts", Fonts()) )
+class Games(resource.Resource):
+	def render_GET(self, req):
+		req.setResponseCode(http.OK)
+		req.setHeader('Content-type', 'text/html')
+		req.setHeader('charset', 'UTF-8')
+		html=header_string
+		if os.path.isfile("/tmp/.gameb"):
+			fd=open("/tmp/.gameb")
+			for b in fd:
+				print b
+				if 'games' in b:
+					html +="<center>" + str(b) + "<a href=\"ipkg?command=install&package=" + str(b) + "\" %s><input type=\"submit\" value=\"Installieren\"></a></center>" % (tself)
+				else:
+					html +="%s" % (kplugins)
+		elif os.path.isfile("/tmp/.gameb") is False:
+			commands.getoutput('cat /usr/lib/ipkg/cross | grep Package | sed "s/Package: //g" | grep games >> /tmp/.gameb')
+			fd=open("/tmp/.gameb")
+			for b in fd:
+				print b
+				if 'games' in b:
+					html +="<center>" + str(b) + "<a href=\"ipkg?command=install&package=" + str(b) + "\" %s><input type=\"submit\" value=\"Installieren\"></a></center>" % (tself)
+				else:
+					html +="%s" % (kplugins)
+		return  html
+addExternalChild( ("Games", Games()) )
+class Infos(resource.Resource):
+	def render_GET(self, req):
+		req.setResponseCode(http.OK)
+		req.setHeader('Content-type', 'text/html')
+		req.setHeader('charset', 'UTF-8')
+		html=header_string
+		if os.path.isfile("/tmp/.infob"):
+			fd=open("/tmp/.infob")
+			for b in fd:
+				print b
+				if 'infos' in b:
+					html +="<center>" + str(b) + "<a href=\"ipkg?command=install&package=" + str(b) + "\" %s><input type=\"submit\" value=\"Installieren\"></a></center>" % (tself)
+				else:
+					html +="%s" % (kplugins)
+		elif os.path.isfile("/tmp/.infob") is False:
+			commands.getoutput('cat /usr/lib/ipkg/cross | grep Package | sed "s/Package: //g" | grep infos >> /tmp/.infob')
+			fd=open("/tmp/.infob")
+			for b in fd:
+				print b
+				if 'infos' in b:
+					html +="<center>" + str(b) + "<a href=\"ipkg?command=install&package=" + str(b) + "\" %s><input type=\"submit\" value=\"Installieren\"></a></center>" % (tself)
+				else:
+					html +="%s" % (kplugins)
+		return  html
+addExternalChild( ("Infos", Infos()) )
+class Keymaps(resource.Resource):
+	def render_GET(self, req):
+		req.setResponseCode(http.OK)
+		req.setHeader('Content-type', 'text/html')
+		req.setHeader('charset', 'UTF-8')
+		html=header_string
+		if os.path.isfile("/tmp/.keymapb"):
+			fd=open("/tmp/.keymapb")
+			for b in fd:
+				print b
+				if 'keymaps' in b:
+					html +="<center>" + str(b) + "<a href=\"ipkg?command=install&package=" + str(b) + "\" %s><input type=\"submit\" value=\"Installieren\"></a></center>" % (tself)
+				else:
+					html +="%s" % (kplugins)
+		elif os.path.isfile("/tmp/.keymapb") is False:
+			commands.getoutput('cat /usr/lib/ipkg/cross | grep Package | sed "s/Package: //g" | grep keymaps >> /tmp/.keymapb')
+			fd=open("/tmp/.keymapb")
+			for b in fd:
+				print b
+				if 'keymaps' in b:
+					html +="<center>" + str(b) + "<a href=\"ipkg?command=install&package=" + str(b) + "\" %s><input type=\"submit\" value=\"Installieren\"></a></center>" % (tself)
+				else:
+					html +="%s" % (kplugins)
+		return  html
+addExternalChild( ("Keymaps", Keymaps()) )
+class MediaCenter(resource.Resource):
+	def render_GET(self, req):
+		req.setResponseCode(http.OK)
+		req.setHeader('Content-type', 'text/html')
+		req.setHeader('charset', 'UTF-8')
+		html=header_string
+		if os.path.isfile("/tmp/.mcb"):
+			fd=open("/tmp/.mcb")
+			for b in fd:
+				print b
+				if 'mediacenter' in b:
+					html +="<center>" + str(b) + "<a href=\"ipkg?command=install&package=" + str(b) + "\" %s><input type=\"submit\" value=\"Installieren\"></a></center>" % (tself)
+				else:
+					html +="%s" % (kplugins)
+		elif os.path.isfile("/tmp/.mcb") is False:
+			commands.getoutput('cat /usr/lib/ipkg/cross | grep Package | sed "s/Package: //g" | grep mediacenter >> /tmp/.mcb')
+			fd=open("/tmp/.mcb")
+			for b in fd:
+				print b
+				if 'mediacenter' in b:
+					html +="<center>" + str(b) + "<a href=\"ipkg?command=install&package=" + str(b) + "\" %s><input type=\"submit\" value=\"Installieren\"></a></center>" % (tself)
+				else:
+					html +="%s" % (kplugins)
+		return  html
+addExternalChild( ("MediaCenter", MediaCenter()) )
+class Picons(resource.Resource):
+	def render_GET(self, req):
+		req.setResponseCode(http.OK)
+		req.setHeader('Content-type', 'text/html')
+		req.setHeader('charset', 'UTF-8')
+		html=header_string
+		if os.path.isfile("/tmp/.piconb"):
+			fd=open("/tmp/.piconb")
+			for b in fd:
+				print b
+				if 'picons' in b:
+					html +="<center>" + str(b) + "<a href=\"ipkg?command=install&package=" + str(b) + "\" %s><input type=\"submit\" value=\"Installieren\"></a></center>" % (tself)
+				else:
+					html +="%s" % (kplugins)
+		elif os.path.isfile("/tmp/.piconb") is False:
+			commands.getoutput('cat /usr/lib/ipkg/cross | grep Package | sed "s/Package: //g" | grep picons >> /tmp/.piconb')
+			fd=open("/tmp/.piconb")
+			for b in fd:
+				print b
+				if 'picons' in b:
+					html +="<center>" + str(b) + "<a href=\"ipkg?command=install&package=" + str(b) + "\" %s><input type=\"submit\" value=\"Installieren\"></a></center>" % (tself)
+				else:
+					html +="%s" % (kplugins)
+		return  html
+addExternalChild( ("Picons", Picons()) )
+class Players(resource.Resource):
+	def render_GET(self, req):
+		req.setResponseCode(http.OK)
+		req.setHeader('Content-type', 'text/html')
+		req.setHeader('charset', 'UTF-8')
+		html=header_string
+		if os.path.isfile("/tmp/.playerb"):
+			fd=open("/tmp/.playerb")
+			for b in fd:
+				print b
+				if 'players' in b:
+					html +="<center>" + str(b) + "<a href=\"ipkg?command=install&package=" + str(b) + "\" %s><input type=\"submit\" value=\"Installieren\"></a></center>" % (tself)
+				else:
+					html +="%s" % (kplugins)
+		elif os.path.isfile("/tmp/.playerb") is False:
+			commands.getoutput('cat /usr/lib/ipkg/cross | grep Package | sed "s/Package: //g" | grep players >> /tmp/.playerb')
+			fd=open("/tmp/.playerb")
+			for b in fd:
+				print b
+				if 'players' in b:
+					html +="<center>" + str(b) + "<a href=\"ipkg?command=install&package=" + str(b) + "\" %s><input type=\"submit\" value=\"Installieren\"></a></center>" % (tself)
+				else:
+					html +="%s" % (kplugins)
+		return  html
+addExternalChild( ("Players", Players()) )
+class RadioLogos(resource.Resource):
+	def render_GET(self, req):
+		req.setResponseCode(http.OK)
+		req.setHeader('Content-type', 'text/html')
+		req.setHeader('charset', 'UTF-8')
+		html=header_string
+		if os.path.isfile("/tmp/.radiob"):
+			fd=open("/tmp/.radiob")
+			for b in fd:
+				print b
+				if 'radiologos' in b:
+					html +="<center>" + str(b) + "<a href=\"ipkg?command=install&package=" + str(b) + "\" %s><input type=\"submit\" value=\"Installieren\"></a></center>" % (tself)
+				else:
+					html +="%s" % (kplugins)
+		elif os.path.isfile("/tmp/.radiob") is False:
+			commands.getoutput('cat /usr/lib/ipkg/cross | grep Package | sed "s/Package: //g" | grep radiologos >> /tmp/.radiob')
+			fd=open("/tmp/.radiob")
+			for b in fd:
+				print b
+				if 'radiologos' in b:
+					html +="<center>" + str(b) + "<a href=\"ipkg?command=install&package=" + str(b) + "\" %s><input type=\"submit\" value=\"Installieren\"></a></center>" % (tself)
+				else:
+					html +="%s" % (kplugins)
+		return  html
+addExternalChild( ("RadioLogos", RadioLogos()) )
+class Sprachen(resource.Resource):
+	def render_GET(self, req):
+		req.setResponseCode(http.OK)
+		req.setHeader('Content-type', 'text/html')
+		req.setHeader('charset', 'UTF-8')
+		html=header_string
+		if os.path.isfile("/tmp/.spracheb"):
+			fd=open("/tmp/.spracheb")
+			for b in fd:
+				print b
+				if 'po' in b:
+					html +="<center>" + str(b) + "<a href=\"ipkg?command=install&package=" + str(b) + "\" %s><input type=\"submit\" value=\"Installieren\"></a></center>" % (tself)
+				else:
+					html +="%s" % (kplugins)
+		elif os.path.isfile("/tmp/.spracheb") is False:
+			commands.getoutput('cat /usr/lib/ipkg/cross | grep Package | sed "s/Package: //g" | grep po >> /tmp/.spracheb')
+			fd=open("/tmp/.spracheb")
+			for b in fd:
+				print b
+				if 'po' in b:
+					html +="<center>" + str(b) + "<a href=\"ipkg?command=install&package=" + str(b) + "\" %s><input type=\"submit\" value=\"Installieren\"></a></center>" % (tself)
+				else:
+					html +="%s" % (kplugins)
+		return  html
+addExternalChild( ("Sprachen", Sprachen()) )
+class Settings(resource.Resource):
+	def render_GET(self, req):
+		req.setResponseCode(http.OK)
+		req.setHeader('Content-type', 'text/html')
+		req.setHeader('charset', 'UTF-8')
+		html=header_string
+		if os.path.isfile("/tmp/.settingb"):
+			fd=open("/tmp/.settingb")
+			for b in fd:
+				print b
+				if 'settings' in b:
+					html +="<center>" + str(b) + "<a href=\"ipkg?command=install&package=" + str(b) + "\" %s><input type=\"submit\" value=\"Installieren\"></a></center>" % (tself)
+				else:
+					html +="%s" % (kplugins)
+		elif os.path.isfile("/tmp/.settingb") is False:
+			commands.getoutput('cat /usr/lib/ipkg/cross | grep Package | sed "s/Package: //g" | grep settings >> /tmp/.settingb')
+			fd=open("/tmp/.settingb")
+			for b in fd:
+				print b
+				if 'settings' in b:
+					html +="<center>" + str(b) + "<a href=\"ipkg?command=install&package=" + str(b) + "\" %s><input type=\"submit\" value=\"Installieren\"></a></center>" % (tself)
+				else:
+					html +="%s" % (kplugins)
+		return  html
+addExternalChild( ("Settings", Settings()) )
+class Skins(resource.Resource):
+	def render_GET(self, req):
+		req.setResponseCode(http.OK)
+		req.setHeader('Content-type', 'text/html')
+		req.setHeader('charset', 'UTF-8')
+		html=header_string
+		if os.path.isfile("/tmp/.skinb"):
+			fd=open("/tmp/.skinb")
+			for b in fd:
+				print b
+				if 'skins' in b:
+					html +="<center>" + str(b) + "<a href=\"ipkg?command=install&package=" + str(b) + "\" %s><input type=\"submit\" value=\"Installieren\"></a></center>" % (tself)
+				else:
+					html +="%s" % (kplugins)
+		elif os.path.isfile("/tmp/.skinb") is False:
+			commands.getoutput('cat /usr/lib/ipkg/cross | grep Package | sed "s/Package: //g" | grep skins >> /tmp/.skinb')
+			fd=open("/tmp/.skinb")
+			for b in fd:
+				print b
+				if 'skins' in b:
+					html +="<center>" + str(b) + "<a href=\"ipkg?command=install&package=" + str(b) + "\" %s><input type=\"submit\" value=\"Installieren\"></a></center>" % (tself)	
+				else:
+					html +="%s" % (kplugins)
+		return  html
+addExternalChild( ("Skins", Skins()) )
+class Spinner(resource.Resource):
+	def render_GET(self, req):
+		req.setResponseCode(http.OK)
+		req.setHeader('Content-type', 'text/html')
+		req.setHeader('charset', 'UTF-8')
+		html=header_string
+		if os.path.isfile("/tmp/.spinnerb"):
+			fd=open("/tmp/.spinnerb")
+			for b in fd:
+				print b
+				if 'spinner' in b:
+					html +="<center>" + str(b) + "<a href=\"ipkg?command=install&package=" + str(b) + "\" %s><input type=\"submit\" value=\"Installieren\"></a></center>" % (tself)	
+				else:
+					html +="%s" % (kplugins)
+		elif os.path.isfile("/tmp/.spinnerb") is False:
+			commands.getoutput('cat /usr/lib/ipkg/cross | grep Package | sed "s/Package: //g" | grep spinner >> /tmp/.spinnerb')
+			fd=open("/tmp/.spinnerb")
+			for b in fd:
+				print b
+				if 'spinner' in b:
+					html +="<center>" + str(b) + "<a href=\"ipkg?command=install&package=" + str(b) + "\" %s><input type=\"submit\" value=\"Installieren\"></a></center>" % (tself)	
+				else:
+					html +="%s" % (kplugins)
+		return  html
+addExternalChild( ("Spinner", Spinner()) )
+class System(resource.Resource):
+	def render_GET(self, req):
+		req.setResponseCode(http.OK)
+		req.setHeader('Content-type', 'text/html')
+		req.setHeader('charset', 'UTF-8')
+		html=header_string
+		if os.path.isfile("/tmp/.systemb"):
+			fd=open("/tmp/.systemb")
+			for b in fd:
+				print b
+				if 'system' in b:
+					html +="<center>" + str(b) + "<a href=\"ipkg?command=install&package=" + str(b) + "\" %s><input type=\"submit\" value=\"Installieren\"></a></center>" % (tself)	
+				else:
+					html +="%s" % (kplugins)
+		elif os.path.isfile("/tmp/.systemb") is False:
+			commands.getoutput('cat /usr/lib/ipkg/cross | grep Package | sed "s/Package: //g" | grep system >> /tmp/.systemb')
+			fd=open("/tmp/.systemb")
+			for b in fd:
+				print b
+				if 'system' in b:
+					html +="<center>" + str(b) + "<a href=\"ipkg?command=install&package=" + str(b) + "\" %s><input type=\"submit\" value=\"Installieren\"></a></center>" % (tself)
+				else:
+					html +="%s" % (kplugins)
+		return  html
+addExternalChild( ("System", System()) )
+#overclock
+class twosixsixmhz(resource.Resource):
+	def render_GET(self, req):
+		req.setResponseCode(http.OK)
+		req.setHeader('Content-type', 'text/html')
+		commands.getoutput("echo 15110 > "+ pllone +"")
+		req.setHeader('charset', 'UTF-8')
+		html=header_string
+		html +="<center>266MHz OK! %s</center>" % (backzu)
+		return  html
+addExternalChild( ("266MHz", twosixsixmhz()) )
+class threehoundredmhz(resource.Resource):
+	def render_GET(self, req):
+		req.setResponseCode(http.OK)
+		req.setHeader('Content-type', 'text/html')
+		commands.getoutput("echo 25609 > "+ pllone +"")
+		req.setHeader('charset', 'UTF-8')
+		html=header_string
+		html +="<center>300MHz OK! %s</center>" % (backzu)
+		return  html
+addExternalChild( ("300MHz", threehoundredmhz()) )
+class threethreethreemhz(resource.Resource):
+	def render_GET(self, req):
+		req.setResponseCode(http.OK)
+		req.setHeader('Content-type', 'text/html')
+		commands.getoutput("echo 9475 > "+ pllone +"")
+		req.setHeader('charset', 'UTF-8')
+		html=header_string
+		html +="<center>333MHz OK! %s</center>" % (backzu)
+		return  html
+addExternalChild( ("333MHz", threethreethreemhz()) )
+class threesixsixmhz(resource.Resource):
+	def render_GET(self, req):
+		req.setResponseCode(http.OK)
+		req.setHeader('Content-type', 'text/html')
+		commands.getoutput("echo 31241 > "+ pllone +"")
+		req.setHeader('charset', 'UTF-8')
+		html=header_string
+		html +="<center>366MHz OK! %s</center>" % (backzu)
+		return  html
+addExternalChild( ("366MHz", threesixsixmhz()) )
+class fourhoundredmhz(resource.Resource):
+	def render_GET(self, req):
+		req.setResponseCode(http.OK)
+		req.setHeader('Content-type', 'text/html')
+		commands.getoutput("echo 22790 > "+ pllone +"")
+		req.setHeader('charset', 'UTF-8')
+		html=header_string
+		html +="<center>400MHz OK! %s</center>" % (backzu)
+		return  html
+addExternalChild( ("400MHz", fourhoundredmhz()) )
+class fourhoundredfivemhz(resource.Resource):
+	def render_GET(self, req):
+		req.setResponseCode(http.OK)
+		req.setHeader('Content-type', 'text/html')
+		commands.getoutput("echo 3841 > "+ pllone +"")
+		req.setHeader('charset', 'UTF-8')
+		html=header_string
+		html +="<center>450MHz OK! %s</center>" % (backzu)
+		return  html
+addExternalChild( ("450MHz", fourhoundredfivemhz()) )
+class fivehoundredmhz(resource.Resource):
+	def render_GET(self, req):
+		req.setResponseCode(http.OK)
+		req.setHeader('Content-type', 'text/html')
+		commands.getoutput("echo 12803 > "+ pllone +"")
+		req.setHeader('charset', 'UTF-8')
+		html=header_string
+		html +="<center>500MHz OK! %s</center>" % (backzu)
+		return  html
+addExternalChild( ("500MHz", fivehoundredmhz()) )
+class sixhoundredmhz(resource.Resource):
+	def render_GET(self, req):
+		req.setResponseCode(http.OK)
+		req.setHeader('Content-type', 'text/html')
+		commands.getoutput("echo 5121 > "+ pllone +"")
+		req.setHeader('charset', 'UTF-8')
+		html=header_string
+		html +="<center>600MHz OK! %s</center>" % (backzu)
+		return  html
+addExternalChild( ("600MHz", sixhoundredmhz()) )
+class sixhoundredfivemhz(resource.Resource):
+	def render_GET(self, req):
+		req.setResponseCode(http.OK)
+		req.setHeader('Content-type', 'text/html')
+		commands.getoutput("echo 16643 > "+ pllone +"")
+		req.setHeader('charset', 'UTF-8')
+		html=header_string
+		html +="<center>650MHz OK! %s</center>" % (backzu)
+		return  html
+addExternalChild( ("650MHz", sixhoundredfivemhz()) )
+class sevenhoundredmhz(resource.Resource):
+	def render_GET(self, req):
+		req.setResponseCode(http.OK)
+		req.setHeader('Content-type', 'text/html')
+		commands.getoutput("echo 17923 > "+ pllone +"")
+		req.setHeader('charset', 'UTF-8')
+		html=header_string
+		html +="<center>700MHz OK! %s</center>" % (backzu)
+		return  html
+addExternalChild( ("700MHz", sevenhoundredmhz()) )
+class twosixsixmhzauto(resource.Resource):
+	def render_GET(self, req):
+		req.setResponseCode(http.OK)
+		req.setHeader('Content-type', 'text/html')
+		commands.getoutput("echo 15110 > "+ pllone +"")
+		req.setHeader('charset', 'UTF-8')
+		html=header_string
+		aucheck=commands.getoutput("cat "+ conf +" | grep pll0")
+		if 'pll0_ndiv' in aucheck:
+			commands.getoutput("sed -i 's/pll0_ndiv_mdiv=.*/pll0_ndiv_mdiv=0/g' "+ conf +"")
+			html +="<center>Gespeichert! %s</center>" % (backzu)
+		else:
+			html +="<center>Fehler! %s</center>" % (backzu)
+		return  html
+addExternalChild( ("266MHzAuto", twosixsixmhzauto()) )
+class threehoundredmhzauto(resource.Resource):
+	def render_GET(self, req):
+		req.setResponseCode(http.OK)
+		
+		req.setHeader('Content-type', 'text/html')
+		commands.getoutput("echo 25609 > "+ pllone +"")
+		req.setHeader('charset', 'UTF-8')
+		html=header_string
+		aucheck=commands.getoutput("cat "+ conf +" | grep pll0")
+		if 'pll0_ndiv' in aucheck:
+			commands.getoutput("sed -i 's/pll0_ndiv_mdiv=.*/pll0_ndiv_mdiv=25609/g' "+ conf +"")
+			html +="<center>Gespeichert! %s</center>" % (backzu)
+		else:
+			html +="<center>Fehler! %s</center>" % (backzu)
+		return  html
+addExternalChild( ("300MHzAuto", threehoundredmhzauto()) )
+class threethreethreemhzauto(resource.Resource):
+	def render_GET(self, req):
+		req.setResponseCode(http.OK)
+		
+		req.setHeader('Content-type', 'text/html')
+		commands.getoutput("echo 9475 > "+ pllone +"")
+		req.setHeader('charset', 'UTF-8')
+		html=header_string
+		aucheck=commands.getoutput("cat "+ conf +" | grep pll0")
+		if 'pll0_ndiv' in aucheck:
+			commands.getoutput("sed -i 's/pll0_ndiv_mdiv=.*/pll0_ndiv_mdiv=9475/g' "+ conf +"")
+			html +="<center>Gespeichert! %s</center>" % (backzu)
+		else:
+			html +="<center>Fehler! %s</center>" % (backzu)
+		return  html
+addExternalChild( ("333MHzAuto", threethreethreemhzauto()) )
+class threesixsixmhzauto(resource.Resource):
+	def render_GET(self, req):
+		req.setResponseCode(http.OK)
+		
+		req.setHeader('Content-type', 'text/html')
+		commands.getoutput("echo 31241 > "+ pllone +"")
+		req.setHeader('charset', 'UTF-8')
+		html=header_string
+		aucheck=commands.getoutput("cat "+ conf +" | grep pll0")
+		html=header_string
+		if 'pll0_ndiv' in aucheck:
+			commands.getoutput("sed -i 's/pll0_ndiv_mdiv=.*/pll0_ndiv_mdiv=31241/g' "+ conf +"")
+			html +="<center>Gespeichert! %s</center>" % (backzu)
+		else:
+			html +="<center>Fehler! %s</center>" % (backzu)
+		return  html
+addExternalChild( ("366MHzAuto", threesixsixmhzauto()) )
+class fourhoundredmhzauto(resource.Resource):
+	def render_GET(self, req):
+		req.setResponseCode(http.OK)
+		
+		req.setHeader('Content-type', 'text/html')
+		commands.getoutput("echo 22790 > "+ pllone +"")
+		req.setHeader('charset', 'UTF-8')
+		aucheck=commands.getoutput("cat "+ conf +" | grep pll0")
+		html=header_string
+		if 'pll0_ndiv_mdiv' in aucheck:
+			commands.getoutput("sed -i 's/pll0_ndiv_mdiv=.*/pll0_ndiv_mdiv=22790/g' "+ conf +"")
+			html +="<center>Gespeichert! %s</center>" % (backzu)
+		else:
+			html +="<center>Fehler! %s</center>" % (backzu)
+		return  html
+addExternalChild( ("400MHzAuto", fourhoundredmhzauto()) )
+class fourhoundredfivemhzauto(resource.Resource):
+	def render_GET(self, req):
+		req.setResponseCode(http.OK)
+		
+		req.setHeader('Content-type', 'text/html')
+		commands.getoutput("echo 3841 > "+ pllone +"")
+		req.setHeader('charset', 'UTF-8')
+		aucheck=commands.getoutput("cat "+ conf +" | grep pll0")
+		html=header_string
+		if 'pll0_ndiv_mdiv' in aucheck:
+			commands.getoutput("sed -i 's/pll0_ndiv_mdiv=.*/pll0_ndiv_mdiv=3841/g' "+ conf +"")
+			html +="<center>Gespeichert! %s</center>" % (backzu)
+		else:
+			html +="<center>Fehler! %s</center>" % (backzu)
+		return  html
+addExternalChild( ("450MHzAuto", fourhoundredfivemhzauto()) )
+class fivehoundredmhzauto(resource.Resource):
+	def render_GET(self, req):
+		req.setResponseCode(http.OK)
+		
+		req.setHeader('Content-type', 'text/html')
+		commands.getoutput("echo 12803 > "+ pllone +"")
+		req.setHeader('charset', 'UTF-8')
+		aucheck=commands.getoutput("cat "+ conf +" | grep pll0")
+		html=header_string
+		if 'pll0_ndiv_mdiv' in aucheck:
+			commands.getoutput("sed -i 's/pll0_ndiv_mdiv=.*/pll0_ndiv_mdiv=12803/g' "+ conf +"")
+			html +="<center>Gespeichert! %s</center>" % (backzu)
+		else:
+			html +="<center>Fehler! %s</center>" % (backzu)
+		return  html
+addExternalChild( ("500MHzAuto", fivehoundredmhzauto()) )
+class sixhoundredmhzauto(resource.Resource):
+	def render_GET(self, req):
+		req.setResponseCode(http.OK)
+		
+		req.setHeader('Content-type', 'text/html')
+		commands.getoutput("echo 5121 > "+ pllone +"")
+		req.setHeader('charset', 'UTF-8')
+		aucheck=commands.getoutput("cat "+ conf +" | grep pll0")
+		html=header_string
+		if 'pll0_ndiv_mdiv' in aucheck:
+			commands.getoutput("sed -i 's/pll0_ndiv_mdiv=.*/pll0_ndiv_mdiv=5121/g' "+ conf +"")
+			html +="<center>Gespeichert! %s</center>" % (backzu)
+		else:
+			html +="<center>Fehler! %s</center>" % (backzu)
+		return  html
+addExternalChild( ("600MHzAuto", sixhoundredmhzauto()) )
+class sixhoundredfivemhzauto(resource.Resource):
+	def render_GET(self, req):
+		req.setResponseCode(http.OK)
+		
+		req.setHeader('Content-type', 'text/html')
+		commands.getoutput("echo 16643 > "+ pllone +"")
+		req.setHeader('charset', 'UTF-8')
+		aucheck=commands.getoutput("cat "+ conf +" | grep pll0")
+		html=header_string
+		if 'pll0_ndiv_mdiv' in aucheck:
+			commands.getoutput("sed -i 's/pll0_ndiv_mdiv=.*/pll0_ndiv_mdiv=16643/g' "+ conf +"")
+			html +="<center>Gespeichert! %s</center>" % (backzu)
+		else:
+			html +="<center>Fehler! %s</center>" % (backzu)
+		return  html
+addExternalChild( ("650MHzAuto", sixhoundredfivemhzauto()) )
+class sevenhoundredmhzauto(resource.Resource):
+	def render_GET(self, req):
+		req.setResponseCode(http.OK)
+		
+		req.setHeader('Content-type', 'text/html')
+		commands.getoutput("echo 17923 > "+ pllone +"")
+		req.setHeader('charset', 'UTF-8')
+		aucheck=commands.getoutput("cat "+ conf +" | grep pll0")
+		html=header_string
+		if 'pll0_ndiv_mdiv' in aucheck:
+			commands.getoutput("sed -i 's/pll0_ndiv_mdiv=.*/pll0_ndiv_mdiv=17923/g' "+ conf +"")
+			html +="<center>Gespeichert! %s</center>" % (backzu)
+		else:
+			html +="<center>Fehler! %s</center>" % (backzu)
+		return  html
+addExternalChild( ("700MHzAuto", sevenhoundredmhzauto()) )
+class stbyaus(resource.Resource):
+	def render_GET(self, req):
+		req.setResponseCode(http.OK)
+		req.setHeader('Content-type', 'text/html')
+		req.setHeader('charset', 'UTF-8')
+		html=header_string
+		commands.getoutput("sed -i 's/standby_overclock=.*/standby_overclock=0/g' "+ conf +"")
+		html +="<center>Gespeichert! %s</center>" % (backzu)
+		return  html
+addExternalChild( ("stbyaus", stbyaus()) )
+class twosixsixstby(resource.Resource):
+	def render_GET(self, req):
+		req.setResponseCode(http.OK)
+		req.setHeader('Content-type', 'text/html')
+		req.setHeader('charset', 'UTF-8')
+		html=header_string
+		commands.getoutput("sed -i 's/standby_overclock=.*/standby_overclock=1/g' "+ conf +" | sed -i 's/standby_freq=.*/standby_freq=15110/g' "+ conf +"")
+		html +="<center>Gespeichert! %s</center>" % (backzu)
+		return  html
+addExternalChild( ("266stby", twosixsixstby()) )
+class twozerostby(resource.Resource):
+	def render_GET(self, req):
+		req.setResponseCode(http.OK)
+		req.setHeader('Content-type', 'text/html')
+		req.setHeader('charset', 'UTF-8')
+		html=header_string
+		commands.getoutput("sed -i 's/standby_overclock=.*/standby_overclock=1/g' "+ conf +" | sed -i 's/standby_freq=.*/standby_freq=51227/g' "+ conf +"")
+		html +="<center>Gespeichert! %s</center>" % (backzu)
+		return  html
+addExternalChild( ("200stby", twozerostby()) )
+class onesixstby(resource.Resource):
+	def render_GET(self, req):
+		req.setResponseCode(http.OK)
+		req.setHeader('Content-type', 'text/html')
+		req.setHeader('charset', 'UTF-8')
+		html=header_string
+		commands.getoutput("sed -i 's/standby_overclock=.*/standby_overclock=1/g' "+ conf +" | sed -i 's/standby_freq=.*/standby_freq=42523/g' "+ conf +"")
+		html +="<center>Gespeichert! %s</center>" % (backzu)
+		return  html
+addExternalChild( ("166stby", onesixstby()) )
+class onethreestby(resource.Resource):
+	def render_GET(self, req):
+		req.setResponseCode(http.OK)
+		req.setHeader('Content-type', 'text/html')
+		req.setHeader('charset', 'UTF-8')
+		html=header_string
+		commands.getoutput("sed -i 's/standby_overclock=.*/standby_overclock=1/g' "+ conf +" | sed -i 's/standby_freq=.*/standby_freq=34075/g' "+ conf +"")
+		html +="<center>Gespeichert! %s</center>" % (backzu)
+		return  html
+addExternalChild( ("133stby", onethreestby()) )
+class fourfivestby(resource.Resource):
+	def render_GET(self, req):
+		req.setResponseCode(http.OK)
+		req.setHeader('Content-type', 'text/html')
+		req.setHeader('charset', 'UTF-8')
+		html=header_string
+		commands.getoutput("sed -i 's/standby_overclock=.*/standby_overclock=1/g' "+ conf +" | sed -i 's/standby_freq=.*/standby_freq=3841/g' "+ conf +"")
+		html +="<center>Gespeichert! %s</center>" % (backzu)
+		return  html
+addExternalChild( ("450stby", fourfivestby()) )
+class threestby(resource.Resource):
+	def render_GET(self, req):
+		req.setResponseCode(http.OK)
+		req.setHeader('Content-type', 'text/html')
+		req.setHeader('charset', 'UTF-8')
+		html=header_string
+		commands.getoutput("sed -i 's/standby_overclock=.*/standby_overclock=1/g' "+ conf +" | sed -i 's/standby_freq=.*/standby_freq=2561/g' "+ conf +"")
+		html +="<center>Gespeichert! %s</center>" % (backzu)
+		return  html
+addExternalChild( ("300stby", threestby()) )
+class twostby(resource.Resource):
+	def render_GET(self, req):
+		req.setResponseCode(http.OK)
+		req.setHeader('Content-type', 'text/html')
+		req.setHeader('charset', 'UTF-8')
+		html=header_string
+		commands.getoutput("sed -i 's/standby_overclock=.*/standby_overclock=1/g' "+ conf +" | sed -i 's/standby_freq=.*/standby_freq=5123/g' "+ conf +"")
+		html +="<center>Gespeichert! %s</center>" % (backzu)
+		return  html
+addExternalChild( ("200stby", twostby()) )
+class onestby(resource.Resource):
+	def render_GET(self, req):
+		req.setResponseCode(http.OK)
+		req.setHeader('Content-type', 'text/html')
+		req.setHeader('charset', 'UTF-8')
+		html=header_string
+		commands.getoutput("sed -i 's/standby_overclock=.*/standby_overclock=1/g' "+ conf +" | sed -i 's/standby_freq=.*/standby_freq=2563/g' "+ conf +"")
+		html +="<center>Gespeichert! %s</center>" % (backzu)
+		return  html
+addExternalChild( ("100stby", onestby()) )
+class overclock(resource.Resource):
+	def render_GET(self, req):
+		req.setResponseCode(http.OK)
+		cpuauto = commands.getoutput('cat '+ conf +' | grep pll0 | cut -d "=" -f2')
+		req.setHeader('Content-type', 'text/html')
+		req.setHeader('charset', 'UTF-8')
+		standcpu = commands.getoutput('cat '+ conf +' | grep standby_freq | cut -d "=" -f2')
+		standstatcpu = commands.getoutput('cat '+ conf +' | grep standby_overclock | cut -d "=" -f2')
+		html=header_string
+		if os.path.isfile(""+ pllone +""):
+			if receiver.upper() == 'UFS912' or receiver.upper() == 'AT7500':
+				if '12803' in cpuauto:
+					cpuau="500MHz"
+				elif '5121' in cpuauto:
+					cpuau="600MHz"
+				elif '16643' in cpuauto:
+					cpuau="650MHz"
+				elif '17923' in cpuauto:
+					cpuau="700MHz"
+				elif '0' in cpuauto:
+					cpuau="standard"
+				else:
+					cpuau="standard"
+				if '0' in standstatcpu:
+					stbycpu="Aus (standard)"
+				else:
+					if '2561' in standcpu:
+						stbycpu="300MHz"
+					elif '5123' in standcpu:
+						stbycpu="200MHz"
+					elif '2563' in standcpu:
+						stbycpu="100MHz"
+					else:
+						stbycpu="standard"
+				cpurinfo = commands.getoutput('cat '+ pllone +' | grep SH4 | cut -d "=" -f2')
+				html +="<center><table style=\"width: 80%%;table-layout: fixed;\" border=\"0\" cellspacing=\"0\"><tr align=\"center\"><td>Aktuelle CPU Frequenz: %s<br>Frequenz in der Start-Config: %s<br>Standby Frequenz: %s</td></tr></table><br><br><br>" % (cpurinfo, cpuau, stbycpu)
+				html +="<table style=\"width: 90%%;table-layout: fixed;\" border=\"0\" cellspacing=\"0\"><tr><td align=\"left\">Tempor&auml;r &auml;ndern:<br><br>%s<option selected>Frequenz ausw&auml;hlen</option><option></option><option value=\"450MHz\">450MHz (standard)</option><option value=\"500MHz\">500MHz</option><option value=\"600MHz\">600MHz</option><option value=\"650MHz\">650MHz</option><option value=\"700MHz\">700MHz</option></select></td><td align=\"center\">StartConfig &auml;ndern:<br><br>%s<option selected>Frequenz ausw&auml;hlen</option><option></option><option value=\"450MHzAuto\">450MHz (standard)</option><option value=\"500MHzAuto\">500MHz</option><option value=\"600MHzAuto\">600MHz</option><option value=\"650MHzAuto\">650MHz</option><option value=\"700MHzAuto\">700MHz</option></select></td><td align=\"right\">Standby &auml;ndern:<br><br>%s<option selected>Frequenz ausw&auml;hlen</option><option></option><option value=\"stbyaus\">Aus</option><option value=\"450stby\">450MHz (standard)</option><option value=\"300stby\">300MHz</option><option value=\"200stby\">200MHz</option><option value=\"100stby\">100MHz</option></select></td></tr></table>" % (wahl, wahl, wahl)
+				html +="</center>"
+			else:
+				cpucur = commands.getoutput('cat /proc/cpuinfo | grep sh4_clk | cut -d ":" -f2')
+				if '25609' in cpuauto:
+					cpuau="300MHz"
+				elif '9475' in cpuauto:
+					cpuau="333MHz"
+				elif '31241' in cpuauto:
+					cpuau="366MHz"
+				elif '22790' in cpuauto:
+					cpuau="400MHz"
+				elif '0' in cpuauto:
+					cpuau="standard"
+				else:
+					cpuau="standard"
+				if '0' in standstatcpu:
+					stbycpu="Aus (standard)"
+				else:
+					if '15110' in standcpu:
+						stbycpu="266MHz (default)"
+					elif '51227' in standcpu:
+						stbycpu="200MHz"
+					elif '42523' in standcpu:
+						stbycpu="166MHz"
+					elif '34075' in standcpu:
+						stbycpu="133MHz"
+					else:
+						stbycpu="default"
+				html +="<center><table style=\"width: 80%%;table-layout: fixed;\" border=\"0\" cellspacing=\"0\"><tr align=\"center\"><td>Aktuelle CPU Frequenz: %s<br>Frequenz in der Start-Config: %s<br>Standby Frequenz: %s</td></tr></table><br><br><br>" % (cpucur, cpuau, stbycpu)
+				html +="<table style=\"width: 90%%;table-layout: fixed;\" border=\"0\" cellspacing=\"0\"><tr><td align=\"left\">Tempor&auml;r &auml;ndern:<br><br>%s<option selected>Frequenz ausw&auml;hlen</option><option></option><option value=\"266MHz\">266MHz (standard)</option><option value=\"300MHz\">300MHz</option><option value=\"333MHz\">333MHz</option><option value=\"366MHz\">366MHz</option><option value=\"400MHz\">400MHz</option></select></td><td align=\"center\">StartConfig &auml;ndern:<br><br>%s<option selected>Frequenz ausw&auml;hlen</option><option></option><option value=\"266MHzAuto\">266MHz (standard)</option><option value=\"300MHzAuto\">300MHz</option><option value=\"333MHzAuto\">333MHz</option><option value=\"366MHzAuto\">366MHz</option><option value=\"400MHzAuto\">400MHz</option></select></td><td align=\"right\">Standby &auml;ndern:<br><br>%s<option selected>Frequenz ausw&auml;hlen</option><option></option><option value=\"stbyaus\">Aus</option><option value=\"266stby\">266MHz (standard)</option><option value=\"200stby\">200MHz</option><option value=\"166stby\">166MHz</option><option value=\"133stby\">133MHz</option></select></td></tr></table>" % (wahl, wahl, wahl)
+				html +="</center>"
+		else:
+			html +="<center>OverClock Modul nicht gefunden oder konnte nicht geladen werden!</center>"
+		return  html
+addExternalChild( ("overclock", overclock()) )
+#Videomode
+class VideoMode(resource.Resource):
+	def render_GET(self, req):
+		req.setResponseCode(http.OK)
+		curvideo = commands.getoutput('cat '+ vmode +'')
+		curcolor = commands.getoutput('sed -n "1p" '+ colormode +' | cut -d "_" -f2')
+		curaudio = commands.getoutput('cat '+ amode +'')
+		curthreedread=open(''+ tmode +'')
+		if curthreedread is not None:
+			for curthree in curthreedread:
+				if 'sbs' in curthree:
+					curthreed="Side-by-Side"
+				elif 'tab' in curthree:
+					curthreed="Top and Bottom"
+				else:
+					curthreed="off"
+			curthreedread.close()
+		req.setHeader('Content-type', 'text/html')
+		req.setHeader('charset', 'UTF-8')
+		html=header_string
+		if receiver.upper() == 'UFS912' or receiver.upper() == 'AT7500':
+			vchoise="<option value=\"576i50\">576i50Hz</option><option value=\"576p50\">576p50Hz</option><option value=\"720p50\">720p50Hz</option><option value=\"720p60\">720p60Hz</option><option value=\"1080i50\">1080i50Hz</option><option value=\"1080i60\">1080i60Hz</option><option value=\"1080p24\">1080p24Hz</option><option value=\"1080p25\">1080p25Hz</option><option value=\"1080p30\">1080p30Hz</option><option value=\"1080p50\">1080p50Hz</option><option value=\"1080p59\">1080p59</option><option value=\"1080p60\">1080p60</option>"
+		else:
+			vchoise="<option value=\"576i50\">576i50Hz</option><option value=\"576p50\">576p50Hz</option><option value=\"720p50\">720p50Hz</option><option value=\"720p60\">720p60Hz</option><option value=\"1080i50\">1080i50Hz</option><option value=\"1080i60\">1080i60Hz</option><option value=\"1080p24\">1080p24Hz</option><option value=\"1080p25\">1080p25Hz</option><option value=\"1080p30\">1080p30Hz</option>"
+		html +="<center><table style=\"width: 80%%;table-layout: fixed;\" border=\"0\" cellspacing=\"0\"><tr align=\"center\"><td>Aktueller Modus: %sHz<br>Aktueller Farbmodus: %s<br>3D Mode: %s<br>Aktueller Audio Source: %s</td></tr></table><br><br><br>" % (curvideo, curcolor, curthreed, curaudio)
+		html +="<table style=\"width: 90%%;table-layout: fixed;\" border=\"0\" cellspacing=\"0\"><tr><td align=\"left\">Aufl&ouml;sung &auml;ndern:<br><br>"+ wahl +"<option selected>Aufl&ouml;sung ausw&auml;hlen</option><option></option>"+ vchoise +"</select></td><td align=\"center\">Farbmodus &auml;ndern:<br><br>"+ wahl +"<option selected>Farbmodus ausw&auml;hlen</option><option></option><option value=\"rgb\">RGB</option><option value=\"yuv\">YUV</option><option value=\"422\">422</option></select></td><td align=\"center\">3D Mode:<br><br>"+ wahl +"<option selected>Bitte ausw&auml;hlen</option><option></option><option value=\"threedmodeoff\">Aus</option><option value=\"threedmodetab\">Top and Bottom</option><option value=\"threedmodesbs\">Side-by-Side</option></select></td><td align=\"right\">Audio Source &auml;ndern:<br><br>"+ wahl +"<option selected>Bitte ausw&auml;hlen</option><option></option><option value=\"pcm\">PCM</option><option value=\"spdif\">SPDIF</option></select></td></tr></table>"
+		html +="</center>"
+		return  html
+addExternalChild( ("VideoMode", VideoMode()) )
+
+class fivesevenihz(resource.Resource):
+	def render_GET(self, req):
+		req.setResponseCode(http.OK)
+		req.setHeader('Content-type', 'text/html')
+		req.setHeader('charset', 'UTF-8')
+		html=header_string
+		commands.getoutput('echo 576i50 > '+ vmode +' | echo 576i50 > '+ vmodee +'')
+		config.av.videomode[port].value = "576i"
+		config.av.videomode[port].save()
+		config.av.videorate[mode].value = "50Hz"
+		config.av.videorate[mode].save()
+		gMainDC.getInstance().setResolution(-1, -1)
+		html +="<center>ok</center>"
+		return  html
+addExternalChild( ("576i50", fivesevenihz()) )
+class fivesevenphz(resource.Resource):
+	def render_GET(self, req):
+		req.setResponseCode(http.OK)
+		req.setHeader('Content-type', 'text/html')
+		req.setHeader('charset', 'UTF-8')
+		html=header_string
+		commands.getoutput('echo 576p50 > '+ vmode +' | echo 576p50 > '+ vmodee +'')
+		config.av.videomode[port].value = "576p"
+		config.av.videomode[port].save()
+		config.av.videorate[mode].value = "50Hz"
+		config.av.videorate[mode].save()
+		gMainDC.getInstance().setResolution(-1, -1)
+		html +="<center>ok</center>"
+		return  html
+addExternalChild( ("576p50", fivesevenphz()) )
+class sevenfivehz(resource.Resource):
+	def render_GET(self, req):
+		req.setResponseCode(http.OK)
+		req.setHeader('Content-type', 'text/html')
+		req.setHeader('charset', 'UTF-8')
+		html=header_string
+		commands.getoutput('echo 720p50 > '+ vmode +' | echo 720p50 > '+ vmodee +'')
+		config.av.videomode[port].value = "720p"
+		config.av.videomode[port].save()
+		config.av.videorate[mode].value = "50Hz"
+		config.av.videorate[mode].save()
+		gMainDC.getInstance().setResolution(-1, -1)
+		html +="<center>ok</center>"
+		return  html
+addExternalChild( ("720p50", sevenfivehz()) )
+class sevensixhz(resource.Resource):
+	def render_GET(self, req):
+		req.setResponseCode(http.OK)
+		req.setHeader('Content-type', 'text/html')
+		req.setHeader('charset', 'UTF-8')
+		html=header_string
+		commands.getoutput('echo 720p60 > '+ vmode +' | echo 720p60 > '+ vmodee +'')
+		config.av.videomode[port].value = "720p"
+		config.av.videomode[port].save()
+		config.av.videorate[mode].value = "60Hz"
+		config.av.videorate[mode].save()
+		gMainDC.getInstance().setResolution(-1, -1)
+		html +="<center>ok</center>"
+		return  html
+addExternalChild( ("720p60", sevensixhz()) )
+class oneeightfivehz(resource.Resource):
+	def render_GET(self, req):
+		req.setResponseCode(http.OK)
+		req.setHeader('Content-type', 'text/html')
+		req.setHeader('charset', 'UTF-8')
+		html=header_string
+		commands.getoutput('echo 1080i50 > '+ vmode +' | echo 1080i50 > '+ vmodee +'')
+		config.av.videomode[port].value = "1080i"
+		config.av.videomode[port].save()
+		config.av.videorate[mode].value = "50Hz"
+		config.av.videorate[mode].save()
+		gMainDC.getInstance().setResolution(-1, -1)
+		html +="<center>ok</center>"
+		return  html
+addExternalChild( ("1080i50", oneeightfivehz()) )
+class oneeightsixhz(resource.Resource):
+	def render_GET(self, req):
+		req.setResponseCode(http.OK)
+		req.setHeader('Content-type', 'text/html')
+		req.setHeader('charset', 'UTF-8')
+		html=header_string
+		commands.getoutput('echo 1080i60 > '+ vmode +' | echo 1080i60 > '+ vmodee +'')
+		config.av.videomode[port].value = "1080i"
+		config.av.videomode[port].save()
+		config.av.videorate[mode].value = "60Hz"
+		config.av.videorate[mode].save()
+		gMainDC.getInstance().setResolution(-1, -1)
+		html +="<center>ok</center>"
+		return  html
+addExternalChild( ("1080i60", oneeightsixhz()) )
+class oneeightptwofourhz(resource.Resource):
+	def render_GET(self, req):
+		req.setResponseCode(http.OK)
+		req.setHeader('Content-type', 'text/html')
+		req.setHeader('charset', 'UTF-8')
+		html=header_string
+		commands.getoutput('echo 1080p24 > '+ vmode +' | echo 1080p24 > '+ vmodee +'')
+		config.av.videomode[port].value = "1080p"
+		config.av.videomode[port].save()
+		config.av.videorate[mode].value = "24Hz"
+		config.av.videorate[mode].save()
+		gMainDC.getInstance().setResolution(-1, -1)
+		html +="<center>ok</center>"
+		return  html
+addExternalChild( ("1080p24", oneeightptwofourhz()) )
+class oneeightptwofivehz(resource.Resource):
+	def render_GET(self, req):
+		req.setResponseCode(http.OK)
+		req.setHeader('Content-type', 'text/html')
+		req.setHeader('charset', 'UTF-8')
+		html=header_string
+		commands.getoutput('echo 1080p25 > '+ vmode +' | echo 1080p25 > '+ vmodee +'')
+		config.av.videomode[port].value = "1080p"
+		config.av.videomode[port].save()
+		config.av.videorate[mode].value = "25Hz"
+		config.av.videorate[mode].save()
+		gMainDC.getInstance().setResolution(-1, -1)
+		html +="<center>ok</center>"
+		return  html
+addExternalChild( ("1080p25", oneeightptwofivehz()) )
+class oneeightpthreehz(resource.Resource):
+	def render_GET(self, req):
+		req.setResponseCode(http.OK)
+		req.setHeader('Content-type', 'text/html')
+		req.setHeader('charset', 'UTF-8')
+		html=header_string
+		commands.getoutput('echo 1080p30 > '+ vmode +' | echo 1080p30 > '+ vmodee +'')
+		config.av.videomode[port].value = "1080p"
+		config.av.videomode[port].save()
+		config.av.videorate[mode].value = "30Hz"
+		config.av.videorate[mode].save()
+		gMainDC.getInstance().setResolution(-1, -1)
+		html +="<center>ok</center>"
+		return  html
+addExternalChild( ("1080p30", oneeightpthreehz()) )
+class oneeightpfivehz(resource.Resource):
+	def render_GET(self, req):
+		req.setResponseCode(http.OK)
+		req.setHeader('Content-type', 'text/html')
+		req.setHeader('charset', 'UTF-8')
+		html=header_string
+		commands.getoutput('echo 1080p50 > '+ vmode +' | echo 1080p50 > '+ vmodee +'')
+		config.av.videomode[port].value = "1080p"
+		config.av.videomode[port].save()
+		config.av.videorate[mode].value = "50Hz"
+		config.av.videorate[mode].save()
+		gMainDC.getInstance().setResolution(-1, -1)
+		html +="<center>ok</center>"
+		return  html
+addExternalChild( ("1080p50", oneeightpfivehz()) )
+class oneeightpfiveninehz(resource.Resource):
+	def render_GET(self, req):
+		req.setResponseCode(http.OK)
+		req.setHeader('Content-type', 'text/html')
+		req.setHeader('charset', 'UTF-8')
+		html=header_string
+		commands.getoutput('echo 1080p59 > '+ vmode +' | echo 1080p59 > '+ vmodee +'')
+		config.av.videomode[port].value = "1080p"
+		config.av.videomode[port].save()
+		config.av.videorate[mode].value = "59Hz"
+		config.av.videorate[mode].save()
+		gMainDC.getInstance().setResolution(-1, -1)
+		html +="<center>ok</center>"
+		return  html
+addExternalChild( ("1080p59", oneeightpfiveninehz()) )
+class oneeightpsixhz(resource.Resource):
+	def render_GET(self, req):
+		req.setResponseCode(http.OK)
+		req.setHeader('Content-type', 'text/html')
+		req.setHeader('charset', 'UTF-8')
+		html=header_string
+		commands.getoutput('echo 1080p60 > '+ vmode +' | echo 1080p60 > '+ vmodee +'')
+		system('/bin/3d-mode 40 &')
+		config.av.videomode[port].value = "1080p"
+		config.av.videomode[port].save()
+		config.av.videorate[mode].value = "60Hz"
+		config.av.videorate[mode].save()
+		gMainDC.getInstance().setResolution(-1, -1)
+		html +="<center>ok</center>"
+		return  html
+addExternalChild( ("1080p60", oneeightpsixhz()) )
+class rgb(resource.Resource):
+	def render_GET(self, req):
+		req.setResponseCode(http.OK)
+		req.setHeader('Content-type', 'text/html')
+		req.setHeader('charset', 'UTF-8')
+		html=header_string
+		config.av.colorformat_hdmi.value = "hdmi_rgb"
+		config.av.colorformat_hdmi.save()
+		html +="<center>ok</center>"
+		return  html
+addExternalChild( ("rgb", rgb()) )
+class yuv(resource.Resource):
+	def render_GET(self, req):
+		req.setResponseCode(http.OK)
+		req.setHeader('Content-type', 'text/html')
+		req.setHeader('charset', 'UTF-8')
+		html=header_string
+		config.av.colorformat_hdmi.value = "hdmi_yuv"
+		config.av.colorformat_hdmi.save()
+		html +="<center>ok</center>"
+		return  html
+addExternalChild( ("yuv", yuv()) )
+class fourtwo(resource.Resource):
+	def render_GET(self, req):
+		req.setResponseCode(http.OK)
+		req.setHeader('Content-type', 'text/html')
+		req.setHeader('charset', 'UTF-8')
+		html=header_string
+		config.av.colorformat_hdmi.value = "hdmi_422"
+		config.av.colorformat_hdmi.save()
+		html +="<center>ok</center>"
+		return  html
+addExternalChild( ("422", fourtwo()) )
+class pcm(resource.Resource):
+	def render_GET(self, req):
+		req.setResponseCode(http.OK)
+		req.setHeader('Content-type', 'text/html')
+		req.setHeader('charset', 'UTF-8')
+		html=header_string
+		commands.getoutput('echo pcm > '+ amode +'')
+		config.av.hdmi_audio_source.value = "pcm"
+		config.av.hdmi_audio_source.save()
+		html +="<center>ok</center>"
+		return  html
+addExternalChild( ("pcm", pcm()) )
+class spdif(resource.Resource):
+	def render_GET(self, req):
+		req.setResponseCode(http.OK)
+		req.setHeader('Content-type', 'text/html')
+		req.setHeader('charset', 'UTF-8')
+		html=header_string
+		commands.getoutput('echo spdif > '+ amode +'')
+		config.av.hdmi_audio_source.value = "spdif"
+		config.av.hdmi_audio_source.save()
+		html +="<center>ok</center>"
+		return  html
+addExternalChild( ("spdif", spdif()) )
+class threedmodeoff(resource.Resource):
+	def render_GET(self, req):
+		req.setResponseCode(http.OK)
+		req.setHeader('Content-type', 'text/html')
+		req.setHeader('charset', 'UTF-8')
+		html=header_string
+		config.av.threedmode.value = "off"
+		config.av.threedmode.save()
+		html +="<center>ok</center>"
+		return  html
+addExternalChild( ("threedmodeoff", threedmodeoff()) )
+class threedmodetab(resource.Resource):
+	def render_GET(self, req):
+		req.setResponseCode(http.OK)
+		req.setHeader('Content-type', 'text/html')
+		req.setHeader('charset', 'UTF-8')
+		html=header_string
+		config.av.threedmode.value = "tab"
+		config.av.threedmode.save()
+		html +="<center>ok</center>"
+		return  html
+addExternalChild( ("threedmodetab", threedmodetab()) )
+class threedmodesbs(resource.Resource):
+	def render_GET(self, req):
+		req.setResponseCode(http.OK)
+		req.setHeader('Content-type', 'text/html')
+		req.setHeader('charset', 'UTF-8')
+		html=header_string
+		config.av.threedmode.value = "sbs"
+		config.av.threedmode.save()
+		html +="<center>ok</center>"
+		return  html
+addExternalChild( ("threedmodesbs", threedmodesbs()) )
Index: ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/WebChilds/External/__init__.py
===================================================================
--- ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/WebChilds/External/__init__.py	(revision 14969)
+++ ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/WebChilds/External/__init__.py	(revision 14969)
@@ -0,0 +1,16 @@
+from os import listdir
+from os.path import abspath, splitext
+from Tools.Directories import resolveFilename, SCOPE_PLUGINS
+def importExternalModules():
+	dir = abspath(resolveFilename(SCOPE_PLUGINS) + "Extensions/WebInterface/WebChilds/External/")
+	for file in listdir(dir):
+		module_name, ext = splitext(file) # Handles no-extension files, etc.
+
+		if ext == '.pyc' and module_name != "__init__":				
+			try:
+				exec "import " + module_name
+				print '[Toplevel.importExternalModules] Imported external module: %s' % (module_name)
+		
+			except ImportError, e:				
+				print '[Toplevel.importExternalModules] Could NOT import external module: %s' % (module_name)
+				print '[Toplevel.importExternalModules] Exception Caught\n%s' %e
Index: ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/WebChilds/FileStreamer.py
===================================================================
--- ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/WebChilds/FileStreamer.py	(revision 14969)
+++ ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/WebChilds/FileStreamer.py	(revision 14969)
@@ -0,0 +1,46 @@
+from twisted.web import resource, http, server, static
+from urllib import unquote
+from os import path as os_path
+
+class FileStreamer(resource.Resource):
+	addSlash = True
+
+	def render(self, request):
+		if 'dir' in request.args:
+			dir = unquote(request.args['dir'][0])
+		elif 'root' in request.args:
+			dir = unquote(request.args['root'][0])
+		else:
+			dir = ''
+
+		if 'file' in request.args:			
+			filename = unquote(request.args["file"][0])
+			path = dir + filename
+
+			#dirty backwards compatibility hack
+			if not os_path.exists(path):
+				path = "/hdd/movie/%s" % (filename)
+			
+			print "[WebChilds.FileStreamer] path is %s" %path
+			
+			if os_path.exists(path):
+				basename = filename.decode('utf-8', 'ignore').encode('ascii', 'ignore')
+				
+				if '/' in basename:
+					basename = basename.split('/')[-1]
+
+				request.setHeader("content-disposition", "attachment;filename=\"%s\"" % (basename))
+				file = static.File(path, defaultType = "application/octet-stream")
+				return file.render(request)
+
+			else:
+				request.setResponseCode(http.OK)
+				request.write("file '%s' was not found" %(dir + filename) )
+				request.finish()
+		else:
+			request.setResponseCode(http.OK)
+			request.write("no file given with file=???")
+			request.finish()
+
+		return server.NOT_DONE_YET
+
Index: ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/WebChilds/IPKG.py
===================================================================
--- ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/WebChilds/IPKG.py	(revision 14969)
+++ ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/WebChilds/IPKG.py	(revision 14969)
@@ -0,0 +1,108 @@
+from enigma import eConsoleAppContainer
+
+from twisted.web import server, resource, http
+
+class IPKGResource(resource.Resource):
+	IPKG_PATH = "/usr/bin/ipkg"
+
+	SIMPLECMDS = ( "list", "list_installed", "update", "upgrade" )
+	PACKAGECMDS = ( "info", "status", "install", "remove" )
+	FILECMDS = ( "search", )
+
+	def render(self, request):
+		self.args = request.args
+		self.command = self.getArg("command")
+
+		if self.command is not None:
+			if self.command in IPKGResource.SIMPLECMDS:
+				return self.execSimpleCmd(request)
+			elif self.command in IPKGResource.PACKAGECMDS:
+				return self.execPackageCmd(request)
+			elif self.command in IPKGResource.FILECMDS:
+				return self.execFileCmd(request)
+			else:
+				return self.doErrorPage(request, "Unknown command: "+ self.command)
+		else:
+			return self.doIndexPage(request)
+
+	def buildCmd(self, parms=[]):
+		cmd = [IPKGResource.IPKG_PATH, "ipkg", self.command] + parms
+		print "[IPKG.py] cmd: %s" % cmd
+		return cmd
+
+	def execCmd(self, request, parms=[]):
+		cmd = self.buildCmd(parms)
+
+		request.setResponseCode(http.OK)
+		IPKGConsoleStream(request, cmd)
+
+		return server.NOT_DONE_YET
+
+	def execSimpleCmd(self, request):
+		 return self.execCmd(request)
+
+	def execPackageCmd(self, request):
+		package = self.getArg("package")
+		if package is not None:
+			return self.execCmd(request, [package])
+		else:
+			return self.doErrorPage(request, "Missing parameter: package")
+
+	def execFileCmd(self, request):
+		file = self.getArg("file")
+		if file is not None:
+			return self.execCmd(request, [file])
+
+		else:
+			return self.doErrorPage("Missing parameter: file")
+
+	def doIndexPage(self, request):
+		html = "<html><body>"
+		html += "<h1>Interface to IPKG</h1>"
+		html += "update, ?command=update<br>"
+		html += "upgrade, ?command=upgrade<br>"
+		html += "list_installed, ?command=list_installed<br>"
+		html += "list, ?command=list<br>"
+		html += "search, ?command=search&file=&lt;filename&gt;<br>"
+		html += "info, ?command=info&package=&lt;packagename&gt;<br>"
+		html += "status, ?command=status&package=&lt;packagename&gt;<br>"
+		html += "install, ?command=install&package=&lt;packagename&gt;<br>"
+		html += "remove, ?command=remove&package=&lt;packagename&gt;<br>"
+		html += "</body></html>"
+
+		request.setResponseCode(http.OK)
+		request.write(html)
+		request.finish()
+
+		return server.NOT_DONE_YET
+
+	def doErrorPage(self, request, errormsg):
+		request.setResponseCode(http.OK)
+		request.write(errormsg)
+		request.finish()
+
+		return server.NOT_DONE_YET
+
+	def getArg(self, key):
+		if key in self.args:
+			return self.args[key][0]
+		else:
+			return None
+
+class IPKGConsoleStream:
+	def __init__(self, request, cmd):
+		self.request = request
+
+		self.container = eConsoleAppContainer()
+
+		self.container.dataAvail.append(self.dataAvail)
+		self.container.appClosed.append(self.cmdFinished)
+
+		self.container.execute(*cmd)
+
+	def cmdFinished(self, data):
+		self.request.finish()
+
+	def dataAvail(self, data):
+		self.request.write(data)
+
Index: ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/WebChilds/PlayService.py
===================================================================
--- ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/WebChilds/PlayService.py	(revision 14969)
+++ ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/WebChilds/PlayService.py	(revision 14969)
@@ -0,0 +1,61 @@
+from enigma import eServiceReference
+from twisted.web import resource, http, server
+from os import path as os_path
+
+class ServiceplayerResource(resource.Resource):
+	def __init__(self, session):
+		resource.Resource.__init__(self)
+		self.session = session
+		self.oldservice = None
+	
+	def render(self, request):
+		if 'file' in request.args:
+			output = self.playFile(request.args['file'][0])
+		elif 'url' in request.args:
+			output = self.playURL(request.args['url'][0])
+		elif 'stop' in request.args:
+			output = self.stopServicePlay()
+		else:
+			output = True, "unknown command"
+			
+		request.setResponseCode(http.OK)
+		request.write(output[1])
+		request.finish()
+					
+		return server.NOT_DONE_YET
+
+	def playFile(self, path):
+		print "[ServiceplayerResource] playing file", path
+		if os_path.exists(path) is not True:
+			return False, "given path is not existing, %s" % path
+		else:
+			sref = "4097:0:0:0:0:0:0:0:0:0:%s" % path
+			self.startServicePlay(eServiceReference(sref))
+			return True, "playing path started, %s" % path
+
+	def playURL(self, url):
+		#url= url.replace("%3a",":").replace("%20"," ")
+		#print "[ServiceplayerResource] playing url",url
+		#sref = "4097:0:0:0:0:0:0:0:0:0:%s"%url
+		#self.startServicePlay(eServiceReference(sref))
+		return False, "Not implemented"
+
+	def startServicePlay(self, esref):
+		print "[ServiceplayerResource] playing sref", esref.toString()
+		csref = self.session.nav.getCurrentlyPlayingServiceReference()
+		if csref is not None:
+			if csref.toString().startswith("4097") is not True:
+				self.oldservice = csref.toString(), csref
+
+		self.session.nav.stopService()
+		self.session.nav.playService(esref)
+
+	def stopServicePlay(self):
+		print "[ServiceplayerResource] stopping service", self.oldservice
+		self.session.nav.stopService()
+		if self.oldservice is not None:
+			self.session.nav.playService(self.oldservice[1])
+			return True, "[ServiceplayerResource] stopped, now playing old service, %s" % self.oldservice[0]
+		else:
+			return True, "[ServiceplayerResource] stopped"
+
Index: ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/WebChilds/RedirecToCurrentStream.py
===================================================================
--- ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/WebChilds/RedirecToCurrentStream.py	(revision 14969)
+++ ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/WebChilds/RedirecToCurrentStream.py	(revision 14969)
@@ -0,0 +1,22 @@
+from twisted.web import resource, server
+from ServiceReference import ServiceReference
+
+class RedirecToCurrentStreamResource(resource.Resource):
+	"""
+		used to redirect the client to the streamproxy with the current service tuned on TV
+	"""
+	def __init__(self, session):
+		resource.Resource.__init__(self)
+		self.session = session
+
+	def render(self, request):
+		currentServiceRef = self.session.nav.getCurrentlyPlayingServiceReference()
+		if currentServiceRef is not None:
+			sref = currentServiceRef.toString()
+		else:
+			sref = "N/A"
+
+		request.redirect("http://%s:8001/%s" % (request.getHost().host, sref))
+		request.finish()
+		return server.NOT_DONE_YET
+
Index: ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/WebChilds/Screengrab.py
===================================================================
--- ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/WebChilds/Screengrab.py	(revision 14969)
+++ ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/WebChilds/Screengrab.py	(revision 14969)
@@ -0,0 +1,193 @@
+from enigma import eConsoleAppContainer
+from Components.Console import Console
+from twisted.web import resource, http, http_headers, server
+from os import path as os_path, remove as os_remove
+from ServiceReference import ServiceReference
+from Tools.Directories import pathExists
+
+class GrabResource(resource.Resource):
+	'''
+		this is a interface to Seddis AiO Dreambox Screengrabber
+	'''
+	GRAB_BIN = '/sbin/stfbshot'
+	SPECIAL_ARGS = ('format', 'filename', 'save')
+	def __init__(self, session, output = None):
+		
+		self.session = session
+		resource.Resource.__init__(self)
+
+	def render(self, request):
+		args = []
+		append = args.append
+		global videoOnly
+		global osdOnly
+		# some presets
+		filename = 'dump'
+		imageformat = 'png'
+		osdOnly = False
+		videoOnly = False
+		save = False
+
+		for key, value in request.args.items():
+			print "key: %s valve:%s" % (key,value)
+
+			if key == "m":
+				print "set osdOnly = True"
+				osdOnly = True
+				
+			elif key == "v":
+				print "set videoOnly = True"
+				videoOnly = True
+
+			elif key == "o":
+				print "set osdOnly = True"
+				osdOnly = True
+
+		request.setHeader('Content-Disposition', 'inline; filename=dump.%s;' %imageformat)
+		request.setHeader('Content-Type','image/%s' %imageformat)
+
+		if videoOnly is False and osdOnly is False:
+			print "[ScreenGrab] screen shoot key =",key
+
+			filename = '/tmp/dump.png'
+			append(filename)
+			oldservice = None
+			currentServiceRef = self.session.nav.getCurrentlyPlayingServiceReference()
+			currservice = currentServiceRef.toString(),ServiceReference(currentServiceRef).getServiceName()
+			for input in currservice:
+				oldservice = input
+				break
+
+			if pathExists("/sbin/ffmpeg"):
+				ffmpeg = "/sbin/ffmpeg"
+			elif pathExists("/var/swap/bin/ffmpeg"):
+				ffmpeg = "/var/swap/bin/ffmpeg"
+			elif pathExists("/var/bin/ffmpeg"):
+				ffmpeg = "/var/bin/ffmpeg"
+			else:
+				ffmpeg = "ffmpeg"
+
+			cmd = ['/sbin/grab.sh %s' % (oldservice)]	
+			GrabStream(request, cmd, filename, save)
+				
+		elif videoOnly is True:
+			print "[ScreenGrab] videoOnly shoot key =",key
+
+			filename = '/tmp/dump.png'
+			append(filename)
+			oldservice = None
+			currentServiceRef = self.session.nav.getCurrentlyPlayingServiceReference()
+			currservice = currentServiceRef.toString(),ServiceReference(currentServiceRef).getServiceName()
+			for input in currservice:
+				oldservice = input
+				break
+
+			if pathExists("/sbin/ffmpeg"):
+				ffmpeg = "/sbin/ffmpeg"
+			elif pathExists("/var/swap/bin/ffmpeg"):
+				ffmpeg = "/var/swap/bin/ffmpeg"
+			elif pathExists("/var/bin/ffmpeg"):
+				ffmpeg = "/var/bin/ffmpeg"
+			else:
+				ffmpeg = "ffmpeg"
+
+#			cmd = ['%s -i http://127.0.0.1:8001/%s -vframes 1 -vcodec png -y -f image2 /tmp/dump.png' % (ffmpeg,oldservice)]
+			cmd = ['%s  -itsoffset -4 -i http://127.0.0.1:8001/%s -vframes 1 -vcodec png -sn -an -y -f image2 /tmp/dump.png' % (ffmpeg,oldservice)]
+
+			GrabStream(request, cmd, filename, save)
+		elif osdOnly is True:
+			print "[ScreenGrab] osdOnly shoot key =",key
+
+			filename = '/tmp/dump.png'
+			append(filename)
+			cmd = ['/sbin/stfbshot PNG /tmp']	
+			GrabStream(request, cmd, filename, save)
+
+		return server.NOT_DONE_YET
+
+class GrabStream:
+	'''
+		used to start the grab-bin in the console in the background
+		while this takes some time, the browser must wait until the grabis finished
+	'''
+	def __init__(self, request, cmd, target=None, save=False):
+		self.target = target
+		self.save = save
+		self.output = ''
+		self.request = request
+
+		self.container = eConsoleAppContainer()
+		self.container.appClosed.append(self.cmdFinished)
+		self.container.dataAvail.append(self.dataAvail)
+
+		print '[Screengrab.py] starting AiO grab with cmdline:', cmd
+		self.container.execute(*cmd)
+
+	def cmdFinished(self, data):
+		print '[Screengrab.py] cmdFinished'
+		print '[Screengrab.py] cmdFinished',int(data)
+		global videoOnly
+		global osdOnly
+		if int(data) is 25 and self.target is not None:
+			print "if", data
+			try:
+				print "try"
+				fp = open(self.target)
+				self.request.write(fp.read())
+				fp.close()
+				if self.save is False:
+					os_remove(self.target)
+					print '[Screengrab.py] %s removed' %self.target
+			except Exception,e:
+				print "exteepd"
+				self.request.write('Internal error while reading target file')
+		elif int(data) is 25 and self.target is None:
+			print "if2", data
+			print "target", self-target
+
+			self.request.write(self.output)
+		elif int(data) is 1:
+			print "if3", data
+
+			self.request.write(self.output)
+		elif int(data) is 0 and videoOnly is False and osdOnly is False:
+		#videoOnly and osdOnly is False
+			print "if0", data
+			try:
+				print "try"
+				fp = open(self.target)
+				self.request.write(fp.read())
+				fp.close()
+				if self.save is False:
+					os_remove(self.target)
+					print '[Screengrab.py] %s removed' %self.target
+			except Exception,e:
+				print "exteepd"
+				self.request.write('Internal error while reading target file')
+		elif int(data) is 0 and videoOnly is True:
+		#videoOnly is True
+			print "if0", data
+			try:
+				print "try"
+				fp = open(self.target)
+				self.request.write(fp.read())
+				fp.close()
+				if self.save is False:
+					os_remove(self.target)
+					print '[Screengrab.py] %s removed' %self.target
+			except Exception,e:
+				print "exteepd"
+				self.request.write('Internal error while reading target file')
+		else:
+			print "if4", data
+
+			self.request.write('Internal error')
+		print "[Screengrab.py] data", data
+		print "[Screengrab.py] target", self.target
+		print "[Screengrab.py] output", self.output
+
+		self.request.finish()
+
+
+	def dataAvail(self, data):
+		print '[Screengrab.py] data Available ', data
Index: ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/WebChilds/Screenpage.py
===================================================================
--- ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/WebChilds/Screenpage.py	(revision 14969)
+++ ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/WebChilds/Screenpage.py	(revision 14969)
@@ -0,0 +1,70 @@
+from twisted.web import resource, http, server, static
+
+from Plugins.Extensions.WebInterface import webif
+
+from os import path as os_path
+
+"""
+	define all files in /web to send no XML-HTTP-Headers here
+	all files listed here will get an Content-Type: application/xhtml+xml charset: UTF-8
+"""
+AppTextHeaderFiles = ['stream.m3u.xml', 'ts.m3u.xml', 'streamcurrent.m3u.xml', 'movielist.m3u.xml', 'services.m3u.xml', ]
+
+"""
+ Actualy, the TextHtmlHeaderFiles should contain the updates.html.xml, but the IE then
+ has problems with unicode-characters
+"""
+TextHtmlHeaderFiles = ['wapremote.xml', 'stream.xml', ]
+
+"""
+	define all files in /web to send no XML-HTTP-Headers here
+	all files listed here will get an Content-Type: text/html charset: UTF-8
+"""
+NoExplicitHeaderFiles = ['getpid.xml', 'tvbrowser.xml', ]
+
+class ScreenPage(resource.Resource):
+	def __init__(self, session, path, addSlash = False):
+		resource.Resource.__init__(self)
+
+		self.session = session
+		self.path = path
+		self.addSlash = addSlash
+
+	def render(self, request):
+		path = self.path
+		if os_path.isfile(path):
+			lastComponent = path.split('/')[-1]
+
+			# Set the Header according to what's requested
+			request.setResponseCode(http.OK)
+			if lastComponent in AppTextHeaderFiles:
+				request.setHeader('Content-Type', 'application/text')
+			elif lastComponent in TextHtmlHeaderFiles or (path.endswith(".html.xml") and lastComponent != "updates.html.xml"):
+				request.setHeader('Content-Type', 'text/html; charset=UTF-8')
+			elif lastComponent not in NoExplicitHeaderFiles:
+				request.setHeader('Content-Type', 'application/xhtml+xml; charset=UTF-8')
+
+			# now go and write the Output
+			# request.finish() is called inside webif.py (requestFinish() which is called via renderPage())
+			webif.renderPage(request, path, self.session) # login?
+
+		elif os_path.isdir(path) and self.addSlash is True:
+			return self.getChild("/", request).render(request)
+
+		else:
+			request.setResponseCode(http.NOT_FOUND)
+			request.write('<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">\n')
+			request.write("<html><head><title>Enigma2 WebControl</title></head><body><h1>404 - Page not found</h1></body></html>")
+			request.finish()
+
+		return server.NOT_DONE_YET
+
+	def getChild(self, path, request):
+		path = "%s/%s" % (self.path, path)
+
+		if path[-1] == "/":
+			path += "index.html"
+
+		path += ".xml"
+		return ScreenPage(self.session, path)
+
Index: ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/WebChilds/ServiceListSave.py
===================================================================
--- ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/WebChilds/ServiceListSave.py	(revision 14969)
+++ ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/WebChilds/ServiceListSave.py	(revision 14969)
@@ -0,0 +1,231 @@
+from twisted.web import resource, http, server
+from enigma import eDVBDB
+import os
+from xml.dom.minidom import parseString as xml_dom_minidom_parseString
+from urllib import unquote as urllib_unquote
+##########################
+class ServiceList(resource.Resource):
+	def __init__(self, session):
+		
+		self.session = session
+		resource.Resource.__init__(self)
+		self.putChild("reload", ServiceListReload())
+		self.putChild("save", ServiceListSave())
+
+class ServiceListReload(resource.Resource):
+	def render(self, request):
+		request.setHeader('Content-type', 'application; xhtml+xml;' )
+		request.setHeader('charset', 'UTF-8')
+				
+		try:
+			db = eDVBDB.getInstance()
+			#db.reloadServicelist() # reloading only lamedb
+			db.reloadBouquets() # reloading *.tv and *.radio
+
+			request.setResponseCode(http.OK)
+			
+			return """<?xml version="1.0" encoding="UTF-8"?>
+						<e2simplexmlresult>	
+							<e2state>True</e2state>
+							<e2statetext>Servicelist reloaded</e2statetext>	
+						</e2simplexmlresult>"""
+						
+		except Exception, e:
+			request.setResponseCode(http.OK)
+
+			return """<?xml version="1.0" encoding="UTF-8"?>
+						<e2simplexmlresult>	
+							<e2state>False</e2state>
+							<e2statetext>Error while loading Servicelist!</e2statetext>	
+						</e2simplexmlresult>"""
+
+class ServiceListSave(resource.Resource):
+	TYPE_TV = 0
+	TYPE_RADIO = 1
+	EXTENSIONS = ['.tv', '.radio']
+	DIR = "/etc/enigma2/"
+	undefinded_tag = "%n/a%"
+	undefinded_and = "%und%"
+
+#	def http_POST(self, request):
+#		"""
+#		overwriten, because we need a custom parsePOSTData
+#		"""
+#		return self.parsePOSTData(request).addCallback(
+#			lambda res: self.render(request))
+#
+#	def parsePOSTData(self, request):
+#		"""
+#		overridden, because we need to set higher values to fileupload.parse_urlencoded
+#		"""
+#		if request.stream.length == 0:
+#			return defer.succeed(None)
+#
+#		parser = None
+#		ctype = request.headers.getHeader('content-type')
+#		print "#" * 20, ctype
+#		if ctype is None:
+#			return defer.succeed(None)
+#
+#		def updateArgs(data):
+#			args = data
+#			request.args.update(args)
+#
+#		def updateArgsAndFiles(data):
+#			args, files = data
+#			request.args.update(args)
+#			request.files.update(files)
+#
+#		def error(f):
+#			f.trap(fileupload.MimeFormatError)
+#			raise http.HTTPError(responsecode.BAD_REQUEST)
+#
+#		if ctype.mediaType == 'application' and ctype.mediaSubtype == 'x-www-form-urlencoded':
+#			d = fileupload.parse_urlencoded(request.stream, maxMem=100 * 1024 * 1024, maxFields=1024)
+#			d.addCallbacks(updateArgs, error)
+#			return d
+#		else:
+#			raise http.HTTPError(responsecode.BAD_REQUEST)
+
+	def render(self, request):			
+		request.setHeader('Content-type', 'application; xhtml+xml;' )
+		request.setHeader('charset', 'UTF-8')
+		
+		try:
+			content = request.args['content'][0].replace("<n/a>", self.undefinded_tag).replace('&', self.undefinded_and)
+			if content.find('undefined') != -1:
+				fp = open('/tmp/savedlist', 'w')
+				fp.write(content)
+				fp.close()
+				result = """<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n
+						<e2simplexmlresult>\n
+							<e2state>False</e2state>
+							<e2statetext>found string 'undefined' in XML DATA... a copy was saved to '/tmp/savedlist'.</e2statetext>
+						</e2simplexmlresult>\n
+					 """
+				request.setResponseCode(http.OK)
+				request.write(result)
+
+			(bouquets_tv, bouquets_radio) = self.parseXML(content)
+			#print "having num %i TV Bouquets and num %i Radio Bouquets" %(len(bouquets_tv),len(bouquets_radio))
+
+			#deleting old files
+			os.system("rm " + self.DIR + "userbouquet*.tv ")
+			os.system("rm " + self.DIR + "userbouquet*.radio ")
+			os.system("rm " + self.DIR + "bouquets.tv ")
+			os.system("rm " + self.DIR + "bouquets.radio ")
+
+			#writing new files
+			self.createIndexFile(self.TYPE_TV, bouquets_tv)
+			counter = 0
+			for bouquet in bouquets_tv:
+				self.createBouquetFile(self.TYPE_TV, bouquet['bname'], bouquet['services'], counter)
+				counter = counter + 1
+
+			self.createIndexFile(self.TYPE_RADIO, bouquets_radio)
+			counter = 0
+			for bouquet in bouquets_radio:
+				self.createBouquetFile(self.TYPE_RADIO, bouquet['bname'], bouquet['services'], counter)
+				counter = counter + 1
+
+			# reloading *.tv and *.radio
+			db = eDVBDB.getInstance()
+			db.reloadBouquets()
+			print "servicelists reloaded"
+			result = """<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n
+						<e2simplexmlresult>\n
+							<e2state>True</e2state>
+							<e2statetext>servicelist saved with %i TV und %i Radio Bouquets and was reloaded</e2statetext>
+						</e2simplexmlresult>\n
+					 """ % (len(bouquets_tv), len(bouquets_radio))
+			
+			request.setResponseCode(http.OK)	
+			request.write(result)
+			
+		except Exception, e:
+			print e
+			result = """<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n
+						<e2simplexmlresult>\n
+							<e2state>False</e2state>
+							<e2statetext>%s</e2statetext>
+						</e2simplexmlresult>\n
+					 """ % e
+					 
+			request.setResponseCode(http.OK)	
+			request.write(result)	
+			
+		request.finish()	 
+		return server.NOT_DONE_YET
+
+	def parseXML(self, xmldata):
+		print "parsing xmldata with length", len(xmldata)
+		xmldoc = xml_dom_minidom_parseString(xmldata);
+		blist = xmldoc.getElementsByTagName("e2bouquetlist")[0]
+		print "Num TV Bouquets", len(blist.getElementsByTagName('e2tvbouquetlist')[0].getElementsByTagName('e2bouquet'))
+		print "Num RADIO Bouquets", len(blist.getElementsByTagName('e2radiobouquetlist')[0].getElementsByTagName('e2bouquet'))
+
+		bouquets_tv = self.parseBouquets(blist.getElementsByTagName('e2tvbouquetlist')[0])
+		bouquets_radio = self.parseBouquets(blist.getElementsByTagName('e2radiobouquetlist')[0])
+		return bouquets_tv, bouquets_radio
+
+	def parseBouquets(self, xmlnode):
+		#print "parsing Bouquets", xmlnode
+		list = []
+		for bouquet in xmlnode.getElementsByTagName('e2bouquet'):
+			bref = urllib_unquote(bouquet.getElementsByTagName('e2bouquetreference')[0].childNodes[0].data)
+			bname = urllib_unquote(bouquet.getElementsByTagName('e2bouquetname')[0].childNodes[0].data)
+			#print "Bouquet",bref,bname
+			list.append({'bname':bname, 'bref':bref, 'services':self.parseServices(bouquet)})
+		return list
+
+	def parseServices(self, xmlnode):
+		#print "parsing Services", xmlnode
+		list = []
+		for service in xmlnode.getElementsByTagName('e2servicelist')[0].getElementsByTagName('e2service'):
+			sref = urllib_unquote(service.getElementsByTagName('e2servicereference')[0].childNodes[0].data)
+			sname = urllib_unquote(service.getElementsByTagName('e2servicename')[0].childNodes[0].data)
+			sname = sname.replace(self.undefinded_tag, "<n/a>").replace(self.undefinded_and, "&")
+			#print sref,sname
+			list.append({'sref':sref, 'sname':sname})
+		return list
+
+	def createBouquetFile(self, type, bname, list_services, counter):
+		print "creating file for bouquet", bname, "with", len(list_services), "services for type", type
+		filename = self.getFilenameForBouquet(type, bname, counter)
+		fcontent = "#NAME %s\n" % bname
+		for service in list_services:
+			fcontent += "#SERVICE %s\n" % service['sref']
+			fcontent += "#DESCRIPTION %s\n" % service['sname']
+		fcontent = fcontent.encode('utf-8')
+		fp = open(self.DIR + filename, "w")
+		fp.write(fcontent)
+		fp.close()
+
+	def createIndexFile(self, type, bouquets):
+		print "creating Indexfile with", len(bouquets), "num bouquets for type", type
+		filename = self.getFilenameForIndex(type)
+		if(type == self.TYPE_TV):
+			fcontent = "#NAME User - bouquets (TV)\n"
+		else:
+			fcontent = "#NAME User - bouquets (Radio)\n"
+		counter = 0
+		for bouquet in bouquets:
+			fcontent += "#SERVICE: 1:7:1:0:0:0:0:0:0:0:FROM BOUQUET \"%s\" ORDER BY bouquet\n" % self.getFilenameForBouquet(type, bouquet['bname'], counter)
+			counter = counter + 1
+
+		fp = open(self.DIR + filename, "w")
+		fp.write(fcontent)
+		fp.close()
+
+	def getFilenameForBouquet(self, type, bouquetname, counter):
+		if bouquetname == "Favourites (TV)" and type == self.TYPE_TV:
+			s = "userbouquet.favourites%s" % self.EXTENSIONS[type]
+		elif bouquetname == "Favourites (Radio)" and type == self.TYPE_RADIO:
+			s = "userbouquet.favourites%s" % self.EXTENSIONS[type]
+		else:
+			s = "userbouquet.%i%s" % (counter, self.EXTENSIONS[type])
+		return s
+
+	def getFilenameForIndex(self, type):
+		return "bouquets" + self.EXTENSIONS[type]
+
Index: ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/WebChilds/Toplevel.py
===================================================================
--- ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/WebChilds/Toplevel.py	(revision 14969)
+++ ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/WebChilds/Toplevel.py	(revision 14969)
@@ -0,0 +1,61 @@
+from twisted.web import resource, static
+from twisted.python import util
+
+from Components.config import config
+
+from Plugins.Extensions.WebInterface import __file__ 
+from Screenpage import ScreenPage
+from FileStreamer import FileStreamer
+from Screengrab import GrabResource
+from IPKG import IPKGResource
+from PlayService import ServiceplayerResource
+from Uploader import UploadResource
+from ServiceListSave import ServiceList
+from RedirecToCurrentStream import RedirecToCurrentStreamResource
+
+from External.__init__ import importExternalModules
+externalChildren = []
+
+def addExternalChild(child):
+	externalChildren.append(child)
+
+def getToplevel(session):
+	root = static.File(util.sibpath(__file__, "web-data/tpl/default"))
+	
+	root.putChild("web", ScreenPage(session, util.sibpath(__file__, "web"), True) ) # "/web/*"
+	root.putChild("web-data", static.File(util.sibpath(__file__, "web-data")))
+	root.putChild("file", FileStreamer())
+	root.putChild("grab", GrabResource(session))
+	root.putChild("ipkg", IPKGResource())
+	root.putChild("play", ServiceplayerResource(session))
+	root.putChild("wap", RedirectorResource("/mobile/"))
+	root.putChild("mobile", ScreenPage(session, util.sibpath(__file__, "mobile"), True) )
+	root.putChild("upload", UploadResource())
+	root.putChild("servicelist", ServiceList(session))
+	root.putChild("streamcurrent", RedirecToCurrentStreamResource(session))
+		
+	if config.plugins.Webinterface.includemedia.value is True:
+		root.putChild("media", static.File("/media"))
+		root.putChild("hdd", static.File("/media/hdd"))
+		
+	
+	importExternalModules()
+
+	for child in externalChildren:
+		if len(child) == 2:
+			root.putChild(child[0], child[1])
+	
+	return root
+		
+class RedirectorResource(resource.Resource):
+	"""
+		this class can be used to redirect a request to a specified uri
+	"""
+	def __init__(self, uri):
+		self.uri = uri
+		resource.Resource.__init__(self)
+	
+	def render(self, request):
+		request.redirect(self.uri)
+		request.finish()
+
Index: ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/WebChilds/Uploader.py
===================================================================
--- ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/WebChilds/Uploader.py	(revision 14969)
+++ ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/WebChilds/Uploader.py	(revision 14969)
@@ -0,0 +1,77 @@
+from os import statvfs, path as os_path, chmod as os_chmod, write as os_write, \
+		close as os_close, unlink as os_unlink, open as os_open, O_WRONLY, \
+		O_CREAT
+from twisted.web import resource, http
+from tempfile import mkstemp
+from re import search
+
+class UploadResource(resource.Resource):
+	default_uploaddir = "/tmp/"
+
+	def render_POST(self, req):
+		uploaddir = self.default_uploaddir
+		if req.args['path'][0]:
+			if os_path.isdir(req.args['path'][0]):
+				uploaddir = req.args['path'][0]
+				if uploaddir[-1] != "/":
+					uploaddir += "/"
+			else:
+				req.setResponseCode(http.OK)
+				req.setHeader('Content-type', 'text/html')
+				return "path '%s' to upload not existing!" % req.args['path'][0]
+
+		data = req.args['file'][0]
+		if not data:
+			req.setResponseCode(http.OK)
+			req.setHeader('Content-type', 'text/html')
+			return "filesize was 0, not uploaded"
+
+		try:
+			matches = search('.*?filename="(.*?)"\r\n.*?', req.content.getvalue())
+			fn=os_path.join(uploaddir, matches.group(1))
+		except Exception, e:
+			fn= None
+
+		# NOTE: we only accept the given filename if no such file exists yet
+		if fn and not os_path.exists(fn):
+			fd = os_open(fn, O_WRONLY | O_CREAT)
+		else:
+			fd, fn = mkstemp(dir = uploaddir)
+		cnt = os_write(fd, data)
+		os_close(fd)
+		os_chmod(fn, 0755)
+		
+		if cnt <= 0: # well, actually we should check against len(data) but lets assume we fail big time or not at all
+			try:
+				os_unlink(fn)
+			except OSError, oe:
+				pass
+			req.setResponseCode(http.OK)
+			req.setHeader('Content-type', 'text/html')
+			return "error writing to disk, not uploaded"
+		else:
+			req.setResponseCode(http.OK)
+			req.setHeader('Content-type', 'text/html')
+			return "uploaded to %s" % fn
+
+	def render_GET(self, req):
+		try:
+			stat = statvfs("/tmp/")
+		except OSError:
+			return - 1
+
+		freespace = stat.f_bfree / 1000 * stat.f_bsize / 1000
+
+		req.setResponseCode(http.OK)
+		req.setHeader('Content-type', 'text/html')
+		return """
+				<form method="POST" enctype="multipart/form-data">
+				<table>
+				<tr><td>Path to save (default is '%s')</td><td><input name="path"></td></tr>
+				<tr><td>File to upload</td><td><input name="file" type="file"></td></tr>
+				<tr><td colspan="2">Filesize must not be greather than %dMB! /tmp/ has not more free space!</td></tr>
+				<tr><td colspan="2"><input type="submit"></td><tr>
+				</table>
+				</form>
+		""" % (self.default_uploaddir, freespace)
+
Index: ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/WebComponents/Converter/HddInfo.py
===================================================================
--- ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/WebComponents/Converter/HddInfo.py	(revision 14969)
+++ ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/WebComponents/Converter/HddInfo.py	(revision 14969)
@@ -0,0 +1,35 @@
+from Components.Converter.Converter import Converter
+
+class HddInfo(Converter):
+	MODEL = 0
+	CAPACITY = 1
+	FREE = 2
+
+	def __init__(self, type):
+		Converter.__init__(self, type)
+
+		self.type = {
+					 "Model" : self.MODEL,
+					 "Capacity" : self.CAPACITY,
+					 "Free" : self.FREE,
+					 }[type]
+
+	def getText(self):
+		hdd = self.source.hdd
+
+		if hdd is not None:
+			if self.type == self.MODEL:
+				return "%s" % hdd.model()
+			elif self.type == self.CAPACITY:
+				return "%s" % hdd.capacity()
+			elif self.type == self.FREE:
+				if hdd.free() > 1024:
+					free = float(hdd.free()) / float(1024)
+					return "%.3f GB" % free
+				else:
+					return "%i MB" % hdd.free()
+
+		return _("N/A")
+
+	text = property(getText)
+
Index: ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/WebComponents/Converter/NetworkInterfaceInfo.py
===================================================================
--- ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/WebComponents/Converter/NetworkInterfaceInfo.py	(revision 14969)
+++ ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/WebComponents/Converter/NetworkInterfaceInfo.py	(revision 14969)
@@ -0,0 +1,37 @@
+from Components.Converter.Converter import Converter
+from Components.Element import cached
+
+class NetworkInfo(Converter):
+	MAC = 0
+	DHCP = 1
+	IP = 2
+	GATEWAY = 3
+	NAMESERVER = 4
+
+	def __init__(self, type):
+		Converter.___init__(self)
+		self.type = {
+					 "Mac" : self.MAC,
+					 "Dhcp" : self.DHCP,
+					 "Ip" : self.IP,
+					 "Gateway" : self.GATEWAY,
+					 "Nameserver" : self.NAMESERVER,
+					 }[type]
+
+	@cached
+	def getText(self):
+		iface = iface.interface
+
+		if self.type is self.MAC:
+			return iface.mac
+		elif self.type is self.DHCP:
+			return iface.dhcp
+		elif self.type is self.IP:
+			return iface.IP
+		elif self.type is self.GATEWAY:
+			return iface.gateway
+		elif self.type is self.NAMESERVER:
+			return iface.nameserver
+
+	text = property(getText)
+
Index: ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/WebComponents/Converter/SimpleResult.py
===================================================================
--- ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/WebComponents/Converter/SimpleResult.py	(revision 14969)
+++ ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/WebComponents/Converter/SimpleResult.py	(revision 14969)
@@ -0,0 +1,25 @@
+from Components.Converter.Converter import Converter
+from Components.Element import cached
+
+class SimpleResult(Converter):
+	RESULT = 0
+	RESULTTEXT = 1
+	
+	def __init__(self, type):
+		Converter.__init__(self, type)
+		self.type = { "Result" : self.RESULT,
+					  "ResultText" : self.RESULTTEXT
+					}[type]
+
+	@cached
+	def getText(self):
+		result = self.source.result
+		
+		if self.type is self.RESULT:
+			return str(result[0])
+		elif self.type is self.RESULTTEXT:
+			return str(result[1])
+		else:
+			return "N/A"
+		
+	text = property(getText)
Index: ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/WebComponents/Converter/VolumeInfo.py
===================================================================
--- ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/WebComponents/Converter/VolumeInfo.py	(revision 14969)
+++ ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/WebComponents/Converter/VolumeInfo.py	(revision 14969)
@@ -0,0 +1,33 @@
+from Components.Converter.Converter import Converter
+from Components.Element import cached
+
+class VolumeInfo(Converter):
+	RESULT = 0
+	RESULTTEXT = 1
+	VOLUME = 2
+	ISMUTED = 3
+	
+	def __init__(self, type):
+		Converter.__init__(self, type)
+		self.type = { "Result" : self.RESULT,
+					  "ResultText" : self.RESULTTEXT,
+					  "Volume" : self.VOLUME,
+					  "IsMuted" : self.ISMUTED
+					}[type]
+
+	@cached
+	def getText(self):
+		volume = self.source.volume
+		
+		if self.type is self.RESULT:
+			return str(volume[0])
+		elif self.type is self.RESULTTEXT:
+			return str(volume[1])
+		elif self.type is self.VOLUME:
+			return str(volume[2])
+		elif self.type is self.ISMUTED:
+			return str(volume[3])
+		else:
+			return "N/A"
+		
+	text = property(getText)
Index: ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/WebComponents/Sources/AT.py
===================================================================
--- ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/WebComponents/Sources/AT.py	(revision 14969)
+++ ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/WebComponents/Sources/AT.py	(revision 14969)
@@ -0,0 +1,165 @@
+# Code for the AutoTimerPlugin
+from Components.Sources.Source import Source
+
+class AT(Source):
+	LIST = 0
+	WRITE = 1
+
+	def __init__(self, session, func=LIST):
+		print "AutoTimer: init: ", func
+		Source.__init__(self)
+		self.func = func
+		self.session = session
+		self.result = []
+
+	def handleCommand(self, cmd):
+		print "AutoTimer: handleCommand: ", cmd
+		if cmd is not None:
+			self.cmd = cmd
+			if self.func is self.LIST:
+				self.result = self.timerList(cmd)
+			elif self.func is self.WRITE:
+				self.result = self.writeTimer(cmd)
+
+	def timerList(self):
+		print "timerList"
+
+		try:
+			from Plugins.Extensions.AutoTimer.plugin import autotimer
+
+			if not autotimer:
+				from Plugins.Extensions.AutoTimer.AutoTimer import AutoTimer
+				autotimer = AutoTimer()
+		except ImportError:
+			return []
+
+		returnList = []
+
+		for timer in autotimer.getTimerList():
+			print "TIMER: ", timer
+			innerList = [
+				timer.getName(),
+				timer.getMatch()
+			]
+
+			if timer.hasAfterEvent():
+				innerList.append(timer.getAfterEvent()) # 2
+			else:
+				innerList.append("") # 2
+
+			#excludes
+			innerList.extend((
+				timer.getExcludedTitle(),
+				timer.getExcludedShort(),
+				timer.getExcludedDescription(),
+				timer.getExcludedDays(),
+												))
+
+			#includes
+			innerList.extend((
+				timer.getIncludedTitle(),
+				timer.getIncludedShort(),
+				timer.getIncludedDescription(),
+				timer.getIncludedDays(),
+												))
+
+			# services
+			innerList.extend((
+				timer.getServices(), # 11
+				timer.getBouquets() # 12
+												))
+
+			if timer.hasTimespan():
+				innerList.extend((
+					timer.getTimespanBegin(), # 13
+					timer.getTimespanEnd() # 14
+												))
+			else:
+				innerList.extend(("", "")) # 13, 14
+
+			if timer.hasDuration():
+				innerList.append(timer.getDuration()) # 15
+			else:
+				innerList.append("") # 15
+
+			if timer.hasCounter():
+				innerList.extend((
+					timer.getCounter(), # 16
+					timer.getCounterLeft() # 17
+												))
+			else:
+				innerList.extend((0, 0)) # 16, 17
+
+			innerList.append(timer.getCounterLimit()) # 18
+
+			if timer.hasDestination():
+				innerList.append(timer.destination) # 19
+			else:
+				innerList.append("/hdd/movie/") # 19
+
+			if timer.hasCounterFormatString():
+				innerList.append(timer.getCounterFormatString()) # 20
+			else:
+				innerList.append("") # 20
+
+			innerList.extend((
+				timer.getLastBegin(), # 21
+				timer.getJustplay(), # 22
+				timer.getAvoidDuplicateDescription() # 23
+												))
+
+			if timer.hasTags():
+				innerList.append(timer.getTags()) # 24
+			else:
+				innerList.append("") # 24
+
+			print "Enabled", timer.getEnabled()
+			innerList.append(timer.getEnabled()) # 25
+			innerList.append("off") # 26
+
+			returnList.append(innerList)
+
+		return returnList
+
+	def writeTimer(self, param):
+		print "writeTimer: ", param
+		# TODO: fix error handling
+		return
+
+	def command(self, param):
+		print "command: ", param
+		return
+
+		param = int(param)
+
+		# TODO: fix error handling
+
+	list = property(timerList)
+	lut = {"Name": 0
+			, "Match": 1
+			, "AfterEvent": 2
+			, "ExcludedTitle": 3
+			, "ExcludedShort": 4
+			, "ExcludedDescription": 5
+			, "ExcludedDays": 6
+			, "IncludedTitle": 7
+			, "IncludedShort": 8
+			, "IncludedDescription": 9
+			, "IncludedDays": 10
+			, "Services": 11
+			, "Bouquets": 12
+			, "TimespanBegin": 13
+			, "TimespanEnd": 14
+			, "Duration": 15
+			, "Counter": 16
+			, "CounterLeft": 17
+			, "CounterLimit": 18
+			, "Destination": 19
+			, "CounterFormatString": 20
+			, "LastBegin": 21
+			, "Justplay": 22
+			, "AvoidDuplicateDescription": 23
+			, "Tags": 24
+			, "Enabled": 25
+			, "toggleDisabledIMG": 26
+			}
Index: ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/WebComponents/Sources/About.py
===================================================================
--- ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/WebComponents/Sources/About.py	(revision 14969)
+++ ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/WebComponents/Sources/About.py	(revision 14969)
@@ -0,0 +1,51 @@
+# Parts of Code and idea by Homey
+from Components.Sources.Source import Source
+from Components.Network import iNetwork
+
+class About(Source):
+	def __init__(self, session):
+		Source.__init__(self)
+		self.session = session
+
+	def handleCommand(self, cmd):
+		self.result = False, "unknown command"
+
+	def command(self):
+		def ConvertIP(list):
+			if len(list) == 4:
+				retstr = "%s.%s.%s.%s" % (list[0], list[1], list[2], list[3])
+			else:
+				retstr = "0.0.0.0"
+			return retstr
+
+		list = []
+
+		if iNetwork.getNumberOfAdapters > 0:
+			iface = iNetwork.getAdapterList()[0]
+			print "[WebComponents.About] iface: %s" % iface
+			list.extend((
+				iNetwork.getAdapterAttribute(iface, "mac"),
+				iNetwork.getAdapterAttribute(iface, "dhcp"),
+				ConvertIP(iNetwork.getAdapterAttribute(iface, "ip")),
+				ConvertIP(iNetwork.getAdapterAttribute(iface, "netmask")),
+				ConvertIP(iNetwork.getAdapterAttribute(iface, "gateway")),
+			))
+		else:
+			print "[WebComponents.About] no network iface configured!"
+			list.extend((
+				"N/A",
+				"N/A",
+				"N/A",
+				"N/A",
+				"N/A",
+			))
+
+		return (list,)
+
+	list = property(command)
+	lut = { "lanMac": 0
+			, "lanDHCP": 1
+			, "lanIP": 2
+			, "lanMask": 3
+			, "lanGW": 4
+		}
Index: ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/WebComponents/Sources/AudioTracks.py
===================================================================
--- ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/WebComponents/Sources/AudioTracks.py	(revision 14969)
+++ ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/WebComponents/Sources/AudioTracks.py	(revision 14969)
@@ -0,0 +1,87 @@
+from Components.Sources.Source import Source
+from Tools.ISO639 import LanguageCodes
+
+class AudioTracks(Source):
+	GET = 0
+	SET = 1
+
+	text = "False"
+
+	def __init__(self, session, func=GET):
+		self.cmd = None
+		self.session = session
+		self.func = func
+		Source.__init__(self)
+
+	def handleCommand(self, cmd):
+		self.cmd = cmd
+
+	def setAudioTrack(self):
+		if self.cmd is not None:
+			service = self.session.nav.getCurrentService()
+			audio = service and service.audioTracks()
+			try:
+				cmd = int(self.cmd)
+			except ValueError:
+				cmd = -1
+
+			print "COMMAND is %s" % self.cmd
+			if self.session.nav.getCurrentService().audioTracks().getNumberOfTracks() > cmd and cmd >= 0:
+				audio.selectTrack(cmd)
+				return "Success"
+			else:
+				return "Error"
+		else:
+			return "Error"
+
+	def getAudioTracks(self):
+		service = self.session.nav.getCurrentService()
+		audio = service and service.audioTracks()
+		n = audio and audio.getNumberOfTracks() or 0
+
+		tracklist = []
+
+		#check for standby
+		if audio is not None and service is not None:
+			currentTrack = audio.getCurrentTrack()
+
+			if n > 0:
+				print "[AudioTracks.py] got %s Audiotracks!" % (n)
+
+				x = 0
+				while x < n:
+					cnt = 0
+					i = audio.getTrackInfo(x)
+
+					languages = i.getLanguage().split('/')
+					description = i.getDescription()
+					pid = i.getPID()
+					language = ''
+
+					for lang in languages:
+						if cnt:
+							language += ' / '
+						if LanguageCodes.has_key(lang):
+							language += LanguageCodes[lang][0]
+						else:
+							language += lang
+						cnt += 1
+
+					if description:
+						description += " (" + language + ")"
+					else:
+						description = language
+
+					if x == currentTrack:
+						active = "True"
+					else:
+						active = "False"
+
+					tracklist.append((description, x, pid, active))
+					x += 1
+
+		return tracklist
+
+	text = property(setAudioTrack)
+	list = property(getAudioTracks)
+	lut = {"Description": 0, "Id": 1, "Pid": 2, "Active": 3}
Index: ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/WebComponents/Sources/CurrentService.py
===================================================================
--- ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/WebComponents/Sources/CurrentService.py	(revision 14969)
+++ ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/WebComponents/Sources/CurrentService.py	(revision 14969)
@@ -0,0 +1,18 @@
+from Components.Sources.Source import Source
+
+class CurrentService(Source):
+	def __init__(self, session):
+		Source.__init__(self)
+		self.session = session
+
+	def command(self):
+		currentServiceRef = self.session.nav.getCurrentlyPlayingServiceReference()
+		if currentServiceRef is not None:
+			text = currentServiceRef.toString()
+		else:
+			text = "N/A"
+
+		return text
+
+	text = property(command)
+
Index: ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/WebComponents/Sources/EPG.py
===================================================================
--- ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/WebComponents/Sources/EPG.py	(revision 14969)
+++ ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/WebComponents/Sources/EPG.py	(revision 14969)
@@ -0,0 +1,237 @@
+from Components.Sources.Source import Source
+from enigma import eServiceCenter, eServiceReference, eEPGCache
+
+class EPG(Source):
+	BOUQUETNOW = 0
+	BOUQUETNEXT = 1
+	SERVICENOW = 2
+	SERVICENEXT = 3
+	SERVICE = 4
+	SEARCH = 5
+	BOUQUET = 6
+	SEARCHSIMILAR = 7
+	
+	def __init__(self, navcore, func=BOUQUETNOW, endtm=False):
+		self.func = func
+		Source.__init__(self)
+		self.navcore = navcore
+		self.epgcache = eEPGCache.getInstance()
+		self.command = None
+		self.endtime = endtm
+		self.search = False
+
+	def handleCommand(self, cmd):
+		print "[WebComponents.EPG] setting command to '%s' " %cmd
+		self.command = cmd
+
+	def do_func(self):
+		if not self.command is None:
+			if self.func is self.SEARCHSIMILAR:
+				func = self.searchSimilarEvent
+			elif self.func is self.SEARCH:
+				func = self.searchEvent
+			elif self.func is self.SERVICE:
+				func = self.getEPGofService
+			elif self.func is self.BOUQUETNOW:
+				func = self.getBouquetEPGNow
+			elif self.func is self.BOUQUETNEXT:
+				func = self.getBouquetEPGNext
+			elif self.func is self.BOUQUET:
+				func = self.getEPGofBouquet
+			elif self.func is self.SERVICENOW:
+				func = self.getServiceEPGNow
+			elif self.func is self.SERVICENEXT:
+				func = self.getServiceEPGNext
+
+			return func(self.command)
+		return ()
+
+	def getBouquetEPGNow(self, ref):
+		return self.getEPGNowNext(ref, 0)
+
+	def getBouquetEPGNext(self, ref):
+		return self.getEPGNowNext(ref, 1)
+
+	def getServiceEPGNow(self, ref):
+		return self.getEPGNowNext(ref, 0, True)
+
+	def getServiceEPGNext(self, ref):
+		return self.getEPGNowNext(ref, 1, True)
+
+	def getEPGNowNext(self, ref, type, service=False):
+		print "[WebComponents.EPG] getting EPG NOW/NEXT", ref
+
+		if service:
+			events = self.epgcache.lookupEvent(['IBDCTSERNX', (ref, type, -1)])
+		else:
+			serviceHandler = eServiceCenter.getInstance()
+			list = serviceHandler.list(eServiceReference(ref))
+			services = list and list.getContent('S')
+			search = ['IBDCTSERNX']
+
+			if services: # It's a Bouquet
+				search.extend([(service, type, -1) for service in services])
+
+			events = self.epgcache.lookupEvent(search)
+
+		if events:
+			return events
+		return ()
+
+	def getEPGofService(self, param, options='IBDCTSERN'):
+		print "[WebComponents.EPG] getEPGofService param: ", param
+		
+		if "sRef" in param:
+			service = param["sRef"]
+		else:
+			return ()
+		
+		time = -1		
+		endtime = -1
+				
+		if "time" in param:
+			if not param["time"] is None:
+				time = int(float(param["time"]))
+				if time < 0:
+					time = -1
+		
+		if "endTime" in param:
+			if not param["endTime"] is None:
+				endtime = int( float(param["endTime"]) )
+				if endtime < 0:
+					endtime = -1
+				
+		events = self.epgcache.lookupEvent([options , (service, 0, time, endtime)]);
+		
+		if events:
+			if self.endtime:
+				list = self.insertEndTime(events)
+				return list
+
+			return events
+		return ()
+
+	def insertEndTime(self, events):
+		list = []
+		for event in events:
+			i = 0
+			evt = []
+			end = event[1] + event[2]
+			for item in event:
+				if i == 3:
+					evt.append(end)
+					i += 1
+
+				evt.append(item)
+				i += 1
+
+			list.append(evt)
+
+		return list
+
+	def getEPGofBouquet(self, param):
+		print "[WebComponents.EPG] getting EPG for Bouquet", param
+
+		if 'bRef' not in param:
+			return ()
+		
+		time = -1
+		
+		if "time" in param:
+			if not param["time"] is None:
+				time = int(float(param["time"]))
+				if time < 0:
+					time = -1
+
+		bRef = param['bRef']
+
+		serviceHandler = eServiceCenter.getInstance()
+		sl = serviceHandler.list(eServiceReference(bRef))
+		services = sl and sl.getContent('S')
+
+		search = ['IBDCTSERN']
+		
+		search.extend([(service, 0, time) for service in services])
+		events = self.epgcache.lookupEvent(search)
+
+		if events:
+			return events
+		return ()
+
+	def searchEvent(self, needle):
+		print "[WebComponents.EPG] searching EPG: ", needle
+		self.search = True
+
+		events = self.epgcache.search(('IBDTSERN', 256, eEPGCache.PARTIAL_TITLE_SEARCH, needle, 1));
+		if events:
+			return events
+		return ()
+
+	def searchSimilarEvent(self, needle):
+		print "[WebComponents.EPG] searching similar eventid: ",needle
+
+		events = self.epgcache.search(('IBDCTSERN', 256, eEPGCache.SIMILAR_BROADCASTINGS_SEARCH, needle['sRef'], int(needle['eventid'])));
+		if events:
+			return events
+		return ()
+
+	def getLut(self):
+		#No Current-Time on EPGSEARCH
+		if self.search:
+			if self.endtime:
+				lut = {
+						"EventID": 0,
+						"TimeStart": 1,
+						"Duration": 2,
+						"TimeEnd": 3,
+						"Title": 4,
+						"Description": 5,
+						"DescriptionExtended": 6,
+						"ServiceReference": 7,
+						"ServiceName": 8
+					}
+				return lut
+			else:
+				lut = {
+					"EventID": 0,
+					"TimeStart": 1,
+					"Duration": 2,
+					"Title": 3,
+					"Description": 4,
+					"DescriptionExtended": 5,
+					"ServiceReference": 6,
+					"ServiceName": 7
+				}			
+		else:
+		
+			if self.endtime:
+				lut = {
+						"EventID": 0,
+						"TimeStart": 1,
+						"Duration": 2,
+						"TimeEnd": 3,
+						"CurrentTime": 4,
+						"Title": 5,
+						"Description": 6,
+						"DescriptionExtended": 7,
+						"ServiceReference": 8,
+						"ServiceName": 9
+					}
+				return lut
+			else:
+				lut = {
+					"EventID": 0,
+					"TimeStart": 1,
+					"Duration": 2,
+					"CurrentTime": 3,
+					"Title": 4,
+					"Description": 5,
+					"DescriptionExtended": 6,
+					"ServiceReference": 7,
+					"ServiceName": 8
+				}
+		return lut
+
+	list = property(do_func)
+
+	lut = property(getLut)
Index: ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/WebComponents/Sources/Frontend.py
===================================================================
--- ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/WebComponents/Sources/Frontend.py	(revision 14969)
+++ ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/WebComponents/Sources/Frontend.py	(revision 14969)
@@ -0,0 +1,19 @@
+from Components.Sources.Source import Source
+from Components.NimManager import nimmanager
+
+class Frontend(Source):
+	def getList(self):
+		nims = []
+		for nim in nimmanager.nimList():
+			info = nim.split(":")
+			nims.append((
+						info[0],
+						info[1]
+					))
+		return nims
+
+	list = property(getList)
+	lut = {
+		"Name" : 0,
+		"Type" : 1
+	}
Index: ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/WebComponents/Sources/Hdd.py
===================================================================
--- ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/WebComponents/Sources/Hdd.py	(revision 14969)
+++ ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/WebComponents/Sources/Hdd.py	(revision 14969)
@@ -0,0 +1,95 @@
+from Components.Sources.Source import Source
+from Components.Harddisk import harddiskmanager
+from Components.UsageConfig import defaultMoviePath
+from os import statvfs, path
+
+class Hdd(Source):
+	def __init__(self, devicecount=0):
+		Source.__init__(self)
+		self.devicecount = devicecount
+		self.recCapacity = '0'
+		self.recFree = '0'
+
+	def getHddData(self):
+		if harddiskmanager.hdd:
+			return harddiskmanager.hdd[0]
+		else:
+			return None
+
+	hdd = property(getHddData)
+
+	def getList(self):
+		disks = []
+		for hdd in harddiskmanager.hdd:
+			model = "%s" % (hdd.model())
+			capacity = "%s" % (hdd.capacity())
+
+			free=None
+
+			# Check if the recording partition is located on this disk, in this case answer free space of recording partition
+			try:
+				mounts = open("/proc/mounts")
+				lines = mounts.readlines()
+				mounts.close()
+				for line in lines:
+					parts = line.strip().split(" ")
+					if    path.realpath(parts[0]).startswith(hdd.partitionPath(""))  \
+					and path.realpath(defaultMoviePath()).find(path.realpath(parts[1]))!=-1:
+						free = self.getRecFree()
+						break;
+
+			except IOError:
+				pass
+
+			if free is None:
+				if hdd.free() <= 1024:
+					free = "%i MB" % (hdd.free())
+				else:
+					free = float(hdd.free()) / float(1024)
+					free = "%.3f GB" % free
+
+			disks.append((model, capacity, free))
+
+		return disks
+
+	def getRecPath(self):
+		return defaultMoviePath()
+
+	def getRecCapacity(self):
+		self.refreshRecInfo(False);
+		return self.recCapacity
+
+	def getRecFree(self):
+		self.refreshRecInfo(True);
+		return self.recFree
+		
+	def refreshRecInfo(self,force):
+		
+		if self.recCapacity == 0 or force == True:
+			try:
+				f = statvfs(defaultMoviePath())
+				self.recFree = f.f_bavail/1000 * f.f_bsize/1000
+				self.recCapacity = f.f_blocks/1000 * f.f_bsize/1000
+
+				if self.recFree < 1024:
+					self.recFree = "%i MB" % (self.recFree)
+				else:
+					self.recFree = float(self.recFree) / float(1024)
+					self.recFree = "%.3f GB" % self.recFree
+
+				if self.recCapacity < 1024:
+					self.recCapacity = "%i MB" % (self.recCapacity)
+				else:
+					self.recCapacity = float(self.recCapacity) / float(1024)
+					self.recCapacity = "%.3f GB" % self.recCapacity
+
+			except OSError:
+				pass
+
+	list = property(getList)
+	lut = { "Model" : 0,
+			"Capacity" : 1,
+			"Free" : 2
+		}
+
+hdd=Hdd()
Index: ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/WebComponents/Sources/LocationsAndTags.py
===================================================================
--- ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/WebComponents/Sources/LocationsAndTags.py	(revision 14969)
+++ ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/WebComponents/Sources/LocationsAndTags.py	(revision 14969)
@@ -0,0 +1,113 @@
+from Components.Sources.Source import Source
+from Components.config import config
+import os
+
+class LocationsAndTags(Source):
+	CURRLOCATION = 0
+	LOCATIONS = 1
+	TAGS = 2
+	ADDLOCATION = 3
+	REMOVELOCATION = 4
+
+	def __init__(self, session, func):
+		self.func = func
+		Source.__init__(self)
+		self.session = session
+		self.result = ( False, "one two three four unknown command" )
+
+	def handleCommand(self, cmd):
+		if self.func is self.CURRLOCATION:
+			self.result = self.getCurrentLocation()
+		elif self.func is self.LOCATIONS:
+			self.result = self.getLocations()
+		elif self.func is self.TAGS:
+			self.result = self.getTags()
+		elif self.func is self.ADDLOCATION:
+			self.result = self.addLocation(cmd)
+		elif self.func is self.REMOVELOCATION:
+			self.result = self.removeLocation(cmd)
+		else:
+			self.result = False
+
+	def getCurrentLocation(self):
+		path = config.movielist.last_videodir.value or "/hdd/movie"
+		if not os.path.exists(path):
+			path = "/hdd/movie"
+		
+		return path
+
+	def getLocations(self):
+		return config.movielist.videodirs.value
+
+	def getTags(self):
+		try:
+			file = open("/etc/enigma2/movietags")
+			tags = [x.rstrip() for x in file.readlines()]
+			while "" in tags:
+				tags.remove("")
+			file.close()
+		except IOError, ioe:
+			tags = ()
+		return tags
+
+	def addLocation(self, param):
+		print "[WebComponents.LocationsAndTags] addLocation: ", param
+		if param['dirname'] is None:
+			return ( False, "Missing Parameter: dirname" )
+		dirname = param['dirname']
+		if len(dirname) == 0:
+			return ( False, "Missing value for parameter dirname" )
+		if not dirname.endswith("/"):
+			dirname += "/"
+		if not os.path.exists(dirname):
+			createFolder = False
+			if param['createFolder'] is not None:
+				if param['createFolder'] == "1":
+					try:
+						createFolder = True
+						os.makedirs(dirname)
+					except OSError:
+						return ( False, "Path %s can not be created" %(dirname) )
+			if not createFolder:
+				return ( False, "Path %s does not exist" %(dirname) )
+		bookmarks = config.movielist.videodirs.value[:] or []
+		if dirname in bookmarks:
+			return ( False, "Location '%s' is already existing" %(dirname) )
+		bookmarks.append(dirname)
+		config.movielist.videodirs.value = bookmarks
+		config.movielist.videodirs.save()
+		return ( True, "Location '%s' added successfully" % (dirname) )
+
+	def removeLocation(self, param):
+		print "[WebComponents.LocationsAndTags] removeLocation: ", param
+		if len(param) == 0:
+			return ( False, "Missing value for parameter dirname" )
+		dirname = param
+		if not dirname.endswith("/"):
+			dirname += "/"
+		bookmarks = config.movielist.videodirs.value[:] or []
+		if dirname in bookmarks:
+			bookmarks.remove(dirname)
+			config.movielist.videodirs.value = bookmarks
+			config.movielist.videodirs.save()
+			return ( True, "Location '%s' removed successfully" % (dirname) )
+		else:
+			return ( False, "Location '%s' does not exist" %(dirname) )
+
+	def getText(self):
+		self.handleCommand(None)
+		if self.result:
+			return str(self.result)
+		else:
+			return ""
+
+	def getList(self):
+		self.handleCommand(None)
+		list = self.result
+		if list is None:
+			list = ()
+
+		return list
+
+	text = property(getText)
+	simplelist = property(getList)
Index: ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/WebComponents/Sources/Message.py
===================================================================
--- ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/WebComponents/Sources/Message.py	(revision 14969)
+++ ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/WebComponents/Sources/Message.py	(revision 14969)
@@ -0,0 +1,93 @@
+from Components.Sources.Source import Source
+from Screens.MessageBox import MessageBox
+from os import system, path
+
+class Message(Source):
+	PRINT = 0
+	ANSWER = 1
+	#TODO FIXME - this could be done with an on-going request that finishes when the answer has been given
+	yesnoFile = "/tmp/yesno"
+
+	def __init__(self, session, func=PRINT):
+		self.cmd = []
+		self.session = session
+
+		self.func = func
+		Source.__init__(self)
+		error = "unknown command (%s)" % func
+		self.res = (False, error)
+
+	def handleCommand(self, cmd):
+		self.cmd = cmd
+		if self.func is self.PRINT:
+			self.res = self.printMessage(cmd)
+		elif self.func is self.ANSWER:
+			self.res = self.getYesNoAnswer(cmd)
+
+	def printMessage(self, param):
+		print "printMessage"
+
+		if self.cmd['text'] == "" or self.cmd['text'] is None:
+			return ( False, "No Messagetext given" )
+		else:
+			mtext = self.cmd['text']
+
+		try:
+			typeint = int(self.cmd['type'])
+		except (ValueError, TypeError), e:
+			return ( False, "type %s is not a number" % self.cmd['type'] )
+
+		if typeint == MessageBox.TYPE_YESNO:
+			#dont know how to give the result to the webif back
+			mtype = MessageBox.TYPE_YESNO
+		elif typeint == MessageBox.TYPE_INFO:
+			mtype = MessageBox.TYPE_INFO
+		elif typeint == MessageBox.TYPE_WARNING:
+			mtype = MessageBox.TYPE_WARNING
+		elif typeint == MessageBox.TYPE_ERROR:
+			mtype = MessageBox.TYPE_ERROR
+		else:
+			return ( False, "Unsupported Messagetype %s" % self.cmd['type'] )
+
+		try:
+			mtimeout = int(self.cmd['timeout'])
+		except (ValueError, TypeError), e:
+			mtimeout = -1
+
+		if typeint == MessageBox.TYPE_YESNO:
+			self.session.openWithCallback(self.yesNoAnswer, MessageBox, mtext, type=mtype, timeout=mtimeout)
+		else:
+			self.session.open(MessageBox, mtext, type=mtype , timeout=mtimeout)
+
+		return ( True, "Message sent successfully!" )
+
+	def yesNoAnswer(self, confirmed):
+		print "yesNoAnswer", confirmed
+		#self.session.messageboxanswer = confirmed
+
+		yesnoFile = self.yesnoFile
+
+		cmdstr = "/bin/echo -n yes > %s" % yesnoFile
+		if not confirmed:
+			cmdstr = "/bin/echo -n no > %s" % yesnoFile
+
+		system(cmdstr)
+
+	def getYesNoAnswer(self, param):
+		print "getYesNoAnswer"#,self.session.messageboxanswer
+		yesnoFile = self.yesnoFile
+		if path.exists(yesnoFile) == True:
+			file = open(yesnoFile, "r")
+			lines = file.readlines()
+			file.close()
+			cmdstr = "rm %s" % yesnoFile
+			system(cmdstr)
+			print "Answer: (%s)" % lines[0]
+			if lines[0] == "yes":
+				return ( True, "Answer is YES!" )
+			else:
+				return ( True, "Answer is NO!" )
+		else:
+			return ( False, "No answer in time" )
+
+	result = property(lambda self: self.res)
Index: ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/WebComponents/Sources/Movie.py
===================================================================
--- ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/WebComponents/Sources/Movie.py	(revision 14969)
+++ ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/WebComponents/Sources/Movie.py	(revision 14969)
@@ -0,0 +1,133 @@
+from enigma import eServiceReference, iServiceInformation, eServiceCenter
+from Components.Sources.Source import Source
+from Components.config import config
+from ServiceReference import ServiceReference
+from Tools.Directories import resolveFilename, SCOPE_HDD
+from Tools.FuzzyDate import FuzzyTime
+
+from os import stat as os_stat
+
+class Movie(Source):
+	LIST = 0
+	DEL = 1
+	TAGS = 2
+
+	def __init__(self, session, movielist, func=LIST):
+		Source.__init__(self)
+		self.func = func
+		self.session = session
+		self.tagfilter = []
+		self.root = eServiceReference("2:0:1:0:0:0:0:0:0:0:" + resolveFilename(SCOPE_HDD))
+		self.movielist = movielist #MovieList(self.root)
+		self.movielist.load(self.root, None)
+		self.cmd = ""
+		self.res = ( False, "Missing or Wrong Argument" )
+
+	def handleCommand(self, cmd):
+		if cmd is not None:
+			self.cmd = cmd
+			if self.func is self.DEL:
+				self.res = self.delMovie(cmd)
+			elif self.func is self.LIST:
+				if cmd['dirname']:
+					self.root = eServiceReference("2:0:1:0:0:0:0:0:0:0:" + cmd['dirname'])
+				self.tagfilter = cmd['tag'] and cmd['tag'].split(' ') or []
+
+	def delMovie(self, param):
+#		print "[WebComponents.delMovie] %s" %param
+
+		if param is None:
+			return False, "Missing Parameter: sRef"
+
+		service = ServiceReference(param)
+		result = False
+
+		if service is not None:
+			#mostly copied from Screens.MovieSelection
+			serviceHandler = eServiceCenter.getInstance()
+			offline = serviceHandler.offlineOperations(service.ref)
+			info = serviceHandler.info(service.ref)
+			name = info and info.getName(service.ref) or "this recording"
+
+			if offline is not None:
+				if not offline.deleteFromDisk(0):
+					result = True
+
+			if result == False:
+				return ( result, "Could not delete Movie '%s'" % name )
+			else:
+				return ( result, "Movie '%s' deleted" % name )
+
+		return ( result, "Illegal Parameter Value: sRef - '%s'" % param )
+
+	def getMovieList(self):
+		self.movielist.reload(root=self.root, filter_tags=self.tagfilter)
+		list = []
+
+		tag = self.cmd['tag']
+		tag = tag and tag.lower()
+		for (serviceref, info, begin, unknown) in self.movielist.list:
+			rtime = info.getInfo(serviceref, iServiceInformation.sTimeCreate)
+
+			if rtime > 0:
+				t = FuzzyTime(rtime)
+				begin_string = t[0] + ", " + t[1]
+			else:
+				begin_string = "undefined"
+
+			if config.plugins.Webinterface.loadmovielength.value:
+				len = info.getLength(serviceref)
+				if len > 0:
+					len = "%d:%02d" % (len / 60, len % 60)
+				else:
+					len = "?:??"
+			else:
+				len = "disabled"
+
+			sourceERef = info.getInfoString(serviceref, iServiceInformation.sServiceref)
+			sourceRef = ServiceReference(sourceERef)
+
+			event = info.getEvent(serviceref)
+			ext = event and event.getExtendedDescription() or ""
+
+			filename = "/" + "/".join(serviceref.toString().split("/")[1:])
+			servicename = ServiceReference(serviceref).getServiceName().replace('\xc2\x86', '').replace('\xc2\x87', '')
+			
+			if not tag or tag in info.getInfoString(serviceref, iServiceInformation.sTags).lower():
+				""" add movie only to list, if a given tag is applied to the movie """
+				list.append((
+					serviceref.toString(),
+					servicename,
+					info.getInfoString(serviceref, iServiceInformation.sDescription),
+					rtime,
+					begin_string,
+					len,
+					sourceRef.getServiceName(),
+					info.getInfoString(serviceref, iServiceInformation.sTags),
+					ext,
+					filename,
+					os_stat(filename)[6]
+				))
+		return list
+
+	def getResult(self):
+		if self.func is self.DEL:
+			return self.res
+
+		return ( False, "illegal call" )
+
+	result = property(getResult)
+
+	list = property(getMovieList)
+	lut = {"ServiceReference": 0
+			, "Title": 1
+			, "Description": 2
+			, "Time": 3
+			, "TimeString": 4
+			, "Length": 5
+			, "ServiceName": 6
+			, "Tags": 7
+			, "DescriptionExtended": 8
+			, "Filename": 9
+			, "Filesize": 10
+		}
Index: ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/WebComponents/Sources/Network.py
===================================================================
--- ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/WebComponents/Sources/Network.py	(revision 14969)
+++ ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/WebComponents/Sources/Network.py	(revision 14969)
@@ -0,0 +1,71 @@
+from Components.Sources.Source import Source
+from Components.Network import iNetwork
+
+class Interface:
+	def __init__(self, name):
+		self.name = name
+		self.mac = None
+		self.dhcp = None
+		self.ip = None
+		self.netmask = None
+		self.gateway = None
+
+class Network(Source):
+	LAN = 0
+	WLAN = 1
+
+	def __init__(self, device=LAN):
+		Source.__init__(self)
+		if device is self.LAN:
+			self.iface = "eth0"
+		elif device is self.WLAN:
+			self.iface = "ath0"
+
+	def ConvertIP(self, list):
+		retstr = None
+		
+		if list != None:
+			if(len(list) == 4):
+				retstr = "%s.%s.%s.%s" % (list[0], list[1], list[2], list[3])
+		
+		if retstr is None:
+			retstr = "0.0.0.0"
+			
+		return retstr
+
+	def getInterface(self):
+		iface = Interface(self.iface)
+		iface.mac = iNetwork.getAdapterAttribute(self.iface, "mac")
+		iface.dhcp = iNetwork.getAdapterAttribute(self.iface, "dhcp")
+		iface.ip = self.ConvertIP(iNetwork.getAdapterAttribute(self.iface, "ip"))
+		iface.netmask = self.ConvertIP(iNetwork.getAdapterAttribute(self.iface, "netmask"))
+		iface.gateway = self.ConvertIP(iNetwork.getAdapterAttribute(self.iface, "gateway"))
+
+		return iface
+
+	interface = property(getInterface)
+
+	def getList(self):
+		return [
+			(
+					ifname,
+					iNetwork.getAdapterAttribute(ifname, "mac"),
+					iNetwork.getAdapterAttribute(ifname, "dhcp"),
+					self.ConvertIP(iNetwork.getAdapterAttribute(ifname, "ip")),
+					self.ConvertIP(iNetwork.getAdapterAttribute(ifname, "netmask")),
+					self.ConvertIP(iNetwork.getAdapterAttribute(ifname, "gateway"))
+			)
+			for ifname in iNetwork.getConfiguredAdapters()
+		]
+
+	list = property(getList)
+
+	lut = {
+			"Name": 0,
+			"Mac" : 1,
+			"Dhcp" : 2,
+			"Ip" : 3,
+			"Netmask" : 4,
+			"Gateway" : 5,
+		   }
+
Index: ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/WebComponents/Sources/ParentControl.py
===================================================================
--- ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/WebComponents/Sources/ParentControl.py	(revision 14969)
+++ ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/WebComponents/Sources/ParentControl.py	(revision 14969)
@@ -0,0 +1,32 @@
+from Components.Sources.Source import Source
+from Components.ParentalControl import parentalControl
+from Components.config import config
+from ServiceReference import ServiceReference
+
+class ParentControl(Source):
+	def __init__(self, session):
+		Source.__init__(self)
+		self.session = session
+
+	def command(self):
+		print "ParentControl was called"
+
+		if config.ParentalControl.configured.value:
+			parentalControl.open()
+			if config.ParentalControl.type.value == "whitelist":
+				servicelist = parentalControl.whitelist
+			else:
+				servicelist = parentalControl.blacklist
+
+			list = [(str(service_ref), ServiceReference(service_ref).getServiceName()) for service_ref in servicelist]
+		else:
+			list = []
+
+		print "list", list
+		return list
+
+	list = property(command)
+	lut = {"ServiceReference": 0
+			, "ServiceName":1
+			}
+
Index: ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/WebComponents/Sources/PowerState.py
===================================================================
--- ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/WebComponents/Sources/PowerState.py	(revision 14969)
+++ ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/WebComponents/Sources/PowerState.py	(revision 14969)
@@ -0,0 +1,55 @@
+from Components.Sources.Source import Source
+
+class PowerState(Source):
+	def __init__(self, session):
+		self.cmd = None
+		self.session = session
+		Source.__init__(self)
+
+	def handleCommand(self, cmd):
+		self.cmd = cmd
+
+	def getStandby(self):
+		from Screens.Standby import inStandby
+		if inStandby == None:
+			return "false"
+		else:
+			return "true"
+
+	def getText(self):
+		if self.cmd == "" or self.cmd is None:
+			return self.getStandby()
+
+		#-1: get current state
+		# 0: toggle standby
+		# 1: poweroff/deepstandby
+		# 2: rebootdreambox
+		# 3: rebootenigma
+		try:
+			type = int(self.cmd)
+			if type == -1:
+				return self.getStandby()
+
+			elif type == 0:
+				print "[PowerState.py] Standby 0"
+				from Screens.Standby import inStandby
+				if inStandby == None:
+					from Screens.Standby import Standby
+					self.session.open(Standby)
+					return "true"
+				else:
+					inStandby.Power()
+					return "false"
+
+			elif 0 < type < 4:
+				print "[PowerState.py] TryQuitMainloop"
+				from Screens.Standby import TryQuitMainloop
+				self.session.open(TryQuitMainloop, type)
+				return "true"
+			else:
+				print "[PowerState.py] cmd unknown" % type
+				return "error"
+		except ValueError:
+			return "error"
+
+	text = property(getText)
Index: ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/WebComponents/Sources/ReadPluginList.py
===================================================================
--- ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/WebComponents/Sources/ReadPluginList.py	(revision 14969)
+++ ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/WebComponents/Sources/ReadPluginList.py	(revision 14969)
@@ -0,0 +1,16 @@
+from Components.Sources.Source import Source
+from Components.PluginComponent import plugins
+from Tools.Directories import resolveFilename, SCOPE_PLUGINS
+
+class ReadPluginList(Source):
+	def __init__(self, session):
+		Source.__init__(self)
+		self.session = session
+
+	def command(self):
+		print "[WebComponents.ReadPluginList] readPluginList"
+
+		plugins.readPluginList(resolveFilename(SCOPE_PLUGINS))
+		return ( True, "List of Plugins has been read" )
+
+	result = property(command)
Index: ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/WebComponents/Sources/RemoteControl.py
===================================================================
--- ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/WebComponents/Sources/RemoteControl.py	(revision 14969)
+++ ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/WebComponents/Sources/RemoteControl.py	(revision 14969)
@@ -0,0 +1,81 @@
+from enigma import eActionMap
+from Components.Sources.Source import Source
+from Tools.HardwareInfo import HardwareInfo
+from Components.config import config
+class RemoteControl(Source):
+	# Flags
+	FLAG_MAKE = 0
+	FLAG_BREAK = 1
+	FLAG_REPEAT = 2
+	FLAG_LONG = 3
+	FLAG_ASCII = 4
+	
+	#Device Types
+	TYPE_STANDARD = "dreambox remote control (native)"
+	TYPE_ADVANCED = "dreambox advanced remote control (native)"
+	TYPE_KEYBOARD = "dreambox ir keyboard"
+		
+	def __init__(self, session):
+		self.cmd = None
+		self.session = session
+		Source.__init__(self)
+		self.res = ( False, "Missing or wrong argument" )
+		self.eam = eActionMap.getInstance()
+		
+		#Advanced remote or standard?
+		
+		if config.misc.rcused.value == 0:
+			self.remotetype = self.TYPE_ADVANCED
+		else:
+			self.remotetype = self.TYPE_STANDARD
+			
+		print "[RemoteControl.__init__] Configured RCU-Type is '%s'" %(self.remotetype)										
+
+	def handleCommand(self, cmd):
+		self.cmd = cmd
+		self.res = self.sendEvent()
+
+	def sendEvent(self):
+		if len(self.cmd) == 0 or self.cmd is None:
+			print "[RemoteControl.sendEvent] cmd is empty or None"
+			return self.res
+		
+		if not "command" in self.cmd:
+			print "[RemoteControl.sendEvent] Obligatory parameter 'command' is missing!"
+			return ( False, "Obligatory parameter 'command' is missing!" )
+		
+		key = int(self.cmd["command"])			
+		
+		if key <= 0:			
+			print "[RemoteControl.sendEvent] command <= 0 (%s)" % key
+			return ( False, "the command was not > 0" )
+		
+		#type can be "long" or "ascii", everything else will result in FLAG_MAKE
+		type = None 
+		if "type" in self.cmd:
+			if self.cmd["type"] != "" and self.cmd["type"] != None:
+				type = self.cmd["type"];
+		
+		#if type is set, set the flag accordingly
+		flag = self.FLAG_MAKE
+		if type != None:
+			if type == "long":
+				#Doesn't work yet (WHY?)
+				#TODO Fix long key press
+				flag = self.FLAG_LONG		
+			elif type == "ascii":
+				flag = self.FLAG_ASCII
+		
+		#If type=="long" we need to press send FLAG_MAKE first 
+		if(flag == self.FLAG_LONG):			
+			self.eam.keyPressed(self.remotetype, key, self.FLAG_MAKE)
+
+		#press the key with the desired flag
+		self.eam.keyPressed(self.remotetype, key, flag)
+		#Release the key		
+		self.eam.keyPressed(self.remotetype, key, self.FLAG_BREAK)
+			
+		print "[RemoteControl.sendEvent] command was was sent (key: %s, flag: %s)" %(key,flag)
+		return ( True, "RC command '" + str(key) + "' has been issued" ) 
+
+	result = property(lambda self: self.res)
Index: ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/WebComponents/Sources/RequestData.py
===================================================================
--- ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/WebComponents/Sources/RequestData.py	(revision 14969)
+++ ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/WebComponents/Sources/RequestData.py	(revision 14969)
@@ -0,0 +1,42 @@
+from Components.Sources.Source import Source
+
+class RequestData(Source):
+	"""
+		a source for requestinformations like the adress that the client requested to reache the box
+	"""
+	HOST = 0
+	PORT = 1
+	METHOD = 2
+	PATH = 3
+	REMOTEADRESS = 4
+	REMOTEPORT = 5
+	REMOTETYPE = 6
+	URI = 7
+
+	def __init__(self, request, what=None):
+		Source.__init__(self)
+		self.request = request
+		self.what = what
+
+	def handleCommand(self, cmd):
+		pass
+
+	def getHTML(self, id):
+		if self.what is self.HOST:
+			return self.request.getRequestHostname()
+		elif self.what is self.PORT:
+			return str(self.request.host.port)
+		elif self.what is self.METHOD:
+			return self.request.method
+		elif self.what is self.PATH:
+			return self.request.path
+		elif self.what is self.REMOTEADRESS:
+			return self.request.client.ip
+		elif self.what is self.REMOTEPORT:
+			return str(self.request.client.port)
+		elif self.what is self.REMOTETYPE:
+			return self.request.client.type
+		elif self.what is self.URI:
+			return self.request.uri
+		else:
+			return "N/A"
Index: ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/WebComponents/Sources/ServiceListRecursive.py
===================================================================
--- ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/WebComponents/Sources/ServiceListRecursive.py	(revision 14969)
+++ ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/WebComponents/Sources/ServiceListRecursive.py	(revision 14969)
@@ -0,0 +1,73 @@
+from Components.Sources.Source import Source
+from Components.Sources.ServiceList import ServiceList
+from Screens.ChannelSelection import service_types_tv
+from enigma import eServiceReference
+
+class ServiceListRecursive(Source):
+	FETCH = 0
+
+	def __init__(self, session, func=FETCH):
+		Source.__init__(self)
+
+		self.session = session
+		self.func = func
+		self.servicelist = {}
+		self.xml = ""
+		self.command = eServiceReference(service_types_tv + ' FROM BOUQUET "bouquets.tv" ORDER BY bouquet')
+
+	def handleCommand(self, cmd):
+		self.command = eServiceReference(cmd)
+
+	def do_func(self):
+		if self.func == self.FETCH:
+			func = self.buildList
+		else:
+			func = self.buildList
+
+		return func(self.command)
+
+	def buildList(self, ref):
+		self.servicelist = ServiceList(ref, command_func=self.getServiceList, validate_commands=False)
+		list = self.servicelist.getServicesAsList()
+		for item in list:
+			self.servicelist.setRoot(eServiceReference(item[0]))
+			sub = self.servicelist.getServicesAsList()
+
+			if sub:
+				self.xml += "\t<e2bouquet>\n"
+				bouquet = True
+
+				subxml = ""
+				for (ref, name) in sub:
+					name = name.replace('\xc2\x86', '').replace('\xc2\x87', '')
+					subxml += "\t\t\t<e2service>\n"
+					subxml += "\t\t\t\t<e2servicereference>%s</e2servicereference>\n\t\t\t\t<e2servicename>%s</e2servicename>\n" % (self.filterXML(ref), self.filterXML(name))
+					subxml += "\t\t\t</e2service>\n"
+
+			else:
+				self.xml += "\t\t<e2service>\n"
+				bouquet = False
+			
+			self.xml += "\t\t<e2servicereference>%s</e2servicereference>\n\t\t<e2servicename>%s</e2servicename>\n" % (self.filterXML(item[0]), self.filterXML(item[1]))
+
+			if bouquet:
+				self.xml += "\t\t<e2servicelist>\n"
+				self.xml += subxml
+				self.xml += "\t\t</e2servicelist>\n"
+				self.xml += "\t</e2bouquet>\n"
+			else:
+				self.xml += "\t</e2service>\n"
+
+		return self.xml
+
+	def filterXML(self, item):
+		item = item.replace("&", "&amp;").replace("<", "&lt;").replace('"', '&quot;').replace(">", "&gt;").replace('\xc2\x86', '').replace('\xc2\x87', '')
+		return item
+
+	def getServiceList(self, ref):
+		self.servicelist.root = ref
+
+	text = property(do_func)
+
+#	list = property(do_func)
+#	lut = {"ServiceReference": 0, "ServiceName": 1 }
Index: ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/WebComponents/Sources/ServiceListReload.py
===================================================================
--- ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/WebComponents/Sources/ServiceListReload.py	(revision 14969)
+++ ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/WebComponents/Sources/ServiceListReload.py	(revision 14969)
@@ -0,0 +1,45 @@
+from enigma import eDVBDB
+from Components.Sources.Source import Source
+
+class ServiceListReload(Source):
+	BOTH = 0
+	LAMEDB = 1
+	USERBOUQUETS = 2
+
+	def __init__(self, session):
+		Source.__init__(self)
+		self.session = session
+		self.eDVBDB = eDVBDB.getInstance()
+		self.res = False
+
+	def handleCommand(self, cmd):
+		try:
+			self.cmd = int(cmd)
+			if self.cmd is self.BOTH:
+				self.reloadLameDB()
+				self.reloadUserBouquets()
+				self.res = ( True, 'reloaded both' )
+			elif self.cmd is self.LAMEDB:
+				self.res = self.reloadLameDB()
+				self.res = ( True, 'reloaded lamedb' )
+			elif self.cmd is self.USERBOUQUETS:
+				self.res = self.reloadUserBouquets()
+				self.res = ( True, 'reloaded bouquets' )
+		except Exception, e:
+			pass
+
+	def reloadLameDB(self):
+		print "[ServiceListReload] reloading lamedb"
+		self.eDVBDB.reloadServicelist()
+
+	def reloadUserBouquets(self):
+		print "[ServiceListReload] reloading userbouquets"
+		self.eDVBDB.reloadBouquets()
+
+	def getResult(self):
+		if self.res:
+			return self.res
+		else:
+			return ( False, "missing or wrong parameter mode [%i=both, %i=lamedb only, %i=userbouqets only]" % (self.BOTH, self.LAMEDB, self.USERBOUQUETS) )
+
+	result = property(getResult)
Index: ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/WebComponents/Sources/ServicePlayable.py
===================================================================
--- ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/WebComponents/Sources/ServicePlayable.py	(revision 14969)
+++ ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/WebComponents/Sources/ServicePlayable.py	(revision 14969)
@@ -0,0 +1,80 @@
+from enigma import eServiceCenter, eServiceReference
+from Components.Sources.Source import Source
+
+class ServicePlayable(Source):
+	
+	SINGLE = 0
+	BOUQUET = 1
+	
+	def __init__(self, session, type=SINGLE):
+		Source.__init__(self)
+		
+		self.session = session
+		self.sci = eServiceCenter.getInstance()
+		self.command = None
+		self.info = None
+		self.type = type
+			
+	
+	def handleCommand(self, cmd):
+		self.command = cmd
+
+
+	def convertStrTrueFalse(self, int):
+		if int > 0:
+			return str(True)
+		else:
+			return str(False)
+
+	
+	def isServicePlayable(self, refToPlay, refPlaying=None):	
+		if self.info is None:
+			self.info = self.sci.info(refToPlay)
+		
+		if refPlaying is None:
+			return self.convertStrTrueFalse( self.info.isPlayable(refToPLay) )
+		else:
+			return self.convertStrTrueFalse( self.info.isPlayable(refToPlay, refPlaying))
+			
+		return false
+
+
+	def getPlayableServices(self, refToPlay, refPlaying=None):		
+		list = []
+		
+		if self.type == self.BOUQUET: #Bouquet
+			slist = self.sci.list(refToPlay)
+			services = slist and slist.getContent('S')
+				
+			if services: 				
+				list.extend([	
+					(service, self.isServicePlayable(eServiceReference(service), refPlaying)) for service in services
+				])
+				
+		else: #Single service
+			playable = self.isServicePlayable(refToPlay, refPlaying)
+			list.append((refToPlay.toString(), playable))
+			
+		return list
+	
+
+	def getList(self):
+		list = []
+
+		if 'sRef' in self.command:
+			refToPlay = eServiceReference(self.command['sRef'])
+			
+			if 'sRefPlaying' in self.command:
+				refPlaying = eServiceReference(self.command['sRef'])				
+				list = self.getPlayableServices(refToPlay, refPlaying)
+				
+			else:
+				list = self.getPlayableServices(refToPlay)
+		
+		return list
+		
+	
+	list = property(getList)
+	lut = { "ServiceReference" : 0,
+			"ServicePlayable" : 1
+			}
Index: ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/WebComponents/Sources/Settings.py
===================================================================
--- ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/WebComponents/Sources/Settings.py	(revision 14969)
+++ ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/WebComponents/Sources/Settings.py	(revision 14969)
@@ -0,0 +1,31 @@
+from Components.config import config
+from Components.Sources.Source import Source
+
+class Settings(Source):
+	def __init__(self, session):
+		self.cmd = []
+		self.session = session
+		Source.__init__(self)
+
+	def handleCommand(self, cmd):
+		self.cmd = cmd
+
+	def do_func(self):
+		result = []
+		self.pickle_this("config", config.saved_value, result)
+		return result
+
+	def pickle_this(self, prefix, topickle, result):
+		for (key, val) in topickle.items():
+			name = prefix + "." + key
+			if isinstance(val, dict):
+				self.pickle_this(name, val, result)
+			elif isinstance(val, tuple):
+				result.append((name, val[0]))
+			else:
+				result.append((name, val))
+
+	list = property(do_func)
+	lut = {"Name": 0
+			, "Value": 1
+			}
Index: ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/WebComponents/Sources/SubServices.py
===================================================================
--- ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/WebComponents/Sources/SubServices.py	(revision 14969)
+++ ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/WebComponents/Sources/SubServices.py	(revision 14969)
@@ -0,0 +1,80 @@
+from Components.Sources.Source import Source
+from ServiceReference import ServiceReference
+#from time import sleep
+
+class SubServices(Source):
+	def __init__(self, session, streamingScreens = None):
+		Source.__init__(self)
+		self.session = session
+		self.streamingScreens = streamingScreens
+		self.cmd = None
+
+	def handleCommand(self, cmd):
+		if cmd is not None:
+			print "[SubServices].handleCommand %s" %cmd
+			self.cmd = cmd
+
+	def getSubservices(self):
+		print "[SubServices].getSubservices called"
+		list = []
+
+		if self.streamingScreens is None:
+			currentServiceRef = self.session.nav.getCurrentlyPlayingServiceReference()
+			if currentServiceRef is not None:
+				list.append((
+					currentServiceRef.toString(),
+					 ServiceReference(currentServiceRef).getServiceName()
+				))
+
+				currentService = self.session.nav.getCurrentService()
+				subservices = currentService and currentService.subServices()
+				if subservices and subservices.getNumberOfSubservices() != 0:
+					n = subservices and subservices.getNumberOfSubservices()
+					x = 0
+					while x < n:
+						sub = subservices.getSubservice(x)
+						list.append((sub.toString(), sub.getName()))
+						x += 1
+
+			else:
+				list = (("N/A", "N/A"),)
+
+			print "SubServices is returning list ", list
+			return list
+
+		elif self.cmd is not None:
+			print "[SubServices].getSubservices for Streaming Service"
+			for screen in self.streamingScreens:
+				if screen is not None:
+					service = screen.getRecordService()
+					sref = ServiceReference(screen.getRecordServiceRef())
+					if service is not None:
+						print "[SubServices] serviceref: %s | cmd: %s" %(sref, self.cmd)
+
+						if sref.__str__() == self.cmd:
+							list.append((sref.__str__(), sref.getServiceName()))
+							print "[SubServices] Matching recordSerivce found!"
+							subservices = service and service.subServices()
+							if subservices and subservices.getNumberOfSubservices() != 0:
+								n = subservices and subservices.getNumberOfSubservices()
+								x = 0
+								while x < n:
+									sub = subservices.getSubservice(x)
+									list.append((sub.toString(), sub.getName()))
+									x += 1
+
+								return list
+							else:
+								print "[SubServices] no items: %s" %subservices
+					else:
+						print "[SubServices] Service is None!"
+		if not list:
+			return (("N/A", "N/A"),)
+
+		return list
+
+	list = property(getSubservices)
+	lut = {"ServiceReference": 0,
+			"Name": 1
+			}
+
Index: ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/WebComponents/Sources/SwitchService.py
===================================================================
--- ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/WebComponents/Sources/SwitchService.py	(revision 14969)
+++ ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/WebComponents/Sources/SwitchService.py	(revision 14969)
@@ -0,0 +1,39 @@
+from Components.Sources.Source import Source
+from Components.config import config
+from enigma import eServiceReference
+
+class SwitchService(Source):
+	def __init__(self, session):
+		Source.__init__(self)
+		self.session = session
+		self.res = ( False, "Parameter sRef is missing" )
+	
+	def handleCommand(self, cmd):		
+		self.res = self.switchService(cmd)
+		
+	def switchService(self, cmd):
+		print "[SwitchService] ref=%s" %cmd["sRef"]
+		
+		pc = config.ParentalControl.configured.value
+
+		"""
+		#HACK
+		switching config.ParentalControl.configured.value
+		"""		
+		if pc:
+			config.ParentalControl.configured.value = False
+		if config.plugins.Webinterface.allowzapping.value:
+			eref= eServiceReference(cmd["sRef"])
+			if cmd["title"] is not None:
+				eref.setName(cmd["title"])
+			self.session.nav.playService(eref)	
+			if pc:
+				config.ParentalControl.configured.value = pc
+			
+			return ( True, "Active service switched to %s" %cmd["sRef"] )
+		
+		else:
+			return ( False, "Zapping is disabled in WebInterface Configuration" )
+	
+	result = property(lambda self: self.res)
+	
Index: ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/WebComponents/Sources/Timer.py
===================================================================
--- ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/WebComponents/Sources/Timer.py	(revision 14969)
+++ ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/WebComponents/Sources/Timer.py	(revision 14969)
@@ -0,0 +1,500 @@
+Version = '$Header$';
+
+from enigma import eServiceReference, eEPGCache
+from Components.Sources.Source import Source
+from Components.config import config
+from ServiceReference import ServiceReference
+from RecordTimer import RecordTimerEntry, RecordTimer, AFTEREVENT, parseEvent
+from Components.config import config
+from xml.sax.saxutils import unescape
+from time import time, strftime, localtime, mktime
+
+class Timer(Source):
+	LIST = 0
+	ADDBYID = 1
+	ADD = 2
+	DEL = 3
+	TVBROWSER = 4
+	CHANGE = 5
+	WRITE = 6
+	RECNOW = 7
+	CLEANUP = 8
+
+	def __init__(self, session, func=LIST):
+		self.func = func
+		Source.__init__(self)
+		self.session = session
+		self.recordtimer = session.nav.RecordTimer
+		self.epgcache = eEPGCache.getInstance()
+		self.res = ( False, "unknown command" )
+
+	def handleCommand(self, cmd):
+		if self.func is self.ADDBYID:
+			self.res = self.addTimerByEventID(cmd)
+			self.writeTimerList()
+
+		elif self.func is self.ADD:
+			self.res = self.editTimer(cmd)
+			self.writeTimerList()
+
+		elif self.func is self.TVBROWSER:
+			self.res = self.tvBrowser(cmd)
+			self.writeTimerList()
+
+		elif self.func is self.DEL:
+			self.res = self.delTimer(cmd)
+			self.writeTimerList()
+
+		elif self.func is self.CHANGE:
+			self.res = self.editTimer(cmd)
+			self.writeTimerList()
+
+		elif self.func is self.WRITE:
+			self.res = self.writeTimerList(force=True)
+
+		elif self.func is self.RECNOW:
+			self.res = self.recordNow(cmd)
+
+		elif self.func is self.CLEANUP:
+			self.res = self.cleanupTimer()
+
+		else:
+			self.res = ( False, "Unknown function: '%s'" % (self.func) )
+
+	def cleanupTimer(self):
+		print "[WebComponents.Timer] cleanupTimer"
+
+		self.session.nav.RecordTimer.cleanup()
+		return ( True, "List of Timers has been cleaned" )
+
+
+	def delTimer(self, param):
+		print "[WebComponents.Timer] delTimer"
+
+		if 'sRef' in param:
+			service_ref = ServiceReference(param['sRef'])
+		else:
+			return ( False, "Missing Parameter: sRef" )
+
+		if 'begin' in param:
+			begin = int(float(param['begin']))
+		else:
+			return ( False, "Missing Parameter: begin" )
+
+		if 'end' in param:
+			end = int(float(param['end']))
+		else:
+			return ( False, "Missing Parameter: end" )
+
+		try:
+			for timer in self.recordtimer.timer_list + self.recordtimer.processed_timers:
+				if str(timer.service_ref) == str(service_ref) and int(timer.begin) == begin and int(timer.end) == end:
+					self.recordtimer.removeEntry(timer)
+					return True, "The timer '%s' has been deleted successfully" % (timer.name)
+		except Exception:
+			return ( False, "The timer has NOT been deleted" )
+
+		return False, "No matching Timer found"
+
+	def tvBrowser(self, param):
+		""" The URL's for the tvBrowser-Capture-Driver are:
+
+			http://dreambox/web/tvbrowser? +
+
+		To add something:
+			&command=add&&year={year}&month={month}&day={day}&shour={start_hour}&smin={start_minute}&ehour={end_hour}&emin={end_minute}&sRef={urlencode(channel_name_external, "utf8")}&name={urlencode(title, "utf8")}&description={urlencode(descr, "utf8")}&dirname={dirname}&tags={urlencode("tag1 tag2...", "utf8")}&afterevent=0&eit=&disabled=0&justplay=0&repeated=0
+
+		to zap for some time:
+			&command=add&&year={year}&month={month}&day={day}&shour={start_hour}&smin={start_minute}&ehour={end_hour}&emin={end_minute}&sRef={urlencode(channel_name_external, "utf8")}&name={urlencode(title, "utf8")}&description={urlencode(descr, "utf8")}&dirname={dirname}&tags={urlencode("tag1 tag2...", "utf8")}&afterevent=0&eit=&disabled=0&justplay=1&repeated=0
+
+		to delete something:
+			&command=del&&year={year}&month={month}&day={day}&shour={start_hour}&smin={start_minute}&ehour={end_hour}&emin={end_minute}&sRef={urlencode(channel_name_external, "utf8")}
+		"""
+		print "[WebComponents.Timer] tvbrowser"
+
+		listDate = ('year', 'month', 'day', 'shour', 'smin', 'ehour', 'emin')
+		for element in listDate:
+			if param[element] is None:
+				if param['s' + element] is None:
+					return ( False, "%s missing" % element )
+				else:
+					param[element] = int(param['s' + element])
+			else:
+				param[element] = int(param[element])
+		param['begin'] = int(mktime((param['year'], param['month'], param['day'], param['shour'], param['smin'], 0, 0, 0, -1)))
+		param['end']	 = int(mktime((param['year'], param['month'], param['day'], param['ehour'], param['emin'], 0, 0, 0, -1)))
+		if param['end'] < param['begin']:
+			param['end'] += 86400
+		for element in listDate:
+			del param[element]
+
+		if param['sRef'] is None:
+			return ( False, "Missing Parameter: sRef" )
+		else:
+			takeApart = param['sRef'].split('|')
+			if len(takeApart) > 1:
+				param['sRef'] = takeApart[1]
+
+		repeated = int(param.get('repeated') or 0)
+		if repeated == 0:
+			for element in ("mo", "tu", "we", "th", "fr", "sa", "su", "ms", "mf"):
+				if element in param:
+					number = param[element] or 0
+					del param[element]
+					repeated = repeated + int(number)
+			if repeated > 127:
+				repeated = 127
+		param['repeated'] = repeated
+
+		if param['command'] == "add":
+			del param['command']
+			return self.editTimer(param)
+		elif param['command'] == "del":
+			del param['command']
+			return self.delTimer(param)
+		elif param['command'] == "change":
+			del param['command']
+			return self.editTimer(param)
+		else:
+			return ( False, "Unknown command: '%s'" % param['command'] )
+
+	def recordNow(self, param):
+		limitEvent = True
+		if param == "undefinitely" or param == "infinite":
+			ret = (True, "Infinite Instant recording started")
+			limitEvent = False
+		else:
+			ret = ( True, "Instant record for current Event started" )
+
+		serviceref = ServiceReference(self.session.nav.getCurrentlyPlayingServiceReference().toString())
+
+		event = None
+
+		try:
+			service = self.session.nav.getCurrentService()
+			event = service.info().getEvent(0)
+		except Exception:
+			print "[Webcomponents.Timer] recordNow Exception!"
+
+		begin = time()
+		end = begin + 3600 * 10
+		name = "instant record"
+		description = ""
+		eventid = 0
+
+		if event is not None:
+			curEvent = parseEvent(event)
+			name = curEvent[2]
+			description = curEvent[3]
+			eventid = curEvent[4]
+			if limitEvent:
+				end = curEvent[1]
+		else:
+			if limitEvent:
+				ret = ( False, "No event found! Not recording!" )
+
+		if ret[0]:
+			location = config.movielist.last_videodir.value
+			timer = RecordTimerEntry(serviceref, begin, end, name, description, eventid, False, False, 0, dirname=location)
+			timer.dontSave = True
+			self.recordtimer.record(timer)
+
+		return ret
+
+
+#===============================================================================
+# This Function can add a new or edit an exisiting Timer.
+# When the Parameter "deleteOldOnSave" is not set, a new Timer will be added.
+# Otherwise, and if the parameters channelOld, beginOld and endOld are set,
+# an existing timer with corresponding values will be changed.
+#===============================================================================
+	def editTimer(self, param):
+		print "[WebComponents.Timer] editTimer"
+
+		#OK first we need to parse all of your Parameters
+		#For some of them (like afterEvent or justplay) we can use default values
+		#for others (the serviceReference or the Begin/End time of the timer
+		#we have to quit if they are not set/have illegal values
+
+		if 'sRef' not in param:
+			return ( False, "Missing Parameter: sRef" )
+		service_ref = ServiceReference(param['sRef'])
+
+		repeated = int(param.get('repeated') or 0)
+
+		if 'begin' not in param:
+			return ( False, "Missing Parameter: begin" )
+		begin = int(float(param['begin']))
+
+		if 'end' not in param:
+			return ( False, "Missing Parameter: end" )
+		end = int(float(param['end']))
+
+		tm = time()
+		if tm <= begin:
+			pass
+		elif tm > begin and tm < end and repeated == 0:
+			begin = time()
+		elif repeated == 0:
+			return ( False, "Illegal Parameter value for Parameter begin : '%s'" % begin )
+
+		if 'name' not in param:
+			return ( False, "Missing Parameter: name" )
+		name = param['name']
+
+		if 'description' not in param:
+			return ( False, "Missing Parameter: description" )
+		description = param['description'].replace("\n", " ")
+
+		disabled = False #Default to: Enabled
+		if 'disabled' in param:
+			if param['disabled'] == "1":
+				disabled = True
+			else:
+				#TODO - maybe we can give the user some useful hint here
+				pass
+
+		justplay = False #Default to: Record
+		if 'justplay' in param:
+			if param['justplay'] == "1":
+				justplay = True
+
+		afterEvent = 3 #Default to Afterevent: Auto
+		if 'afterevent' in param:
+			if (param['afterevent'] == "0") or (param['afterevent'] == "1") or (param['afterevent'] == "2"):
+				afterEvent = int(param['afterevent'])
+
+		dirname = config.movielist.last_timer_videodir.value
+		if 'dirname' in param and param['dirname']:
+			dirname = param['dirname']
+
+		tags = []
+		if 'tags' in param and param['tags']:
+			tags = unescape(param['tags']).split(' ')
+
+		delold = 0
+		if 'deleteOldOnSave' in param:
+			delold = int(param['deleteOldOnSave'])
+
+		#Try to edit an existing Timer
+		if delold:
+			if 'channelOld' in param and param['channelOld']:
+				channelOld = ServiceReference(param['channelOld'])
+			else:
+				return ( False, "Missing Parameter: channelOld" )
+			# We do need all of the following Parameters, too, for being able of finding the Timer.
+			# Therefore so we can neither use default values in this part nor can we
+			# continue if a parameter is missing
+			if 'beginOld' not in param:
+				return ( False, "Missing Parameter: beginOld" )
+			beginOld = int(param['beginOld'])
+
+			if 'endOld' not in param:
+				return ( False, "Missing Parameter: endOld" )
+			endOld = int(param['endOld'])
+
+			#let's try to find the timer
+			try:
+				for timer in self.recordtimer.timer_list + self.recordtimer.processed_timers:
+					if str(timer.service_ref) == str(channelOld):
+						if int(timer.begin) == beginOld:
+							if int(timer.end) == endOld:								
+								#we've found the timer we've been searching for								
+								
+								#Delete the old entry
+								self.recordtimer.removeEntry(timer)
+								old = timer
+								
+								timer = RecordTimerEntry(service_ref, begin, end, name, description, 0, disabled, justplay, afterEvent, dirname=dirname, tags=tags)
+								timer.repeated = repeated
+								timer.log_entries = old.log_entries								
+								
+								timer.processRepeated()								
+								#send the changed timer back to enigma2 and hope it's good
+								
+								conflicts = self.recordtimer.record(timer)
+								if conflicts is None:
+									print "[WebComponents.Timer] editTimer: Timer changed!"
+									return ( True, "Timer '%s' changed" %(timer.name) )
+								else:
+									print "[WebComponents.Timer] editTimer conflicting Timers: %s" %(conflicts)
+									msg = ""
+									for timer in conflicts:
+										msg = "%s / %s" %(msg, timer.name)				
+										
+									return (False, "Conflicting Timer(s) detected! %s" %(msg)) 
+
+			except Exception:
+				#obviously some value was not good, return an error
+				return ( False, "Changing the timer for '%s' failed!" % name )
+
+			return ( False, "Could not find timer '%s' with given start and end time!" % name )
+
+		#Try adding a new Timer
+
+		try:
+			#Create a new instance of recordtimerentry
+			timer = RecordTimerEntry(service_ref, begin, end, name, description, 0, disabled, justplay, afterEvent, dirname=dirname, tags=tags)
+			timer.repeated = repeated
+			#add the new timer
+			conflicts = self.recordtimer.record(timer)
+			if conflicts is None:
+				return ( True, "Timer '%s' added" %(timer.name) )
+			else:
+				print "[WebComponents.Timer] editTimer conflicting Timers: %s" %(conflicts)
+				msg = ""
+				for timer in conflicts:
+					msg = "%s / %s" %(msg, timer.name)				
+					
+				return (False, "Conflicting Timer(s) detected! %s" %(msg)) 
+				
+		except Exception, e:
+			#something went wrong, most possibly one of the given paramater-values was wrong
+			print "[WebComponents.Timer] editTimer exception: %s" %(e)
+			return ( False, "Could not add timer '%s'!" % name )
+
+		return ( False, "Unexpected Error" )
+
+	def addTimerByEventID(self, param):
+		print "[WebComponents.Timer] addTimerByEventID", param
+		if param['sRef'] is None:
+			return ( False, "Missing Parameter: sRef" )
+		if param['eventid'] is None:
+			return ( False, "Missing Parameter: eventid" )
+
+		justplay = False
+		if param['justplay'] is not None:
+			if param['justplay'] == "1":
+				justplay = True
+
+		location = config.movielist.last_timer_videodir.value
+		if 'dirname' in param and param['dirname']:
+			location = param['dirname']
+
+		tags = []
+		if 'tags' in param and param['tags']:
+			tags = unescape(param['tags']).split(' ')
+
+		epgcache = eEPGCache.getInstance()
+		event = epgcache.lookupEventId(eServiceReference(param['sRef']), int(param['eventid']))
+		if event is None:
+			return ( False, "EventId not found" )
+
+		(begin, end, name, description, eit) = parseEvent(event)
+
+		timer = RecordTimerEntry(ServiceReference(param['sRef']), begin , end, name, description, eit, False, justplay, AFTEREVENT.AUTO, dirname=location, tags=tags)
+		
+		conflicts = self.recordtimer.record(timer)
+		if conflicts is None:
+			return ( True, "Timer '%s' added" %(timer.name) )
+		else:
+			print "[WebComponents.Timer] editTimer conflicting Timers: %s" %(conflicts)
+			msg = ""
+			for timer in conflicts:
+				msg = "%s / %s" %(msg, timer.name)				
+				
+			return (False, "Conflicting Timer(s) detected! %s" %(msg)) 
+
+
+	def writeTimerList(self, force=False):
+		# is there an easier and better way? :\
+		if config.plugins.Webinterface.autowritetimer.value or force:
+			print "Timer.py writing timer to flash"
+			self.session.nav.RecordTimer.saveTimer()
+			return ( True, "TimerList has been saved " )
+		else:
+			return ( False, "TimerList has not been saved " )
+
+
+	def getResult(self):
+		return self.res
+
+	result = property(getResult)
+
+	## part for listfiller requests
+	def getList(self):
+		timerlist = []
+
+		for item in self.recordtimer.timer_list + self.recordtimer.processed_timers:
+			timer = [
+				item.service_ref,
+				item.service_ref.getServiceName(),
+				item.eit,
+				item.name,
+				item.description,
+				"1" if item.disabled else "0",
+				item.begin,
+				item.end,
+				item.end - item.begin,
+				item.start_prepare,
+				1 if item.justplay else 0,
+				item.afterEvent,
+				item.dirname,
+				" ".join(item.tags),
+				item.log_entries,
+				item.backoff,
+				item.first_try_prepare,
+				item.state,
+				item.repeated,
+				1 if item.dontSave else 0,
+				item.cancelled,
+			]
+
+			try:
+				timer.append(item.Filename)
+			except AttributeError:
+				timer.append("")
+
+			try:
+				timer.append(item.next_activation)
+			except AttributeError:
+				timer.append("")
+
+			if item.eit is not None:
+				event = self.epgcache.lookupEvent(['EX', ("%s" % item.service_ref , 2, item.eit)])
+				if event and event[0][0] is not None:
+					timer.append(event[0][0])
+				else:
+					timer.append("N/A")
+			else:
+				timer.append("N/A")
+
+			#toggleDisabled
+			if item.disabled:
+				timer.extend(("0", "on"))
+			else:
+				timer.extend(("1", "off"))
+
+			timerlist.append(timer)
+
+		return timerlist
+
+	list = property(getList)
+	lut = {
+				"ServiceReference":0,
+				"ServiceName": 1,
+				"EIT":2,
+				"Name":3,
+				"Description":4,
+				"Disabled":5,
+				"TimeBegin":6,
+				"TimeEnd":7,
+				"Duration":8,
+				"startPrepare":9,
+				"justPlay":10,
+				"afterEvent":11,
+				"Location":12,
+				"Tags":13,
+				"LogEntries":14,
+				"Backoff":15,
+				"firstTryPrepare":16,
+				"State":17,
+				"Repeated":18,
+				"dontSave":19,
+				"Cancled":20,
+				"Filename":21,
+				"nextActivation":22,
+				"DescriptionExtended":23,
+				"toggleDisabled":24,
+				"toggleDisabledIMG":25,
+			}
Index: ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/WebComponents/Sources/Volume.py
===================================================================
--- ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/WebComponents/Sources/Volume.py	(revision 14969)
+++ ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/WebComponents/Sources/Volume.py	(revision 14969)
@@ -0,0 +1,53 @@
+from enigma import eDVBVolumecontrol #this is not nice
+from Components.Sources.Source import Source
+from GlobalActions import globalActionMap
+from Components.VolumeControl import VolumeControl
+
+class Volume(Source):
+	def __init__(self, session, command_default="state"):
+		self.cmd = command_default
+		Source.__init__(self)
+		global globalActionMap # hackalert :)
+		self.actionmap = globalActionMap
+		self.volctrl = eDVBVolumecontrol.getInstance() # this is not nice
+		self.vol = ( True, "State", self.volctrl.getVolume(), self.volctrl.isMuted() )
+
+	def handleCommand(self, cmd):
+		self.cmd = cmd
+		self.vol = self.handleVolume()
+
+	def handleVolume(self):
+		list = []
+		if self.cmd == "state":
+			list.extend((True, "State"))
+		elif self.cmd == "up":
+			self.actionmap.actions["volumeUp"]()
+			list.extend((True, "Volume changed"))
+		elif self.cmd == "down":
+			self.actionmap.actions["volumeDown"]()
+			list.extend((True, "Volume changed"))
+		elif self.cmd == "mute":
+			self.actionmap.actions["volumeMute"]()
+			list.extend((True, "Mute toggled"))
+		elif self.cmd.startswith("set"):
+			try:
+				targetvol = int(self.cmd[3:])
+				if targetvol > 100:
+					targetvol = 100
+				if targetvol < 0:
+					targetvol = 0
+
+				self.volctrl.setVolume(targetvol, targetvol)
+
+				list.extend((True, "Volume set to %i" % targetvol))
+			except ValueError: # if cmd was set12NotInt
+				list.extend((False, "Wrong parameter format 'set=%s'. Use set=set15 " % self.cmd))
+		else:
+			list.extend((False, "Unknown Volume command %s" % self.cmd))
+
+		list.extend((self.volctrl.getVolume(), self.volctrl.isMuted()))
+
+		return list
+
+	volume = property(lambda self: self.vol)
+
Index: ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/WebComponents/Sources/WAPfunctions.py
===================================================================
--- ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/WebComponents/Sources/WAPfunctions.py	(revision 14969)
+++ ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/WebComponents/Sources/WAPfunctions.py	(revision 14969)
@@ -0,0 +1,350 @@
+Version = '$Header$';
+
+from Components.Sources.Source import Source
+from Components.Sources.ServiceList import ServiceList
+from Components.config import config
+from enigma import eServiceReference
+
+from re import sub
+from time import strftime, localtime, time
+
+class WAPfunctions(Source):
+	LISTTIME = 0
+	REPEATED = 1
+	SERVICELIST = 2
+	OPTIONLIST = 3
+	FILLVALUE = 4
+	LOCATIONLIST = 5
+	TAGLIST = 6
+	DELETEOLD = 7
+
+	lut = {	"Name":0,
+			"Value":1,
+			"Selected":2
+	}
+
+	def __init__(self, session, func=LISTTIME):
+		self.func = func
+		Source.__init__(self)
+		self.session = session
+		self.result = ( "unknown command (%s)" % (self.func), )
+
+	def handleCommand(self, cmd):
+		print "WAPfunctions: handleCommand", cmd
+		if self.func is self.LISTTIME:
+			self.result = self.fillListTime(cmd)
+		elif self.func is self.REPEATED:
+			self.result = self.fillRepeated(cmd)
+		elif self.func is self.SERVICELIST:
+			self.result = self.serviceList(cmd)
+		elif self.func is self.OPTIONLIST:
+			self.result = self.fillOptionList(cmd)
+		elif self.func is self.FILLVALUE:
+			self.result = self.fillValue(cmd)
+		elif self.func is self.LOCATIONLIST:
+			self.result = self.locationList(cmd)
+		elif self.func is self.TAGLIST:
+			self.result = self.tagList(cmd)
+		elif self.func is self.DELETEOLD:
+			self.result = self.deleteOldSaved(cmd)
+		else:
+			self.result = ( "unknown command cmd(%s) self.func(%s)" % (cmd, self.func), )
+
+	def fillListTime(self, param):
+		print "fillListTime", param
+
+		input = 0
+		start = 1
+		end = 1
+
+		timeNow = time()
+		timePlusTwo = timeNow + 7200
+
+		if 'begin' in param:
+			begin = param['begin'] or 0
+			begin = int(begin)
+			del param['begin']
+			if begin > 0:
+				timeNow = begin
+		if 'end' in param:
+			end = param['end'] or 0
+			end = int(end)
+			del param['end']
+			if end > 0:
+				timePlusTwo = end
+
+		t = {}
+		t["sday"] = t["day"] = strftime("%d", localtime(timeNow))
+		t["smonth"] = t["month"] = strftime("%m", localtime(timeNow))
+		t["syear"] = t["year"] = strftime("%Y", localtime(timeNow))
+		t["smin"] = strftime("%M", localtime(timeNow))
+		t["shour"] = strftime("%H", localtime(timeNow))
+		t["emin"] = strftime("%M", localtime(timePlusTwo))
+		t["ehour"] = strftime("%H", localtime(timePlusTwo))
+
+		key = ""
+		for i in param:
+			p = str(i)
+			if p != "sRef" and param[p] != None:
+				key = p
+
+		if key == "smin" or key == "emin" :
+			start = 0
+			end = 59
+		elif key == "shour" or key == "ehour":
+			start = 0
+			end = 23
+		elif key == "day" or key == "sday":
+			start = 1
+			end = 31
+		elif key == "month" or key == "smonth":
+			start = 1
+			end = 12
+		else:
+			start = int(t[key])
+			end = int(t[key]) + 2
+
+		if param[key] == "now" or param[key] == "end" or param[key] == "begin":
+			input = int(t[key])
+		else:
+			input = param[key] or 0
+			input = int(input)
+
+		self.result = self.fillOptionListAny(input, start, end)
+		return self.result
+
+	def fillOptionListAny(self, input, start, end):
+		returnList = []
+		for i in range(start, end + 1, 1):
+			returnList1 = []
+			j = str(i)
+			if len(j) == 1:
+				j = "0%s" % j
+			returnList1.extend((j, i))
+			if i == input:
+				returnList1.append("selected")
+			else:
+				returnList1.append("")
+			returnList.append(returnList1)
+		return returnList
+
+	def fillRepeated(self, param):
+		print "fillRepeated", param
+		repeated = param or 0
+		repeated = int(repeated)
+
+		self.lut = {"Name":0
+			, "Value":1
+			, "Description":2
+			, "Selected":3
+		}
+
+		mo = ["mo", 	1, "Mo "]#"Monday"]
+		tu = ["tu", 	2, "Tu "]#"Tuesday"]
+		we = ["we", 	4, "We "]#"Wednesday"]
+		th = ["th", 	8, "Th "]#"Thursday"]
+		fr = ["fr", 16, "Fr "]#"Friday"]
+		sa = ["sa", 32, "Sa "]#"Saturday"]
+		su = ["su", 64, "Su "]#"Sunday"]
+		mf = ["mf", 31, "Mo-Fr"]
+		ms = ["ms", 127, "Mo-Su"]
+
+		if repeated == 127:
+			repeated = repeated - 127
+			ms.append("checked")
+		else:
+			ms.append("")
+
+		if repeated >= 64:
+			repeated = repeated - 64
+			su.append("checked")
+		else:
+			su.append("")
+
+		if repeated >= 32:
+			repeated = repeated - 32
+			sa.append("checked")
+		else:
+			sa.append("")
+
+		if repeated == 31:
+			repeated = repeated - 31
+			mf.append("checked")
+		else:
+			mf.append("")
+
+		if repeated >= 16:
+			repeated = repeated - 16
+			fr.append("checked")
+		else:
+			fr.append("")
+
+		if repeated >= 8:
+			repeated = repeated - 8
+			th.append("checked")
+		else:
+			th.append("")
+
+		if repeated >= 4:
+			repeated = repeated - 4
+			we.append("checked")
+		else:
+			we.append("")
+
+		if repeated >= 2:
+			repeated = repeated - 2
+			tu.append("checked")
+		else:
+			tu.append("")
+
+		if repeated == 1:
+			repeated = repeated - 1
+			mo.append("checked")
+		else:
+			mo.append("")
+
+		return [
+			mo,
+			tu,
+			we,
+			th,
+			fr,
+			sa,
+			su,
+			mf,
+			ms,
+		]
+
+	def serviceListOne(self, bouquet, selref):
+		ref = eServiceReference(bouquet)
+		self.servicelist = ServiceList(ref, command_func=self.getServiceList, validate_commands=False)
+		self.servicelist.setRoot(ref)
+		returnList = []
+		for (ref2, name) in self.servicelist.getServicesAsList():
+			print "ref2: (", ref2, ") name: (", name, ")"
+			returnListPart = [
+				name,
+				ref2
+			]
+			if ref2 == str(selref):
+				returnListPart.append("selected")
+				self.sRefFound = 1
+			else:
+				returnListPart.append("")
+			returnList.append(returnListPart)
+		return returnList
+
+	def serviceList(self, param):
+		print "serviceList: ", param
+		sRef = str(param["sRef"])
+		bouquet = str(param["bouquet"])
+		self.sRefFound = 0
+
+		if bouquet == '':
+			returnList = []
+			bouquet = '1:7:1:0:0:0:0:0:0:0:FROM BOUQUET "bouquets.tv" ORDER BY bouquet'
+			ref = eServiceReference(bouquet)
+			self.servicelist = ServiceList(ref, command_func=self.getServiceList, validate_commands=False)
+			self.servicelist.setRoot(ref)
+			for (ref2, name) in self.servicelist.getServicesAsList():
+				part = self.serviceListOne(ref2, sRef)
+				if part:
+					returnList = returnList + [["-- " + name + " --", "<" + name + ">", ""]] + part
+			bouquet = '1:7:1:0:0:0:0:0:0:0:FROM BOUQUET "bouquets.radio" ORDER BY bouquet'
+			ref = eServiceReference(bouquet)
+			self.servicelist = ServiceList(ref, command_func=self.getServiceList, validate_commands=False)
+			self.servicelist.setRoot(ref)
+			for (ref2, name) in self.servicelist.getServicesAsList():
+				part = self.serviceListOne(ref2, sRef)
+				if part:
+					returnList = returnList + [["-- " + name + " --", "<" + name + ">", ""]] + part
+		else:
+			returnList = self.serviceListOne(bouquet, sRef)
+
+		if self.sRefFound == 0 and sRef != '':
+			returnListPart = ["Inserted", sRef, "selected"]
+			returnList = [returnListPart] + returnList
+		#print returnList
+		return returnList
+
+	def getServiceList(self, ref):
+		self.servicelist.root = ref
+
+	def locationList(self, param):
+		print "locationList", param
+		dirname = param
+		lst = config.movielist.videodirs.value
+		if not dirname:
+			dirname = "/hdd/movie/"
+		if not dirname in lst:
+			lst = [dirname] + lst
+		returnList = [[lst[i], i, dirname == lst[i] and "selected" or ""] for i in range(len(lst))]
+		return returnList
+
+	def tagList(self, param):
+		print "tagList", param
+		tag = param
+		try:
+			file = open("/etc/enigma2/movietags")
+			taglist = [x.rstrip() for x in file.readlines()]
+			while "" in taglist:
+				taglist.remove("")
+			file.close()
+		except IOError, ioe:
+			taglist = []
+		if not tag in taglist:
+			taglist = [tag] + taglist
+		if not "" in taglist:
+			taglist.append("")
+		returnList = [[taglist[i], i, tag == taglist[i] and "selected" or ""] for i in range(len(taglist))]
+		return returnList
+
+	def fillOptionList(self, param):
+		print "fillOptionList", param
+		if "justplay" in param:
+			number = param["justplay"] or 0
+			number = int(number)
+			return (
+				("Record", 0, number == 0 and "selected" or ""),
+				("Zap", 1, number == 1 and "selected" or "")
+			)
+		elif "afterevent" in param:
+			number = param["afterevent"] or 0
+			number = int(number)
+			return (
+				("Nothing", 0, number == 0 and "selected" or ""),
+				("Standby", 1, number == 1 and "selected" or ""),
+				("Deepstandby/Shutdown", 2, number == 2 and "selected" or ""),
+				("Auto", 3, number == 3 and "selected" or "")
+			)
+		else:
+			return ()
+
+	def deleteOldSaved(self, param):
+		print "deleteOldSaved", param
+		returnList = [
+			("deleteOldOnSave", param["deleteOldOnSave"], ""),
+			("command", param["command"], "")
+		]
+		if int(param["deleteOldOnSave"]) == 1:
+			returnList.extend((
+				("channelOld", param["sRef"], ""),
+				("beginOld", param["begin"], ""),
+				("endOld", param["end"], "")
+			))
+		return returnList
+
+	def fillValue(self, param):
+		print "fillValue: ", param
+		return (("", param, ""),)
+
+	def getText(self):
+		(result, text) = self.result
+		return text
+
+	def filterXML(self, item):
+		item = item.replace("&", "&amp;").replace("<", "&lt;").replace('"', '&quot;').replace(">", "&gt;")
+		return item
+
+	text = property(getText)
+	list = property(lambda self: self.result)
Index: ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/WebIfConfig.py
===================================================================
--- ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/WebIfConfig.py	(revision 14969)
+++ ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/WebIfConfig.py	(revision 14969)
@@ -0,0 +1,105 @@
+Version = '$Header$';
+
+from __init__ import _
+
+from enigma import eListboxPythonMultiContent, gFont
+from Screens.Screen import Screen
+from Screens.MessageBox import MessageBox
+
+from Components.config import config, getConfigListEntry, ConfigSubsection, ConfigInteger, ConfigYesNo, ConfigText, ConfigSelection
+from Components.ConfigList import ConfigListScreen
+from Components.Sources.StaticText import StaticText
+from Components.MenuList import MenuList
+from Components.MultiContent import MultiContentEntryText
+
+from Components.ActionMap import ActionMap
+			
+class WebIfConfigScreen(ConfigListScreen, Screen):
+	skin = """
+		<screen name="WebIfConfigScreen" position="center,center" size="560,400" title="Webinterface: Main Setup">
+			<ePixmap pixmap="skin_default/buttons/red.png" position="0,0" size="140,40" alphatest="on" />
+			<ePixmap pixmap="skin_default/buttons/green.png" position="140,0" size="140,40" alphatest="on" />
+			<widget source="key_red" render="Label" position="0,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#9f1313" transparent="1" />
+			<widget source="key_green" render="Label" position="140,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#1f771f" transparent="1" />
+			<widget name="config" position="5,50" size="550,360" scrollbarMode="showOnDemand" zPosition="1"/>
+		</screen>"""
+
+	def __init__(self, session, args=0):
+		Screen.__init__(self, session)
+		
+
+		ConfigListScreen.__init__(self, [])		
+		self.createSetup()
+		
+		self["key_red"] = StaticText(_("Cancel"))
+		self["key_green"] = StaticText(_("OK"))
+		# SKIN Compat HACK!
+		self["key_yellow"] = StaticText("")
+		# EO SKIN Compat HACK!
+		self["setupActions"] = ActionMap(["SetupActions", "ColorActions"],
+		{
+			"red": self.cancel,
+			"green": self.save,
+			"save": self.save,
+			"cancel": self.cancel,
+			"ok": self.save,
+		}, -2)
+				
+		self.onLayoutFinish.append(self.layoutFinished)
+	
+	def keyLeft(self):
+		ConfigListScreen.keyLeft(self)
+		self.createSetup()
+
+	def keyRight(self):
+		ConfigListScreen.keyRight(self)
+		self.createSetup()
+		
+	def createSetup(self):
+		list = [
+			getConfigListEntry(_("Start Webinterface"), config.plugins.Webinterface.enabled),
+			getConfigListEntry(_("Enable /media"), config.plugins.Webinterface.includemedia),
+			getConfigListEntry(_("Allow zapping via Webinterface"), config.plugins.Webinterface.allowzapping),
+			getConfigListEntry(_("Autowrite timer"), config.plugins.Webinterface.autowritetimer),
+			getConfigListEntry(_("Load movie-length"), config.plugins.Webinterface.loadmovielength),
+			getConfigListEntry(_("Enable HTTP Access"), config.plugins.Webinterface.http.enabled)
+		]
+		
+		if config.plugins.Webinterface.http.enabled.value == True:
+			sublist = [
+				getConfigListEntry(_("HTTP Port"), config.plugins.Webinterface.http.port),
+				getConfigListEntry(_("Enable HTTP Authentication"), config.plugins.Webinterface.http.auth)				
+			]
+			
+			list.extend(sublist)
+		
+		#list.append( getConfigListEntry(_("Enable HTTPS Access"), config.plugins.Webinterface.https.enabled) )
+		
+		if config.plugins.Webinterface.https.enabled.value == True:
+			sublist = [
+				#getConfigListEntry(_("HTTPS Port"), config.plugins.Webinterface.https.port),
+				#getConfigListEntry(_("Enable HTTPS Authentication"), config.plugins.Webinterface.https.auth)				
+			]
+			
+			list.	extend(sublist)
+		
+		#Auth for Streaming (127.0.0.1 Listener)
+		list.append(getConfigListEntry(_("Enable Streaming Authentication"), config.plugins.Webinterface.streamauth))
+		
+		self["config"].list = list
+		self["config"].l.setList(list)
+		
+	def layoutFinished(self):
+		self.setTitle(_("Webinterface: Main Setup"))
+
+	def save(self):
+		print "[Webinterface] Saving Configuration"		
+		for x in self["config"].list:
+			x[1].save()
+		self.close(True, self.session)
+
+	def cancel(self):
+		print "[Webinterface] Cancel setup changes"
+		for x in self["config"].list:
+			x[1].cancel()
+		self.close(False, self.session)
Index: ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/WebScreens.py
===================================================================
--- ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/WebScreens.py	(revision 14969)
+++ ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/WebScreens.py	(revision 14969)
@@ -0,0 +1,357 @@
+from enigma import eServiceReference
+from Screens.Screen import Screen
+from WebComponents.Sources.RequestData import RequestData
+
+class WebScreen(Screen):
+	def __init__(self, session, request):
+		Screen.__init__(self, session)
+		self.stand_alone = True
+		self.request = request
+		self.instance = None
+
+class DummyWebScreen(WebScreen):
+	#use it, if you dont need any source, just to can do a static file with an xml-file
+	def __init__(self, session, request):
+		WebScreen.__init__(self, session, request)
+
+class UpdateWebScreen(WebScreen):
+	def __init__(self, session, request):
+		WebScreen.__init__(self, session, request)
+		from Components.Sources.Clock import Clock
+
+		self["CurrentTime"] = Clock()
+
+class MessageWebScreen(WebScreen):
+	def __init__(self, session, request):
+		WebScreen.__init__(self, session, request)
+		from WebComponents.Sources.Message import Message
+
+		self["Message"] = Message(session, func=Message.PRINT)
+		self["GetAnswer"] = Message(session, func=Message.ANSWER)
+
+class ServiceListReloadWebScreen(WebScreen):
+	def __init__(self, session, request):
+		WebScreen.__init__(self, session, request)
+		from WebComponents.Sources.ServiceListReload import ServiceListReload
+
+		self["ServiceListReload"] = ServiceListReload(session)
+
+class AudioWebScreen(WebScreen):
+	def __init__(self, session, request):
+		WebScreen.__init__(self, session, request)
+		from WebComponents.Sources.AudioTracks import AudioTracks
+
+		self["AudioTracks"] = AudioTracks(session, func=AudioTracks.GET)
+		self["SelectAudioTrack"] = AudioTracks(session, func=AudioTracks.SET)
+
+class AboutWebScreen(WebScreen):
+	def __init__(self, session, request):
+		WebScreen.__init__(self, session, request)
+		from WebComponents.Sources.About import About
+		from WebComponents.Sources.Frontend import Frontend
+		from WebComponents.Sources.Hdd import Hdd
+		from WebComponents.Sources.Network import Network
+		from Components.config import config
+		from Components.About import about
+		from Components.Sources.StaticText import StaticText
+		from Tools.DreamboxHardware import getFPVersion
+		from Tools.HardwareInfo import HardwareInfo
+
+		hw = HardwareInfo()
+
+		self["About"] = About(session)
+
+		self["Network"] = Network()
+		self["Hdd"] = Hdd()
+		self["Frontends"] = Frontend()
+		self["EnigmaVersion"] = StaticText(about.getEnigmaVersionString())
+		self["ImageVersion"] = StaticText(about.getVersionString())
+		self["WebIfVersion"] = StaticText(config.plugins.Webinterface.version.value)
+		self["FpVersion"] = StaticText(str(getFPVersion()))
+		self["DeviceName"] = StaticText(hw.get_device_name())
+
+class VolumeWebScreen(WebScreen):
+	def __init__(self, session, request):
+		WebScreen.__init__(self, session, request)
+
+		from WebComponents.Sources.Volume import Volume
+		self["Volume"] = Volume(session)
+
+class SettingsWebScreen(WebScreen):
+	def __init__(self, session, request):
+		WebScreen.__init__(self, session, request)
+		from WebComponents.Sources.Settings import Settings
+
+		self["Settings"] = Settings(session)
+
+class SubServiceWebScreen(WebScreen):
+	def __init__(self, session, request):
+		WebScreen.__init__(self, session, request)
+		from WebComponents.Sources.SubServices import SubServices
+
+		self["SubServices"] = SubServices(session)
+
+class StreamSubServiceWebScreen(WebScreen):
+	def __init__(self, session, request):
+		WebScreen.__init__(self, session, request)
+		from WebComponents.Sources.SubServices import SubServices
+
+		self["StreamSubServices"] = SubServices(session, streamingScreens)
+
+class ServiceListWebScreen(WebScreen):
+	def __init__(self, session, request):
+		WebScreen.__init__(self, session, request)
+		
+		from Components.Sources.ServiceList import ServiceList
+		from Screens.ChannelSelection import service_types_tv
+	
+		fav = eServiceReference(service_types_tv + ' FROM BOUQUET "bouquets.tv" ORDER BY bouquet')
+		self["ServiceList"] = ServiceList(fav, command_func=self.getServiceList, validate_commands=False)
+		self["localip"] = RequestData(request, what=RequestData.HOST)
+		
+	def getServiceList(self, sRef):
+		self["ServiceList"].root = sRef	
+
+class ServiceListRecursiveWebScreen(WebScreen):
+	def __init__(self, session, request):
+		WebScreen.__init__(self, session, request)
+		
+		from WebComponents.Sources.ServiceListRecursive import ServiceListRecursive
+		self["ServiceListRecursive"] = ServiceListRecursive(session, func=ServiceListRecursive.FETCH)
+
+class SwitchServiceWebScreen(WebScreen):
+	def __init__(self, session, request):
+		WebScreen.__init__(self, session, request)
+		
+		from WebComponents.Sources.SwitchService import SwitchService
+		self["SwitchService"] = SwitchService(session)
+
+class ReadPluginListWebScreen(WebScreen):
+	def __init__(self, session, request):
+		WebScreen.__init__(self, session, request)
+		from WebComponents.Sources.ReadPluginList import ReadPluginList
+		self["ReadPluginList"] = ReadPluginList(session)
+
+class LocationsAndTagsWebScreen(WebScreen):
+	def __init__(self, session, request):
+		WebScreen.__init__(self, session, request)
+		from WebComponents.Sources.LocationsAndTags import LocationsAndTags
+
+		self["CurrentLocation"] = LocationsAndTags(session, LocationsAndTags.CURRLOCATION)
+		self["Locations"] = LocationsAndTags(session, LocationsAndTags.LOCATIONS)
+		self["AddLocation"] = LocationsAndTags(session, LocationsAndTags.ADDLOCATION)
+		self["RemoveLocation"] = LocationsAndTags(session, LocationsAndTags.REMOVELOCATION)
+		self["Tags"] = LocationsAndTags(session, LocationsAndTags.TAGS)
+
+class EpgWebScreen(WebScreen):
+	def __init__(self, session, request):
+		WebScreen.__init__(self, session, request)
+		from WebComponents.Sources.EPG import EPG
+
+		self["EpgSearch"] = EPG(session, func=EPG.SEARCH)
+		self["EpgSearchSimilar"] = EPG(session, func=EPG.SEARCHSIMILAR)
+		self["EpgService"] = EPG(session, func=EPG.SERVICE)
+		self["EpgBouquetNow"] = EPG(session, func=EPG.BOUQUETNOW)
+		self["EpgBouquetNext"] = EPG(session, func=EPG.BOUQUETNEXT)
+		self["EpgServiceNow"] = EPG(session, func=EPG.SERVICENOW)
+		self["EpgServiceNext"] = EPG(session, func=EPG.SERVICENEXT)
+		self["EpgBouquet"] = EPG(session, func=EPG.BOUQUET)
+		self["localip"] = RequestData(request, what=RequestData.HOST)
+
+		self["EpgServiceWap"] = EPG(session, func=EPG.SERVICE, endtm=True)
+
+	def getServiceList(self, sRef):
+		self["ServiceList"].root = sRef
+
+class MovieWebScreen(WebScreen):
+	def __init__(self, session, request):
+		WebScreen.__init__(self, session, request)
+		from Components.MovieList import MovieList
+		from Tools.Directories import resolveFilename, SCOPE_HDD
+		from WebComponents.Sources.Movie import Movie
+
+		movielist = MovieList(eServiceReference("2:0:1:0:0:0:0:0:0:0:" + resolveFilename(SCOPE_HDD)))
+		self["MovieList"] = Movie(session, movielist, func=Movie.LIST)
+		self["MovieFileDel"] = Movie(session, movielist, func=Movie.DEL)
+		self["localip"] = RequestData(request, what=RequestData.HOST)
+
+class AutoTimerWebScreen(WebScreen):
+	def __init__(self, session, request):
+		WebScreen.__init__(self, session, request)
+		from WebComponents.Sources.AT import AT
+
+		self["AutoTimerList"] = AT(session, func=AT.LIST)
+		self["AutoTimerWrite"] = AT(session, func=AT.WRITE)
+
+class TimerWebScreen(WebScreen):
+	def __init__(self, session, request):
+		WebScreen.__init__(self, session, request)
+		from WebComponents.Sources.Timer import Timer
+
+		self["TimerList"] = Timer(session, func=Timer.LIST)
+		self["TimerAddEventID"] = Timer(session, func=Timer.ADDBYID)
+		self["TimerAdd"] = Timer(session, func=Timer.ADD)
+		self["TimerDel"] = Timer(session, func=Timer.DEL)
+		self["TimerChange"] = Timer(session, func=Timer.CHANGE)
+		self["TimerListWrite"] = Timer(session, func=Timer.WRITE)
+		self["TVBrowser"] = Timer(session, func=Timer.TVBROWSER)
+		self["RecordNow"] = Timer(session, func=Timer.RECNOW)
+		self["TimerCleanup"] = Timer(session, func=Timer.CLEANUP)
+
+class RemoteWebScreen(WebScreen):
+	def __init__(self, session, request):
+		WebScreen.__init__(self, session, request)
+		from WebComponents.Sources.RemoteControl import RemoteControl
+
+		self["RemoteControl"] = RemoteControl(session)
+
+class PowerWebScreen(WebScreen):
+	def __init__(self, session, request):
+		WebScreen.__init__(self, session, request)
+		from WebComponents.Sources.PowerState import PowerState
+
+		self["PowerState"] = PowerState(session)
+
+class ParentControlWebScreen(WebScreen):
+	def __init__(self, session, request):
+		WebScreen.__init__(self, session, request)
+		from WebComponents.Sources.ParentControl import ParentControl
+
+		self["ParentControlList"] = ParentControl(session)
+
+class WapWebScreen(WebScreen):
+	def __init__(self, session, request):
+		WebScreen.__init__(self, session, request)
+		from WebComponents.Sources.WAPfunctions import WAPfunctions
+
+		self["WAPFillOptionListYear"] = WAPfunctions(session, func=WAPfunctions.LISTTIME)
+		self["WAPFillOptionListDay"] = WAPfunctions(session, func=WAPfunctions.LISTTIME)
+		self["WAPFillOptionListMonth"] = WAPfunctions(session, func=WAPfunctions.LISTTIME)
+		self["WAPFillOptionListShour"] = WAPfunctions(session, func=WAPfunctions.LISTTIME)
+		self["WAPFillOptionListSmin"] = WAPfunctions(session, func=WAPfunctions.LISTTIME)
+		self["WAPFillOptionListEhour"] = WAPfunctions(session, func=WAPfunctions.LISTTIME)
+		self["WAPFillOptionListEmin"] = WAPfunctions(session, func=WAPfunctions.LISTTIME)
+
+		self["WAPFillOptionListRecord"] = WAPfunctions(session, func=WAPfunctions.OPTIONLIST)
+		self["WAPFillOptionListAfterEvent"] = WAPfunctions(session, func=WAPfunctions.OPTIONLIST)
+
+		self["WAPFillValueName"] = WAPfunctions(session, func=WAPfunctions.FILLVALUE)
+		self["WAPFillValueDescr"] = WAPfunctions(session, func=WAPfunctions.FILLVALUE)
+		self["WAPFillLocation"] = WAPfunctions(session, func=WAPfunctions.LOCATIONLIST)
+		self["WAPFillTags"] = WAPfunctions(session, func=WAPfunctions.TAGLIST)
+
+		self["WAPFillOptionListRepeated"] = WAPfunctions(session, func=WAPfunctions.REPEATED)
+		self["WAPServiceList"] = WAPfunctions(session, func=WAPfunctions.SERVICELIST)
+
+		self["WAPdeleteOldOnSave"] = WAPfunctions(session, func=WAPfunctions.DELETEOLD)
+
+streamingScreens = []
+
+class StreamingWebScreen(WebScreen):
+	def __init__(self, session, request):
+		WebScreen.__init__(self, session, request)
+		from Components.Sources.StreamService import StreamService
+		self["StreamService"] = StreamService(self.session.nav)
+		streamingScreens.append(self)
+		self.screenIndex = len(streamingScreens) - 1
+
+	def getRecordService(self):
+		if self.has_key("StreamService"):
+			return self["StreamService"].getService()
+		return None
+
+	def getRecordServiceRef(self):
+		if self.has_key("StreamService"):
+			return self["StreamService"].ref
+		return None
+
+class M3uStreamingWebScreen(WebScreen):
+	def __init__(self, session, request):
+		WebScreen.__init__(self, session, request)
+		from Components.Sources.StaticText import StaticText
+		from Components.Sources.Config import Config
+		from Components.config import config
+		self["ref"] = StaticText()
+		self["localip"] = RequestData(request, what=RequestData.HOST)
+
+class M3uStreamingCurrentServiceWebScreen(WebScreen):
+	def __init__(self, session, request):
+		WebScreen.__init__(self, session, request)
+		from WebComponents.Sources.CurrentService import CurrentService
+
+		self["CurrentService"] = CurrentService(session)
+		self["localip"] = RequestData(request, what=RequestData.HOST)
+
+class TsM3uWebScreen(WebScreen):
+	def __init__(self, session, request):
+		WebScreen.__init__(self, session, request)
+		from Components.Sources.StaticText import StaticText
+		from Components.Sources.Config import Config
+		from Components.config import config
+		self["file"] = StaticText()
+		self["localip"] = RequestData(request, what=RequestData.HOST)
+		self["localport"] = RequestData(request, what=RequestData.PORT)
+
+class RestartWebScreen(WebScreen):
+	def __init__(self, session, request):
+		WebScreen.__init__(self, session, request)
+		import plugin
+		plugin.restartWebserver(session)
+
+class GetPidWebScreen(WebScreen):
+	def __init__(self, session, request):
+		 WebScreen.__init__(self, session, request)
+		 from Components.Sources.StaticText import StaticText
+		 from enigma import iServiceInformation
+		 pids = self.session.nav.getCurrentService()
+		 if pids is not None:
+		 	pidinfo = pids.info()
+		 	VPID = hex(pidinfo.getInfo(iServiceInformation.sVideoPID))
+			APID = hex(pidinfo.getInfo(iServiceInformation.sAudioPID))
+			PPID = hex(pidinfo.getInfo(iServiceInformation.sPMTPID))
+			self["pids"] = StaticText("%s,%s,%s" % (PPID.lstrip("0x"), VPID.lstrip("0x"), APID.lstrip("0x")))
+		 else:
+			self["pids"] = StaticText("0x,0x,0x")
+
+		 self["localip"] = RequestData(request, what=RequestData.HOST)
+
+class DeviceInfoWebScreen(WebScreen):
+	def __init__(self, session, request):
+		WebScreen.__init__(self, session, request)
+		from WebComponents.Sources.Network import Network
+		from WebComponents.Sources.Hdd import *
+		from WebComponents.Sources.Frontend import Frontend
+		from Components.config import config
+		from Components.About import about
+		from Components.Sources.StaticText import StaticText
+		from Tools.DreamboxHardware import getFPVersion
+		from Tools.HardwareInfo import HardwareInfo
+
+		hw = HardwareInfo()
+
+		self["Network"] = Network()
+		self["Hdd"] = Hdd()
+		self["Frontends"] = Frontend()
+		self["EnigmaVersion"] = StaticText(about.getEnigmaVersionString())
+		self["ImageVersion"] = StaticText(about.getVersionString())
+		self["WebIfVersion"] = StaticText(config.plugins.Webinterface.version.value)
+		self["FpVersion"] = StaticText(str(getFPVersion()))
+		self["DeviceName"] = StaticText(hw.get_device_name())
+		self["recPath"] = StaticText(hdd.getRecPath())
+		self["recCapacity"] = StaticText(hdd.getRecCapacity())
+		self["recFree"] = StaticText(hdd.getRecFree())
+
+class ServicePlayableWebScreen(WebScreen):
+	def __init__(self, session, request):
+		WebScreen.__init__(self, session, request)
+		from WebComponents.Sources.ServicePlayable import ServicePlayable
+		
+		self["ServicePlayable"] = ServicePlayable(session, type=ServicePlayable.SINGLE)
+
+class ServiceListPlayableWebScreen(WebScreen):
+	def __init__(self, session, request):
+		WebScreen.__init__(self, session, request)
+		from WebComponents.Sources.ServicePlayable import ServicePlayable
+		
+		self["ServiceListPlayable"] = ServicePlayable(session, type=ServicePlayable.BOUQUET)
+		
Index: ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/__init__.py
===================================================================
--- ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/__init__.py	(revision 14969)
+++ ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/__init__.py	(revision 14969)
@@ -0,0 +1,25 @@
+import Plugins.Plugin
+from Components.Language import language
+from Tools.Directories import resolveFilename, SCOPE_PLUGINS, SCOPE_LANGUAGE
+import os,gettext
+
+__version__ = "1.6.2"
+
+PluginLanguageDomain = "WebInterface"
+PluginLanguagePath = "Extensions/WebInterface/locale"
+
+def localeInit():
+	lang = language.getLanguage()[:2] # getLanguage returns e.g. "fi_FI" for "language_country"
+	os.environ["LANGUAGE"] = lang # Enigma doesn't set this (or LC_ALL, LC_MESSAGES, LANG). gettext needs it!
+	print "[WebInterface] set language to ", lang
+	gettext.bindtextdomain(PluginLanguageDomain, resolveFilename(SCOPE_PLUGINS, PluginLanguagePath))
+
+def _(txt):
+	t = gettext.dgettext(PluginLanguageDomain, txt)
+	if t == txt:
+		print "[WebInterface] fallback to default translation for", txt
+		t = gettext.gettext(txt)
+	return t
+
+localeInit()
+language.addCallback(localeInit)
Index: ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/maintainer.info
===================================================================
--- ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/maintainer.info	(revision 14969)
+++ ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/maintainer.info	(revision 14969)
@@ -0,0 +1,2 @@
+stephan@reichholf.net
+WebInterface
Index: ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/mobile/bouquets.html.xml
===================================================================
--- ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/mobile/bouquets.html.xml	(revision 14969)
+++ ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/mobile/bouquets.html.xml	(revision 14969)
@@ -0,0 +1,29 @@
+<e2:screen name="ServiceListWebScreen">&lt;html>
+<head>
+  <link href="/web-data/tpl/default/style.css" type="text/css" rel="stylesheet" />
+</head>
+<body>
+
+<p>E2mobile - Bouquets</p>
+<table border="1" cellspacing="0" cellpadding="0">
+	<tr>
+		<td><b>Bouquet</b></td>
+		<td><b>Channellist</b></td>
+	</tr>
+	<e2:element source="ServiceList" id="sRef"><e2:convert type="web:ListFiller" >
+	&lt;tr>
+		&lt;td><e2:item name="Name" filter="xml"/>&lt;/td>
+		&lt;td>
+			&lt;a href='/mobile/services.html?sRef=<e2:item name="Reference" filter="uri"/>'>
+				&lt;img src="/web-data/img/epg.png" title="Channellist" border="0">
+			&lt;/a>
+		&lt;/td> 
+	&lt;/tr>
+	</e2:convert><e2:convert type="web:TextToHTML" /></e2:element>
+</table>
+
+
+</body>
+</e2:screen>
+
+
Index: ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/mobile/epg.html.xml
===================================================================
--- ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/mobile/epg.html.xml	(revision 14969)
+++ ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/mobile/epg.html.xml	(revision 14969)
@@ -0,0 +1,32 @@
+<e2:screen name="EpgWebScreen">&lt;html>
+<head>
+  <link href="/web-data/tpl/default/style.css" type="text/css" rel="stylesheet" />
+</head>
+<body>
+<p>E2mobile - EPG</p>
+<table border="1" cellspacing="0" cellpadding="0">
+	<tr>
+		<td><b>Channel</b></td>
+		<td><b>Name</b></td>
+		<td><b>Description</b></td>
+		<td><b>Starttime</b></td>
+		<td><b>Endtime</b></td>
+		<td><b>Duration</b></td>
+		<td><b>Timer</b></td>
+	</tr>
+	<e2:element source="EpgServiceWap" id="sRef,time,endTime"><e2:convert type="web:ListFiller" >
+	&lt;tr>
+		&lt;td><e2:item name="ServiceName" filter="xml"/>&lt;/td>
+		&lt;td><e2:item name="Title" filter="xml"/>&lt;p><e2:item name="Description" filter="xml"/>&lt;/td>   
+		&lt;td><e2:item name="DescriptionExtended" filter="xml"/>&lt;/td>
+		&lt;td><e2:item name="TimeStart" filter="time"/>&lt;/td>
+		&lt;td><e2:item name="TimeEnd" filter="time"/>&lt;/td>
+		&lt;td><e2:item name="Duration" filter="minutes"/>&lt;/td>
+		&lt;td>
+			&lt;a href=&quot;/mobile/timeredit.html?bouquet=&amp;sRef=<e2:item name="ServiceReference"/>&amp;begin=<e2:item name="TimeStart"/>&amp;end=<e2:item name="TimeEnd"/>&amp;name=<e2:item name="Title"/>&amp;description=<e2:item name="Description"/>&amp;afterevent=&amp;justplay=&amp;dirname=&amp;tags=&amp;repeated=&amp;disabled=&amp;deleteOldOnSave=0&amp;command=add&amp;ehour=end&amp;emin=end&amp;day=begin&amp;month=begin&amp;year=begin&amp;shour=begin&amp;smin=begin&quot;>&lt;img src=/web-data/img/timer.png title=AddTimer border=0 />&lt;/a>
+		&lt;/td>
+	&lt;/tr>
+	</e2:convert><e2:convert type="web:TextToHTML" /></e2:element>
+</table>
+</body>
+</e2:screen>
Index: ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/mobile/index.html.xml
===================================================================
--- ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/mobile/index.html.xml	(revision 14969)
+++ ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/mobile/index.html.xml	(revision 14969)
@@ -0,0 +1,26 @@
+<e2:screen name="DummyWebScreen">
+<html>
+<head>
+	<meta content="text/html; charset=UTF-8" http-equiv="content-type"/>
+	<title>E2mobile</title>
+
+	<link href="/web-data/tpl/default/style.css" type="text/css" rel="stylesheet" />
+	<link rel="shortcut icon" type="image/x-icon" href="/web-data/img/favicon.ico"/>
+
+</head>
+<body>
+
+<h1 style="text-align: center;"><big>Enigma 2</big></h1>
+<h1 style="text-align: center;">WebInterface for Mobiles</h1>
+<br/>
+<div class="wap" style="text-align: center;">
+<a href="/mobile/wapremote.html?command=0">Remote Control</a><br/>
+<a href="/mobile/timerlist.html">Timerlist</a><br/>
+<a href="/mobile/timeredit.html?name=&amp;description=&amp;dirname=&amp;tags=&amp;justplay=&amp;afterevent=&amp;repeated=&amp;bouquet=&amp;sRef=&amp;ehour=now&amp;shour=now&amp;emin=now&amp;smin=now&amp;day=now&amp;month=now&amp;year=now&amp;end=&amp;begin=&amp;deleteOldOnSave=0&amp;command=add">Add Timer</a><br/>
+<a href="/mobile/services.html?sRef=1%3A7%3A1%3A0%3A0%3A0%3A0%3A0%3A0%3A0%3AFROM%20BOUQUET%20%22userbouquet.0.tv%22%20ORDER%20BY%20bouquet">Channellist Favorites</a><br/>
+<a href="/mobile/bouquets.html?sRef=1%3A7%3A1%3A0%3A0%3A0%3A0%3A0%3A0%3A0%3A(type%20%3D%3D%201)%20||%20(type%20%3D%3D%2017)%20||%20(type%20%3D%3D%20195)%20||%20(type%20%3D%3D%2025)FROM%20BOUQUET%20%22bouquets.tv%22%20ORDER%20BY%20bouquet">Bouquetlist</a><br/>
+<a href="/mobile/power.html">PowerState</a><br/>
+</div>
+</body>
+</html>
+</e2:screen>
Index: ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/mobile/power.html.xml
===================================================================
--- ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/mobile/power.html.xml	(revision 14969)
+++ ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/mobile/power.html.xml	(revision 14969)
@@ -0,0 +1,19 @@
+<e2:screen name="DummyWebScreen">
+<html>
+<head>
+	<meta content="text/html; charset=UTF-8" http-equiv="content-type"/>
+	<title>E2mobile - Powercontrol)</title>
+
+	<link href="/web-data/tpl/default/style.css" type="text/css" rel="stylesheet" />
+	<link rel="shortcut icon" type="image/x-icon" href="/web-data/img/favicon.ico"/>
+</head>
+<body>
+<div class="wap">
+	<p><center><a href="/web/powerstate?newstate=1">Deepstandby AAF-box</a></center></p>
+	<p><center><a href="/web/powerstate?newstate=2">Reboot AAF-box</a></center></p>
+	<hr/>
+	<p><center><a href="/web/powerstate?newstate=3">Restart Enigma2</a></center></p>
+</div>
+</body>
+</html>
+</e2:screen>
Index: ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/mobile/services.html.xml
===================================================================
--- ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/mobile/services.html.xml	(revision 14969)
+++ ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/mobile/services.html.xml	(revision 14969)
@@ -0,0 +1,25 @@
+<e2:screen name="ServiceListWebScreen">&lt;html>
+<head>
+  <link href="/web-data/tpl/default/style.css" type="text/css" rel="stylesheet" />
+  <title>E2mobile - Servicelist</title>
+</head>
+<body>
+<h1>Enigma2 Servicelist - Favorites</h1>
+<table border="1" cellpadding="0" cellspacing="0">
+	<tr>
+		<td><b>Channel</b></td>
+		<td><b>ZAP</b></td>
+		<td><b>EPG</b></td>
+	</tr>
+<e2:element source="ServiceList" id="sRef"><e2:convert type="web:ListFiller" >
+        &lt;tr>
+        &lt;td><e2:item name="Name" filter="xml"/>&lt;/td>
+        &lt;td>&lt;a href='/web/zap?sRef=<e2:item name="Reference" filter="uri"/>'>&lt;img src=/web-data/img/zap.png title=ZAP border=0>&lt;/a>&lt;/td>
+        &lt;td>&lt;a href='/mobile/epg.html?sRef=<e2:item name="Reference" filter="uri"/>'>&lt;img src=/web-data/img/epg.png title=EPG border=0>&lt;/a>&lt;/td>
+        &lt;/tr>
+        </e2:convert><e2:convert type="web:TextToHTML" /></e2:element>
+</table>
+
+
+</body>
+</e2:screen>
Index: ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/mobile/subservices.html.xml
===================================================================
--- ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/mobile/subservices.html.xml	(revision 14969)
+++ ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/mobile/subservices.html.xml	(revision 14969)
@@ -0,0 +1,23 @@
+<e2:screen name="SubServiceWebScreen">&lt;html>
+<head>
+  <link href="/web-data/tpl/default/style.css" type="text/css" rel="stylesheet" />
+  <title>E2mobile - SubServicelist</title>
+</head>
+<body>
+<h1>Enigma2 SubServicelist</h1>
+<table border="1" cellpadding="0" cellspacing="0">
+	<tr>
+		<td><b>Channel</b></td>
+		<td><b>ZAP</b></td>
+	</tr>
+<e2:element source="SubServices" id="sRef"><e2:convert type="web:ListFiller" >
+        &lt;tr>
+        &lt;td><e2:item name="Name" filter="xml"/>&lt;/td>
+        &lt;td>&lt;a href=&quot;/web/zap?sRef=<e2:item name="ServiceReference" filter="uri"/>&quot;>&lt;img src=/web-data/img/zap.png title=ZAP border=0>&lt;/a>&lt;/td>
+        &lt;/tr>
+        </e2:convert><e2:convert type="web:TextToHTML" /></e2:element>
+</table>
+
+
+</body>
+</e2:screen>
Index: ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/mobile/timeradd.xml
===================================================================
--- ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/mobile/timeradd.xml	(revision 14969)
+++ ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/mobile/timeradd.xml	(revision 14969)
@@ -0,0 +1,10 @@
+<e2:screen name="TimerWebScreen">&lt;?xml version="1.0" encoding="UTF-8"?>
+	<e2:element source="TVBrowser" id="sRef,name,description,dirname,tags,eit,disabled,justplay,afterevent,year,month,day,shour,smin,ehour,emin,mo,tu,we,th,fr,sa,su,mf,ms,command,deleteOldOnSave,beginOld,endOld,channelOld">
+		<e2:convert type="web:Null" />
+	</e2:element>
+	
+<e2simplexmlresult>
+	<e2state><e2:element source="TVBrowser"><e2:convert type="SimpleResult">Result</e2:convert><e2:convert type="web:TextToHTML" /></e2:element></e2state>
+	<e2statetext><e2:element source="TVBrowser"><e2:convert type="SimpleResult">ResultText</e2:convert><e2:convert type="web:TextToHTML" /></e2:element></e2statetext>	
+</e2simplexmlresult>	
+</e2:screen>
Index: ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/mobile/timerchange.html.xml
===================================================================
--- ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/mobile/timerchange.html.xml	(revision 14969)
+++ ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/mobile/timerchange.html.xml	(revision 14969)
@@ -0,0 +1,15 @@
+<e2:screen name="TimerWebScreen"><html>
+<head>
+	<meta content="text/html; charset=UTF-8" http-equiv="content-type"/>
+	<title>E2mobile - Change Timer</title>
+	<meta http-equiv="refresh" content="1; URL=/mobile/timerlist.html"/>
+	<link rel="shortcut icon" type="image/x-icon" href="/web-data/img/favicon.ico"/>
+</head>
+<body>
+<p><center>You will be redirected in a second</center></p>
+</body>
+</html>
+<e2:element source="TimerChange" id="sRef,begin,end,name,description,dirname,tags,eit,disabled,justplay,afterevent,repeated,channelOld,beginOld,endOld,deleteOldOnSave">
+		<e2:convert type="web:TextToHTML" />
+	</e2:element>
+</e2:screen>
Index: ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/mobile/timerdelete.html.xml
===================================================================
--- ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/mobile/timerdelete.html.xml	(revision 14969)
+++ ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/mobile/timerdelete.html.xml	(revision 14969)
@@ -0,0 +1,15 @@
+<e2:screen name="TimerWebScreen"><html>
+<head>
+	<meta content="text/html; charset=UTF-8" http-equiv="content-type"/>
+	<title>E2mobile - Delete Timer</title>
+	<meta http-equiv="refresh" content="1; URL=/mobile/timerlist.html"/>
+	<link rel="shortcut icon" type="image/x-icon" href="/web-data/img/favicon.ico"/>
+</head>
+<body>
+<p><center>You will be redirected in a second</center></p>
+</body>
+</html>
+	<e2:element source="TimerDel" id="sRef,begin,end">
+		<e2:convert type="web:TextToHTML" />
+	</e2:element>
+</e2:screen>
Index: ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/mobile/timeredit.html.xml
===================================================================
--- ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/mobile/timeredit.html.xml	(revision 14969)
+++ ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/mobile/timeredit.html.xml	(revision 14969)
@@ -0,0 +1,143 @@
+<e2:screen name="WapWebScreen"><html>
+<head>
+	<meta content="text/html; charset=UTF-8" http-equiv="content-type"/>
+	<title>E2mobile - Edit Timer</title>
+<!--	<link href="/web-data/tpl/default/style.css" type="text/css" rel="stylesheet" />-->
+	<link rel="shortcut icon" type="image/x-icon" href="/web-data/img/favicon.ico"/>
+</head>
+<body>
+<form action="/mobile/timeradd" method="get">
+<table>
+<tr>
+	<td colspan="3">Action:</td>
+	<td colspan="3"><select name="justplay">
+		<e2:element source="WAPFillOptionListRecord" id="justplay,sRef"><e2:convert type="web:ListFiller">
+		&lt;option value=&quot;<e2:item name="Value"/>&quot; <e2:item name="Selected"/>><e2:item name="Name"/>&lt;/option>
+		</e2:convert>
+		<e2:convert type="web:TextToHTML"/></e2:element>
+	</select>
+	</td>
+</tr><tr>
+	<td colspan="3"></td>
+	<td colspan="3">Note: For recurring events date is not required.</td>
+</tr><tr>
+	<td colspan="3">Date:</td><td colspan="3">
+	<select name="year" size="1">
+		<e2:element source="WAPFillOptionListYear" id="year,sRef,begin,syear"><e2:convert type="web:ListFiller" >
+		&lt;option value=&quot;<e2:item name="Value"/>&quot; <e2:item name="Selected"/>><e2:item name="Name"/>&lt;/option>
+		</e2:convert>
+	<e2:convert type="web:TextToHTML"/></e2:element>
+	</select>.
+	<select name="month">
+		<e2:element source="WAPFillOptionListMonth" id="month,sRef,begin,smonth"><e2:convert type="web:ListFiller" >
+		&lt;option value=&quot;<e2:item name="Value"/>&quot; <e2:item name="Selected"/>><e2:item name="Name"/>&lt;/option>
+		</e2:convert>
+	<e2:convert type="web:TextToHTML"/></e2:element>
+	</select>.
+	<select name="day">
+		<e2:element source="WAPFillOptionListDay" id="day,sRef,begin,sday"><e2:convert type="web:ListFiller" >
+		&lt;option value=&quot;<e2:item name="Value"/>&quot; <e2:item name="Selected"/>><e2:item name="Name"/>&lt;/option>
+		</e2:convert>
+	<e2:convert type="web:TextToHTML"/></e2:element>
+	</select></td>
+</tr><tr>
+	<td colspan="3">Start:</td><td colspan="3">
+	<select name="shour">
+		<e2:element source="WAPFillOptionListShour" id="shour,sRef,begin"><e2:convert type="web:ListFiller" >
+		&lt;option value=&quot;<e2:item name="Value"/>&quot; <e2:item name="Selected"/>><e2:item name="Name"/>&lt;/option>
+		</e2:convert>
+	<e2:convert type="web:TextToHTML"/></e2:element>
+</select>:
+	<select name="smin">
+		<e2:element source="WAPFillOptionListSmin" id="smin,sRef,begin"><e2:convert type="web:ListFiller" >
+		&lt;option value=&quot;<e2:item name="Value"/>&quot; <e2:item name="Selected"/>><e2:item name="Name"/>&lt;/option>
+		</e2:convert>
+	<e2:convert type="web:TextToHTML"/></e2:element>
+	</select></td>
+</tr><tr>
+	<td colspan="3">End:</td><td colspan="3">
+	<select name="ehour">
+		<e2:element source="WAPFillOptionListEhour" id="ehour,sRef,end"><e2:convert type="web:ListFiller" >
+		&lt;option value=&quot;<e2:item name="Value"/>&quot; <e2:item name="Selected"/>><e2:item name="Name"/>&lt;/option>
+		</e2:convert>
+	<e2:convert type="web:TextToHTML"/></e2:element>
+</select>:
+	<select name="emin">
+		<e2:element source="WAPFillOptionListEmin" id="emin,sRef,end"><e2:convert type="web:ListFiller" >
+		&lt;option value=&quot;<e2:item name="Value"/>&quot; <e2:item name="Selected"/>><e2:item name="Name"/>&lt;/option>
+		</e2:convert>
+		<e2:convert type="web:TextToHTML"/></e2:element>
+</select>
+	</td>
+</tr><tr>
+	<td colspan="3"></td><td colspan="3">Note: For one-time events the "days" field doesn't have to be specified.</td>
+</tr><tr>
+	<td colspan="3">Days:</td><td colspan="3">
+		<e2:element source="WAPFillOptionListRepeated" id="repeated"><e2:convert type="web:ListFiller" >
+			&lt;input type="checkbox" name=&quot;<e2:item name="Name"/>&quot; value=&quot;<e2:item name="Value"/>&quot; <e2:item name="Selected"/>/><e2:item name="Description"/>
+			</e2:convert>
+		<e2:convert type="web:TextToHTML"/></e2:element>
+	</td>
+</tr><tr>
+	<td colspan="3">Channel:</td><td colspan="3">
+	<select name="sRef">
+	<e2:element source="WAPServiceList" id="sRef,bouquet"><e2:convert type="web:ListFiller" >
+		&lt;option value=&quot;<e2:item name="Value"/>&quot; <e2:item name="Selected"/>><e2:item name="Name"/>&lt;/option>
+		</e2:convert>
+	<e2:convert type="web:TextToHTML"/></e2:element>
+	</select>
+	</td>
+</tr><tr>
+	<td colspan="3">Name:</td><td colspan="3">
+	<e2:element source="WAPFillValueName" id="name"><e2:convert type="web:ListFiller" >
+		&lt;input name=name type=text size=60 maxlength=60 value=&quot;<e2:item name="Value"/>&quot;>
+		</e2:convert>
+		<e2:convert type="web:TextToHTML"/></e2:element>
+	</td>
+</tr><tr>
+	<td colspan="3">Description:</td><td colspan="3">
+	<e2:element source="WAPFillValueDescr" id="description"><e2:convert type="web:ListFiller" >
+		&lt;input name=description type=text size=60 maxlength=60 value=&quot;<e2:item name="Value"/>&quot;>
+		</e2:convert>
+		<e2:convert type="web:TextToHTML"/></e2:element>
+	</td>
+</tr><tr>
+	<td colspan="3">Location:</td><td colspan="3">
+	<select name="dirname" size="1">
+	<e2:element source="WAPFillLocation" id="dirname"><e2:convert type="web:ListFiller" >
+		&lt;option value=&quot;<e2:item name="Name"/>&quot; <e2:item name="Selected"/>><e2:item name="Name"/>&lt;/option>
+		</e2:convert>
+		<e2:convert type="web:TextToHTML"/></e2:element>
+	</select>
+	</td>
+</tr><tr>
+	<td colspan="3">Tags:</td><td colspan="3">
+	<select name="tags" size="1">
+	<e2:element source="WAPFillTags" id="tags"><e2:convert type="web:ListFiller" >
+		&lt;option value=&quot;<e2:item name="Name"/>&quot; <e2:item name="Selected"/>><e2:item name="Name"/>&lt;/option>
+		</e2:convert>
+		<e2:convert type="web:TextToHTML"/></e2:element>
+	</select>
+	</td>
+</tr><tr>
+	<td colspan="3">After event do:</td><td colspan="3"><select name="afterevent" size="1">
+		<e2:element source="WAPFillOptionListAfterEvent" id="afterevent,sRef"><e2:convert type="web:ListFiller" >
+		&lt;option value=&quot;<e2:item name="Value"/>&quot; <e2:item name="Selected"/>><e2:item name="Name"/>&lt;/option>
+		</e2:convert>
+		<e2:convert type="web:TextToHTML"/></e2:element>
+</select>
+</td>
+</tr><tr></tr><tr>
+	<td colspan="3"></td>
+	<td colspan="3">
+	<input name="disabled" type="hidden" value="0"/>
+	<e2:element source="WAPdeleteOldOnSave" id="deleteOldOnSave,sRef,begin,end,command"><e2:convert type="web:ListFiller" >
+		&lt;input type=hidden value=&quot;<e2:item name="Value"/>&quot; name=&quot;<e2:item name="Name"/>&quot;/>
+		</e2:convert>
+	<e2:convert type="web:TextToHTML"/></e2:element>
+	<input type="submit" name="save" value="Add/Save"/>
+</td></tr>
+</table></form>
+</body>
+</html>	
+</e2:screen>
Index: ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/mobile/timerlist.html.xml
===================================================================
--- ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/mobile/timerlist.html.xml	(revision 14969)
+++ ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/mobile/timerlist.html.xml	(revision 14969)
@@ -0,0 +1,40 @@
+<e2:screen name="TimerWebScreen"><html>
+<head>
+<!--
+Version = '$Header$';
+-->
+	<meta content="text/html; charset=UTF-8" http-equiv="content-type" />
+	<title>E2mobile - Timer</title>
+
+	<link href="/web-data/tpl/default/style.css" type="text/css" rel="stylesheet" />
+	<link rel="shortcut icon" type="image/x-icon" href="/web-data/img/favicon.ico" />
+</head>
+
+<body>
+<p>Enigma2 WAP - EPG</p>
+<div class="wap" style="text-align: center;">
+<table border="1" cellspacing="0" cellpadding="0">
+		<tr>
+		<td><b>Channel</b></td>
+		<td><b>Name</b></td>
+		<td><b>Description</b></td>
+		<td><b>Action</b></td>
+		</tr>		
+		<e2:element source="TimerList" ><e2:convert type="web:ListFiller" >
+		&lt;tr>
+		&lt;td>&lt;font><e2:item name="ServiceName"/> &lt;/font>&lt;/td>
+		&lt;td>&lt;font><e2:item name="Name"/> &lt;/font>&lt;/td>
+		&lt;td>&lt;font><e2:item name="Description"/> &lt;/font>&lt;/td>
+		&lt;td>&lt;a href=&quot;/web/timerdelete?sRef=<e2:item name="ServiceReference"/>&amp;begin=<e2:item name="TimeBegin"/>&amp;end=<e2:item name="TimeEnd"/>&quot;>&lt;img src=/web-data/img/delete.png title=delete_timer_entry border=0>&lt;/a>
+		&lt;a href=&quot;/mobile/timerchange.html?sRef=<e2:item name="ServiceReference"/>&amp;begin=<e2:item name="TimeBegin"/>&amp;end=<e2:item name="TimeEnd"/>&amp;name=<e2:item name="Name"/>&amp;description=<e2:item name="Description"/>&amp;afterevent=<e2:item name="afterEvent"/>&amp;justplay=<e2:item name="justPlay"/>&amp;dirname=<e2:item name="Location"/>&amp;tags=<e2:item name="Tags"/>&amp;repeated=<e2:item name="Repeated"/>&amp;disabled=<e2:item name="toggleDisabled"/>&amp;channelOld=<e2:item name="ServiceReference"/>&amp;beginOld=<e2:item name="TimeBegin"/>&amp;endOld=<e2:item name="TimeEnd"/>&amp;deleteOldOnSave=1&quot;>&lt;img src=/web-data/img/<e2:item name="toggleDisabledIMG"/>.png title=toggleOnOff border=0>&lt;/a>
+		&lt;a href=&quot;/mobile/timeredit.html?bouquet=&amp;sRef=<e2:item name="ServiceReference"/>&amp;begin=<e2:item name="TimeBegin"/>&amp;end=<e2:item name="TimeEnd"/>&amp;name=<e2:item name="Name"/>&amp;description=<e2:item name="Description"/>&amp;afterevent=<e2:item name="afterEvent"/>&amp;justplay=<e2:item name="justPlay"/>&amp;dirname=<e2:item name="Location"/>&amp;tags=<e2:item name="Tags"/>&amp;repeated=<e2:item name="Repeated"/>&amp;disabled=<e2:item name="toggleDisabled"/>&amp;deleteOldOnSave=1&amp;command=change&amp;ehour=end&amp;emin=end&amp;day=begin&amp;month=begin&amp;year=begin&amp;shour=begin&amp;smin=begin&quot;>&lt;img src=/web-data/img/edit.png title=EditTimer border=0>&lt;/a>
+			&lt;/td>
+		&lt;/tr>
+	</e2:convert>
+	<e2:convert type="web:TextToHTML" /></e2:element>
+</table>
+
+</div>
+</body>
+</html>
+</e2:screen>
Index: ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/mobile/wapremote.html.xml
===================================================================
--- ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/mobile/wapremote.html.xml	(revision 14969)
+++ ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/mobile/wapremote.html.xml	(revision 14969)
@@ -0,0 +1,66 @@
+<e2:screen name="RemoteWebScreen">
+
+<html>
+<head>
+	<meta content="text/html; charset=UTF-8" http-equiv="content-type" />
+	<title>E2mobile - Remote</title>
+
+	<link href="/web-data/tpl/default/style.css" type="text/css" rel="stylesheet" />
+	<link rel="shortcut icon" type="image/x-icon" href="/web-data/img/favicon.ico" />
+</head>
+
+<body>
+	<div style="text-align: center;">
+		<img border="0" usemap="#RemoteControl" src="/web-data/gfx/remotecontrol_static.jpg" />
+		
+		<map name="RemoteControl">
+        <area shape="circle" coords="84,17,7" href="/mobile/wapremote.html?command=116" alt="onoff"/>
+        <area shape="circle" coords="17,38,7" href="/mobile/wapremote.html?command=2" alt="1"/>
+        <area shape="circle" coords="51,37,7" href="/mobile/wapremote.html?command=3" alt="2"/>
+        <area shape="circle" coords="83,39,7" href="/mobile/wapremote.html?command=4" alt="3"/>
+        <area shape="circle" coords="18,61,7" href="/mobile/wapremote.html?command=5" alt="4"/>
+        <area shape="circle" coords="51,60,7" href="/mobile/wapremote.html?command=6" alt="5"/>
+        <area shape="circle" coords="83,63,7" href="/mobile/wapremote.html?command=7" alt="6"/>
+        <area shape="circle" coords="19,83,7" href="/mobile/wapremote.html?command=8" alt="7"/>
+        <area shape="circle" coords="51,81,7" href="/mobile/wapremote.html?command=9" alt="8"/>
+        <area shape="circle" coords="82,83,7" href="/mobile/wapremote.html?command=10" alt="9"/>
+        <area shape="circle" coords="51,104,7" href="/mobile/wapremote.html?command=11" alt="0"/>
+        <area shape="rect" coords="76,100,90,113" href="/mobile/wapremote.html?command=388" alt="text"/>
+        <area shape="circle" coords="21,160,9" href="/mobile/wapremote.html?command=115" alt="vup"/>
+        <area shape="circle" coords="21,189,9" href="/mobile/wapremote.html?command=114" alt="vdown"/>
+        <area shape="circle" coords="16,16,7" href="/mobile/wapremote.html?command=113" alt="mute"/>
+        <area shape="rect" coords="13,229,28,244" href="/mobile/wapremote.html?command=102" alt="exit"/>
+        <area shape="rect" coords="43,153,60,172" href="/mobile/wapremote.html?command=138" alt="info"/>
+        <area shape="rect" coords="12,99,26,113" href="/mobile/wapremote.html?command=139" alt="menu"/>
+        <area shape="circle" coords="81,189,8" href="/mobile/wapremote.html?command=105" alt="program down"/>
+        <area shape="circle" coords="81,160,10" href="/mobile/wapremote.html?command=106" alt="program up"/>
+        <area shape="rect" coords="42,182,60,197" href="/mobile/wapremote.html?command=103" alt="up"/>
+        <area shape="rect" coords="43,230,60,247" href="/mobile/wapremote.html?command=108" alt="down"/>
+        <area shape="rect" coords="13,205,29,220" href="/mobile/wapremote.html?command=105" alt="left"/>
+        <area shape="rect" coords="72,207,89,221" href="/mobile/wapremote.html?command=106" alt="rigth"/>
+        <area shape="rect" coords="42,205,61,222" href="/mobile/wapremote.html?command=352" alt="ok"/>
+        <area shape="rect" coords="12,124,23,143" href="/mobile/wapremote.html?command=398" alt="red"/>
+        <area shape="rect" coords="34,123,44,141" href="/mobile/wapremote.html?command=399" alt="green"/>
+        <area shape="rect" coords="59,123,68,142" href="/mobile/wapremote.html?command=400" alt="yellow"/>
+        <area shape="rect" coords="81,123,92,144" href="/mobile/wapremote.html?command=401" alt="blue"/>
+        <area shape="rect" coords="74,231,89,246" href="/mobile/wapremote.html?command=174" alt="epg"/>
+        
+        <area shape="circle" coords="20,262,9" href="/mobile/wapremote.html?command=168" alt="2xleft"/>
+        <area shape="circle" coords="52,264,9" href="/mobile/wapremote.html?command=207" alt="play"/>
+        <area shape="circle" coords="82,263,9" href="/mobile/wapremote.html?command=208" alt="2xright"/>
+        <area shape="circle" coords="20,286,9" href="/mobile/wapremote.html?command=119" alt="pause"/>
+        <area shape="circle" coords="50,287,9" href="/mobile/wapremote.html?command=167" alt="rec"/>
+		<area shape="circle" coords="82,287,9" href="/mobile/wapremote.html?command=128" alt="stop"/>
+        
+      </map>
+	</div>
+	
+	<div>
+	<e2:element source="RemoteControl" id="command,type"><e2:convert type="web:Null" /></e2:element>
+	<e2:element source="RemoteControl"><e2:convert type="SimpleResult">ResultText</e2:convert><e2:convert type="web:TextToHTML" /></e2:element>
+	</div>
+
+</body>
+</html>
+
+</e2:screen>
Index: ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/plugin.py
===================================================================
--- ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/plugin.py	(revision 14969)
+++ ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/plugin.py	(revision 14969)
@@ -0,0 +1,549 @@
+Version = '$Header$';
+
+from enigma import eConsoleAppContainer
+from Plugins.Plugin import PluginDescriptor
+
+from Components.config import config, ConfigBoolean, ConfigSubsection, ConfigInteger, ConfigYesNo, ConfigText
+from Components.Network import iNetwork
+from Screens.MessageBox import MessageBox
+from WebIfConfig import WebIfConfigScreen
+from WebChilds.Toplevel import getToplevel
+
+from Tools.Directories import copyfile, resolveFilename, SCOPE_PLUGINS, SCOPE_CONFIG
+
+#from twisted.internet import reactor, ssl
+from twisted.internet import reactor
+from twisted.web import server, http, util, static, resource
+
+from zope.interface import Interface, implements
+from socket import gethostname as socket_gethostname
+#from OpenSSL import SSL
+
+from os.path import isfile as os_isfile
+
+
+
+from __init__ import _, __version__
+
+#CONFIG INIT
+
+#init the config
+config.plugins.Webinterface = ConfigSubsection()
+config.plugins.Webinterface.enabled = ConfigYesNo(default=True)
+config.plugins.Webinterface.allowzapping = ConfigYesNo(default=True)
+config.plugins.Webinterface.includemedia = ConfigYesNo(default=False)
+config.plugins.Webinterface.autowritetimer = ConfigYesNo(default=False)
+config.plugins.Webinterface.loadmovielength = ConfigYesNo(default=True)
+config.plugins.Webinterface.version = ConfigText(__version__) # used to make the versioninfo accessible enigma2-wide, not confgurable in GUI.
+
+config.plugins.Webinterface.http = ConfigSubsection()
+config.plugins.Webinterface.http.enabled = ConfigYesNo(default=True)
+config.plugins.Webinterface.http.port = ConfigInteger(default = 80, limits=(1, 65535) )
+config.plugins.Webinterface.http.auth = ConfigYesNo(default=False)
+
+config.plugins.Webinterface.https = ConfigSubsection()
+config.plugins.Webinterface.https.enabled = ConfigYesNo(default=False)
+config.plugins.Webinterface.https.port = ConfigInteger(default = 443, limits=(1, 65535) )
+config.plugins.Webinterface.https.auth = ConfigYesNo(default=False)
+
+config.plugins.Webinterface.streamauth = ConfigYesNo(default=False)
+
+global running_defered, waiting_shutdown, toplevel
+
+running_defered = []
+waiting_shutdown = 0
+toplevel = None
+server.VERSION = "Enigma2 WebInterface Server $Revision$".replace("$Revi", "").replace("sion: ", "").replace("$", "")
+
+#===============================================================================
+# Helperclass to close running Instances of the Webinterface
+#===============================================================================
+class Closer:
+	counter = 0
+	def __init__(self, session, callback=None):
+		self.callback = callback
+		self.session = session
+
+#===============================================================================
+# Closes all running Instances of the Webinterface
+#===============================================================================
+	def stop(self):
+		global running_defered
+		for d in running_defered:
+			print "[Webinterface] stopping interface on ", d.interface, " with port", d.port
+			x = d.stopListening()
+			
+			try:
+				x.addCallback(self.isDown)
+				self.counter += 1
+			except AttributeError:
+				pass
+		running_defered = []
+		if self.counter < 1:
+			if self.callback is not None:
+				self.callback(self.session)
+
+#===============================================================================
+# #Is it already down?
+#===============================================================================
+	def isDown(self, s):
+		self.counter -= 1
+		if self.counter < 1:
+			if self.callback is not None:
+				self.callback(self.session)
+
+def checkCertificates():
+	print "[WebInterface] checking for SSL Certificates"
+	srvcert = '%sserver.pem' %resolveFilename(SCOPE_CONFIG) 
+	cacert = '%scacert.pem' %resolveFilename(SCOPE_CONFIG)
+
+	# Check whether there are regular certificates, if not copy the default ones over
+	if not os_isfile(srvcert) or not os_isfile(cacert):
+		return False
+	
+	else:
+		return True
+		
+def installCertificates(session, callback = None):
+	print "[WebInterface] Installing SSL Certificates to %s" %resolveFilename(SCOPE_CONFIG)
+	
+	srvcert = '%sserver.pem' %resolveFilename(SCOPE_CONFIG) 
+	cacert = '%scacert.pem' %resolveFilename(SCOPE_CONFIG)	
+	scope_webif = '%sExtensions/WebInterface/' %resolveFilename(SCOPE_PLUGINS)
+	
+	source = '%setc/server.pem' %scope_webif
+	target = srvcert
+	ret = copyfile(source, target)
+	
+	if ret == 0:
+		source = '%setc/cacert.pem' %scope_webif
+		target = cacert
+		ret = copyfile(source, target)
+		
+		if ret == 0 and callback != None:
+			callback(session)
+	
+	if ret < 0:
+		config.plugins.Webinterface.https.enabled.value = False
+		config.plugins.Webinterface.https.enabled.save()
+		
+		# Start without https
+		callback(session)
+		
+		#Inform the user
+		session.open(MessageBox, "Couldn't install SSL-Certifactes for https access\nHttps access is now disabled!", MessageBox.TYPE_ERROR)
+	
+#===============================================================================
+# restart the Webinterface for all configured Interfaces
+#===============================================================================
+def restartWebserver(session):
+	try:
+		del session.mediaplayer
+		del session.messageboxanswer
+	except NameError:
+		pass
+	except AttributeError:
+		pass
+
+	global running_defered
+	if len(running_defered) > 0:
+		Closer(session, startWebserver).stop()
+	else:
+		startWebserver(session)
+	
+#===============================================================================
+# start the Webinterface for all configured Interfaces
+#===============================================================================
+def startWebserver(session):
+	global running_defered
+	global toplevel
+
+	# Exception handling added by Topfi: Otherwise you get GS when changing Network Settings
+	try:
+		session.mediaplayer = None
+		session.messageboxanswer = None
+	except NameError:
+		pass
+	except AttributeError:
+		pass
+
+	if toplevel is None:
+		toplevel = getToplevel(session)
+	
+	errors = ""
+	
+	if config.plugins.Webinterface.enabled.value is not True:
+		print "[Webinterface] is disabled!"
+	
+	else:
+		# IF SSL is enabled we need to check for the certs first
+		# If they're not there we'll exit via return here 
+		# and get called after Certificates are installed properly
+		if config.plugins.Webinterface.https.enabled.value:
+			if not checkCertificates():
+				print "[Webinterface] Installing Webserver Certificates for SSL encryption"
+				installCertificates(session, startWebserver)
+				return
+				
+		for adaptername in iNetwork.ifaces:				
+			ip = '.'.join("%d" % d for d in iNetwork.ifaces[adaptername]['ip'])
+						
+			#Only if it's up and has a "good" IP
+			if ip != '0.0.0.0' and iNetwork.ifaces[adaptername]['up'] == True:
+			#HTTP
+				if config.plugins.Webinterface.http.enabled.value is True:
+					ret = startServerInstance(session, ip, config.plugins.Webinterface.http.port.value, config.plugins.Webinterface.http.auth.value)
+					if ret == False:
+						errors = "%s%s:%i\n" %(errors, ip, config.plugins.Webinterface.http.port.value)
+					else:
+						registerBonjourService('http', config.plugins.Webinterface.http.port.value)
+			#HTTPS		
+				if config.plugins.Webinterface.https.enabled.value is True:					
+					ret = startServerInstance(session, ip, config.plugins.Webinterface.https.port.value, config.plugins.Webinterface.https.auth.value, True)
+					if ret == False:
+						errors = "%s%s:%i\n" %(errors, ip, config.plugins.Webinterface.https.port.value)
+					else:
+						registerBonjourService('https', config.plugins.Webinterface.https.port.value)
+	
+	#LOCAL HTTP Connections (Streamproxy)
+		ret = startServerInstance(session, '127.0.0.1', 80, config.plugins.Webinterface.streamauth.value)			
+		#if ret == False:
+		#	errors = "%s%s:%i\n" %(errors, '127.0.0.1', 80)
+		
+		#if errors != "":
+		#	session.open(MessageBox, "Webinterface - Couldn't listen on:\n %s" % (errors), type=MessageBox.TYPE_ERROR, timeout=0)
+		
+#===============================================================================
+# stop the Webinterface for all configured Interfaces
+#===============================================================================
+def stopWebserver(session):
+	try:
+		del session.mediaplayer
+		del session.messageboxanswer
+	except NameError:
+		pass
+	except AttributeError:
+		pass
+
+	global running_defered
+	if len(running_defered) > 0:
+		Closer(session).stop()
+
+#===============================================================================
+# startServerInstance
+# Starts an Instance of the Webinterface
+# on given ipaddress, port, w/o auth, w/o ssl
+#===============================================================================
+def startServerInstance(session, ipaddress, port, useauth=False, usessl=False):
+	try:
+		if useauth:
+# HTTPAuthResource handles the authentication for every Resource you want it to			
+			root = HTTPAuthResource(toplevel, "Enigma2 WebInterface")
+			site = server.Site(root)			
+		else:
+			site = server.Site(toplevel)
+	
+		if usessl:
+			
+			ctx = ssl.DefaultOpenSSLContextFactory('/etc/enigma2/server.pem', '/etc/enigma2/cacert.pem', sslmethod=SSL.SSLv23_METHOD)
+			d = reactor.listenSSL(port, site, ctx, interface=ipaddress)
+		else:
+			d = reactor.listenTCP(port, site, interface=ipaddress)
+		running_defered.append(d)		
+		print "[Webinterface] started on %s:%i" % (ipaddress, port), "auth=", useauth, "ssl=", usessl
+		return True
+	
+	except Exception, e:
+		print "[Webinterface] starting FAILED on %s:%i!" % (ipaddress, port), e		
+		return False
+#===============================================================================
+# HTTPAuthResource
+# Handles HTTP Authorization for a given Resource
+#===============================================================================
+class HTTPAuthResource(resource.Resource):
+	def __init__(self, res, realm):
+		resource.Resource.__init__(self)
+		self.resource = res
+		self.realm = realm
+		self.authorized = False
+		self.tries = 0
+		self.unauthorizedResource = UnauthorizedResource(self.realm)		
+	
+	def unautorized(self, request):
+		request.setResponseCode(http.UNAUTHORIZED)
+		request.setHeader('WWW-authenticate', 'basic realm="%s"' % self.realm)
+
+		return self.unauthorizedResource
+	
+	def isAuthenticated(self, request):
+		# get the Session from the Request
+		sessionNs = request.getSession().sessionNamespaces
+		
+		# if the auth-information has not yet been stored to the session
+		if not sessionNs.has_key('authenticated'):
+			sessionNs['authenticated'] = check_passwd(request.getUser(), request.getPassword())
+		
+		#if the auth-information already is in the session				
+		else:
+			if sessionNs['authenticated'] is False:
+				sessionNs['authenticated'] = check_passwd(request.getUser(), request.getPassword() )
+		
+		#return the current authentication status						
+		return sessionNs['authenticated']
+													
+#===============================================================================
+# Call render of self.resource (if authenticated)													
+#===============================================================================
+	def render(self, request):			
+		if self.isAuthenticated(request) is True:	
+			return self.resource.render(request)
+		
+		else:
+			return self.unautorized(request).render(request)
+
+#===============================================================================
+# Override to call getChildWithDefault of self.resource (if authenticated)	
+#===============================================================================
+	def getChildWithDefault(self, path, request):
+		if self.isAuthenticated(request) is True:
+			return self.resource.getChildWithDefault(path, request)
+		
+		else:
+			return self.unautorized(request)
+
+#===============================================================================
+# UnauthorizedResource
+# Returns a simple html-ified "Access Denied"
+#===============================================================================
+class UnauthorizedResource(resource.Resource):
+	def __init__(self, realm):
+		resource.Resource.__init__(self)
+		self.realm = realm
+		self.errorpage = static.Data('<html><body>Access Denied.</body></html>', 'text/html')
+	
+	def getChild(self, path, request):
+		return self.errorpage
+		
+	def render(self, request):	
+		return self.errorpage.render(request)
+
+# Password verfication stuff
+
+from hashlib import md5 as md5_new
+from crypt import crypt
+
+#===============================================================================
+# getpwnam
+# 
+# Get a password database entry for the given user name
+# Example from the Python Library Reference.
+#===============================================================================
+def getpwnam(name, pwfile=None):
+	if not pwfile:
+		pwfile = '/etc/passwd'
+
+	f = open(pwfile)
+	while 1:
+		line = f.readline()
+		if not line:
+			f.close()
+			raise KeyError, name
+		entry = tuple(line.strip().split(':', 6))
+		if entry[0] == name:
+			f.close()
+			return entry
+
+#===============================================================================
+# passcrypt
+#
+# Encrypt a password
+#===============================================================================
+def passcrypt(passwd, salt=None, method='des', magic='$1$'):
+	"""Encrypt a string according to rules in crypt(3)."""
+	if method.lower() == 'des':
+		return crypt(passwd, salt)
+	elif method.lower() == 'md5':
+		return passcrypt_md5(passwd, salt, magic)
+	elif method.lower() == 'clear':
+		return passwd
+
+#===============================================================================
+# check_passwd
+#
+# Checks username and Password against a given Unix Password file 
+# The default path is '/etc/passwd'
+#===============================================================================
+def check_passwd(name, passwd, pwfile='/etc/passwd'):
+	"""Validate given user, passwd pair against password database."""
+
+	if not pwfile or type(pwfile) == type(''):
+		getuser = lambda x, pwfile = pwfile: getpwnam(x, pwfile)[1]
+	else:
+		getuser = pwfile.get_passwd
+
+	try:
+		enc_passwd = getuser(name)
+	except (KeyError, IOError):
+		print "!!! EXCEPT"
+		return False
+	if not enc_passwd:
+		"!!! NOT ENC_PASSWD"
+		return False
+	elif len(enc_passwd) >= 3 and enc_passwd[:3] == '$1$':
+		salt = enc_passwd[3:enc_passwd.find('$', 3)]
+		return enc_passwd == passcrypt(passwd, salt, 'md5')
+	else:
+		return enc_passwd == passcrypt(passwd, enc_passwd[:2])
+
+def _to64(v, n):
+	DES_SALT = list('./0123456789' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz')
+	r = ''
+	while (n - 1 >= 0):
+		r = r + DES_SALT[v & 0x3F]
+		v = v >> 6
+		n = n - 1
+	return r
+
+#===============================================================================
+# passcrypt_md5
+# Encrypt a password via md5
+#===============================================================================
+def passcrypt_md5(passwd, salt=None, magic='$1$'):
+	if not salt:
+		pass
+	elif salt[:len(magic)] == magic:
+		# remove magic from salt if present
+		salt = salt[len(magic):]
+
+	# salt only goes up to first '$'
+	salt = salt.split('$')[0]
+	# limit length of salt to 8
+	salt = salt[:8]
+
+	ctx = md5_new(passwd)
+	ctx.update(magic)
+	ctx.update(salt)
+
+	ctx1 = md5_new(passwd)
+	ctx1.update(salt)
+	ctx1.update(passwd)
+
+	final = ctx1.digest()
+
+	for i in range(len(passwd), 0 , -16):
+		if i > 16:
+			ctx.update(final)
+		else:
+			ctx.update(final[:i])
+
+	i = len(passwd)
+	while i:
+		if i & 1:
+			ctx.update('\0')
+		else:
+			ctx.update(passwd[:1])
+		i = i >> 1
+	final = ctx.digest()
+
+	for i in range(1000):
+		ctx1 = md5_new()
+		if i & 1:
+			ctx1.update(passwd)
+		else:
+			ctx1.update(final)
+		if i % 3: ctx1.update(salt)
+		if i % 7: ctx1.update(passwd)
+		if i & 1:
+			ctx1.update(final)
+		else:
+			ctx1.update(passwd)
+		final = ctx1.digest()
+
+	rv = magic + salt + '$'
+	final = map(ord, final)
+	l = (final[0] << 16) + (final[6] << 8) + final[12]
+	rv = rv + _to64(l, 4)
+	l = (final[1] << 16) + (final[7] << 8) + final[13]
+	rv = rv + _to64(l, 4)
+	l = (final[2] << 16) + (final[8] << 8) + final[14]
+	rv = rv + _to64(l, 4)
+	l = (final[3] << 16) + (final[9] << 8) + final[15]
+	rv = rv + _to64(l, 4)
+	l = (final[4] << 16) + (final[10] << 8) + final[5]
+	rv = rv + _to64(l, 4)
+	l = final[11]
+	rv = rv + _to64(l, 2)
+
+	return rv
+
+global_session = None
+
+#===============================================================================
+# sessionstart
+# Actions to take place on Session start 
+#===============================================================================
+def sessionstart(reason, session):
+	global global_session
+	global_session = session
+
+
+def registerBonjourService(protocol, port):	
+	try:
+		from Plugins.Extensions.Bonjour.Bonjour import bonjour
+				
+		service = bonjour.buildService(protocol, port)
+		bonjour.registerService(service, True)
+		print "[WebInterface.registerBonjourService] Service for protocol '%s' with port '%i' registered!" %(protocol, port) 
+		return True
+		
+	except ImportError, e:
+		print "[WebInterface.registerBonjourService] %s" %e
+		return False
+
+def unregisterBonjourService(protocol):	
+	try:
+		from Plugins.Extensions.Bonjour.Bonjour import bonjour
+						
+		bonjour.unregisterService(protocol)
+		print "[WebInterface.unregisterBonjourService] Service for protocol '%s' unregistered!" %(protocol) 
+		return True
+		
+	except ImportError, e:
+		print "[WebInterface.unregisterBonjourService] %s" %e
+		return False
+	
+def checkBonjour():
+	if ( not config.plugins.Webinterface.http.enabled.value ) or ( not config.plugins.Webinterface.enabled.value ):
+		unregisterBonjourService('http')
+	if ( not config.plugins.Webinterface.https.enabled.value ) or ( not config.plugins.Webinterface.enabled.value ):
+		unregisterBonjourService('https')
+		
+#===============================================================================
+# networkstart
+# Actions to take place after Network is up (startup the Webserver)
+#===============================================================================
+def networkstart(reason, **kwargs):
+	if reason is True:
+		startWebserver(global_session)
+		checkBonjour()
+		
+	elif reason is False:
+		stopWebserver(global_session)
+		checkBonjour()
+
+def openconfig(session, **kwargs):
+	session.openWithCallback(configCB, WebIfConfigScreen)
+
+def configCB(result, session):
+	if result is True:
+		print "[WebIf] config changed"
+		restartWebserver(session)
+		checkBonjour()
+	else:
+		print "[WebIf] config not changed"
+
+def Plugins(**kwargs):
+	return [PluginDescriptor(where=[PluginDescriptor.WHERE_SESSIONSTART], fnc=sessionstart),
+			PluginDescriptor(where=[PluginDescriptor.WHERE_NETWORKCONFIG_READ], fnc=networkstart),
+			PluginDescriptor(name=_("Webinterface"), description=_("Configuration for the Webinterface"),
+							where=[PluginDescriptor.WHERE_PLUGINMENU], icon="plugin.png", fnc=openconfig)]
Index: ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web-data/IEFixes.htc
===================================================================
--- ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web-data/IEFixes.htc	(revision 14969)
+++ ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web-data/IEFixes.htc	(revision 14969)
@@ -0,0 +1,21 @@
+<PUBLIC:ATTACH EVENT="onmouseover" ONEVENT="DoHover()" />
+<PUBLIC:ATTACH EVENT="onmouseout"  ONEVENT="RestoreHover()" />
+<PUBLIC:ATTACH EVENT="onmousedown" ONEVENT="DoActive()" />
+<PUBLIC:ATTACH EVENT="onmouseup"   ONEVENT="RestoreActive()" />
+<SCRIPT LANGUAGE="JScript">
+function DoHover()
+  { element.className += ' hover';
+  }
+
+function DoActive()
+  { element.className += ' active';
+  }
+
+function RestoreHover()
+  { element.className = element.className.replace(/\bhover\b/,'');
+  }
+
+function RestoreActive()
+  { element.className = element.className.replace(/\bactive\b/,'');
+  }
+</SCRIPT>
Index: ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web-data/lib/curvycorners.js
===================================================================
--- ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web-data/lib/curvycorners.js	(revision 14969)
+++ ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web-data/lib/curvycorners.js	(revision 14969)
@@ -0,0 +1,1433 @@
+ /****************************************************************
+  *                                                              *
+  *  CurvyCorners                                                *
+  *  ------------                                                *
+  *                                                              *
+  *  This script generates rounded corners for your boxes.       *
+  *                                                              *
+  *  Version 2.0.5pre14                                          *
+  *  Copyright (c) 2009 Cameron Cooke                            *
+  *  Contributors: Tim Hutchison, CPK Smithies, Terry Rigel,     *
+  *                Simó Albert.                                  *
+  *                                                              *
+  *  Website: http://www.curvycorners.net                        *
+  *  SVN:     http://curvycorners.googlecode.com/                *
+  *  Email:   cameron@curvycorners.net                           *
+  *  Discuss: http://groups.google.com/group/curvycorners        *
+  *                                                              *
+  *  Please consult the SVN for a list of changes since the last *
+  *  revision.                                                   *
+  *                                                              *
+  *  This library is free software; you can redistribute         *
+  *  it and/or modify it under the terms of the GNU              *
+  *  Lesser General Public License as published by the           *
+  *  Free Software Foundation; either version 2.1 of the         *
+  *  License, or (at your option) any later version.             *
+  *                                                              *
+  *  This library is distributed in the hope that it will        *
+  *  be useful, but WITHOUT ANY WARRANTY; without even the       *
+  *  implied warranty of MERCHANTABILITY or FITNESS FOR A        *
+  *  PARTICULAR PURPOSE. See the GNU Lesser General Public       *
+  *  License for more details.                                   *
+  *                                                              *
+  *  You should have received a copy of the GNU Lesser           *
+  *  General Public License along with this library;             *
+  *  Inc., 59 Temple Place, Suite 330, Boston,                   *
+  *  MA 02111-1307 USA                                           *
+  *                                                              *
+  ****************************************************************/
+
+/*
+Version 2.x now autoMagically applies borders via CSS rules.
+Safari, Chrome and Mozilla support rounded borders via
+
+-webkit-border-radius, -moz-border-radius
+
+We let these browsers render their borders natively.
+Firefox for Windows renders non-antialiased
+borders so they look a bit ugly. Google's Chrome will render its "ugly"
+borders as well. So if we let FireFox, Safari, and Chrome render their
+borders natively, then we only have to support IE and Opera
+for rounded borders. Fortunately IE reads CSS properties
+that it doesn't understand (Opera, Firefox and Safari discard them);
+so for IE and Opera we find and apply -webkit-border-radius and friends.
+
+So to make curvycorners work with any major browser simply add the following
+CSS declarations and it should be good to go...
+
+.round {
+  -webkit-border-radius: 3ex;
+  -moz-border-radius: 3ex;
+}
+
+NB at present you must (for Opera's sake) include these styles in
+the page itself.
+*/
+
+function browserdetect() {
+  var agent = navigator.userAgent.toLowerCase();
+  this.isIE = agent.indexOf("msie") > -1;
+  if (this.isIE) {
+    this.ieVer = /msie\s(\d\.\d)/.exec(agent)[1];
+    this.quirksMode = !document.compatMode || document.compatMode.indexOf("BackCompat") > -1;
+    this.get_style = function(obj, prop) {
+      if (!(prop in obj.currentStyle)) return "";
+      var matches = /^([\d.]+)(\w*)/.exec(obj.currentStyle[prop]);
+      if (!matches) return obj.currentStyle[prop];
+      if (matches[1] == 0) return '0';
+      // now convert to pixels if necessary
+      if (matches[2] && matches[2] !== 'px') {
+        var style = obj.style.left;
+        var rtStyle = obj.runtimeStyle.left;
+        obj.runtimeStyle.left = obj.currentStyle.left;
+        obj.style.left = matches[1] + matches[2];
+        matches[0] = obj.style.pixelLeft;
+        obj.style.left = style;
+        obj.runtimeStyle.left = rtStyle;
+      }
+      return matches[0];
+    };
+  }
+  else {
+    this.ieVer = this.quirksMode = 0;
+    this.isMoz     = agent.indexOf('firefox') !== -1 || ('style' in document.childNodes[1] && 'MozBorderRadius' in document.childNodes[1].style);
+    this.isSafari  = agent.indexOf('safari') != -1;
+    this.isOp      = 'opera' in window;
+    this.isWebKit  = agent.indexOf('webkit') != -1;
+    this.get_style = function(obj, prop) {
+      prop = prop.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase();
+      return document.defaultView.getComputedStyle(obj, '').getPropertyValue(prop);
+    };
+  }
+}
+var curvyBrowser = new browserdetect;
+
+/* Force caching of bg images in IE6 */
+if (curvyBrowser.isIE) {
+  try {
+    document.execCommand("BackgroundImageCache", false, true);
+  }
+  catch(e) {};
+}
+
+// object that parses border-radius properties for a box
+
+function curvyCnrSpec(selText) {
+  this.selectorText = selText;
+  this.tlR = this.trR = this.blR = this.brR = 0;
+  this.tlu = this.tru = this.blu = this.bru = "";
+  this.antiAlias = true; // default true
+}
+curvyCnrSpec.prototype.setcorner = function(tb, lr, radius, unit) {
+  if (!tb) { // no corner specified
+    this.tlR = this.trR = this.blR = this.brR = parseInt(radius);
+    this.tlu = this.tru = this.blu = this.bru = unit;
+  }
+  else { // corner specified
+    propname = tb.charAt(0) + lr.charAt(0);
+    this[propname + 'R'] = parseInt(radius);
+    this[propname + 'u'] = unit;
+  }
+}
+/*
+  get(propstring)
+  where propstring is:
+  - 'tR' or 'bR' : returns top or bottom radius.
+  - 'tlR', 'trR', 'blR' or 'brR' : returns top/bottom left/right radius.
+  - 'tlu', 'tru', 'blr' or 'bru' : returns t/b l/r unit (px, em...)
+  - 'tRu' or 'bRu' : returns top/bottom radius+unit
+  - 'tlRu', 'trRu', 'blRu', 'brRu' : returns t/b l/r radius+unit
+*/
+curvyCnrSpec.prototype.get = function(prop) {
+  if (/^(t|b)(l|r)(R|u)$/.test(prop)) return this[prop];
+  if (/^(t|b)(l|r)Ru$/.test(prop)) {
+    var pname = prop.charAt(0) + prop.charAt(1);
+    return this[pname + 'R'] + this[pname + 'u'];
+  }
+  if (/^(t|b)Ru?$/.test(prop)) {
+    var tb = prop.charAt(0);
+    tb += this[tb + 'lR'] > this[tb + 'rR'] ? 'l' : 'r';
+    var retval = this[tb + 'R'];
+    if (prop.length === 3 && prop.charAt(2) === 'u')
+      retval += this[tb = 'u'];
+    return retval;
+  }
+  throw new Error('Don\'t recognize property ' + prop);
+}
+curvyCnrSpec.prototype.radiusdiff = function(tb) {
+  if (tb !== 't' && tb !== 'b') throw new Error("Param must be 't' or 'b'");
+  return Math.abs(this[tb + 'lR'] - this[tb + 'rR']);
+}
+curvyCnrSpec.prototype.setfrom = function(obj) {
+  this.tlu = this.tru = this.blu = this.bru = 'px'; // default to px
+  if ('tl' in obj) this.tlR = obj.tl.radius;
+  if ('tr' in obj) this.trR = obj.tr.radius;
+  if ('bl' in obj) this.blR = obj.bl.radius;
+  if ('br' in obj) this.brR = obj.br.radius;
+  if ('antiAlias' in obj) this.antiAlias = obj.antiAlias;
+};
+curvyCnrSpec.prototype.cloneOn = function(box) { // not needed by IE
+  var props = ['tl', 'tr', 'bl', 'br'];
+  var converted = 0;
+  var i, propu;
+
+  for (i in props) if (!isNaN(i)) {
+    propu = this[props[i] + 'u'];
+    if (propu !== '' && propu !== 'px') {
+      converted = new curvyCnrSpec;
+      break;
+    }
+  }
+  if (!converted)
+    converted = this; // no need to clone
+  else {
+    var propi, propR, save = curvyBrowser.get_style(box, 'left');
+    for (i in props) if (!isNaN(i)) {
+      propi = props[i];
+      propu = this[propi + 'u'];
+      propR = this[propi + 'R'];
+      if (propu !== 'px') {
+        var save = box.style.left;
+        box.style.left = propR + propu;
+        propR = box.style.pixelLeft;
+        box.style.left = save;
+      }
+      converted[propi + 'R'] = propR;
+      converted[propi + 'u'] = 'px';
+    }
+    box.style.left = save;
+  }
+  return converted;
+}
+curvyCnrSpec.prototype.radiusSum = function(tb) {
+  if (tb !== 't' && tb !== 'b') throw new Error("Param must be 't' or 'b'");
+  return this[tb + 'lR'] + this[tb + 'rR'];
+}
+curvyCnrSpec.prototype.radiusCount = function(tb) {
+  var count = 0;
+  if (this[tb + 'lR']) ++count;
+  if (this[tb + 'rR']) ++count;
+  return count;
+}
+curvyCnrSpec.prototype.cornerNames = function() {
+  var ret = [];
+  if (this.tlR) ret.push('tl');
+  if (this.trR) ret.push('tr');
+  if (this.blR) ret.push('bl');
+  if (this.brR) ret.push('br');
+  return ret;
+}
+
+/*
+  Object that parses Opera CSS
+*/
+function operasheet(sheetnumber) {
+  var txt = document.styleSheets.item(sheetnumber).ownerNode.text;
+  txt = txt.replace(/\/\*(\n|\r|.)*?\*\//g, ''); // strip comments
+  // this pattern extracts all border-radius-containing rulesets
+  // matches will be:
+  // [0] = the whole lot
+  // [1] = the selector text
+  // [2] = all the rule text between braces
+  // [3] = top/bottom and left/right parts if present (only if webkit/CSS3)
+  // [4] = top|bottom
+  // [5] = left|right
+  // .. but 3..5 are useless as they're only the first match.
+  var pat = new RegExp("^\\s*([\\w.#][-\\w.#, ]+)[\\n\\s]*\\{([^}]+border-((top|bottom)-(left|right)-)?radius[^}]*)\\}", "mg");
+  var matches;
+  this.rules = [];
+  while ((matches = pat.exec(txt)) !== null) {
+
+    var pat2 = new RegExp("(..)border-((top|bottom)-(left|right)-)?radius:\\s*([\\d.]+)(in|em|px|ex|pt)", "g");
+    var submatches, cornerspec = new curvyCnrSpec(matches[1]);
+    while ((submatches = pat2.exec(matches[2])) !== null)
+      if (submatches[1] !== "z-")
+        cornerspec.setcorner(submatches[3], submatches[4], submatches[5], submatches[6]);
+    this.rules.push(cornerspec);
+  }
+}
+// static class function to determine if the sheet is worth parsing
+operasheet.contains_border_radius = function(sheetnumber) {
+  return /border-((top|bottom)-(left|right)-)?radius/.test(document.styleSheets.item(sheetnumber).ownerNode.text);
+}
+
+/*
+Usage:
+
+  curvyCorners(settingsObj, "selectorStr");
+  curvyCorners(settingsObj, domObj1[, domObj2[, domObj3[, . . . [, domObjN]]]]);
+  selectorStr::= "<complexSelector>[, <complexSelector>]..."
+  complexSelector::= <selector>[ <selector]
+  selector::= "[<elementname>].classname" | "#id"
+*/
+
+function curvyCorners() {
+  var i, j, boxCol, settings, startIndex;
+  // Check parameters
+  if (typeof arguments[0] !== "object") throw curvyCorners.newError("First parameter of curvyCorners() must be an object.");
+  if (arguments[0] instanceof curvyCnrSpec) {
+    settings = arguments[0];
+    if (!settings.selectorText && typeof arguments[1] === 'string')
+      settings.selectorText = arguments[1];
+  }
+  else {
+    if (typeof arguments[1] !== "object" && typeof arguments[1] !== "string") throw curvyCorners.newError("Second parameter of curvyCorners() must be an object or a class name.");
+    j = arguments[1];
+    if (typeof j !== 'string') j = '';
+    if (j !== '' && j.charAt(0) !== '.' && 'autoPad' in arguments[0]) j = '.' + j; // for compatibility, prefix with dot
+    settings = new curvyCnrSpec(j);
+    settings.setfrom(arguments[0]);
+  }
+
+  // Get object(s)
+  if (settings.selectorText) {
+    startIndex = 0;
+    var args = settings.selectorText.replace(/\s+$/,'').split(/,\s*/); // handle comma-separated selector list
+    boxCol = new Array;
+
+    // converts div#mybox to #mybox
+    function idof(str) {
+      var ret = str.split('#');
+      return (ret.length === 2 ? "#" : "") + ret.pop();
+    }
+
+    for (i = 0; i < args.length; ++i) {
+      var arg = idof(args[i]);
+      var argbits = arg.split(' ');
+      switch (arg.charAt(0)) {
+        case '#' : // id
+          j = argbits.length === 1 ? arg : argbits[0];
+          j = document.getElementById(j.substr(1));
+          if (j === null)
+            curvyCorners.alert("No object with ID " + arg + " exists yet.\nCall curvyCorners(settings, obj) when it is created.");
+          else if (argbits.length === 1)
+            boxCol.push(j);
+          else
+            boxCol = boxCol.concat(curvyCorners.getElementsByClass(argbits[1], j));
+        break;
+        default :
+          if (argbits.length === 1)
+            boxCol = boxCol.concat(curvyCorners.getElementsByClass(arg));
+          else {
+            var encloser = curvyCorners.getElementsByClass(argbits[0]);
+            for (j = 0; j < encloser.length; ++j) {
+              boxCol = boxCol.concat(curvyCorners.getElementsByClass(argbits[1], encloser[j]));
+            }
+          }
+        //break;
+      }
+    }
+  }
+  else {
+    // Get objects
+    startIndex = 1;
+    boxCol = arguments;
+  }
+
+  // Loop through each argument
+  for (i = startIndex, j = boxCol.length; i < j; ++i) {
+    if (boxCol[i] && (!('IEborderRadius' in boxCol[i].style) || boxCol[i].style.IEborderRadius != 'set')) {
+      if (boxCol[i].className && boxCol[i].className.indexOf('curvyRedraw') !== -1) {
+        if (typeof curvyCorners.redrawList === 'undefined') curvyCorners.redrawList = new Array;
+        curvyCorners.redrawList.push({
+          node : boxCol[i],
+          spec : settings,
+          copy : boxCol[i].cloneNode(false)
+        });
+      }
+      boxCol[i].style.IEborderRadius = 'set';
+      var obj = new curvyObject(settings, boxCol[i]);
+      obj.applyCorners();
+    }
+  }
+}
+curvyCorners.prototype.applyCornersToAll = function () { // now redundant
+  throw curvyCorners.newError('This function is now redundant. Just call curvyCorners(). See documentation.');
+};
+
+curvyCorners.redraw = function() {
+  if (!curvyBrowser.isOp && !curvyBrowser.isIE) return;
+  if (!curvyCorners.redrawList) throw curvyCorners.newError('curvyCorners.redraw() has nothing to redraw.');
+  var old_block_value = curvyCorners.block_redraw;
+  curvyCorners.block_redraw = true;
+  for (var i in curvyCorners.redrawList) {
+    if (isNaN(i)) continue; // in case of added prototype methods
+    var o = curvyCorners.redrawList[i];
+    if (!o.node.clientWidth) continue; // don't resize hidden boxes
+    var newchild = o.copy.cloneNode(false);
+    for (var contents = o.node.firstChild; contents != null; contents = contents.nextSibling)
+      if (contents.className === 'autoPadDiv') break;
+    if (!contents) {
+      curvyCorners.alert('Couldn\'t find autoPad DIV');
+      break;
+    }
+    o.node.parentNode.replaceChild(newchild, o.node);
+    // remove script elements, if any
+    var scripts = contents.getElementsByTagName('script');
+    for (var j = scripts.length - 1; j >= 0; --j)
+      scripts[j].parentNode.removeChild(scripts[j]);
+    while (contents.firstChild) newchild.appendChild(contents.removeChild(contents.firstChild));
+    o = new curvyObject(o.spec, o.node = newchild);
+    o.applyCorners();
+  }
+  curvyCorners.block_redraw = old_block_value;
+}
+curvyCorners.adjust = function(obj, prop, newval) {
+  if (curvyBrowser.isOp || curvyBrowser.isIE) {
+    if (!curvyCorners.redrawList) throw curvyCorners.newError('curvyCorners.adjust() has nothing to adjust.');
+    var i, j = curvyCorners.redrawList.length;
+    for (i = 0; i < j; ++i) if (curvyCorners.redrawList[i].node === obj) break;
+    if (i === j) throw curvyCorners.newError('Object not redrawable');
+    obj = curvyCorners.redrawList[i].copy;
+  }
+  if (prop.indexOf('.') === -1)
+    obj[prop] = newval;
+  else eval('obj.' + prop + "='" + newval + "'");
+}
+curvyCorners.handleWinResize = function() {
+  if (!curvyCorners.block_redraw) curvyCorners.redraw();
+}
+curvyCorners.setWinResize = function(onoff) {
+  curvyCorners.block_redraw = !onoff;
+}
+curvyCorners.newError = function(errorMessage) {
+  return new Error("curvyCorners Error:\n" + errorMessage)
+}
+curvyCorners.alert = function(errorMessage) {
+  if (typeof curvyCornersVerbose === 'undefined' || curvyCornersVerbose) alert(errorMessage);
+}
+
+// curvyCorners object (can be called directly)
+
+function curvyObject() {
+  var boxDisp;
+  this.box              = arguments[1];
+  this.settings         = arguments[0];
+  this.topContainer = this.bottomContainer = this.shell = boxDisp = null;
+  var boxWidth = this.box.clientWidth; // browser-independent IE-emulation (NB includes padding)
+
+  if (('canHaveChildren' in this.box && !this.box.canHaveChildren) || this.box.tagName === 'TABLE')
+    throw new Error(this.errmsg("You cannot apply corners to " + this.box.tagName + " elements.", "Error"));
+  if (!boxWidth && curvyBrowser.isIE) {
+    this.box.style.zoom = 1; // can force IE to calculate width
+    boxWidth = this.box.clientWidth;
+  }
+
+  // try to handle attempts to style inline elements
+
+  if (!boxWidth && curvyBrowser.get_style(this.box, 'display') === 'inline') {
+    this.box.style.display = 'inline-block';
+    curvyCorners.alert(this.errmsg("Converting inline element to inline-block", "warning"));
+    boxWidth = this.box.clientWidth;
+  }
+
+  // if still no clientWidth, maybe the box or a parent has 'display:none'.
+
+  if (!boxWidth) {
+    if (!this.box.parentNode) throw this.newError("box has no parent!"); // unlikely...
+    for (boxDisp = this.box; ; boxDisp = boxDisp.parentNode) {
+      if (!boxDisp || boxDisp.tagName === 'BODY') { // we've hit the buffers
+        this.applyCorners = function() {} // make the error benign
+        curvyCorners.alert(this.errmsg("zero-width box with no accountable parent", "warning"));
+        return;
+      }
+      if (curvyBrowser.get_style(boxDisp, 'display') === 'none') break;
+    }
+    // here, we've found the box whose display is set to 'none'.
+    var boxDispSave = boxDisp.style.display;
+    boxDisp.style.display = 'block'; // display in order to get browser to calculate clientWidth
+    boxWidth = this.box.clientWidth;
+  }
+
+  // all attempts have failed
+
+  if (!boxWidth) {
+    curvyCorners.alert(this.errmsg("zero-width box, cannot display", "error"));
+    this.applyCorners = function() {} // make the error harmless
+    return;
+  }
+  if (arguments[0] instanceof curvyCnrSpec)
+    this.spec = arguments[0].cloneOn(this.box); // convert non-pixel units
+  else {
+    this.spec = new curvyCnrSpec('');
+    this.spec.setfrom(this.settings); // no need for unit conversion, use settings param. directly
+  }
+
+  // Get box formatting details
+  var borderWidth     = curvyBrowser.get_style(this.box, "borderTopWidth");
+  var borderWidthB    = curvyBrowser.get_style(this.box, "borderBottomWidth");
+  var borderWidthL    = curvyBrowser.get_style(this.box, "borderLeftWidth");
+  var borderWidthR    = curvyBrowser.get_style(this.box, "borderRightWidth");
+  var borderColour    = curvyBrowser.get_style(this.box, "borderTopColor");
+  var borderColourB   = curvyBrowser.get_style(this.box, "borderBottomColor");
+  var borderColourL   = curvyBrowser.get_style(this.box, "borderLeftColor");
+  var borderColourR   = curvyBrowser.get_style(this.box, "borderRightColor");
+  var borderStyle     = curvyBrowser.get_style(this.box, "borderTopStyle");
+  var borderStyleB    = curvyBrowser.get_style(this.box, "borderBottomStyle");
+  var borderStyleL    = curvyBrowser.get_style(this.box, "borderLeftStyle");
+  var borderStyleR    = curvyBrowser.get_style(this.box, "borderRightStyle");
+
+  var boxColour       = curvyBrowser.get_style(this.box, "backgroundColor");
+  var backgroundImage = curvyBrowser.get_style(this.box, "backgroundImage");
+  var backgroundRepeat= curvyBrowser.get_style(this.box, "backgroundRepeat");
+  if (this.box.currentStyle && this.box.currentStyle.backgroundPositionX) {
+  var backgroundPosX  = curvyBrowser.get_style(this.box, "backgroundPositionX");
+  var backgroundPosY  = curvyBrowser.get_style(this.box, "backgroundPositionY");
+  }
+  else {
+    var backgroundPosX = curvyBrowser.get_style(this.box, 'backgroundPosition');
+    backgroundPosX = backgroundPosX.split(' ');
+    var backgroundPosY = backgroundPosX[1];
+    backgroundPosX = backgroundPosX[0];
+  }
+  var boxPosition     = curvyBrowser.get_style(this.box, "position");
+  var topPadding      = curvyBrowser.get_style(this.box, "paddingTop");
+  var bottomPadding   = curvyBrowser.get_style(this.box, "paddingBottom");
+  var leftPadding     = curvyBrowser.get_style(this.box, "paddingLeft");
+  var rightPadding    = curvyBrowser.get_style(this.box, "paddingRight");
+  var border          = curvyBrowser.get_style(this.box, "border");
+  var filter = curvyBrowser.ieVer > 7 ? curvyBrowser.get_style(this.box, 'filter') : null; // IE8 bug fix
+
+  var topMaxRadius    = this.spec.get('tR');
+  var botMaxRadius    = this.spec.get('bR');
+  var styleToNPx = function(val) {
+    if (typeof val === 'number') return val;
+    if (typeof val !== 'string') throw new Error('unexpected styleToNPx type ' + typeof val);
+    var matches = /^[-\d.]([a-z]+)$/.exec(val);
+    if (matches && matches[1] != 'px') throw new Error('Unexpected unit ' + matches[1]);
+    if (isNaN(val = parseInt(val))) val = 0;
+    return val;
+  }
+  var min0Px = function(val) {
+    return val <= 0 ? "0" : val + "px";
+  }
+
+  // Set formatting properties
+  try {
+    this.borderWidth     = styleToNPx(borderWidth);
+    this.borderWidthB    = styleToNPx(borderWidthB);
+    this.borderWidthL    = styleToNPx(borderWidthL);
+    this.borderWidthR    = styleToNPx(borderWidthR);
+    this.boxColour       = curvyObject.format_colour(boxColour);
+    this.topPadding      = styleToNPx(topPadding);
+    this.bottomPadding   = styleToNPx(bottomPadding);
+    this.leftPadding     = styleToNPx(leftPadding);
+    this.rightPadding    = styleToNPx(rightPadding);
+    this.boxWidth        = boxWidth;
+    this.boxHeight       = this.box.clientHeight;
+    this.borderColour    = curvyObject.format_colour(borderColour);
+    this.borderColourB   = curvyObject.format_colour(borderColourB);
+    this.borderColourL   = curvyObject.format_colour(borderColourL);
+    this.borderColourR   = curvyObject.format_colour(borderColourR);
+    this.borderString    = this.borderWidth + "px" + " " + borderStyle + " " + this.borderColour;
+    this.borderStringB   = this.borderWidthB + "px" + " " + borderStyleB + " " + this.borderColourB;
+    this.borderStringL   = this.borderWidthL + "px" + " " + borderStyleL + " " + this.borderColourL;
+    this.borderStringR   = this.borderWidthR + "px" + " " + borderStyleR + " " + this.borderColourR;
+    this.backgroundImage = ((backgroundImage != "none")? backgroundImage : "");
+    this.backgroundRepeat= backgroundRepeat;
+  }
+  catch(e) {
+    throw this.newError(e.message);
+  }
+  var clientHeight = this.boxHeight;
+  var clientWidth = boxWidth; // save it as it gets trampled on later
+  if (curvyBrowser.isOp) {
+    backgroundPosX = styleToNPx(backgroundPosX);
+    backgroundPosY = styleToNPx(backgroundPosY);
+    if (backgroundPosX) {
+      var t = clientWidth + this.borderWidthL + this.borderWidthR;
+      if (backgroundPosX > t) backgroundPosX = t;
+      backgroundPosX = (t / backgroundPosX * 100) + '%'; // convert to percentage
+    }
+    if (backgroundPosY) {
+      var t = clientHeight + this.borderWidth + this.borderWidthB;
+      if (backgroundPosY > t) backgroundPosY = t;
+      backgroundPosY = (t / backgroundPosY * 100) + '%'; // convert to percentage
+    }
+  }
+  if (curvyBrowser.quirksMode) {
+  }
+  else {
+    this.boxWidth -= this.leftPadding + this.rightPadding;
+    this.boxHeight -= this.topPadding + this.bottomPadding;
+  }
+
+  // Create content container
+  this.contentContainer = document.createElement("div");
+  if (filter) this.contentContainer.style.filter = filter; // IE8 bug fix
+  while (this.box.firstChild) this.contentContainer.appendChild(this.box.removeChild(this.box.firstChild));
+
+  if (boxPosition != "absolute") this.box.style.position = "relative";
+  this.box.style.padding = '0';
+  this.box.style.border = this.box.style.backgroundImage = 'none';
+  this.box.style.backgroundColor = 'transparent';
+
+  this.box.style.width   = (clientWidth + this.borderWidthL + this.borderWidthR) + 'px';
+  this.box.style.height  = (clientHeight + this.borderWidth + this.borderWidthB) + 'px';
+
+  // Ok we add an inner div to actually put things into this will allow us to keep the height
+
+  var newMainContainer = document.createElement("div");
+  newMainContainer.style.position = "absolute";
+  if (filter) newMainContainer.style.filter = filter; // IE8 bug fix
+  if (curvyBrowser.quirksMode) {
+    newMainContainer.style.width  = (clientWidth + this.borderWidthL + this.borderWidthR) + 'px';
+  } else {
+    newMainContainer.style.width  = clientWidth + 'px';
+  }
+  newMainContainer.style.height = min0Px(clientHeight + this.borderWidth + this.borderWidthB - topMaxRadius - botMaxRadius);
+  newMainContainer.style.padding  = "0";
+  newMainContainer.style.top    = topMaxRadius + "px";
+  newMainContainer.style.left   = "0";
+  if (this.borderWidthL)
+    newMainContainer.style.borderLeft = this.borderStringL;
+  if (this.borderWidth && !topMaxRadius)
+    newMainContainer.style.borderTop = this.borderString;
+  if (this.borderWidthR)
+    newMainContainer.style.borderRight = this.borderStringR;
+  if (this.borderWidthB && !botMaxRadius)
+    newMainContainer.style.borderBottom = this.borderStringB;
+  newMainContainer.style.backgroundColor    = boxColour;
+  newMainContainer.style.backgroundImage    = this.backgroundImage;
+  newMainContainer.style.backgroundRepeat   = this.backgroundRepeat;
+  newMainContainer.style.direction = 'ltr';
+  this.shell = this.box.appendChild(newMainContainer);
+
+  boxWidth = curvyBrowser.get_style(this.shell, "width");
+  if (boxWidth === "" || boxWidth === "auto" || boxWidth.indexOf("%") !== -1) throw this.newError('Shell width is ' + boxWidth);
+  this.boxWidth = (boxWidth != "" && boxWidth != "auto" && boxWidth.indexOf("%") == -1) ? parseInt(boxWidth) : this.shell.clientWidth;
+
+  /*
+    This method creates the corners and
+    applies them to the div element.
+  */
+  this.applyCorners = function() {
+    /*
+      Set up background offsets. This may need to be delayed until
+      the background image is loaded.
+    */
+    this.backgroundPosX = this.backgroundPosY = 0;
+    if (this.backgroundObject) {
+      var bgOffset = function(style, imglen, boxlen) {
+        if (style === 0) return 0;
+        var retval;
+        if (style === 'right' || style === 'bottom') return boxlen - imglen;
+        if (style === 'center') return (boxlen - imglen) / 2;
+        if (style.indexOf('%') > 0) return (boxlen - imglen) * 100 / parseInt(style);
+        return styleToNPx(style);
+      }
+      this.backgroundPosX  = bgOffset(backgroundPosX, this.backgroundObject.width, clientWidth);
+      this.backgroundPosY  = bgOffset(backgroundPosY, this.backgroundObject.height, clientHeight);
+    }
+    else if (this.backgroundImage) {
+      this.backgroundPosX = styleToNPx(backgroundPosX);
+      this.backgroundPosY = styleToNPx(backgroundPosY);
+    }
+    /*
+      Create top and bottom containers.
+      These will be used as a parent for the corners and bars.
+    */
+    // Build top bar only if a top corner is to be drawn
+    if (topMaxRadius) {
+      newMainContainer = document.createElement("div");
+      newMainContainer.style.width = this.boxWidth + "px";
+      newMainContainer.style.fontSize = "1px";
+      newMainContainer.style.overflow = "hidden";
+      newMainContainer.style.position = "absolute";
+      newMainContainer.style.paddingLeft  = this.borderWidth + "px";
+      newMainContainer.style.paddingRight = this.borderWidth + "px";
+      newMainContainer.style.height = topMaxRadius + "px";
+      newMainContainer.style.top    = -topMaxRadius + "px";
+      newMainContainer.style.left   = -this.borderWidthL + "px";
+      this.topContainer = this.shell.appendChild(newMainContainer);
+    }
+    // Build bottom bar only if a bottom corner is to be drawn
+    if (botMaxRadius) {
+      var newMainContainer = document.createElement("div");
+      newMainContainer.style.width = this.boxWidth + "px";
+      newMainContainer.style.fontSize = "1px";
+      newMainContainer.style.overflow = "hidden";
+      newMainContainer.style.position = "absolute";
+      newMainContainer.style.paddingLeft  = this.borderWidthB + "px";
+      newMainContainer.style.paddingRight = this.borderWidthB + "px";
+      newMainContainer.style.height   =  botMaxRadius + "px";
+      newMainContainer.style.bottom   = -botMaxRadius + "px";
+      newMainContainer.style.left     = -this.borderWidthL + "px";
+      this.bottomContainer = this.shell.appendChild(newMainContainer);
+    }
+
+    var corners = this.spec.cornerNames();  // array of available corners
+
+    /*
+    Loop for each corner
+    */
+    for (var i in corners) if (!isNaN(i)) {
+      // Get current corner type from array
+      var cc = corners[i];
+      var specRadius = this.spec[cc + 'R'];
+      // Has the user requested the currentCorner be round?
+      // Code to apply correct color to top or bottom
+      var bwidth, bcolor, borderRadius, borderWidthTB;
+      if (cc == "tr" || cc == "tl") {
+        bwidth = this.borderWidth;
+        bcolor = this.borderColour;
+        borderWidthTB = this.borderWidth;
+      } else {
+        bwidth = this.borderWidthB;
+        bcolor = this.borderColourB;
+        borderWidthTB = this.borderWidthB;
+      }
+      borderRadius = specRadius - borderWidthTB;
+      var newCorner = document.createElement("div");
+      newCorner.style.height = this.spec.get(cc + 'Ru');
+      newCorner.style.width  = this.spec.get(cc + 'Ru');
+      newCorner.style.position = "absolute";
+      newCorner.style.fontSize = "1px";
+      newCorner.style.overflow = "hidden";
+      // THE FOLLOWING BLOCK OF CODE CREATES A ROUNDED CORNER
+      // ---------------------------------------------------- TOP
+      var intx, inty, outsideColour;
+      var trans = filter ? parseInt(/alpha\(opacity.(\d+)\)/.exec(filter)[1]) : 100; // IE8 bug fix
+      // Cycle the x-axis
+      for (intx = 0; intx < specRadius; ++intx) {
+        // Calculate the value of y1 which identifies the pixels inside the border
+        var y1 = (intx + 1 >= borderRadius) ? -1 : Math.floor(Math.sqrt(Math.pow(borderRadius, 2) - Math.pow(intx + 1, 2))) - 1;
+        // Calculate y2 and y3 only if there is a border defined
+        if (borderRadius != specRadius) {
+          var y2 = (intx >= borderRadius) ? -1 : Math.ceil(Math.sqrt(Math.pow(borderRadius, 2) - Math.pow(intx, 2)));
+          var y3 = (intx + 1 >= specRadius) ? -1 : Math.floor(Math.sqrt(Math.pow(specRadius, 2) - Math.pow((intx+1), 2))) - 1;
+        }
+        // Calculate y4
+        var y4 = (intx >= specRadius) ? -1 : Math.ceil(Math.sqrt(Math.pow(specRadius, 2) - Math.pow(intx, 2)));
+        // Draw bar on inside of the border with foreground colour
+        if (y1 > -1) this.drawPixel(intx, 0, this.boxColour, trans, (y1 + 1), newCorner, true, specRadius);
+        // Draw border/foreground antialiased pixels and border only if there is a border defined
+        if (borderRadius != specRadius) {
+          // Cycle the y-axis
+          if (this.spec.antiAlias) {
+            for (inty = y1 + 1; inty < y2; ++inty) {
+              // For each of the pixels that need anti aliasing between the foreground and border colour draw single pixel divs
+              if (this.backgroundImage != "") {
+                var borderFract = curvyObject.pixelFraction(intx, inty, borderRadius) * 100;
+                this.drawPixel(intx, inty, bcolor, trans, 1, newCorner, borderFract >= 30, specRadius);
+              }
+              else if (this.boxColour !== 'transparent') {
+                var pixelcolour = curvyObject.BlendColour(this.boxColour, bcolor, curvyObject.pixelFraction(intx, inty, borderRadius));
+                this.drawPixel(intx, inty, pixelcolour, trans, 1, newCorner, false, specRadius);
+              }
+              else this.drawPixel(intx, inty, bcolor, trans >> 1, 1, newCorner, false, specRadius);
+            }
+            // Draw bar for the border
+            if (y3 >= y2) {
+              if (y2 == -1) y2 = 0;
+              this.drawPixel(intx, y2, bcolor, trans, (y3 - y2 + 1), newCorner, false, 0);
+            }
+            outsideColour = bcolor;  // Set the colour for the outside AA curve
+            inty = y3;               // start_pos - 1 for y-axis AA pixels
+          }
+          else { // no antiAlias
+            if (y3 > y1) { // NB condition was >=, changed to avoid zero-height divs
+              this.drawPixel(intx, (y1 + 1), bcolor, trans, (y3 - y1), newCorner, false, 0);
+            }
+          }
+        }
+        else {
+          outsideColour = this.boxColour;  // Set the colour for the outside curve
+          inty = y1;               // start_pos - 1 for y-axis AA pixels
+        }
+        // Draw aa pixels?
+        if (this.spec.antiAlias) {
+          // Cycle the y-axis and draw the anti aliased pixels on the outside of the curve
+          while (++inty < y4) {
+            // For each of the pixels that need anti aliasing between the foreground/border colour & background draw single pixel divs
+            this.drawPixel(intx, inty, outsideColour, (curvyObject.pixelFraction(intx, inty , specRadius) * trans), 1, newCorner, borderWidthTB <= 0, specRadius);
+          }
+        }
+      }
+      // END OF CORNER CREATION
+      // ---------------------------------------------------- END
+
+      /*
+      Now we have a new corner we need to reposition all the pixels unless
+      the current corner is the bottom right.
+      */
+      // Loop through all children (pixel bars)
+      for (var t = 0, k = newCorner.childNodes.length; t < k; ++t) {
+        // Get current pixel bar
+        var pixelBar = newCorner.childNodes[t];
+        // Get current top and left properties
+        var pixelBarTop    = parseInt(pixelBar.style.top);
+        var pixelBarLeft   = parseInt(pixelBar.style.left);
+        var pixelBarHeight = parseInt(pixelBar.style.height);
+        // Reposition pixels
+        if (cc == "tl" || cc == "bl") {
+          pixelBar.style.left = (specRadius - pixelBarLeft - 1) + "px"; // Left
+        }
+        if (cc == "tr" || cc == "tl"){
+          pixelBar.style.top =  (specRadius - pixelBarHeight - pixelBarTop) + "px"; // Top
+        }
+        pixelBar.style.backgroundRepeat = this.backgroundRepeat;
+
+        if (this.backgroundImage) switch(cc) {
+          case "tr":
+            pixelBar.style.backgroundPosition = (this.backgroundPosX - this.borderWidthL + specRadius - clientWidth - pixelBarLeft) + "px " + (this.backgroundPosY + pixelBarHeight + pixelBarTop + this.borderWidth - specRadius) + "px";
+          break;
+          case "tl":
+            pixelBar.style.backgroundPosition = (this.backgroundPosX - specRadius + pixelBarLeft + 1 + this.borderWidthL) + "px " + (this.backgroundPosY - specRadius + pixelBarHeight + pixelBarTop + this.borderWidth) + "px";
+          break;
+          case "bl":
+            pixelBar.style.backgroundPosition = (this.backgroundPosX - specRadius + pixelBarLeft + 1 + this.borderWidthL) + "px " + (this.backgroundPosY - clientHeight - this.borderWidth + (curvyBrowser.quirksMode ? pixelBarTop : -pixelBarTop) + specRadius) + "px";
+          break;
+          case "br":
+            if (curvyBrowser.quirksMode) {
+              pixelBar.style.backgroundPosition = (this.backgroundPosX - this.borderWidthL - clientWidth + specRadius - pixelBarLeft) + "px " + (this.backgroundPosY - clientHeight - this.borderWidth + pixelBarTop + specRadius) + "px";
+            } else {
+              pixelBar.style.backgroundPosition = (this.backgroundPosX - this.borderWidthL - clientWidth + specRadius - pixelBarLeft) + "px " + (this.backgroundPosY - clientHeight - this.borderWidth + specRadius - pixelBarTop) + "px";
+            }
+          //break;
+        }
+      }
+
+      // Position the container
+      switch (cc) {
+        case "tl":
+          newCorner.style.top = newCorner.style.left = "0";
+          this.topContainer.appendChild(newCorner);
+        break;
+        case "tr":
+          newCorner.style.top = newCorner.style.right = "0";
+          this.topContainer.appendChild(newCorner);
+        break;
+        case "bl":
+          newCorner.style.bottom = newCorner.style.left = "0";
+          this.bottomContainer.appendChild(newCorner);
+        break;
+        case "br":
+          newCorner.style.bottom = newCorner.style.right = "0";
+          this.bottomContainer.appendChild(newCorner);
+        //break;
+      }
+    }
+
+    /*
+      The last thing to do is draw the rest of the filler DIVs.
+    */
+
+    // Find out which corner has the bigger radius and get the difference amount
+    var radiusDiff = {
+      t : this.spec.radiusdiff('t'),
+      b : this.spec.radiusdiff('b')
+    };
+
+    for (z in radiusDiff) {
+      if (typeof z === 'function') continue; // for prototype, mootools frameworks
+      if (!this.spec.get(z + 'R')) continue; // no need if no corners
+      if (radiusDiff[z]) {
+        // Get the type of corner that is the smaller one
+        var smallerCornerType = (this.spec[z + "lR"] < this.spec[z + "rR"]) ? z + "l" : z + "r";
+
+        // First we need to create a DIV for the space under the smaller corner
+        var newFiller = document.createElement("div");
+        newFiller.style.height = radiusDiff[z] + "px";
+        newFiller.style.width  =  this.spec.get(smallerCornerType + 'Ru');
+        newFiller.style.position = "absolute";
+        newFiller.style.fontSize = "1px";
+        newFiller.style.overflow = "hidden";
+        newFiller.style.backgroundColor = this.boxColour;
+        if (filter) newFiller.style.filter = filter; // IE8 bug fix
+        // Set background image with original features
+        newFiller.style.backgroundImage = this.backgroundImage;
+        newFiller.style.backgroundRepeat = this.backgroundRepeat;
+
+        // Position filler
+        switch (smallerCornerType) {
+          case "tl":
+            newFiller.style.bottom =
+            newFiller.style.left   = "0";
+            newFiller.style.borderLeft = this.borderStringL;
+            // Set background image in original position
+            newFiller.style.backgroundPosition = this.backgroundPosX + "px " + (this.borderWidth + this.backgroundPosY - this.spec.tlR) + "px";
+            this.topContainer.appendChild(newFiller);
+          break;
+          case "tr":
+            newFiller.style.bottom =
+            newFiller.style.right  = "0";
+            newFiller.style.borderRight = this.borderStringR;
+            // Set background image in original position
+            newFiller.style.backgroundPosition = (this.backgroundPosX - this.boxWidth + this.spec.trR) + "px " + (this.borderWidth + this.backgroundPosY - this.spec.trR) + "px";
+            this.topContainer.appendChild(newFiller);
+          break;
+          case "bl":
+            newFiller.style.top    =
+            newFiller.style.left   = "0";
+            newFiller.style.borderLeft = this.borderStringL;
+            // Set background image in original position
+            newFiller.style.backgroundPosition = this.backgroundPosX + "px " + (this.backgroundPosY - this.borderWidth - this.boxHeight + radiusDiff[z] + this.spec.blR) + "px";
+            this.bottomContainer.appendChild(newFiller);
+          break;
+          case "br":
+            newFiller.style.top    =
+            newFiller.style.right  = "0";
+            newFiller.style.borderRight = this.borderStringR;
+            // Set background image in original position.
+            newFiller.style.backgroundPosition = (this.borderWidthL + this.backgroundPosX - this.boxWidth + this.spec.brR) + "px " + (this.backgroundPosY - this.borderWidth - this.boxHeight + radiusDiff[z] + this.spec.brR) + "px";
+            this.bottomContainer.appendChild(newFiller);
+          //break;
+        }
+      }
+
+      // Create the bar to fill the gap between each corner horizontally
+      var newFillerBar = document.createElement("div");
+      if (filter) newFillerBar.style.filter = filter; // IE8 bug fix
+      newFillerBar.style.position = "relative";
+      newFillerBar.style.fontSize = "1px";
+      newFillerBar.style.overflow = "hidden";
+      newFillerBar.style.width = this.fillerWidth(z);
+      newFillerBar.style.backgroundColor = this.boxColour;
+      newFillerBar.style.backgroundImage = this.backgroundImage;
+      newFillerBar.style.backgroundRepeat= this.backgroundRepeat;
+
+      switch (z) {
+        case "t":
+          // Top Bar
+          if (this.topContainer) {
+            if (curvyBrowser.quirksMode) {
+              newFillerBar.style.height = 100 + topMaxRadius + "px";
+            } else {
+              newFillerBar.style.height = 100 + topMaxRadius - this.borderWidth + "px";
+            }
+            newFillerBar.style.marginLeft  = this.spec.tlR ? (this.spec.tlR - this.borderWidthL) + "px" : "0";
+            newFillerBar.style.borderTop   = this.borderString;
+            if (this.backgroundImage) {
+              var x_offset = this.spec.tlR ?
+                (this.borderWidthL + this.backgroundPosX - this.spec.tlR) + "px " : this.backgroundPosX + "px ";
+              newFillerBar.style.backgroundPosition  = x_offset + this.backgroundPosY + "px";
+              // Reposition the box's background image
+              this.shell.style.backgroundPosition = this.backgroundPosX + "px " + (this.backgroundPosY - topMaxRadius + this.borderWidthL) + "px";
+            }
+            this.topContainer.appendChild(newFillerBar);
+          }
+        break;
+        case "b":
+          if (this.bottomContainer) {
+            // Bottom Bar
+            if (curvyBrowser.quirksMode) {
+              newFillerBar.style.height     = botMaxRadius + "px";
+            } else {
+              newFillerBar.style.height     = botMaxRadius - this.borderWidthB + "px";
+            }
+            newFillerBar.style.marginLeft   = this.spec.blR ? (this.spec.blR - this.borderWidthL) + "px" : "0";
+            newFillerBar.style.borderBottom = this.borderStringB;
+            if (this.backgroundImage) {
+              var x_offset = this.spec.blR ?
+                (this.backgroundPosX + this.borderWidthL - this.spec.blR) + "px " : this.backgroundPosX + "px ";
+              newFillerBar.style.backgroundPosition = x_offset + (this.backgroundPosY - clientHeight - this.borderWidth + botMaxRadius) + "px";
+            }
+            this.bottomContainer.appendChild(newFillerBar);
+          }
+        //break;
+      }
+    }
+
+    // style content container
+    this.contentContainer.style.position = "absolute";
+    // contentContainer.style.border = "1px dotted #000"; // DEBUG, comment for production
+    this.contentContainer.className    = "autoPadDiv";
+    this.contentContainer.style.left   = this.borderWidthL + "px";
+    // Get padding amounts
+    // Apply top padding
+    this.contentContainer.style.paddingTop = this.topPadding + "px";
+    this.contentContainer.style.top = this.borderWidth + "px";
+    // skip bottom padding - it doesn't show!
+    // Apply left and right padding
+    this.contentContainer.style.paddingLeft = this.leftPadding + "px";
+    this.contentContainer.style.paddingRight = this.rightPadding + "px";
+    z = clientWidth;
+    if (!curvyBrowser.quirksMode) z -= this.leftPadding + this.rightPadding;
+    this.contentContainer.style.width = z + "px";
+    this.contentContainer.style.textAlign = curvyBrowser.get_style(this.box, 'textAlign');
+    this.box.style.textAlign = 'left'; // important otherwise layout goes wild
+
+    this.box.appendChild(this.contentContainer);
+    if (boxDisp) boxDisp.style.display = boxDispSave;
+  }
+  if (this.backgroundImage) {
+    backgroundPosX = this.backgroundCheck(backgroundPosX);
+    backgroundPosY = this.backgroundCheck(backgroundPosY);
+    if (this.backgroundObject) {
+      this.backgroundObject.holdingElement = this;
+      this.dispatch = this.applyCorners;
+      this.applyCorners = function() {
+        if (this.backgroundObject.complete)
+          this.dispatch();
+        else this.backgroundObject.onload = new Function('curvyObject.dispatch(this.holdingElement);');
+      }
+    }
+  }
+}
+
+curvyObject.prototype.backgroundCheck = function(style) {
+  if (style === 'top' || style === 'left' || parseInt(style) === 0) return 0;
+  if (!(/^[-\d.]+px$/.test(style))  && !this.backgroundObject) {
+    this.backgroundObject = new Image;
+    var imgName = function(str) {
+      var matches = /url\("?([^'"]+)"?\)/.exec(str);
+      return (matches ? matches[1] : str);
+    }
+    this.backgroundObject.src = imgName(this.backgroundImage);
+  }
+  return style;
+}
+
+curvyObject.dispatch = function(obj) {
+  if ('dispatch' in obj)
+    obj.dispatch();
+  else throw obj.newError('No dispatch function');
+}
+
+// append a pixel DIV to newCorner
+
+curvyObject.prototype.drawPixel = function(intx, inty, colour, transAmount, height, newCorner, image, cornerRadius) {
+  var pixel = document.createElement("div");
+  pixel.style.height   = height + "px";
+  pixel.style.width    = "1px";
+  pixel.style.position = "absolute";
+  pixel.style.fontSize = "1px";
+  pixel.style.overflow = "hidden";
+  var topMaxRadius = this.spec.get('tR');
+  pixel.style.backgroundColor = colour;
+  // Don't apply background image to border pixels
+  if (image && this.backgroundImage != "") {
+    pixel.style.backgroundImage = this.backgroundImage;
+    pixel.style.backgroundPosition  = "-" + (this.boxWidth - (cornerRadius - intx) + this.borderWidth) + "px -" + ((this.boxHeight + topMaxRadius + inty) - this.borderWidth) + "px";
+  }
+  // Set opacity if the transparency is anything other than 100
+  if (transAmount != 100) curvyObject.setOpacity(pixel, transAmount);
+  // Set position
+  pixel.style.top = inty + "px";
+  pixel.style.left = intx + "px";
+  //pixel.nodeValue = ' ';
+  newCorner.appendChild(pixel);
+}
+
+curvyObject.prototype.fillerWidth = function(tb) {
+  var b_width, f_width;
+  b_width = curvyBrowser.quirksMode ? 0 : this.spec.radiusCount(tb) * this.borderWidthL;
+  if ((f_width = this.boxWidth - this.spec.radiusSum(tb) + b_width) < 0)
+    throw this.newError("Radius exceeds box width");
+  return f_width + 'px';
+}
+
+curvyObject.prototype.errmsg = function(msg, gravity) {
+  var extradata = "\ntag: " + this.box.tagName;
+  if (this.box.id) extradata += "\nid: " + this.box.id;
+  if (this.box.className) extradata += "\nclass: " + this.box.className;
+  var parent;
+  if ((parent = this.box.parentNode) === null)
+    extradata += "\n(box has no parent)";
+  else {
+    extradata += "\nParent tag: " + parent.tagName;
+    if (parent.id) extradata += "\nParent ID: " + parent.id;
+    if (parent.className) extradata += "\nParent class: " + parent.className;
+  }
+  if (gravity === undefined) gravity = 'warning';
+  return 'curvyObject ' + gravity + ":\n" + msg + extradata;
+}
+
+curvyObject.prototype.newError = function(msg) {
+  return new Error(this.errmsg(msg, 'exception'));
+}
+
+// ------------- UTILITY FUNCTIONS
+
+//  Convert a number 0..255 to hex
+
+
+curvyObject.IntToHex = function(strNum) {
+  var hexdig = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' ];
+
+  return hexdig[strNum >>> 4] + '' + hexdig[strNum & 15];
+}
+
+/*
+  Blends the two colours by the fraction
+  returns the resulting colour as a string in the format "#FFFFFF"
+*/
+
+curvyObject.BlendColour = function(Col1, Col2, Col1Fraction) {
+  if (Col1 === 'transparent' || Col2 === 'transparent') throw this.newError('Cannot blend with transparent');
+  if (Col1.charAt(0) !== '#') {
+    //curvyCorners.alert('Found colour1 ' + Col1 + ': please let us know you saw this report.');
+    Col1 = curvyObject.format_colour(Col1);
+  }
+  if (Col2.charAt(0) !== '#') {
+    //curvyCorners.alert('Found colour2 ' + Col2 + ': please let us know you saw this report.');
+    Col2 = curvyObject.format_colour(Col2);
+  }
+  var red1 = parseInt(Col1.substr(1, 2), 16);
+  var green1 = parseInt(Col1.substr(3, 2), 16);
+  var blue1 = parseInt(Col1.substr(5, 2), 16);
+  var red2 = parseInt(Col2.substr(1, 2), 16);
+  var green2 = parseInt(Col2.substr(3, 2), 16);
+  var blue2 = parseInt(Col2.substr(5, 2), 16);
+
+  if (Col1Fraction > 1 || Col1Fraction < 0) Col1Fraction = 1;
+
+  var endRed = Math.round((red1 * Col1Fraction) + (red2 * (1 - Col1Fraction)));
+  if (endRed > 255) endRed = 255;
+  if (endRed < 0) endRed = 0;
+
+  var endGreen = Math.round((green1 * Col1Fraction) + (green2 * (1 - Col1Fraction)));
+  if (endGreen > 255) endGreen = 255;
+  if (endGreen < 0) endGreen = 0;
+
+  var endBlue = Math.round((blue1 * Col1Fraction) + (blue2 * (1 - Col1Fraction)));
+  if (endBlue > 255) endBlue = 255;
+  if (endBlue < 0) endBlue = 0;
+
+  return "#" + curvyObject.IntToHex(endRed) + curvyObject.IntToHex(endGreen)+ curvyObject.IntToHex(endBlue);
+}
+
+/*
+  For a pixel cut by the line determines the fraction of the pixel on the 'inside' of the
+  line.  Returns a number between 0 and 1
+*/
+
+curvyObject.pixelFraction = function(x, y, r) {
+  var fraction;
+  var rsquared = r * r;
+
+  /*
+    determine the co-ordinates of the two points on the perimeter of the pixel that the
+    circle crosses
+  */
+  var xvalues = new Array(2);
+  var yvalues = new Array(2);
+  var point = 0;
+  var whatsides = "";
+
+  // x + 0 = Left
+  var intersect = Math.sqrt(rsquared - Math.pow(x, 2));
+
+  if (intersect >= y && intersect < (y + 1)) {
+    whatsides = "Left";
+    xvalues[point] = 0;
+    yvalues[point] = intersect - y;
+    ++point;
+  }
+  // y + 1 = Top
+  intersect = Math.sqrt(rsquared - Math.pow(y + 1, 2));
+
+  if (intersect >= x && intersect < (x + 1)) {
+    whatsides += "Top";
+    xvalues[point] = intersect - x;
+    yvalues[point] = 1;
+    ++point;
+  }
+  // x + 1 = Right
+  intersect = Math.sqrt(rsquared - Math.pow(x + 1, 2));
+
+  if (intersect >= y && intersect < (y + 1)) {
+    whatsides += "Right";
+    xvalues[point] = 1;
+    yvalues[point] = intersect - y;
+    ++point;
+  }
+  // y + 0 = Bottom
+  intersect = Math.sqrt(rsquared - Math.pow(y, 2));
+
+  if (intersect >= x && intersect < (x + 1)) {
+    whatsides += "Bottom";
+    xvalues[point] = intersect - x;
+    yvalues[point] = 0;
+  }
+
+  /*
+    depending on which sides of the perimeter of the pixel the circle crosses calculate the
+    fraction of the pixel inside the circle
+  */
+  switch (whatsides) {
+    case "LeftRight":
+      fraction = Math.min(yvalues[0], yvalues[1]) + ((Math.max(yvalues[0], yvalues[1]) - Math.min(yvalues[0], yvalues[1])) / 2);
+    break;
+
+    case "TopRight":
+      fraction = 1 - (((1 - xvalues[0]) * (1 - yvalues[1])) / 2);
+    break;
+
+    case "TopBottom":
+      fraction = Math.min(xvalues[0], xvalues[1]) + ((Math.max(xvalues[0], xvalues[1]) - Math.min(xvalues[0], xvalues[1])) / 2);
+    break;
+
+    case "LeftBottom":
+      fraction = yvalues[0] * xvalues[1] / 2;
+    break;
+
+    default:
+      fraction = 1;
+  }
+
+  return fraction;
+}
+
+// Returns an array of rgb values
+
+curvyObject.rgb2Array = function(rgbColour) {
+  // Remove rgb()
+  var rgbValues = rgbColour.substring(4, rgbColour.indexOf(")"));
+
+  // Split RGB into array
+  return rgbValues.split(", ");
+}
+
+// This function converts CSS rgb(x, x, x) to hexadecimal
+
+curvyObject.rgb2Hex = function(rgbColour) {
+  try {
+    // Get array of RGB values
+    var rgbArray = curvyObject.rgb2Array(rgbColour);
+
+    // Get RGB values
+    var red   = parseInt(rgbArray[0]);
+    var green = parseInt(rgbArray[1]);
+    var blue  = parseInt(rgbArray[2]);
+
+    // Build hex colour code
+    var hexColour = "#" + curvyObject.IntToHex(red) + curvyObject.IntToHex(green) + curvyObject.IntToHex(blue);
+  }
+  catch (e) {
+    var msg = 'getMessage' in e ? e.getMessage() : e.message;
+    throw new Error("Error (" + msg + ") converting RGB value to Hex in rgb2Hex");
+  }
+
+  return hexColour;
+}
+
+/*
+  Function by Simon Willison from sitepoint.com
+  Modified by Cameron Cooke adding Safari's rgba support
+*/
+
+curvyObject.setOpacity = function(obj, opacity) {
+  opacity = (opacity == 100) ? 99.999 : opacity;
+
+  if (curvyBrowser.isSafari && obj.tagName != "IFRAME") {
+    // Get array of RGB values
+    var rgbArray = curvyObject.rgb2Array(obj.style.backgroundColor);
+
+    // Get RGB values
+    var red   = parseInt(rgbArray[0]);
+    var green = parseInt(rgbArray[1]);
+    var blue  = parseInt(rgbArray[2]);
+
+    // Safari using RGBA support
+    obj.style.backgroundColor = "rgba(" + red + ", " + green + ", " + blue + ", " + opacity/100 + ")";
+  }
+  else if (typeof obj.style.opacity !== "undefined") { // W3C
+    obj.style.opacity = opacity / 100;
+  }
+  else if (typeof obj.style.MozOpacity !== "undefined") { // Older Mozilla
+    obj.style.MozOpacity = opacity / 100;
+  }
+  else if (typeof obj.style.filter !== "undefined") { // IE
+    obj.style.filter = "alpha(opacity=" + opacity + ")";
+  }
+  else if (typeof obj.style.KHTMLOpacity !== "undefined") { // Older KHTML-based browsers
+    obj.style.KHTMLOpacity = opacity / 100;
+  }
+}
+
+
+// Cross browser add event wrapper
+
+curvyCorners.addEvent = function(elm, evType, fn, useCapture) {
+  if (elm.addEventListener) {
+    elm.addEventListener(evType, fn, useCapture);
+    return true;
+  }
+  if (elm.attachEvent) return elm.attachEvent('on' + evType, fn);
+  elm['on' + evType] = fn;
+  return false;
+}
+if (typeof addEvent === 'undefined') addEvent = curvyCorners.addEvent; // only if necessary
+
+// Gets the computed colour.
+curvyObject.getComputedColour = function(colour) {
+  var d = document.createElement('DIV');
+  d.style.backgroundColor = colour;
+  document.body.appendChild(d);
+
+  if (window.getComputedStyle) { // Mozilla, Opera, Chrome, Safari
+    var rtn = document.defaultView.getComputedStyle(d, null).getPropertyValue('background-color');
+    d.parentNode.removeChild(d);
+    if (rtn.substr(0, 3) === "rgb") rtn = curvyObject.rgb2Hex(rtn);
+    return rtn;
+  }
+  else { // IE
+    var rng = document.body.createTextRange();
+    rng.moveToElementText(d);
+    rng.execCommand('ForeColor', false, colour);
+    var iClr = rng.queryCommandValue('ForeColor');
+    var rgb = "rgb("+(iClr & 0xFF)+", "+((iClr & 0xFF00)>>8)+", "+((iClr & 0xFF0000)>>16)+")";
+    d.parentNode.removeChild(d);
+    rng = null;
+    return curvyObject.rgb2Hex(rgb);
+  }
+}
+
+// convert colour name, rgb() and #RGB to #RRGGBB
+curvyObject.format_colour = function(colour) {
+  // Make sure colour is set and not transparent
+  if (colour != "" && colour != "transparent") {
+    // RGB Value?
+    if (colour.substr(0, 3) === "rgb") {
+      // Get HEX aquiv.
+      colour = curvyObject.rgb2Hex(colour);
+    }
+    else if (colour.charAt(0) !== '#') {
+      // Convert colour name to hex value
+      colour = curvyObject.getComputedColour(colour);
+    }
+    else if (colour.length === 4) {
+      // 3 chr colour code add remainder
+      colour = "#" + colour.charAt(1) + colour.charAt(1) + colour.charAt(2) + colour.charAt(2) + colour.charAt(3) + colour.charAt(3);
+    }
+  }
+  return colour;
+}
+
+// Get elements by class by Dustin Diaz / CPKS
+// NB if searchClass is a class name, it MUST be preceded by '.'
+
+curvyCorners.getElementsByClass = function(searchClass, node) {
+  var classElements = new Array;
+  if (node === undefined) node = document;
+  searchClass = searchClass.split('.'); // see if there's a tag in there
+  var tag = '*'; // prepare for no tag
+  if (searchClass.length === 1) {
+    tag = searchClass[0];
+    searchClass = false;
+  }
+  else {
+    if (searchClass[0]) tag = searchClass[0];
+    searchClass = searchClass[1];
+  }
+  var i, els, elsLen;
+  if (tag.charAt(0) === '#') {
+    els = document.getElementById(tag.substr(1));
+    if (els) classElements.push(els);
+  }
+  else {
+    els = node.getElementsByTagName(tag);
+    elsLen = els.length;
+    if (searchClass) {
+      var pattern = new RegExp("(^|\\s)" + searchClass + "(\\s|$)");
+      for (i = 0; i < elsLen; ++i) {
+        if (pattern.test(els[i].className)) classElements.push(els[i]);
+      }
+    }
+    else for (i = 0; i < elsLen; ++i) classElements.push(els[i]);
+  }
+  return classElements;
+}
+
+if (curvyBrowser.isMoz || curvyBrowser.isWebKit) {
+  var curvyCornersNoAutoScan = true; // it won't do anything anyway.
+  curvyCorners.init = function() {}; // make it harmless
+}
+else {
+
+  // autoscan code
+
+  curvyCorners.scanStyles = function() {
+    function units(num) {
+      if (!parseInt(num)) return 'px'; // '0' becomes '0px' for simplicity's sake
+      var matches = /^[\d.]+(\w+)$/.exec(num);
+      return matches[1];
+    }
+    var t, i, j;
+
+    if (curvyBrowser.isIE) {
+      function procIEStyles(rule) {
+        var style = rule.style;
+
+        if (curvyBrowser.ieVer > 6.0) {
+          var allR = style['-webkit-border-radius'] || 0;
+          var tR   = style['-webkit-border-top-right-radius'] || 0;
+          var tL   = style['-webkit-border-top-left-radius'] || 0;
+          var bR   = style['-webkit-border-bottom-right-radius'] || 0;
+          var bL   = style['-webkit-border-bottom-left-radius'] || 0;
+        }
+        else {
+          var allR = style['webkit-border-radius'] || 0;
+          var tR   = style['webkit-border-top-right-radius'] || 0;
+          var tL   = style['webkit-border-top-left-radius'] || 0;
+          var bR   = style['webkit-border-bottom-right-radius'] || 0;
+          var bL   = style['webkit-border-bottom-left-radius'] || 0;
+        }
+        if (allR || tL || tR || bR || bL) {
+          var settings = new curvyCnrSpec(rule.selectorText);
+          if (allR)
+            settings.setcorner(null, null, parseInt(allR), units(allR));
+          else {
+            if (tR) settings.setcorner('t', 'r', parseInt(tR), units(tR));
+            if (tL) settings.setcorner('t', 'l', parseInt(tL), units(tL));
+            if (bL) settings.setcorner('b', 'l', parseInt(bL), units(bL));
+            if (bR) settings.setcorner('b', 'r', parseInt(bR), units(bR));
+          }
+          curvyCorners(settings);
+        }
+      }
+      for (t = 0; t < document.styleSheets.length; ++t) {
+        try {
+          if (document.styleSheets[t].imports) {
+            for (i = 0; i < document.styleSheets[t].imports.length; ++i)
+              for (j = 0; j < document.styleSheets[t].imports[i].rules.length; ++j)
+                procIEStyles(document.styleSheets[t].imports[i].rules[j]);
+          }
+          for (i = 0; i < document.styleSheets[t].rules.length; ++i)
+            procIEStyles(document.styleSheets[t].rules[i]);
+        }
+        catch (e) {
+          if (typeof curvyCornersVerbose !== 'undefined' && curvyCornersVerbose)
+            alert(e.message + " - ignored");
+        } // catch but ignore any permission error
+      }
+    }
+    else if (curvyBrowser.isOp) {
+      for (t = 0; t < document.styleSheets.length; ++t) {
+        if (operasheet.contains_border_radius(t)) {
+          j = new operasheet(t);
+          for (i in j.rules) if (!isNaN(i))
+            curvyCorners(j.rules[i]);
+        }
+      }
+    }
+    else curvyCorners.alert('Scanstyles does nothing in Webkit/Firefox');
+  };
+
+  // Dean Edwards/Matthias Miller/John Resig
+
+  curvyCorners.init = function() {
+    // quit if this function has already been called
+    if (arguments.callee.done) return;
+
+    // flag this function so we don't do the same thing twice
+    arguments.callee.done = true;
+
+    // kill the timer
+    if (curvyBrowser.isWebKit && curvyCorners.init.timer) {
+      clearInterval(curvyCorners.init.timer);
+      curvyCorners.init.timer = null;
+    }
+
+    // do stuff
+    curvyCorners.scanStyles();
+  };
+}
+
+if (typeof curvyCornersNoAutoScan === 'undefined' || curvyCornersNoAutoScan === false) {
+  if (curvyBrowser.isOp)
+    document.addEventListener("DOMContentLoaded", curvyCorners.init, false);
+  else curvyCorners.addEvent(window, 'load', curvyCorners.init, false);
+}
Index: ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web-data/lib/libs_minified.js
===================================================================
--- ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web-data/lib/libs_minified.js	(revision 14969)
+++ ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web-data/lib/libs_minified.js	(revision 14969)
@@ -0,0 +1,771 @@
+var Prototype={Version:'1.6.1',Browser:(function(){var ua=navigator.userAgent;var isOpera=Object.prototype.toString.call(window.opera)=='[object Opera]';return{IE:!!window.attachEvent&&!isOpera,Opera:isOpera,WebKit:ua.indexOf('AppleWebKit/')>-1,Gecko:ua.indexOf('Gecko')>-1&&ua.indexOf('KHTML')===-1,MobileSafari:/Apple.*Mobile.*Safari/.test(ua)}})(),BrowserFeatures:{XPath:!!document.evaluate,SelectorsAPI:!!document.querySelector,ElementExtensions:(function(){var constructor=window.Element||window.HTMLElement;return!!(constructor&&constructor.prototype);})(),SpecificElementExtensions:(function(){if(typeof window.HTMLDivElement!=='undefined')
+return true;var div=document.createElement('div');var form=document.createElement('form');var isSupported=false;if(div['__proto__']&&(div['__proto__']!==form['__proto__'])){isSupported=true;}
+div=form=null;return isSupported;})()},ScriptFragment:'<script[^>]*>([\\S\\s]*?)<\/script>',JSONFilter:/^\/\*-secure-([\s\S]*)\*\/\s*$/,emptyFunction:function(){},K:function(x){return x}};if(Prototype.Browser.MobileSafari)
+Prototype.BrowserFeatures.SpecificElementExtensions=false;var Abstract={};var Try={these:function(){var returnValue;for(var i=0,length=arguments.length;i<length;i++){var lambda=arguments[i];try{returnValue=lambda();break;}catch(e){}}
+return returnValue;}};var Class=(function(){function subclass(){};function create(){var parent=null,properties=$A(arguments);if(Object.isFunction(properties[0]))
+parent=properties.shift();function klass(){this.initialize.apply(this,arguments);}
+Object.extend(klass,Class.Methods);klass.superclass=parent;klass.subclasses=[];if(parent){subclass.prototype=parent.prototype;klass.prototype=new subclass;parent.subclasses.push(klass);}
+for(var i=0;i<properties.length;i++)
+klass.addMethods(properties[i]);if(!klass.prototype.initialize)
+klass.prototype.initialize=Prototype.emptyFunction;klass.prototype.constructor=klass;return klass;}
+function addMethods(source){var ancestor=this.superclass&&this.superclass.prototype;var properties=Object.keys(source);if(!Object.keys({toString:true}).length){if(source.toString!=Object.prototype.toString)
+properties.push("toString");if(source.valueOf!=Object.prototype.valueOf)
+properties.push("valueOf");}
+for(var i=0,length=properties.length;i<length;i++){var property=properties[i],value=source[property];if(ancestor&&Object.isFunction(value)&&value.argumentNames().first()=="$super"){var method=value;value=(function(m){return function(){return ancestor[m].apply(this,arguments);};})(property).wrap(method);value.valueOf=method.valueOf.bind(method);value.toString=method.toString.bind(method);}
+this.prototype[property]=value;}
+return this;}
+return{create:create,Methods:{addMethods:addMethods}};})();(function(){var _toString=Object.prototype.toString;function extend(destination,source){for(var property in source)
+destination[property]=source[property];return destination;}
+function inspect(object){try{if(isUndefined(object))return'undefined';if(object===null)return'null';return object.inspect?object.inspect():String(object);}catch(e){if(e instanceof RangeError)return'...';throw e;}}
+function toJSON(object){var type=typeof object;switch(type){case'undefined':case'function':case'unknown':return;case'boolean':return object.toString();}
+if(object===null)return'null';if(object.toJSON)return object.toJSON();if(isElement(object))return;var results=[];for(var property in object){var value=toJSON(object[property]);if(!isUndefined(value))
+results.push(property.toJSON()+': '+value);}
+return'{'+results.join(', ')+'}';}
+function toQueryString(object){return $H(object).toQueryString();}
+function toHTML(object){return object&&object.toHTML?object.toHTML():String.interpret(object);}
+function keys(object){var results=[];for(var property in object)
+results.push(property);return results;}
+function values(object){var results=[];for(var property in object)
+results.push(object[property]);return results;}
+function clone(object){return extend({},object);}
+function isElement(object){return!!(object&&object.nodeType==1);}
+function isArray(object){return _toString.call(object)=="[object Array]";}
+function isHash(object){return object instanceof Hash;}
+function isFunction(object){return typeof object==="function";}
+function isString(object){return _toString.call(object)=="[object String]";}
+function isNumber(object){return _toString.call(object)=="[object Number]";}
+function isUndefined(object){return typeof object==="undefined";}
+extend(Object,{extend:extend,inspect:inspect,toJSON:toJSON,toQueryString:toQueryString,toHTML:toHTML,keys:keys,values:values,clone:clone,isElement:isElement,isArray:isArray,isHash:isHash,isFunction:isFunction,isString:isString,isNumber:isNumber,isUndefined:isUndefined});})();Object.extend(Function.prototype,(function(){var slice=Array.prototype.slice;function update(array,args){var arrayLength=array.length,length=args.length;while(length--)array[arrayLength+length]=args[length];return array;}
+function merge(array,args){array=slice.call(array,0);return update(array,args);}
+function argumentNames(){var names=this.toString().match(/^[\s\(]*function[^(]*\(([^)]*)\)/)[1].replace(/\/\/.*?[\r\n]|\/\*(?:.|[\r\n])*?\*\//g,'').replace(/\s+/g,'').split(',');return names.length==1&&!names[0]?[]:names;}
+function bind(context){if(arguments.length<2&&Object.isUndefined(arguments[0]))return this;var __method=this,args=slice.call(arguments,1);return function(){var a=merge(args,arguments);return __method.apply(context,a);}}
+function bindAsEventListener(context){var __method=this,args=slice.call(arguments,1);return function(event){var a=update([event||window.event],args);return __method.apply(context,a);}}
+function curry(){if(!arguments.length)return this;var __method=this,args=slice.call(arguments,0);return function(){var a=merge(args,arguments);return __method.apply(this,a);}}
+function delay(timeout){var __method=this,args=slice.call(arguments,1);timeout=timeout*1000
+return window.setTimeout(function(){return __method.apply(__method,args);},timeout);}
+function defer(){var args=update([0.01],arguments);return this.delay.apply(this,args);}
+function wrap(wrapper){var __method=this;return function(){var a=update([__method.bind(this)],arguments);return wrapper.apply(this,a);}}
+function methodize(){if(this._methodized)return this._methodized;var __method=this;return this._methodized=function(){var a=update([this],arguments);return __method.apply(null,a);};}
+return{argumentNames:argumentNames,bind:bind,bindAsEventListener:bindAsEventListener,curry:curry,delay:delay,defer:defer,wrap:wrap,methodize:methodize}})());Date.prototype.toJSON=function(){return'"'+this.getUTCFullYear()+'-'+
+(this.getUTCMonth()+1).toPaddedString(2)+'-'+
+this.getUTCDate().toPaddedString(2)+'T'+
+this.getUTCHours().toPaddedString(2)+':'+
+this.getUTCMinutes().toPaddedString(2)+':'+
+this.getUTCSeconds().toPaddedString(2)+'Z"';};RegExp.prototype.match=RegExp.prototype.test;RegExp.escape=function(str){return String(str).replace(/([.*+?^=!:${}()|[\]\/\\])/g,'\\$1');};var PeriodicalExecuter=Class.create({initialize:function(callback,frequency){this.callback=callback;this.frequency=frequency;this.currentlyExecuting=false;this.registerCallback();},registerCallback:function(){this.timer=setInterval(this.onTimerEvent.bind(this),this.frequency*1000);},execute:function(){this.callback(this);},stop:function(){if(!this.timer)return;clearInterval(this.timer);this.timer=null;},onTimerEvent:function(){if(!this.currentlyExecuting){try{this.currentlyExecuting=true;this.execute();this.currentlyExecuting=false;}catch(e){this.currentlyExecuting=false;throw e;}}}});Object.extend(String,{interpret:function(value){return value==null?'':String(value);},specialChar:{'\b':'\\b','\t':'\\t','\n':'\\n','\f':'\\f','\r':'\\r','\\':'\\\\'}});Object.extend(String.prototype,(function(){function prepareReplacement(replacement){if(Object.isFunction(replacement))return replacement;var template=new Template(replacement);return function(match){return template.evaluate(match)};}
+function gsub(pattern,replacement){var result='',source=this,match;replacement=prepareReplacement(replacement);if(Object.isString(pattern))
+pattern=RegExp.escape(pattern);if(!(pattern.length||pattern.source)){replacement=replacement('');return replacement+source.split('').join(replacement)+replacement;}
+while(source.length>0){if(match=source.match(pattern)){result+=source.slice(0,match.index);result+=String.interpret(replacement(match));source=source.slice(match.index+match[0].length);}else{result+=source,source='';}}
+return result;}
+function sub(pattern,replacement,count){replacement=prepareReplacement(replacement);count=Object.isUndefined(count)?1:count;return this.gsub(pattern,function(match){if(--count<0)return match[0];return replacement(match);});}
+function scan(pattern,iterator){this.gsub(pattern,iterator);return String(this);}
+function truncate(length,truncation){length=length||30;truncation=Object.isUndefined(truncation)?'...':truncation;return this.length>length?this.slice(0,length-truncation.length)+truncation:String(this);}
+function strip(){return this.replace(/^\s+/,'').replace(/\s+$/,'');}
+function stripTags(){return this.replace(/<\w+(\s+("[^"]*"|'[^']*'|[^>])+)?>|<\/\w+>/gi,'');}
+function stripScripts(){return this.replace(new RegExp(Prototype.ScriptFragment,'img'),'');}
+function extractScripts(){var matchAll=new RegExp(Prototype.ScriptFragment,'img');var matchOne=new RegExp(Prototype.ScriptFragment,'im');return(this.match(matchAll)||[]).map(function(scriptTag){return(scriptTag.match(matchOne)||['',''])[1];});}
+function evalScripts(){return this.extractScripts().map(function(script){return eval(script)});}
+function escapeHTML(){return this.replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;');}
+function unescapeHTML(){return this.stripTags().replace(/&lt;/g,'<').replace(/&gt;/g,'>').replace(/&amp;/g,'&');}
+function toQueryParams(separator){var match=this.strip().match(/([^?#]*)(#.*)?$/);if(!match)return{};return match[1].split(separator||'&').inject({},function(hash,pair){if((pair=pair.split('='))[0]){var key=decodeURIComponent(pair.shift());var value=pair.length>1?pair.join('='):pair[0];if(value!=undefined)value=decodeURIComponent(value);if(key in hash){if(!Object.isArray(hash[key]))hash[key]=[hash[key]];hash[key].push(value);}
+else hash[key]=value;}
+return hash;});}
+function toArray(){return this.split('');}
+function succ(){return this.slice(0,this.length-1)+
+String.fromCharCode(this.charCodeAt(this.length-1)+1);}
+function times(count){return count<1?'':new Array(count+1).join(this);}
+function camelize(){var parts=this.split('-'),len=parts.length;if(len==1)return parts[0];var camelized=this.charAt(0)=='-'?parts[0].charAt(0).toUpperCase()+parts[0].substring(1):parts[0];for(var i=1;i<len;i++)
+camelized+=parts[i].charAt(0).toUpperCase()+parts[i].substring(1);return camelized;}
+function capitalize(){return this.charAt(0).toUpperCase()+this.substring(1).toLowerCase();}
+function underscore(){return this.replace(/::/g,'/').replace(/([A-Z]+)([A-Z][a-z])/g,'$1_$2').replace(/([a-z\d])([A-Z])/g,'$1_$2').replace(/-/g,'_').toLowerCase();}
+function dasherize(){return this.replace(/_/g,'-');}
+function inspect(useDoubleQuotes){var escapedString=this.replace(/[\x00-\x1f\\]/g,function(character){if(character in String.specialChar){return String.specialChar[character];}
+return'\\u00'+character.charCodeAt().toPaddedString(2,16);});if(useDoubleQuotes)return'"'+escapedString.replace(/"/g,'\\"')+'"';return"'"+escapedString.replace(/'/g,'\\\'')+"'";}
+function toJSON(){return this.inspect(true);}
+function unfilterJSON(filter){return this.replace(filter||Prototype.JSONFilter,'$1');}
+function isJSON(){var str=this;if(str.blank())return false;str=this.replace(/\\./g,'@').replace(/"[^"\\\n\r]*"/g,'');return(/^[,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t]*$/).test(str);}
+function evalJSON(sanitize){var json=this.unfilterJSON();try{if(!sanitize||json.isJSON())return eval('('+json+')');}catch(e){}
+throw new SyntaxError('Badly formed JSON string: '+this.inspect());}
+function include(pattern){return this.indexOf(pattern)>-1;}
+function startsWith(pattern){return this.indexOf(pattern)===0;}
+function endsWith(pattern){var d=this.length-pattern.length;return d>=0&&this.lastIndexOf(pattern)===d;}
+function empty(){return this=='';}
+function blank(){return/^\s*$/.test(this);}
+function interpolate(object,pattern){return new Template(this,pattern).evaluate(object);}
+return{gsub:gsub,sub:sub,scan:scan,truncate:truncate,strip:String.prototype.trim?String.prototype.trim:strip,stripTags:stripTags,stripScripts:stripScripts,extractScripts:extractScripts,evalScripts:evalScripts,escapeHTML:escapeHTML,unescapeHTML:unescapeHTML,toQueryParams:toQueryParams,parseQuery:toQueryParams,toArray:toArray,succ:succ,times:times,camelize:camelize,capitalize:capitalize,underscore:underscore,dasherize:dasherize,inspect:inspect,toJSON:toJSON,unfilterJSON:unfilterJSON,isJSON:isJSON,evalJSON:evalJSON,include:include,startsWith:startsWith,endsWith:endsWith,empty:empty,blank:blank,interpolate:interpolate};})());var Template=Class.create({initialize:function(template,pattern){this.template=template.toString();this.pattern=pattern||Template.Pattern;},evaluate:function(object){if(object&&Object.isFunction(object.toTemplateReplacements))
+object=object.toTemplateReplacements();return this.template.gsub(this.pattern,function(match){if(object==null)return(match[1]+'');var before=match[1]||'';if(before=='\\')return match[2];var ctx=object,expr=match[3];var pattern=/^([^.[]+|\[((?:.*?[^\\])?)\])(\.|\[|$)/;match=pattern.exec(expr);if(match==null)return before;while(match!=null){var comp=match[1].startsWith('[')?match[2].replace(/\\\\]/g,']'):match[1];ctx=ctx[comp];if(null==ctx||''==match[3])break;expr=expr.substring('['==match[3]?match[1].length:match[0].length);match=pattern.exec(expr);}
+return before+String.interpret(ctx);});}});Template.Pattern=/(^|.|\r|\n)(#\{(.*?)\})/;var $break={};var Enumerable=(function(){function each(iterator,context){var index=0;try{this._each(function(value){iterator.call(context,value,index++);});}catch(e){if(e!=$break)throw e;}
+return this;}
+function eachSlice(number,iterator,context){var index=-number,slices=[],array=this.toArray();if(number<1)return array;while((index+=number)<array.length)
+slices.push(array.slice(index,index+number));return slices.collect(iterator,context);}
+function all(iterator,context){iterator=iterator||Prototype.K;var result=true;this.each(function(value,index){result=result&&!!iterator.call(context,value,index);if(!result)throw $break;});return result;}
+function any(iterator,context){iterator=iterator||Prototype.K;var result=false;this.each(function(value,index){if(result=!!iterator.call(context,value,index))
+throw $break;});return result;}
+function collect(iterator,context){iterator=iterator||Prototype.K;var results=[];this.each(function(value,index){results.push(iterator.call(context,value,index));});return results;}
+function detect(iterator,context){var result;this.each(function(value,index){if(iterator.call(context,value,index)){result=value;throw $break;}});return result;}
+function findAll(iterator,context){var results=[];this.each(function(value,index){if(iterator.call(context,value,index))
+results.push(value);});return results;}
+function grep(filter,iterator,context){iterator=iterator||Prototype.K;var results=[];if(Object.isString(filter))
+filter=new RegExp(RegExp.escape(filter));this.each(function(value,index){if(filter.match(value))
+results.push(iterator.call(context,value,index));});return results;}
+function include(object){if(Object.isFunction(this.indexOf))
+if(this.indexOf(object)!=-1)return true;var found=false;this.each(function(value){if(value==object){found=true;throw $break;}});return found;}
+function inGroupsOf(number,fillWith){fillWith=Object.isUndefined(fillWith)?null:fillWith;return this.eachSlice(number,function(slice){while(slice.length<number)slice.push(fillWith);return slice;});}
+function inject(memo,iterator,context){this.each(function(value,index){memo=iterator.call(context,memo,value,index);});return memo;}
+function invoke(method){var args=$A(arguments).slice(1);return this.map(function(value){return value[method].apply(value,args);});}
+function max(iterator,context){iterator=iterator||Prototype.K;var result;this.each(function(value,index){value=iterator.call(context,value,index);if(result==null||value>=result)
+result=value;});return result;}
+function min(iterator,context){iterator=iterator||Prototype.K;var result;this.each(function(value,index){value=iterator.call(context,value,index);if(result==null||value<result)
+result=value;});return result;}
+function partition(iterator,context){iterator=iterator||Prototype.K;var trues=[],falses=[];this.each(function(value,index){(iterator.call(context,value,index)?trues:falses).push(value);});return[trues,falses];}
+function pluck(property){var results=[];this.each(function(value){results.push(value[property]);});return results;}
+function reject(iterator,context){var results=[];this.each(function(value,index){if(!iterator.call(context,value,index))
+results.push(value);});return results;}
+function sortBy(iterator,context){return this.map(function(value,index){return{value:value,criteria:iterator.call(context,value,index)};}).sort(function(left,right){var a=left.criteria,b=right.criteria;return a<b?-1:a>b?1:0;}).pluck('value');}
+function toArray(){return this.map();}
+function zip(){var iterator=Prototype.K,args=$A(arguments);if(Object.isFunction(args.last()))
+iterator=args.pop();var collections=[this].concat(args).map($A);return this.map(function(value,index){return iterator(collections.pluck(index));});}
+function size(){return this.toArray().length;}
+function inspect(){return'#<Enumerable:'+this.toArray().inspect()+'>';}
+return{each:each,eachSlice:eachSlice,all:all,every:all,any:any,some:any,collect:collect,map:collect,detect:detect,findAll:findAll,select:findAll,filter:findAll,grep:grep,include:include,member:include,inGroupsOf:inGroupsOf,inject:inject,invoke:invoke,max:max,min:min,partition:partition,pluck:pluck,reject:reject,sortBy:sortBy,toArray:toArray,entries:toArray,zip:zip,size:size,inspect:inspect,find:detect};})();function $A(iterable){if(!iterable)return[];if('toArray'in Object(iterable))return iterable.toArray();var length=iterable.length||0,results=new Array(length);while(length--)results[length]=iterable[length];return results;}
+function $w(string){if(!Object.isString(string))return[];string=string.strip();return string?string.split(/\s+/):[];}
+Array.from=$A;(function(){var arrayProto=Array.prototype,slice=arrayProto.slice,_each=arrayProto.forEach;function each(iterator){for(var i=0,length=this.length;i<length;i++)
+iterator(this[i]);}
+if(!_each)_each=each;function clear(){this.length=0;return this;}
+function first(){return this[0];}
+function last(){return this[this.length-1];}
+function compact(){return this.select(function(value){return value!=null;});}
+function flatten(){return this.inject([],function(array,value){if(Object.isArray(value))
+return array.concat(value.flatten());array.push(value);return array;});}
+function without(){var values=slice.call(arguments,0);return this.select(function(value){return!values.include(value);});}
+function reverse(inline){return(inline!==false?this:this.toArray())._reverse();}
+function uniq(sorted){return this.inject([],function(array,value,index){if(0==index||(sorted?array.last()!=value:!array.include(value)))
+array.push(value);return array;});}
+function intersect(array){return this.uniq().findAll(function(item){return array.detect(function(value){return item===value});});}
+function clone(){return slice.call(this,0);}
+function size(){return this.length;}
+function inspect(){return'['+this.map(Object.inspect).join(', ')+']';}
+function toJSON(){var results=[];this.each(function(object){var value=Object.toJSON(object);if(!Object.isUndefined(value))results.push(value);});return'['+results.join(', ')+']';}
+function indexOf(item,i){i||(i=0);var length=this.length;if(i<0)i=length+i;for(;i<length;i++)
+if(this[i]===item)return i;return-1;}
+function lastIndexOf(item,i){i=isNaN(i)?this.length:(i<0?this.length+i:i)+1;var n=this.slice(0,i).reverse().indexOf(item);return(n<0)?n:i-n-1;}
+function concat(){var array=slice.call(this,0),item;for(var i=0,length=arguments.length;i<length;i++){item=arguments[i];if(Object.isArray(item)&&!('callee'in item)){for(var j=0,arrayLength=item.length;j<arrayLength;j++)
+array.push(item[j]);}else{array.push(item);}}
+return array;}
+Object.extend(arrayProto,Enumerable);if(!arrayProto._reverse)
+arrayProto._reverse=arrayProto.reverse;Object.extend(arrayProto,{_each:_each,clear:clear,first:first,last:last,compact:compact,flatten:flatten,without:without,reverse:reverse,uniq:uniq,intersect:intersect,clone:clone,toArray:clone,size:size,inspect:inspect,toJSON:toJSON});var CONCAT_ARGUMENTS_BUGGY=(function(){return[].concat(arguments)[0][0]!==1;})(1,2)
+if(CONCAT_ARGUMENTS_BUGGY)arrayProto.concat=concat;if(!arrayProto.indexOf)arrayProto.indexOf=indexOf;if(!arrayProto.lastIndexOf)arrayProto.lastIndexOf=lastIndexOf;})();function $H(object){return new Hash(object);};var Hash=Class.create(Enumerable,(function(){function initialize(object){this._object=Object.isHash(object)?object.toObject():Object.clone(object);}
+function _each(iterator){for(var key in this._object){var value=this._object[key],pair=[key,value];pair.key=key;pair.value=value;iterator(pair);}}
+function set(key,value){return this._object[key]=value;}
+function get(key){if(this._object[key]!==Object.prototype[key])
+return this._object[key];}
+function unset(key){var value=this._object[key];delete this._object[key];return value;}
+function toObject(){return Object.clone(this._object);}
+function keys(){return this.pluck('key');}
+function values(){return this.pluck('value');}
+function index(value){var match=this.detect(function(pair){return pair.value===value;});return match&&match.key;}
+function merge(object){return this.clone().update(object);}
+function update(object){return new Hash(object).inject(this,function(result,pair){result.set(pair.key,pair.value);return result;});}
+function toQueryPair(key,value){if(Object.isUndefined(value))return key;return key+'='+encodeURIComponent(String.interpret(value));}
+function toQueryString(){return this.inject([],function(results,pair){var key=encodeURIComponent(pair.key),values=pair.value;if(values&&typeof values=='object'){if(Object.isArray(values))
+return results.concat(values.map(toQueryPair.curry(key)));}else results.push(toQueryPair(key,values));return results;}).join('&');}
+function inspect(){return'#<Hash:{'+this.map(function(pair){return pair.map(Object.inspect).join(': ');}).join(', ')+'}>';}
+function toJSON(){return Object.toJSON(this.toObject());}
+function clone(){return new Hash(this);}
+return{initialize:initialize,_each:_each,set:set,get:get,unset:unset,toObject:toObject,toTemplateReplacements:toObject,keys:keys,values:values,index:index,merge:merge,update:update,toQueryString:toQueryString,inspect:inspect,toJSON:toJSON,clone:clone};})());Hash.from=$H;Object.extend(Number.prototype,(function(){function toColorPart(){return this.toPaddedString(2,16);}
+function succ(){return this+1;}
+function times(iterator,context){$R(0,this,true).each(iterator,context);return this;}
+function toPaddedString(length,radix){var string=this.toString(radix||10);return'0'.times(length-string.length)+string;}
+function toJSON(){return isFinite(this)?this.toString():'null';}
+function abs(){return Math.abs(this);}
+function round(){return Math.round(this);}
+function ceil(){return Math.ceil(this);}
+function floor(){return Math.floor(this);}
+return{toColorPart:toColorPart,succ:succ,times:times,toPaddedString:toPaddedString,toJSON:toJSON,abs:abs,round:round,ceil:ceil,floor:floor};})());function $R(start,end,exclusive){return new ObjectRange(start,end,exclusive);}
+var ObjectRange=Class.create(Enumerable,(function(){function initialize(start,end,exclusive){this.start=start;this.end=end;this.exclusive=exclusive;}
+function _each(iterator){var value=this.start;while(this.include(value)){iterator(value);value=value.succ();}}
+function include(value){if(value<this.start)
+return false;if(this.exclusive)
+return value<this.end;return value<=this.end;}
+return{initialize:initialize,_each:_each,include:include};})());var Ajax={getTransport:function(){return Try.these(function(){return new XMLHttpRequest()},function(){return new ActiveXObject('Msxml2.XMLHTTP')},function(){return new ActiveXObject('Microsoft.XMLHTTP')})||false;},activeRequestCount:0};Ajax.Responders={responders:[],_each:function(iterator){this.responders._each(iterator);},register:function(responder){if(!this.include(responder))
+this.responders.push(responder);},unregister:function(responder){this.responders=this.responders.without(responder);},dispatch:function(callback,request,transport,json){this.each(function(responder){if(Object.isFunction(responder[callback])){try{responder[callback].apply(responder,[request,transport,json]);}catch(e){}}});}};Object.extend(Ajax.Responders,Enumerable);Ajax.Responders.register({onCreate:function(){Ajax.activeRequestCount++},onComplete:function(){Ajax.activeRequestCount--}});Ajax.Base=Class.create({initialize:function(options){this.options={method:'post',asynchronous:true,contentType:'application/x-www-form-urlencoded',encoding:'UTF-8',parameters:'',evalJSON:true,evalJS:true};Object.extend(this.options,options||{});this.options.method=this.options.method.toLowerCase();if(Object.isString(this.options.parameters))
+this.options.parameters=this.options.parameters.toQueryParams();else if(Object.isHash(this.options.parameters))
+this.options.parameters=this.options.parameters.toObject();}});Ajax.Request=Class.create(Ajax.Base,{_complete:false,initialize:function($super,url,options){$super(options);this.transport=Ajax.getTransport();this.request(url);},request:function(url){this.url=url;this.method=this.options.method;var params=Object.clone(this.options.parameters);if(!['get','post'].include(this.method)){params['_method']=this.method;this.method='post';}
+this.parameters=params;if(params=Object.toQueryString(params)){if(this.method=='get')
+this.url+=(this.url.include('?')?'&':'?')+params;else if(/Konqueror|Safari|KHTML/.test(navigator.userAgent))
+params+='&_=';}
+try{var response=new Ajax.Response(this);if(this.options.onCreate)this.options.onCreate(response);Ajax.Responders.dispatch('onCreate',this,response);this.transport.open(this.method.toUpperCase(),this.url,this.options.asynchronous);if(this.options.asynchronous)this.respondToReadyState.bind(this).defer(1);this.transport.onreadystatechange=this.onStateChange.bind(this);this.setRequestHeaders();this.body=this.method=='post'?(this.options.postBody||params):null;this.transport.send(this.body);if(!this.options.asynchronous&&this.transport.overrideMimeType)
+this.onStateChange();}
+catch(e){this.dispatchException(e);}},onStateChange:function(){var readyState=this.transport.readyState;if(readyState>1&&!((readyState==4)&&this._complete))
+this.respondToReadyState(this.transport.readyState);},setRequestHeaders:function(){var headers={'X-Requested-With':'XMLHttpRequest','X-Prototype-Version':Prototype.Version,'Accept':'text/javascript, text/html, application/xml, text/xml, */*'};if(this.method=='post'){headers['Content-type']=this.options.contentType+
+(this.options.encoding?'; charset='+this.options.encoding:'');if(this.transport.overrideMimeType&&(navigator.userAgent.match(/Gecko\/(\d{4})/)||[0,2005])[1]<2005)
+headers['Connection']='close';}
+if(typeof this.options.requestHeaders=='object'){var extras=this.options.requestHeaders;if(Object.isFunction(extras.push))
+for(var i=0,length=extras.length;i<length;i+=2)
+headers[extras[i]]=extras[i+1];else
+$H(extras).each(function(pair){headers[pair.key]=pair.value});}
+for(var name in headers)
+this.transport.setRequestHeader(name,headers[name]);},success:function(){var status=this.getStatus();return!status||(status>=200&&status<300);},getStatus:function(){try{return this.transport.status||0;}catch(e){return 0}},respondToReadyState:function(readyState){var state=Ajax.Request.Events[readyState],response=new Ajax.Response(this);if(state=='Complete'){try{this._complete=true;(this.options['on'+response.status]||this.options['on'+(this.success()?'Success':'Failure')]||Prototype.emptyFunction)(response,response.headerJSON);}catch(e){this.dispatchException(e);}
+var contentType=response.getHeader('Content-type');if(this.options.evalJS=='force'||(this.options.evalJS&&this.isSameOrigin()&&contentType&&contentType.match(/^\s*(text|application)\/(x-)?(java|ecma)script(;.*)?\s*$/i)))
+this.evalResponse();}
+try{(this.options['on'+state]||Prototype.emptyFunction)(response,response.headerJSON);Ajax.Responders.dispatch('on'+state,this,response,response.headerJSON);}catch(e){this.dispatchException(e);}
+if(state=='Complete'){this.transport.onreadystatechange=Prototype.emptyFunction;}},isSameOrigin:function(){var m=this.url.match(/^\s*https?:\/\/[^\/]*/);return!m||(m[0]=='#{protocol}//#{domain}#{port}'.interpolate({protocol:location.protocol,domain:document.domain,port:location.port?':'+location.port:''}));},getHeader:function(name){try{return this.transport.getResponseHeader(name)||null;}catch(e){return null;}},evalResponse:function(){try{return eval((this.transport.responseText||'').unfilterJSON());}catch(e){this.dispatchException(e);}},dispatchException:function(exception){(this.options.onException||Prototype.emptyFunction)(this,exception);Ajax.Responders.dispatch('onException',this,exception);}});Ajax.Request.Events=['Uninitialized','Loading','Loaded','Interactive','Complete'];Ajax.Response=Class.create({initialize:function(request){this.request=request;var transport=this.transport=request.transport,readyState=this.readyState=transport.readyState;if((readyState>2&&!Prototype.Browser.IE)||readyState==4){this.status=this.getStatus();this.statusText=this.getStatusText();this.responseText=String.interpret(transport.responseText);this.headerJSON=this._getHeaderJSON();}
+if(readyState==4){var xml=transport.responseXML;this.responseXML=Object.isUndefined(xml)?null:xml;this.responseJSON=this._getResponseJSON();}},status:0,statusText:'',getStatus:Ajax.Request.prototype.getStatus,getStatusText:function(){try{return this.transport.statusText||'';}catch(e){return''}},getHeader:Ajax.Request.prototype.getHeader,getAllHeaders:function(){try{return this.getAllResponseHeaders();}catch(e){return null}},getResponseHeader:function(name){return this.transport.getResponseHeader(name);},getAllResponseHeaders:function(){return this.transport.getAllResponseHeaders();},_getHeaderJSON:function(){var json=this.getHeader('X-JSON');if(!json)return null;json=decodeURIComponent(escape(json));try{return json.evalJSON(this.request.options.sanitizeJSON||!this.request.isSameOrigin());}catch(e){this.request.dispatchException(e);}},_getResponseJSON:function(){var options=this.request.options;if(!options.evalJSON||(options.evalJSON!='force'&&!(this.getHeader('Content-type')||'').include('application/json'))||this.responseText.blank())
+return null;try{return this.responseText.evalJSON(options.sanitizeJSON||!this.request.isSameOrigin());}catch(e){this.request.dispatchException(e);}}});Ajax.Updater=Class.create(Ajax.Request,{initialize:function($super,container,url,options){this.container={success:(container.success||container),failure:(container.failure||(container.success?null:container))};options=Object.clone(options);var onComplete=options.onComplete;options.onComplete=(function(response,json){this.updateContent(response.responseText);if(Object.isFunction(onComplete))onComplete(response,json);}).bind(this);$super(url,options);},updateContent:function(responseText){var receiver=this.container[this.success()?'success':'failure'],options=this.options;if(!options.evalScripts)responseText=responseText.stripScripts();if(receiver=$(receiver)){if(options.insertion){if(Object.isString(options.insertion)){var insertion={};insertion[options.insertion]=responseText;receiver.insert(insertion);}
+else options.insertion(receiver,responseText);}
+else receiver.update(responseText);}}});Ajax.PeriodicalUpdater=Class.create(Ajax.Base,{initialize:function($super,container,url,options){$super(options);this.onComplete=this.options.onComplete;this.frequency=(this.options.frequency||2);this.decay=(this.options.decay||1);this.updater={};this.container=container;this.url=url;this.start();},start:function(){this.options.onComplete=this.updateComplete.bind(this);this.onTimerEvent();},stop:function(){this.updater.options.onComplete=undefined;clearTimeout(this.timer);(this.onComplete||Prototype.emptyFunction).apply(this,arguments);},updateComplete:function(response){if(this.options.decay){this.decay=(response.responseText==this.lastText?this.decay*this.options.decay:1);this.lastText=response.responseText;}
+this.timer=this.onTimerEvent.bind(this).delay(this.decay*this.frequency);},onTimerEvent:function(){this.updater=new Ajax.Updater(this.container,this.url,this.options);}});function $(element){if(arguments.length>1){for(var i=0,elements=[],length=arguments.length;i<length;i++)
+elements.push($(arguments[i]));return elements;}
+if(Object.isString(element))
+element=document.getElementById(element);return Element.extend(element);}
+if(Prototype.BrowserFeatures.XPath){document._getElementsByXPath=function(expression,parentElement){var results=[];var query=document.evaluate(expression,$(parentElement)||document,null,XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,null);for(var i=0,length=query.snapshotLength;i<length;i++)
+results.push(Element.extend(query.snapshotItem(i)));return results;};}
+if(!window.Node)var Node={};if(!Node.ELEMENT_NODE){Object.extend(Node,{ELEMENT_NODE:1,ATTRIBUTE_NODE:2,TEXT_NODE:3,CDATA_SECTION_NODE:4,ENTITY_REFERENCE_NODE:5,ENTITY_NODE:6,PROCESSING_INSTRUCTION_NODE:7,COMMENT_NODE:8,DOCUMENT_NODE:9,DOCUMENT_TYPE_NODE:10,DOCUMENT_FRAGMENT_NODE:11,NOTATION_NODE:12});}
+(function(global){var SETATTRIBUTE_IGNORES_NAME=(function(){var elForm=document.createElement("form");var elInput=document.createElement("input");var root=document.documentElement;elInput.setAttribute("name","test");elForm.appendChild(elInput);root.appendChild(elForm);var isBuggy=elForm.elements?(typeof elForm.elements.test=="undefined"):null;root.removeChild(elForm);elForm=elInput=null;return isBuggy;})();var element=global.Element;global.Element=function(tagName,attributes){attributes=attributes||{};tagName=tagName.toLowerCase();var cache=Element.cache;if(SETATTRIBUTE_IGNORES_NAME&&attributes.name){tagName='<'+tagName+' name="'+attributes.name+'">';delete attributes.name;return Element.writeAttribute(document.createElement(tagName),attributes);}
+if(!cache[tagName])cache[tagName]=Element.extend(document.createElement(tagName));return Element.writeAttribute(cache[tagName].cloneNode(false),attributes);};Object.extend(global.Element,element||{});if(element)global.Element.prototype=element.prototype;})(this);Element.cache={};Element.idCounter=1;Element.Methods={visible:function(element){return $(element).style.display!='none';},toggle:function(element){element=$(element);Element[Element.visible(element)?'hide':'show'](element);return element;},hide:function(element){element=$(element);element.style.display='none';return element;},show:function(element){element=$(element);element.style.display='';return element;},remove:function(element){element=$(element);element.parentNode.removeChild(element);return element;},update:(function(){var SELECT_ELEMENT_INNERHTML_BUGGY=(function(){var el=document.createElement("select"),isBuggy=true;el.innerHTML="<option value=\"test\">test</option>";if(el.options&&el.options[0]){isBuggy=el.options[0].nodeName.toUpperCase()!=="OPTION";}
+el=null;return isBuggy;})();var TABLE_ELEMENT_INNERHTML_BUGGY=(function(){try{var el=document.createElement("table");if(el&&el.tBodies){el.innerHTML="<tbody><tr><td>test</td></tr></tbody>";var isBuggy=typeof el.tBodies[0]=="undefined";el=null;return isBuggy;}}catch(e){return true;}})();var SCRIPT_ELEMENT_REJECTS_TEXTNODE_APPENDING=(function(){var s=document.createElement("script"),isBuggy=false;try{s.appendChild(document.createTextNode(""));isBuggy=!s.firstChild||s.firstChild&&s.firstChild.nodeType!==3;}catch(e){isBuggy=true;}
+s=null;return isBuggy;})();function update(element,content){element=$(element);if(content&&content.toElement)
+content=content.toElement();if(Object.isElement(content))
+return element.update().insert(content);content=Object.toHTML(content);var tagName=element.tagName.toUpperCase();if(tagName==='SCRIPT'&&SCRIPT_ELEMENT_REJECTS_TEXTNODE_APPENDING){element.text=content;return element;}
+if(SELECT_ELEMENT_INNERHTML_BUGGY||TABLE_ELEMENT_INNERHTML_BUGGY){if(tagName in Element._insertionTranslations.tags){while(element.firstChild){element.removeChild(element.firstChild);}
+Element._getContentFromAnonymousElement(tagName,content.stripScripts()).each(function(node){element.appendChild(node)});}
+else{element.innerHTML=content.stripScripts();}}
+else{element.innerHTML=content.stripScripts();}
+content.evalScripts.bind(content).defer();return element;}
+return update;})(),replace:function(element,content){element=$(element);if(content&&content.toElement)content=content.toElement();else if(!Object.isElement(content)){content=Object.toHTML(content);var range=element.ownerDocument.createRange();range.selectNode(element);content.evalScripts.bind(content).defer();content=range.createContextualFragment(content.stripScripts());}
+element.parentNode.replaceChild(content,element);return element;},insert:function(element,insertions){element=$(element);if(Object.isString(insertions)||Object.isNumber(insertions)||Object.isElement(insertions)||(insertions&&(insertions.toElement||insertions.toHTML)))
+insertions={bottom:insertions};var content,insert,tagName,childNodes;for(var position in insertions){content=insertions[position];position=position.toLowerCase();insert=Element._insertionTranslations[position];if(content&&content.toElement)content=content.toElement();if(Object.isElement(content)){insert(element,content);continue;}
+content=Object.toHTML(content);tagName=((position=='before'||position=='after')?element.parentNode:element).tagName.toUpperCase();childNodes=Element._getContentFromAnonymousElement(tagName,content.stripScripts());if(position=='top'||position=='after')childNodes.reverse();childNodes.each(insert.curry(element));content.evalScripts.bind(content).defer();}
+return element;},wrap:function(element,wrapper,attributes){element=$(element);if(Object.isElement(wrapper))
+$(wrapper).writeAttribute(attributes||{});else if(Object.isString(wrapper))wrapper=new Element(wrapper,attributes);else wrapper=new Element('div',wrapper);if(element.parentNode)
+element.parentNode.replaceChild(wrapper,element);wrapper.appendChild(element);return wrapper;},inspect:function(element){element=$(element);var result='<'+element.tagName.toLowerCase();$H({'id':'id','className':'class'}).each(function(pair){var property=pair.first(),attribute=pair.last();var value=(element[property]||'').toString();if(value)result+=' '+attribute+'='+value.inspect(true);});return result+'>';},recursivelyCollect:function(element,property){element=$(element);var elements=[];while(element=element[property])
+if(element.nodeType==1)
+elements.push(Element.extend(element));return elements;},ancestors:function(element){return Element.recursivelyCollect(element,'parentNode');},descendants:function(element){return Element.select(element,"*");},firstDescendant:function(element){element=$(element).firstChild;while(element&&element.nodeType!=1)element=element.nextSibling;return $(element);},immediateDescendants:function(element){if(!(element=$(element).firstChild))return[];while(element&&element.nodeType!=1)element=element.nextSibling;if(element)return[element].concat($(element).nextSiblings());return[];},previousSiblings:function(element){return Element.recursivelyCollect(element,'previousSibling');},nextSiblings:function(element){return Element.recursivelyCollect(element,'nextSibling');},siblings:function(element){element=$(element);return Element.previousSiblings(element).reverse().concat(Element.nextSiblings(element));},match:function(element,selector){if(Object.isString(selector))
+selector=new Selector(selector);return selector.match($(element));},up:function(element,expression,index){element=$(element);if(arguments.length==1)return $(element.parentNode);var ancestors=Element.ancestors(element);return Object.isNumber(expression)?ancestors[expression]:Selector.findElement(ancestors,expression,index);},down:function(element,expression,index){element=$(element);if(arguments.length==1)return Element.firstDescendant(element);return Object.isNumber(expression)?Element.descendants(element)[expression]:Element.select(element,expression)[index||0];},previous:function(element,expression,index){element=$(element);if(arguments.length==1)return $(Selector.handlers.previousElementSibling(element));var previousSiblings=Element.previousSiblings(element);return Object.isNumber(expression)?previousSiblings[expression]:Selector.findElement(previousSiblings,expression,index);},next:function(element,expression,index){element=$(element);if(arguments.length==1)return $(Selector.handlers.nextElementSibling(element));var nextSiblings=Element.nextSiblings(element);return Object.isNumber(expression)?nextSiblings[expression]:Selector.findElement(nextSiblings,expression,index);},select:function(element){var args=Array.prototype.slice.call(arguments,1);return Selector.findChildElements(element,args);},adjacent:function(element){var args=Array.prototype.slice.call(arguments,1);return Selector.findChildElements(element.parentNode,args).without(element);},identify:function(element){element=$(element);var id=Element.readAttribute(element,'id');if(id)return id;do{id='anonymous_element_'+Element.idCounter++}while($(id));Element.writeAttribute(element,'id',id);return id;},readAttribute:function(element,name){element=$(element);if(Prototype.Browser.IE){var t=Element._attributeTranslations.read;if(t.values[name])return t.values[name](element,name);if(t.names[name])name=t.names[name];if(name.include(':')){return(!element.attributes||!element.attributes[name])?null:element.attributes[name].value;}}
+return element.getAttribute(name);},writeAttribute:function(element,name,value){element=$(element);var attributes={},t=Element._attributeTranslations.write;if(typeof name=='object')attributes=name;else attributes[name]=Object.isUndefined(value)?true:value;for(var attr in attributes){name=t.names[attr]||attr;value=attributes[attr];if(t.values[attr])name=t.values[attr](element,value);if(value===false||value===null)
+element.removeAttribute(name);else if(value===true)
+element.setAttribute(name,name);else element.setAttribute(name,value);}
+return element;},getHeight:function(element){return Element.getDimensions(element).height;},getWidth:function(element){return Element.getDimensions(element).width;},classNames:function(element){return new Element.ClassNames(element);},hasClassName:function(element,className){if(!(element=$(element)))return;var elementClassName=element.className;return(elementClassName.length>0&&(elementClassName==className||new RegExp("(^|\\s)"+className+"(\\s|$)").test(elementClassName)));},addClassName:function(element,className){if(!(element=$(element)))return;if(!Element.hasClassName(element,className))
+element.className+=(element.className?' ':'')+className;return element;},removeClassName:function(element,className){if(!(element=$(element)))return;element.className=element.className.replace(new RegExp("(^|\\s+)"+className+"(\\s+|$)"),' ').strip();return element;},toggleClassName:function(element,className){if(!(element=$(element)))return;return Element[Element.hasClassName(element,className)?'removeClassName':'addClassName'](element,className);},cleanWhitespace:function(element){element=$(element);var node=element.firstChild;while(node){var nextNode=node.nextSibling;if(node.nodeType==3&&!/\S/.test(node.nodeValue))
+element.removeChild(node);node=nextNode;}
+return element;},empty:function(element){return $(element).innerHTML.blank();},descendantOf:function(element,ancestor){element=$(element),ancestor=$(ancestor);if(element.compareDocumentPosition)
+return(element.compareDocumentPosition(ancestor)&8)===8;if(ancestor.contains)
+return ancestor.contains(element)&&ancestor!==element;while(element=element.parentNode)
+if(element==ancestor)return true;return false;},scrollTo:function(element){element=$(element);var pos=Element.cumulativeOffset(element);window.scrollTo(pos[0],pos[1]);return element;},getStyle:function(element,style){element=$(element);style=style=='float'?'cssFloat':style.camelize();var value=element.style[style];if(!value||value=='auto'){var css=document.defaultView.getComputedStyle(element,null);value=css?css[style]:null;}
+if(style=='opacity')return value?parseFloat(value):1.0;return value=='auto'?null:value;},getOpacity:function(element){return $(element).getStyle('opacity');},setStyle:function(element,styles){element=$(element);var elementStyle=element.style,match;if(Object.isString(styles)){element.style.cssText+=';'+styles;return styles.include('opacity')?element.setOpacity(styles.match(/opacity:\s*(\d?\.?\d*)/)[1]):element;}
+for(var property in styles)
+if(property=='opacity')element.setOpacity(styles[property]);else
+elementStyle[(property=='float'||property=='cssFloat')?(Object.isUndefined(elementStyle.styleFloat)?'cssFloat':'styleFloat'):property]=styles[property];return element;},setOpacity:function(element,value){element=$(element);element.style.opacity=(value==1||value==='')?'':(value<0.00001)?0:value;return element;},getDimensions:function(element){element=$(element);var display=Element.getStyle(element,'display');if(display!='none'&&display!=null)
+return{width:element.offsetWidth,height:element.offsetHeight};var els=element.style;var originalVisibility=els.visibility;var originalPosition=els.position;var originalDisplay=els.display;els.visibility='hidden';if(originalPosition!='fixed')
+els.position='absolute';els.display='block';var originalWidth=element.clientWidth;var originalHeight=element.clientHeight;els.display=originalDisplay;els.position=originalPosition;els.visibility=originalVisibility;return{width:originalWidth,height:originalHeight};},makePositioned:function(element){element=$(element);var pos=Element.getStyle(element,'position');if(pos=='static'||!pos){element._madePositioned=true;element.style.position='relative';if(Prototype.Browser.Opera){element.style.top=0;element.style.left=0;}}
+return element;},undoPositioned:function(element){element=$(element);if(element._madePositioned){element._madePositioned=undefined;element.style.position=element.style.top=element.style.left=element.style.bottom=element.style.right='';}
+return element;},makeClipping:function(element){element=$(element);if(element._overflow)return element;element._overflow=Element.getStyle(element,'overflow')||'auto';if(element._overflow!=='hidden')
+element.style.overflow='hidden';return element;},undoClipping:function(element){element=$(element);if(!element._overflow)return element;element.style.overflow=element._overflow=='auto'?'':element._overflow;element._overflow=null;return element;},cumulativeOffset:function(element){var valueT=0,valueL=0;do{valueT+=element.offsetTop||0;valueL+=element.offsetLeft||0;element=element.offsetParent;}while(element);return Element._returnOffset(valueL,valueT);},positionedOffset:function(element){var valueT=0,valueL=0;do{valueT+=element.offsetTop||0;valueL+=element.offsetLeft||0;element=element.offsetParent;if(element){if(element.tagName.toUpperCase()=='BODY')break;var p=Element.getStyle(element,'position');if(p!=='static')break;}}while(element);return Element._returnOffset(valueL,valueT);},absolutize:function(element){element=$(element);if(Element.getStyle(element,'position')=='absolute')return element;var offsets=Element.positionedOffset(element);var top=offsets[1];var left=offsets[0];var width=element.clientWidth;var height=element.clientHeight;element._originalLeft=left-parseFloat(element.style.left||0);element._originalTop=top-parseFloat(element.style.top||0);element._originalWidth=element.style.width;element._originalHeight=element.style.height;element.style.position='absolute';element.style.top=top+'px';element.style.left=left+'px';element.style.width=width+'px';element.style.height=height+'px';return element;},relativize:function(element){element=$(element);if(Element.getStyle(element,'position')=='relative')return element;element.style.position='relative';var top=parseFloat(element.style.top||0)-(element._originalTop||0);var left=parseFloat(element.style.left||0)-(element._originalLeft||0);element.style.top=top+'px';element.style.left=left+'px';element.style.height=element._originalHeight;element.style.width=element._originalWidth;return element;},cumulativeScrollOffset:function(element){var valueT=0,valueL=0;do{valueT+=element.scrollTop||0;valueL+=element.scrollLeft||0;element=element.parentNode;}while(element);return Element._returnOffset(valueL,valueT);},getOffsetParent:function(element){if(element.offsetParent)return $(element.offsetParent);if(element==document.body)return $(element);while((element=element.parentNode)&&element!=document.body)
+if(Element.getStyle(element,'position')!='static')
+return $(element);return $(document.body);},viewportOffset:function(forElement){var valueT=0,valueL=0;var element=forElement;do{valueT+=element.offsetTop||0;valueL+=element.offsetLeft||0;if(element.offsetParent==document.body&&Element.getStyle(element,'position')=='absolute')break;}while(element=element.offsetParent);element=forElement;do{if(!Prototype.Browser.Opera||(element.tagName&&(element.tagName.toUpperCase()=='BODY'))){valueT-=element.scrollTop||0;valueL-=element.scrollLeft||0;}}while(element=element.parentNode);return Element._returnOffset(valueL,valueT);},clonePosition:function(element,source){var options=Object.extend({setLeft:true,setTop:true,setWidth:true,setHeight:true,offsetTop:0,offsetLeft:0},arguments[2]||{});source=$(source);var p=Element.viewportOffset(source);element=$(element);var delta=[0,0];var parent=null;if(Element.getStyle(element,'position')=='absolute'){parent=Element.getOffsetParent(element);delta=Element.viewportOffset(parent);}
+if(parent==document.body){delta[0]-=document.body.offsetLeft;delta[1]-=document.body.offsetTop;}
+if(options.setLeft)element.style.left=(p[0]-delta[0]+options.offsetLeft)+'px';if(options.setTop)element.style.top=(p[1]-delta[1]+options.offsetTop)+'px';if(options.setWidth)element.style.width=source.offsetWidth+'px';if(options.setHeight)element.style.height=source.offsetHeight+'px';return element;}};Object.extend(Element.Methods,{getElementsBySelector:Element.Methods.select,childElements:Element.Methods.immediateDescendants});Element._attributeTranslations={write:{names:{className:'class',htmlFor:'for'},values:{}}};if(Prototype.Browser.Opera){Element.Methods.getStyle=Element.Methods.getStyle.wrap(function(proceed,element,style){switch(style){case'left':case'top':case'right':case'bottom':if(proceed(element,'position')==='static')return null;case'height':case'width':if(!Element.visible(element))return null;var dim=parseInt(proceed(element,style),10);if(dim!==element['offset'+style.capitalize()])
+return dim+'px';var properties;if(style==='height'){properties=['border-top-width','padding-top','padding-bottom','border-bottom-width'];}
+else{properties=['border-left-width','padding-left','padding-right','border-right-width'];}
+return properties.inject(dim,function(memo,property){var val=proceed(element,property);return val===null?memo:memo-parseInt(val,10);})+'px';default:return proceed(element,style);}});Element.Methods.readAttribute=Element.Methods.readAttribute.wrap(function(proceed,element,attribute){if(attribute==='title')return element.title;return proceed(element,attribute);});}
+else if(Prototype.Browser.IE){Element.Methods.getOffsetParent=Element.Methods.getOffsetParent.wrap(function(proceed,element){element=$(element);try{element.offsetParent}
+catch(e){return $(document.body)}
+var position=element.getStyle('position');if(position!=='static')return proceed(element);element.setStyle({position:'relative'});var value=proceed(element);element.setStyle({position:position});return value;});$w('positionedOffset viewportOffset').each(function(method){Element.Methods[method]=Element.Methods[method].wrap(function(proceed,element){element=$(element);try{element.offsetParent}
+catch(e){return Element._returnOffset(0,0)}
+var position=element.getStyle('position');if(position!=='static')return proceed(element);var offsetParent=element.getOffsetParent();if(offsetParent&&offsetParent.getStyle('position')==='fixed')
+offsetParent.setStyle({zoom:1});element.setStyle({position:'relative'});var value=proceed(element);element.setStyle({position:position});return value;});});Element.Methods.cumulativeOffset=Element.Methods.cumulativeOffset.wrap(function(proceed,element){try{element.offsetParent}
+catch(e){return Element._returnOffset(0,0)}
+return proceed(element);});Element.Methods.getStyle=function(element,style){element=$(element);style=(style=='float'||style=='cssFloat')?'styleFloat':style.camelize();var value=element.style[style];if(!value&&element.currentStyle)value=element.currentStyle[style];if(style=='opacity'){if(value=(element.getStyle('filter')||'').match(/alpha\(opacity=(.*)\)/))
+if(value[1])return parseFloat(value[1])/100;return 1.0;}
+if(value=='auto'){if((style=='width'||style=='height')&&(element.getStyle('display')!='none'))
+return element['offset'+style.capitalize()]+'px';return null;}
+return value;};Element.Methods.setOpacity=function(element,value){function stripAlpha(filter){return filter.replace(/alpha\([^\)]*\)/gi,'');}
+element=$(element);var currentStyle=element.currentStyle;if((currentStyle&&!currentStyle.hasLayout)||(!currentStyle&&element.style.zoom=='normal'))
+element.style.zoom=1;var filter=element.getStyle('filter'),style=element.style;if(value==1||value===''){(filter=stripAlpha(filter))?style.filter=filter:style.removeAttribute('filter');return element;}else if(value<0.00001)value=0;style.filter=stripAlpha(filter)+'alpha(opacity='+(value*100)+')';return element;};Element._attributeTranslations=(function(){var classProp='className';var forProp='for';var el=document.createElement('div');el.setAttribute(classProp,'x');if(el.className!=='x'){el.setAttribute('class','x');if(el.className==='x'){classProp='class';}}
+el=null;el=document.createElement('label');el.setAttribute(forProp,'x');if(el.htmlFor!=='x'){el.setAttribute('htmlFor','x');if(el.htmlFor==='x'){forProp='htmlFor';}}
+el=null;return{read:{names:{'class':classProp,'className':classProp,'for':forProp,'htmlFor':forProp},values:{_getAttr:function(element,attribute){return element.getAttribute(attribute);},_getAttr2:function(element,attribute){return element.getAttribute(attribute,2);},_getAttrNode:function(element,attribute){var node=element.getAttributeNode(attribute);return node?node.value:"";},_getEv:(function(){var el=document.createElement('div');el.onclick=Prototype.emptyFunction;var value=el.getAttribute('onclick');var f;if(String(value).indexOf('{')>-1){f=function(element,attribute){attribute=element.getAttribute(attribute);if(!attribute)return null;attribute=attribute.toString();attribute=attribute.split('{')[1];attribute=attribute.split('}')[0];return attribute.strip();};}
+else if(value===''){f=function(element,attribute){attribute=element.getAttribute(attribute);if(!attribute)return null;return attribute.strip();};}
+el=null;return f;})(),_flag:function(element,attribute){return $(element).hasAttribute(attribute)?attribute:null;},style:function(element){return element.style.cssText.toLowerCase();},title:function(element){return element.title;}}}}})();Element._attributeTranslations.write={names:Object.extend({cellpadding:'cellPadding',cellspacing:'cellSpacing'},Element._attributeTranslations.read.names),values:{checked:function(element,value){element.checked=!!value;},style:function(element,value){element.style.cssText=value?value:'';}}};Element._attributeTranslations.has={};$w('colSpan rowSpan vAlign dateTime accessKey tabIndex '+'encType maxLength readOnly longDesc frameBorder').each(function(attr){Element._attributeTranslations.write.names[attr.toLowerCase()]=attr;Element._attributeTranslations.has[attr.toLowerCase()]=attr;});(function(v){Object.extend(v,{href:v._getAttr2,src:v._getAttr2,type:v._getAttr,action:v._getAttrNode,disabled:v._flag,checked:v._flag,readonly:v._flag,multiple:v._flag,onload:v._getEv,onunload:v._getEv,onclick:v._getEv,ondblclick:v._getEv,onmousedown:v._getEv,onmouseup:v._getEv,onmouseover:v._getEv,onmousemove:v._getEv,onmouseout:v._getEv,onfocus:v._getEv,onblur:v._getEv,onkeypress:v._getEv,onkeydown:v._getEv,onkeyup:v._getEv,onsubmit:v._getEv,onreset:v._getEv,onselect:v._getEv,onchange:v._getEv});})(Element._attributeTranslations.read.values);if(Prototype.BrowserFeatures.ElementExtensions){(function(){function _descendants(element){var nodes=element.getElementsByTagName('*'),results=[];for(var i=0,node;node=nodes[i];i++)
+if(node.tagName!=="!")
+results.push(node);return results;}
+Element.Methods.down=function(element,expression,index){element=$(element);if(arguments.length==1)return element.firstDescendant();return Object.isNumber(expression)?_descendants(element)[expression]:Element.select(element,expression)[index||0];}})();}}
+else if(Prototype.Browser.Gecko&&/rv:1\.8\.0/.test(navigator.userAgent)){Element.Methods.setOpacity=function(element,value){element=$(element);element.style.opacity=(value==1)?0.999999:(value==='')?'':(value<0.00001)?0:value;return element;};}
+else if(Prototype.Browser.WebKit){Element.Methods.setOpacity=function(element,value){element=$(element);element.style.opacity=(value==1||value==='')?'':(value<0.00001)?0:value;if(value==1)
+if(element.tagName.toUpperCase()=='IMG'&&element.width){element.width++;element.width--;}else try{var n=document.createTextNode(' ');element.appendChild(n);element.removeChild(n);}catch(e){}
+return element;};Element.Methods.cumulativeOffset=function(element){var valueT=0,valueL=0;do{valueT+=element.offsetTop||0;valueL+=element.offsetLeft||0;if(element.offsetParent==document.body)
+if(Element.getStyle(element,'position')=='absolute')break;element=element.offsetParent;}while(element);return Element._returnOffset(valueL,valueT);};}
+if('outerHTML'in document.documentElement){Element.Methods.replace=function(element,content){element=$(element);if(content&&content.toElement)content=content.toElement();if(Object.isElement(content)){element.parentNode.replaceChild(content,element);return element;}
+content=Object.toHTML(content);var parent=element.parentNode,tagName=parent.tagName.toUpperCase();if(Element._insertionTranslations.tags[tagName]){var nextSibling=element.next();var fragments=Element._getContentFromAnonymousElement(tagName,content.stripScripts());parent.removeChild(element);if(nextSibling)
+fragments.each(function(node){parent.insertBefore(node,nextSibling)});else
+fragments.each(function(node){parent.appendChild(node)});}
+else element.outerHTML=content.stripScripts();content.evalScripts.bind(content).defer();return element;};}
+Element._returnOffset=function(l,t){var result=[l,t];result.left=l;result.top=t;return result;};Element._getContentFromAnonymousElement=function(tagName,html){var div=new Element('div'),t=Element._insertionTranslations.tags[tagName];if(t){div.innerHTML=t[0]+html+t[1];t[2].times(function(){div=div.firstChild});}else div.innerHTML=html;return $A(div.childNodes);};Element._insertionTranslations={before:function(element,node){element.parentNode.insertBefore(node,element);},top:function(element,node){element.insertBefore(node,element.firstChild);},bottom:function(element,node){element.appendChild(node);},after:function(element,node){element.parentNode.insertBefore(node,element.nextSibling);},tags:{TABLE:['<table>','</table>',1],TBODY:['<table><tbody>','</tbody></table>',2],TR:['<table><tbody><tr>','</tr></tbody></table>',3],TD:['<table><tbody><tr><td>','</td></tr></tbody></table>',4],SELECT:['<select>','</select>',1]}};(function(){var tags=Element._insertionTranslations.tags;Object.extend(tags,{THEAD:tags.TBODY,TFOOT:tags.TBODY,TH:tags.TD});})();Element.Methods.Simulated={hasAttribute:function(element,attribute){attribute=Element._attributeTranslations.has[attribute]||attribute;var node=$(element).getAttributeNode(attribute);return!!(node&&node.specified);}};Element.Methods.ByTag={};Object.extend(Element,Element.Methods);(function(div){if(!Prototype.BrowserFeatures.ElementExtensions&&div['__proto__']){window.HTMLElement={};window.HTMLElement.prototype=div['__proto__'];Prototype.BrowserFeatures.ElementExtensions=true;}
+div=null;})(document.createElement('div'))
+Element.extend=(function(){function checkDeficiency(tagName){if(typeof window.Element!='undefined'){var proto=window.Element.prototype;if(proto){var id='_'+(Math.random()+'').slice(2);var el=document.createElement(tagName);proto[id]='x';var isBuggy=(el[id]!=='x');delete proto[id];el=null;return isBuggy;}}
+return false;}
+function extendElementWith(element,methods){for(var property in methods){var value=methods[property];if(Object.isFunction(value)&&!(property in element))
+element[property]=value.methodize();}}
+var HTMLOBJECTELEMENT_PROTOTYPE_BUGGY=checkDeficiency('object');if(Prototype.BrowserFeatures.SpecificElementExtensions){if(HTMLOBJECTELEMENT_PROTOTYPE_BUGGY){return function(element){if(element&&typeof element._extendedByPrototype=='undefined'){var t=element.tagName;if(t&&(/^(?:object|applet|embed)$/i.test(t))){extendElementWith(element,Element.Methods);extendElementWith(element,Element.Methods.Simulated);extendElementWith(element,Element.Methods.ByTag[t.toUpperCase()]);}}
+return element;}}
+return Prototype.K;}
+var Methods={},ByTag=Element.Methods.ByTag;var extend=Object.extend(function(element){if(!element||typeof element._extendedByPrototype!='undefined'||element.nodeType!=1||element==window)return element;var methods=Object.clone(Methods),tagName=element.tagName.toUpperCase();if(ByTag[tagName])Object.extend(methods,ByTag[tagName]);extendElementWith(element,methods);element._extendedByPrototype=Prototype.emptyFunction;return element;},{refresh:function(){if(!Prototype.BrowserFeatures.ElementExtensions){Object.extend(Methods,Element.Methods);Object.extend(Methods,Element.Methods.Simulated);}}});extend.refresh();return extend;})();Element.hasAttribute=function(element,attribute){if(element.hasAttribute)return element.hasAttribute(attribute);return Element.Methods.Simulated.hasAttribute(element,attribute);};Element.addMethods=function(methods){var F=Prototype.BrowserFeatures,T=Element.Methods.ByTag;if(!methods){Object.extend(Form,Form.Methods);Object.extend(Form.Element,Form.Element.Methods);Object.extend(Element.Methods.ByTag,{"FORM":Object.clone(Form.Methods),"INPUT":Object.clone(Form.Element.Methods),"SELECT":Object.clone(Form.Element.Methods),"TEXTAREA":Object.clone(Form.Element.Methods)});}
+if(arguments.length==2){var tagName=methods;methods=arguments[1];}
+if(!tagName)Object.extend(Element.Methods,methods||{});else{if(Object.isArray(tagName))tagName.each(extend);else extend(tagName);}
+function extend(tagName){tagName=tagName.toUpperCase();if(!Element.Methods.ByTag[tagName])
+Element.Methods.ByTag[tagName]={};Object.extend(Element.Methods.ByTag[tagName],methods);}
+function copy(methods,destination,onlyIfAbsent){onlyIfAbsent=onlyIfAbsent||false;for(var property in methods){var value=methods[property];if(!Object.isFunction(value))continue;if(!onlyIfAbsent||!(property in destination))
+destination[property]=value.methodize();}}
+function findDOMClass(tagName){var klass;var trans={"OPTGROUP":"OptGroup","TEXTAREA":"TextArea","P":"Paragraph","FIELDSET":"FieldSet","UL":"UList","OL":"OList","DL":"DList","DIR":"Directory","H1":"Heading","H2":"Heading","H3":"Heading","H4":"Heading","H5":"Heading","H6":"Heading","Q":"Quote","INS":"Mod","DEL":"Mod","A":"Anchor","IMG":"Image","CAPTION":"TableCaption","COL":"TableCol","COLGROUP":"TableCol","THEAD":"TableSection","TFOOT":"TableSection","TBODY":"TableSection","TR":"TableRow","TH":"TableCell","TD":"TableCell","FRAMESET":"FrameSet","IFRAME":"IFrame"};if(trans[tagName])klass='HTML'+trans[tagName]+'Element';if(window[klass])return window[klass];klass='HTML'+tagName+'Element';if(window[klass])return window[klass];klass='HTML'+tagName.capitalize()+'Element';if(window[klass])return window[klass];var element=document.createElement(tagName);var proto=element['__proto__']||element.constructor.prototype;element=null;return proto;}
+var elementPrototype=window.HTMLElement?HTMLElement.prototype:Element.prototype;if(F.ElementExtensions){copy(Element.Methods,elementPrototype);copy(Element.Methods.Simulated,elementPrototype,true);}
+if(F.SpecificElementExtensions){for(var tag in Element.Methods.ByTag){var klass=findDOMClass(tag);if(Object.isUndefined(klass))continue;copy(T[tag],klass.prototype);}}
+Object.extend(Element,Element.Methods);delete Element.ByTag;if(Element.extend.refresh)Element.extend.refresh();Element.cache={};};document.viewport={getDimensions:function(){return{width:this.getWidth(),height:this.getHeight()};},getScrollOffsets:function(){return Element._returnOffset(window.pageXOffset||document.documentElement.scrollLeft||document.body.scrollLeft,window.pageYOffset||document.documentElement.scrollTop||document.body.scrollTop);}};(function(viewport){var B=Prototype.Browser,doc=document,element,property={};function getRootElement(){if(B.WebKit&&!doc.evaluate)
+return document;if(B.Opera&&window.parseFloat(window.opera.version())<9.5)
+return document.body;return document.documentElement;}
+function define(D){if(!element)element=getRootElement();property[D]='client'+D;viewport['get'+D]=function(){return element[property[D]]};return viewport['get'+D]();}
+viewport.getWidth=define.curry('Width');viewport.getHeight=define.curry('Height');})(document.viewport);Element.Storage={UID:1};Element.addMethods({getStorage:function(element){if(!(element=$(element)))return;var uid;if(element===window){uid=0;}else{if(typeof element._prototypeUID==="undefined")
+element._prototypeUID=[Element.Storage.UID++];uid=element._prototypeUID[0];}
+if(!Element.Storage[uid])
+Element.Storage[uid]=$H();return Element.Storage[uid];},store:function(element,key,value){if(!(element=$(element)))return;if(arguments.length===2){Element.getStorage(element).update(key);}else{Element.getStorage(element).set(key,value);}
+return element;},retrieve:function(element,key,defaultValue){if(!(element=$(element)))return;var hash=Element.getStorage(element),value=hash.get(key);if(Object.isUndefined(value)){hash.set(key,defaultValue);value=defaultValue;}
+return value;},clone:function(element,deep){if(!(element=$(element)))return;var clone=element.cloneNode(deep);clone._prototypeUID=void 0;if(deep){var descendants=Element.select(clone,'*'),i=descendants.length;while(i--){descendants[i]._prototypeUID=void 0;}}
+return Element.extend(clone);}});var Selector=Class.create({initialize:function(expression){this.expression=expression.strip();if(this.shouldUseSelectorsAPI()){this.mode='selectorsAPI';}else if(this.shouldUseXPath()){this.mode='xpath';this.compileXPathMatcher();}else{this.mode="normal";this.compileMatcher();}},shouldUseXPath:(function(){var IS_DESCENDANT_SELECTOR_BUGGY=(function(){var isBuggy=false;if(document.evaluate&&window.XPathResult){var el=document.createElement('div');el.innerHTML='<ul><li></li></ul><div><ul><li></li></ul></div>';var xpath=".//*[local-name()='ul' or local-name()='UL']"+"//*[local-name()='li' or local-name()='LI']";var result=document.evaluate(xpath,el,null,XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,null);isBuggy=(result.snapshotLength!==2);el=null;}
+return isBuggy;})();return function(){if(!Prototype.BrowserFeatures.XPath)return false;var e=this.expression;if(Prototype.Browser.WebKit&&(e.include("-of-type")||e.include(":empty")))
+return false;if((/(\[[\w-]*?:|:checked)/).test(e))
+return false;if(IS_DESCENDANT_SELECTOR_BUGGY)return false;return true;}})(),shouldUseSelectorsAPI:function(){if(!Prototype.BrowserFeatures.SelectorsAPI)return false;if(Selector.CASE_INSENSITIVE_CLASS_NAMES)return false;if(!Selector._div)Selector._div=new Element('div');try{Selector._div.querySelector(this.expression);}catch(e){return false;}
+return true;},compileMatcher:function(){var e=this.expression,ps=Selector.patterns,h=Selector.handlers,c=Selector.criteria,le,p,m,len=ps.length,name;if(Selector._cache[e]){this.matcher=Selector._cache[e];return;}
+this.matcher=["this.matcher = function(root) {","var r = root, h = Selector.handlers, c = false, n;"];while(e&&le!=e&&(/\S/).test(e)){le=e;for(var i=0;i<len;i++){p=ps[i].re;name=ps[i].name;if(m=e.match(p)){this.matcher.push(Object.isFunction(c[name])?c[name](m):new Template(c[name]).evaluate(m));e=e.replace(m[0],'');break;}}}
+this.matcher.push("return h.unique(n);\n}");eval(this.matcher.join('\n'));Selector._cache[this.expression]=this.matcher;},compileXPathMatcher:function(){var e=this.expression,ps=Selector.patterns,x=Selector.xpath,le,m,len=ps.length,name;if(Selector._cache[e]){this.xpath=Selector._cache[e];return;}
+this.matcher=['.//*'];while(e&&le!=e&&(/\S/).test(e)){le=e;for(var i=0;i<len;i++){name=ps[i].name;if(m=e.match(ps[i].re)){this.matcher.push(Object.isFunction(x[name])?x[name](m):new Template(x[name]).evaluate(m));e=e.replace(m[0],'');break;}}}
+this.xpath=this.matcher.join('');Selector._cache[this.expression]=this.xpath;},findElements:function(root){root=root||document;var e=this.expression,results;switch(this.mode){case'selectorsAPI':if(root!==document){var oldId=root.id,id=$(root).identify();id=id.replace(/([\.:])/g,"\\$1");e="#"+id+" "+e;}
+results=$A(root.querySelectorAll(e)).map(Element.extend);root.id=oldId;return results;case'xpath':return document._getElementsByXPath(this.xpath,root);default:return this.matcher(root);}},match:function(element){this.tokens=[];var e=this.expression,ps=Selector.patterns,as=Selector.assertions;var le,p,m,len=ps.length,name;while(e&&le!==e&&(/\S/).test(e)){le=e;for(var i=0;i<len;i++){p=ps[i].re;name=ps[i].name;if(m=e.match(p)){if(as[name]){this.tokens.push([name,Object.clone(m)]);e=e.replace(m[0],'');}else{return this.findElements(document).include(element);}}}}
+var match=true,name,matches;for(var i=0,token;token=this.tokens[i];i++){name=token[0],matches=token[1];if(!Selector.assertions[name](element,matches)){match=false;break;}}
+return match;},toString:function(){return this.expression;},inspect:function(){return"#<Selector:"+this.expression.inspect()+">";}});if(Prototype.BrowserFeatures.SelectorsAPI&&document.compatMode==='BackCompat'){Selector.CASE_INSENSITIVE_CLASS_NAMES=(function(){var div=document.createElement('div'),span=document.createElement('span');div.id="prototype_test_id";span.className='Test';div.appendChild(span);var isIgnored=(div.querySelector('#prototype_test_id .test')!==null);div=span=null;return isIgnored;})();}
+Object.extend(Selector,{_cache:{},xpath:{descendant:"//*",child:"/*",adjacent:"/following-sibling::*[1]",laterSibling:'/following-sibling::*',tagName:function(m){if(m[1]=='*')return'';return"[local-name()='"+m[1].toLowerCase()+"' or local-name()='"+m[1].toUpperCase()+"']";},className:"[contains(concat(' ', @class, ' '), ' #{1} ')]",id:"[@id='#{1}']",attrPresence:function(m){m[1]=m[1].toLowerCase();return new Template("[@#{1}]").evaluate(m);},attr:function(m){m[1]=m[1].toLowerCase();m[3]=m[5]||m[6];return new Template(Selector.xpath.operators[m[2]]).evaluate(m);},pseudo:function(m){var h=Selector.xpath.pseudos[m[1]];if(!h)return'';if(Object.isFunction(h))return h(m);return new Template(Selector.xpath.pseudos[m[1]]).evaluate(m);},operators:{'=':"[@#{1}='#{3}']",'!=':"[@#{1}!='#{3}']",'^=':"[starts-with(@#{1}, '#{3}')]",'$=':"[substring(@#{1}, (string-length(@#{1}) - string-length('#{3}') + 1))='#{3}']",'*=':"[contains(@#{1}, '#{3}')]",'~=':"[contains(concat(' ', @#{1}, ' '), ' #{3} ')]",'|=':"[contains(concat('-', @#{1}, '-'), '-#{3}-')]"},pseudos:{'first-child':'[not(preceding-sibling::*)]','last-child':'[not(following-sibling::*)]','only-child':'[not(preceding-sibling::* or following-sibling::*)]','empty':"[count(*) = 0 and (count(text()) = 0)]",'checked':"[@checked]",'disabled':"[(@disabled) and (@type!='hidden')]",'enabled':"[not(@disabled) and (@type!='hidden')]",'not':function(m){var e=m[6],p=Selector.patterns,x=Selector.xpath,le,v,len=p.length,name;var exclusion=[];while(e&&le!=e&&(/\S/).test(e)){le=e;for(var i=0;i<len;i++){name=p[i].name
+if(m=e.match(p[i].re)){v=Object.isFunction(x[name])?x[name](m):new Template(x[name]).evaluate(m);exclusion.push("("+v.substring(1,v.length-1)+")");e=e.replace(m[0],'');break;}}}
+return"[not("+exclusion.join(" and ")+")]";},'nth-child':function(m){return Selector.xpath.pseudos.nth("(count(./preceding-sibling::*) + 1) ",m);},'nth-last-child':function(m){return Selector.xpath.pseudos.nth("(count(./following-sibling::*) + 1) ",m);},'nth-of-type':function(m){return Selector.xpath.pseudos.nth("position() ",m);},'nth-last-of-type':function(m){return Selector.xpath.pseudos.nth("(last() + 1 - position()) ",m);},'first-of-type':function(m){m[6]="1";return Selector.xpath.pseudos['nth-of-type'](m);},'last-of-type':function(m){m[6]="1";return Selector.xpath.pseudos['nth-last-of-type'](m);},'only-of-type':function(m){var p=Selector.xpath.pseudos;return p['first-of-type'](m)+p['last-of-type'](m);},nth:function(fragment,m){var mm,formula=m[6],predicate;if(formula=='even')formula='2n+0';if(formula=='odd')formula='2n+1';if(mm=formula.match(/^(\d+)$/))
+return'['+fragment+"= "+mm[1]+']';if(mm=formula.match(/^(-?\d*)?n(([+-])(\d+))?/)){if(mm[1]=="-")mm[1]=-1;var a=mm[1]?Number(mm[1]):1;var b=mm[2]?Number(mm[2]):0;predicate="[((#{fragment} - #{b}) mod #{a} = 0) and "+"((#{fragment} - #{b}) div #{a} >= 0)]";return new Template(predicate).evaluate({fragment:fragment,a:a,b:b});}}}},criteria:{tagName:'n = h.tagName(n, r, "#{1}", c);      c = false;',className:'n = h.className(n, r, "#{1}", c);    c = false;',id:'n = h.id(n, r, "#{1}", c);           c = false;',attrPresence:'n = h.attrPresence(n, r, "#{1}", c); c = false;',attr:function(m){m[3]=(m[5]||m[6]);return new Template('n = h.attr(n, r, "#{1}", "#{3}", "#{2}", c); c = false;').evaluate(m);},pseudo:function(m){if(m[6])m[6]=m[6].replace(/"/g,'\\"');return new Template('n = h.pseudo(n, "#{1}", "#{6}", r, c); c = false;').evaluate(m);},descendant:'c = "descendant";',child:'c = "child";',adjacent:'c = "adjacent";',laterSibling:'c = "laterSibling";'},patterns:[{name:'laterSibling',re:/^\s*~\s*/},{name:'child',re:/^\s*>\s*/},{name:'adjacent',re:/^\s*\+\s*/},{name:'descendant',re:/^\s/},{name:'tagName',re:/^\s*(\*|[\w\-]+)(\b|$)?/},{name:'id',re:/^#([\w\-\*]+)(\b|$)/},{name:'className',re:/^\.([\w\-\*]+)(\b|$)/},{name:'pseudo',re:/^:((first|last|nth|nth-last|only)(-child|-of-type)|empty|checked|(en|dis)abled|not)(\((.*?)\))?(\b|$|(?=\s|[:+~>]))/},{name:'attrPresence',re:/^\[((?:[\w-]+:)?[\w-]+)\]/},{name:'attr',re:/\[((?:[\w-]*:)?[\w-]+)\s*(?:([!^$*~|]?=)\s*((['"])([^\4]*?)\4|([^'"][^\]]*?)))?\]/}],assertions:{tagName:function(element,matches){return matches[1].toUpperCase()==element.tagName.toUpperCase();},className:function(element,matches){return Element.hasClassName(element,matches[1]);},id:function(element,matches){return element.id===matches[1];},attrPresence:function(element,matches){return Element.hasAttribute(element,matches[1]);},attr:function(element,matches){var nodeValue=Element.readAttribute(element,matches[1]);return nodeValue&&Selector.operators[matches[2]](nodeValue,matches[5]||matches[6]);}},handlers:{concat:function(a,b){for(var i=0,node;node=b[i];i++)
+a.push(node);return a;},mark:function(nodes){var _true=Prototype.emptyFunction;for(var i=0,node;node=nodes[i];i++)
+node._countedByPrototype=_true;return nodes;},unmark:(function(){var PROPERTIES_ATTRIBUTES_MAP=(function(){var el=document.createElement('div'),isBuggy=false,propName='_countedByPrototype',value='x'
+el[propName]=value;isBuggy=(el.getAttribute(propName)===value);el=null;return isBuggy;})();return PROPERTIES_ATTRIBUTES_MAP?function(nodes){for(var i=0,node;node=nodes[i];i++)
+node.removeAttribute('_countedByPrototype');return nodes;}:function(nodes){for(var i=0,node;node=nodes[i];i++)
+node._countedByPrototype=void 0;return nodes;}})(),index:function(parentNode,reverse,ofType){parentNode._countedByPrototype=Prototype.emptyFunction;if(reverse){for(var nodes=parentNode.childNodes,i=nodes.length-1,j=1;i>=0;i--){var node=nodes[i];if(node.nodeType==1&&(!ofType||node._countedByPrototype))node.nodeIndex=j++;}}else{for(var i=0,j=1,nodes=parentNode.childNodes;node=nodes[i];i++)
+if(node.nodeType==1&&(!ofType||node._countedByPrototype))node.nodeIndex=j++;}},unique:function(nodes){if(nodes.length==0)return nodes;var results=[],n;for(var i=0,l=nodes.length;i<l;i++)
+if(typeof(n=nodes[i])._countedByPrototype=='undefined'){n._countedByPrototype=Prototype.emptyFunction;results.push(Element.extend(n));}
+return Selector.handlers.unmark(results);},descendant:function(nodes){var h=Selector.handlers;for(var i=0,results=[],node;node=nodes[i];i++)
+h.concat(results,node.getElementsByTagName('*'));return results;},child:function(nodes){var h=Selector.handlers;for(var i=0,results=[],node;node=nodes[i];i++){for(var j=0,child;child=node.childNodes[j];j++)
+if(child.nodeType==1&&child.tagName!='!')results.push(child);}
+return results;},adjacent:function(nodes){for(var i=0,results=[],node;node=nodes[i];i++){var next=this.nextElementSibling(node);if(next)results.push(next);}
+return results;},laterSibling:function(nodes){var h=Selector.handlers;for(var i=0,results=[],node;node=nodes[i];i++)
+h.concat(results,Element.nextSiblings(node));return results;},nextElementSibling:function(node){while(node=node.nextSibling)
+if(node.nodeType==1)return node;return null;},previousElementSibling:function(node){while(node=node.previousSibling)
+if(node.nodeType==1)return node;return null;},tagName:function(nodes,root,tagName,combinator){var uTagName=tagName.toUpperCase();var results=[],h=Selector.handlers;if(nodes){if(combinator){if(combinator=="descendant"){for(var i=0,node;node=nodes[i];i++)
+h.concat(results,node.getElementsByTagName(tagName));return results;}else nodes=this[combinator](nodes);if(tagName=="*")return nodes;}
+for(var i=0,node;node=nodes[i];i++)
+if(node.tagName.toUpperCase()===uTagName)results.push(node);return results;}else return root.getElementsByTagName(tagName);},id:function(nodes,root,id,combinator){var targetNode=$(id),h=Selector.handlers;if(root==document){if(!targetNode)return[];if(!nodes)return[targetNode];}else{if(!root.sourceIndex||root.sourceIndex<1){var nodes=root.getElementsByTagName('*');for(var j=0,node;node=nodes[j];j++){if(node.id===id)return[node];}}}
+if(nodes){if(combinator){if(combinator=='child'){for(var i=0,node;node=nodes[i];i++)
+if(targetNode.parentNode==node)return[targetNode];}else if(combinator=='descendant'){for(var i=0,node;node=nodes[i];i++)
+if(Element.descendantOf(targetNode,node))return[targetNode];}else if(combinator=='adjacent'){for(var i=0,node;node=nodes[i];i++)
+if(Selector.handlers.previousElementSibling(targetNode)==node)
+return[targetNode];}else nodes=h[combinator](nodes);}
+for(var i=0,node;node=nodes[i];i++)
+if(node==targetNode)return[targetNode];return[];}
+return(targetNode&&Element.descendantOf(targetNode,root))?[targetNode]:[];},className:function(nodes,root,className,combinator){if(nodes&&combinator)nodes=this[combinator](nodes);return Selector.handlers.byClassName(nodes,root,className);},byClassName:function(nodes,root,className){if(!nodes)nodes=Selector.handlers.descendant([root]);var needle=' '+className+' ';for(var i=0,results=[],node,nodeClassName;node=nodes[i];i++){nodeClassName=node.className;if(nodeClassName.length==0)continue;if(nodeClassName==className||(' '+nodeClassName+' ').include(needle))
+results.push(node);}
+return results;},attrPresence:function(nodes,root,attr,combinator){if(!nodes)nodes=root.getElementsByTagName("*");if(nodes&&combinator)nodes=this[combinator](nodes);var results=[];for(var i=0,node;node=nodes[i];i++)
+if(Element.hasAttribute(node,attr))results.push(node);return results;},attr:function(nodes,root,attr,value,operator,combinator){if(!nodes)nodes=root.getElementsByTagName("*");if(nodes&&combinator)nodes=this[combinator](nodes);var handler=Selector.operators[operator],results=[];for(var i=0,node;node=nodes[i];i++){var nodeValue=Element.readAttribute(node,attr);if(nodeValue===null)continue;if(handler(nodeValue,value))results.push(node);}
+return results;},pseudo:function(nodes,name,value,root,combinator){if(nodes&&combinator)nodes=this[combinator](nodes);if(!nodes)nodes=root.getElementsByTagName("*");return Selector.pseudos[name](nodes,value,root);}},pseudos:{'first-child':function(nodes,value,root){for(var i=0,results=[],node;node=nodes[i];i++){if(Selector.handlers.previousElementSibling(node))continue;results.push(node);}
+return results;},'last-child':function(nodes,value,root){for(var i=0,results=[],node;node=nodes[i];i++){if(Selector.handlers.nextElementSibling(node))continue;results.push(node);}
+return results;},'only-child':function(nodes,value,root){var h=Selector.handlers;for(var i=0,results=[],node;node=nodes[i];i++)
+if(!h.previousElementSibling(node)&&!h.nextElementSibling(node))
+results.push(node);return results;},'nth-child':function(nodes,formula,root){return Selector.pseudos.nth(nodes,formula,root);},'nth-last-child':function(nodes,formula,root){return Selector.pseudos.nth(nodes,formula,root,true);},'nth-of-type':function(nodes,formula,root){return Selector.pseudos.nth(nodes,formula,root,false,true);},'nth-last-of-type':function(nodes,formula,root){return Selector.pseudos.nth(nodes,formula,root,true,true);},'first-of-type':function(nodes,formula,root){return Selector.pseudos.nth(nodes,"1",root,false,true);},'last-of-type':function(nodes,formula,root){return Selector.pseudos.nth(nodes,"1",root,true,true);},'only-of-type':function(nodes,formula,root){var p=Selector.pseudos;return p['last-of-type'](p['first-of-type'](nodes,formula,root),formula,root);},getIndices:function(a,b,total){if(a==0)return b>0?[b]:[];return $R(1,total).inject([],function(memo,i){if(0==(i-b)%a&&(i-b)/a>=0)memo.push(i);return memo;});},nth:function(nodes,formula,root,reverse,ofType){if(nodes.length==0)return[];if(formula=='even')formula='2n+0';if(formula=='odd')formula='2n+1';var h=Selector.handlers,results=[],indexed=[],m;h.mark(nodes);for(var i=0,node;node=nodes[i];i++){if(!node.parentNode._countedByPrototype){h.index(node.parentNode,reverse,ofType);indexed.push(node.parentNode);}}
+if(formula.match(/^\d+$/)){formula=Number(formula);for(var i=0,node;node=nodes[i];i++)
+if(node.nodeIndex==formula)results.push(node);}else if(m=formula.match(/^(-?\d*)?n(([+-])(\d+))?/)){if(m[1]=="-")m[1]=-1;var a=m[1]?Number(m[1]):1;var b=m[2]?Number(m[2]):0;var indices=Selector.pseudos.getIndices(a,b,nodes.length);for(var i=0,node,l=indices.length;node=nodes[i];i++){for(var j=0;j<l;j++)
+if(node.nodeIndex==indices[j])results.push(node);}}
+h.unmark(nodes);h.unmark(indexed);return results;},'empty':function(nodes,value,root){for(var i=0,results=[],node;node=nodes[i];i++){if(node.tagName=='!'||node.firstChild)continue;results.push(node);}
+return results;},'not':function(nodes,selector,root){var h=Selector.handlers,selectorType,m;var exclusions=new Selector(selector).findElements(root);h.mark(exclusions);for(var i=0,results=[],node;node=nodes[i];i++)
+if(!node._countedByPrototype)results.push(node);h.unmark(exclusions);return results;},'enabled':function(nodes,value,root){for(var i=0,results=[],node;node=nodes[i];i++)
+if(!node.disabled&&(!node.type||node.type!=='hidden'))
+results.push(node);return results;},'disabled':function(nodes,value,root){for(var i=0,results=[],node;node=nodes[i];i++)
+if(node.disabled)results.push(node);return results;},'checked':function(nodes,value,root){for(var i=0,results=[],node;node=nodes[i];i++)
+if(node.checked)results.push(node);return results;}},operators:{'=':function(nv,v){return nv==v;},'!=':function(nv,v){return nv!=v;},'^=':function(nv,v){return nv==v||nv&&nv.startsWith(v);},'$=':function(nv,v){return nv==v||nv&&nv.endsWith(v);},'*=':function(nv,v){return nv==v||nv&&nv.include(v);},'~=':function(nv,v){return(' '+nv+' ').include(' '+v+' ');},'|=':function(nv,v){return('-'+(nv||"").toUpperCase()+'-').include('-'+(v||"").toUpperCase()+'-');}},split:function(expression){var expressions=[];expression.scan(/(([\w#:.~>+()\s-]+|\*|\[.*?\])+)\s*(,|$)/,function(m){expressions.push(m[1].strip());});return expressions;},matchElements:function(elements,expression){var matches=$$(expression),h=Selector.handlers;h.mark(matches);for(var i=0,results=[],element;element=elements[i];i++)
+if(element._countedByPrototype)results.push(element);h.unmark(matches);return results;},findElement:function(elements,expression,index){if(Object.isNumber(expression)){index=expression;expression=false;}
+return Selector.matchElements(elements,expression||'*')[index||0];},findChildElements:function(element,expressions){expressions=Selector.split(expressions.join(','));var results=[],h=Selector.handlers;for(var i=0,l=expressions.length,selector;i<l;i++){selector=new Selector(expressions[i].strip());h.concat(results,selector.findElements(element));}
+return(l>1)?h.unique(results):results;}});if(Prototype.Browser.IE){Object.extend(Selector.handlers,{concat:function(a,b){for(var i=0,node;node=b[i];i++)
+if(node.tagName!=="!")a.push(node);return a;}});}
+function $$(){return Selector.findChildElements(document,$A(arguments));}
+var Form={reset:function(form){form=$(form);form.reset();return form;},serializeElements:function(elements,options){if(typeof options!='object')options={hash:!!options};else if(Object.isUndefined(options.hash))options.hash=true;var key,value,submitted=false,submit=options.submit;var data=elements.inject({},function(result,element){if(!element.disabled&&element.name){key=element.name;value=$(element).getValue();if(value!=null&&element.type!='file'&&(element.type!='submit'||(!submitted&&submit!==false&&(!submit||key==submit)&&(submitted=true)))){if(key in result){if(!Object.isArray(result[key]))result[key]=[result[key]];result[key].push(value);}
+else result[key]=value;}}
+return result;});return options.hash?data:Object.toQueryString(data);}};Form.Methods={serialize:function(form,options){return Form.serializeElements(Form.getElements(form),options);},getElements:function(form){var elements=$(form).getElementsByTagName('*'),element,arr=[],serializers=Form.Element.Serializers;for(var i=0;element=elements[i];i++){arr.push(element);}
+return arr.inject([],function(elements,child){if(serializers[child.tagName.toLowerCase()])
+elements.push(Element.extend(child));return elements;})},getInputs:function(form,typeName,name){form=$(form);var inputs=form.getElementsByTagName('input');if(!typeName&&!name)return $A(inputs).map(Element.extend);for(var i=0,matchingInputs=[],length=inputs.length;i<length;i++){var input=inputs[i];if((typeName&&input.type!=typeName)||(name&&input.name!=name))
+continue;matchingInputs.push(Element.extend(input));}
+return matchingInputs;},disable:function(form){form=$(form);Form.getElements(form).invoke('disable');return form;},enable:function(form){form=$(form);Form.getElements(form).invoke('enable');return form;},findFirstElement:function(form){var elements=$(form).getElements().findAll(function(element){return'hidden'!=element.type&&!element.disabled;});var firstByIndex=elements.findAll(function(element){return element.hasAttribute('tabIndex')&&element.tabIndex>=0;}).sortBy(function(element){return element.tabIndex}).first();return firstByIndex?firstByIndex:elements.find(function(element){return/^(?:input|select|textarea)$/i.test(element.tagName);});},focusFirstElement:function(form){form=$(form);form.findFirstElement().activate();return form;},request:function(form,options){form=$(form),options=Object.clone(options||{});var params=options.parameters,action=form.readAttribute('action')||'';if(action.blank())action=window.location.href;options.parameters=form.serialize(true);if(params){if(Object.isString(params))params=params.toQueryParams();Object.extend(options.parameters,params);}
+if(form.hasAttribute('method')&&!options.method)
+options.method=form.method;return new Ajax.Request(action,options);}};Form.Element={focus:function(element){$(element).focus();return element;},select:function(element){$(element).select();return element;}};Form.Element.Methods={serialize:function(element){element=$(element);if(!element.disabled&&element.name){var value=element.getValue();if(value!=undefined){var pair={};pair[element.name]=value;return Object.toQueryString(pair);}}
+return'';},getValue:function(element){element=$(element);var method=element.tagName.toLowerCase();return Form.Element.Serializers[method](element);},setValue:function(element,value){element=$(element);var method=element.tagName.toLowerCase();Form.Element.Serializers[method](element,value);return element;},clear:function(element){$(element).value='';return element;},present:function(element){return $(element).value!='';},activate:function(element){element=$(element);try{element.focus();if(element.select&&(element.tagName.toLowerCase()!='input'||!(/^(?:button|reset|submit)$/i.test(element.type))))
+element.select();}catch(e){}
+return element;},disable:function(element){element=$(element);element.disabled=true;return element;},enable:function(element){element=$(element);element.disabled=false;return element;}};var Field=Form.Element;var $F=Form.Element.Methods.getValue;Form.Element.Serializers={input:function(element,value){switch(element.type.toLowerCase()){case'checkbox':case'radio':return Form.Element.Serializers.inputSelector(element,value);default:return Form.Element.Serializers.textarea(element,value);}},inputSelector:function(element,value){if(Object.isUndefined(value))return element.checked?element.value:null;else element.checked=!!value;},textarea:function(element,value){if(Object.isUndefined(value))return element.value;else element.value=value;},select:function(element,value){if(Object.isUndefined(value))
+return this[element.type=='select-one'?'selectOne':'selectMany'](element);else{var opt,currentValue,single=!Object.isArray(value);for(var i=0,length=element.length;i<length;i++){opt=element.options[i];currentValue=this.optionValue(opt);if(single){if(currentValue==value){opt.selected=true;return;}}
+else opt.selected=value.include(currentValue);}}},selectOne:function(element){var index=element.selectedIndex;return index>=0?this.optionValue(element.options[index]):null;},selectMany:function(element){var values,length=element.length;if(!length)return null;for(var i=0,values=[];i<length;i++){var opt=element.options[i];if(opt.selected)values.push(this.optionValue(opt));}
+return values;},optionValue:function(opt){return Element.extend(opt).hasAttribute('value')?opt.value:opt.text;}};Abstract.TimedObserver=Class.create(PeriodicalExecuter,{initialize:function($super,element,frequency,callback){$super(callback,frequency);this.element=$(element);this.lastValue=this.getValue();},execute:function(){var value=this.getValue();if(Object.isString(this.lastValue)&&Object.isString(value)?this.lastValue!=value:String(this.lastValue)!=String(value)){this.callback(this.element,value);this.lastValue=value;}}});Form.Element.Observer=Class.create(Abstract.TimedObserver,{getValue:function(){return Form.Element.getValue(this.element);}});Form.Observer=Class.create(Abstract.TimedObserver,{getValue:function(){return Form.serialize(this.element);}});Abstract.EventObserver=Class.create({initialize:function(element,callback){this.element=$(element);this.callback=callback;this.lastValue=this.getValue();if(this.element.tagName.toLowerCase()=='form')
+this.registerFormCallbacks();else
+this.registerCallback(this.element);},onElementEvent:function(){var value=this.getValue();if(this.lastValue!=value){this.callback(this.element,value);this.lastValue=value;}},registerFormCallbacks:function(){Form.getElements(this.element).each(this.registerCallback,this);},registerCallback:function(element){if(element.type){switch(element.type.toLowerCase()){case'checkbox':case'radio':Event.observe(element,'click',this.onElementEvent.bind(this));break;default:Event.observe(element,'change',this.onElementEvent.bind(this));break;}}}});Form.Element.EventObserver=Class.create(Abstract.EventObserver,{getValue:function(){return Form.Element.getValue(this.element);}});Form.EventObserver=Class.create(Abstract.EventObserver,{getValue:function(){return Form.serialize(this.element);}});(function(){var Event={KEY_BACKSPACE:8,KEY_TAB:9,KEY_RETURN:13,KEY_ESC:27,KEY_LEFT:37,KEY_UP:38,KEY_RIGHT:39,KEY_DOWN:40,KEY_DELETE:46,KEY_HOME:36,KEY_END:35,KEY_PAGEUP:33,KEY_PAGEDOWN:34,KEY_INSERT:45,cache:{}};var docEl=document.documentElement;var MOUSEENTER_MOUSELEAVE_EVENTS_SUPPORTED='onmouseenter'in docEl&&'onmouseleave'in docEl;var _isButton;if(Prototype.Browser.IE){var buttonMap={0:1,1:4,2:2};_isButton=function(event,code){return event.button===buttonMap[code];};}else if(Prototype.Browser.WebKit){_isButton=function(event,code){switch(code){case 0:return event.which==1&&!event.metaKey;case 1:return event.which==1&&event.metaKey;default:return false;}};}else{_isButton=function(event,code){return event.which?(event.which===code+1):(event.button===code);};}
+function isLeftClick(event){return _isButton(event,0)}
+function isMiddleClick(event){return _isButton(event,1)}
+function isRightClick(event){return _isButton(event,2)}
+function element(event){event=Event.extend(event);var node=event.target,type=event.type,currentTarget=event.currentTarget;if(currentTarget&&currentTarget.tagName){if(type==='load'||type==='error'||(type==='click'&&currentTarget.tagName.toLowerCase()==='input'&&currentTarget.type==='radio'))
+node=currentTarget;}
+if(node.nodeType==Node.TEXT_NODE)
+node=node.parentNode;return Element.extend(node);}
+function findElement(event,expression){var element=Event.element(event);if(!expression)return element;var elements=[element].concat(element.ancestors());return Selector.findElement(elements,expression,0);}
+function pointer(event){return{x:pointerX(event),y:pointerY(event)};}
+function pointerX(event){var docElement=document.documentElement,body=document.body||{scrollLeft:0};return event.pageX||(event.clientX+
+(docElement.scrollLeft||body.scrollLeft)-
+(docElement.clientLeft||0));}
+function pointerY(event){var docElement=document.documentElement,body=document.body||{scrollTop:0};return event.pageY||(event.clientY+
+(docElement.scrollTop||body.scrollTop)-
+(docElement.clientTop||0));}
+function stop(event){Event.extend(event);event.preventDefault();event.stopPropagation();event.stopped=true;}
+Event.Methods={isLeftClick:isLeftClick,isMiddleClick:isMiddleClick,isRightClick:isRightClick,element:element,findElement:findElement,pointer:pointer,pointerX:pointerX,pointerY:pointerY,stop:stop};var methods=Object.keys(Event.Methods).inject({},function(m,name){m[name]=Event.Methods[name].methodize();return m;});if(Prototype.Browser.IE){function _relatedTarget(event){var element;switch(event.type){case'mouseover':element=event.fromElement;break;case'mouseout':element=event.toElement;break;default:return null;}
+return Element.extend(element);}
+Object.extend(methods,{stopPropagation:function(){this.cancelBubble=true},preventDefault:function(){this.returnValue=false},inspect:function(){return'[object Event]'}});Event.extend=function(event,element){if(!event)return false;if(event._extendedByPrototype)return event;event._extendedByPrototype=Prototype.emptyFunction;var pointer=Event.pointer(event);Object.extend(event,{target:event.srcElement||element,relatedTarget:_relatedTarget(event),pageX:pointer.x,pageY:pointer.y});return Object.extend(event,methods);};}else{Event.prototype=window.Event.prototype||document.createEvent('HTMLEvents').__proto__;Object.extend(Event.prototype,methods);Event.extend=Prototype.K;}
+function _createResponder(element,eventName,handler){var registry=Element.retrieve(element,'prototype_event_registry');if(Object.isUndefined(registry)){CACHE.push(element);registry=Element.retrieve(element,'prototype_event_registry',$H());}
+var respondersForEvent=registry.get(eventName);if(Object.isUndefined(respondersForEvent)){respondersForEvent=[];registry.set(eventName,respondersForEvent);}
+if(respondersForEvent.pluck('handler').include(handler))return false;var responder;if(eventName.include(":")){responder=function(event){if(Object.isUndefined(event.eventName))
+return false;if(event.eventName!==eventName)
+return false;Event.extend(event,element);handler.call(element,event);};}else{if(!MOUSEENTER_MOUSELEAVE_EVENTS_SUPPORTED&&(eventName==="mouseenter"||eventName==="mouseleave")){if(eventName==="mouseenter"||eventName==="mouseleave"){responder=function(event){Event.extend(event,element);var parent=event.relatedTarget;while(parent&&parent!==element){try{parent=parent.parentNode;}
+catch(e){parent=element;}}
+if(parent===element)return;handler.call(element,event);};}}else{responder=function(event){Event.extend(event,element);handler.call(element,event);};}}
+responder.handler=handler;respondersForEvent.push(responder);return responder;}
+function _destroyCache(){for(var i=0,length=CACHE.length;i<length;i++){Event.stopObserving(CACHE[i]);CACHE[i]=null;}}
+var CACHE=[];if(Prototype.Browser.IE)
+window.attachEvent('onunload',_destroyCache);if(Prototype.Browser.WebKit)
+window.addEventListener('unload',Prototype.emptyFunction,false);var _getDOMEventName=Prototype.K;if(!MOUSEENTER_MOUSELEAVE_EVENTS_SUPPORTED){_getDOMEventName=function(eventName){var translations={mouseenter:"mouseover",mouseleave:"mouseout"};return eventName in translations?translations[eventName]:eventName;};}
+function observe(element,eventName,handler){element=$(element);var responder=_createResponder(element,eventName,handler);if(!responder)return element;if(eventName.include(':')){if(element.addEventListener)
+element.addEventListener("dataavailable",responder,false);else{element.attachEvent("ondataavailable",responder);element.attachEvent("onfilterchange",responder);}}else{var actualEventName=_getDOMEventName(eventName);if(element.addEventListener)
+element.addEventListener(actualEventName,responder,false);else
+element.attachEvent("on"+actualEventName,responder);}
+return element;}
+function stopObserving(element,eventName,handler){element=$(element);var registry=Element.retrieve(element,'prototype_event_registry');if(Object.isUndefined(registry))return element;if(eventName&&!handler){var responders=registry.get(eventName);if(Object.isUndefined(responders))return element;responders.each(function(r){Element.stopObserving(element,eventName,r.handler);});return element;}else if(!eventName){registry.each(function(pair){var eventName=pair.key,responders=pair.value;responders.each(function(r){Element.stopObserving(element,eventName,r.handler);});});return element;}
+var responders=registry.get(eventName);if(!responders)return;var responder=responders.find(function(r){return r.handler===handler;});if(!responder)return element;var actualEventName=_getDOMEventName(eventName);if(eventName.include(':')){if(element.removeEventListener)
+element.removeEventListener("dataavailable",responder,false);else{element.detachEvent("ondataavailable",responder);element.detachEvent("onfilterchange",responder);}}else{if(element.removeEventListener)
+element.removeEventListener(actualEventName,responder,false);else
+element.detachEvent('on'+actualEventName,responder);}
+registry.set(eventName,responders.without(responder));return element;}
+function fire(element,eventName,memo,bubble){element=$(element);if(Object.isUndefined(bubble))
+bubble=true;if(element==document&&document.createEvent&&!element.dispatchEvent)
+element=document.documentElement;var event;if(document.createEvent){event=document.createEvent('HTMLEvents');event.initEvent('dataavailable',true,true);}else{event=document.createEventObject();event.eventType=bubble?'ondataavailable':'onfilterchange';}
+event.eventName=eventName;event.memo=memo||{};if(document.createEvent)
+element.dispatchEvent(event);else
+element.fireEvent(event.eventType,event);return Event.extend(event);}
+Object.extend(Event,Event.Methods);Object.extend(Event,{fire:fire,observe:observe,stopObserving:stopObserving});Element.addMethods({fire:fire,observe:observe,stopObserving:stopObserving});Object.extend(document,{fire:fire.methodize(),observe:observe.methodize(),stopObserving:stopObserving.methodize(),loaded:false});if(window.Event)Object.extend(window.Event,Event);else window.Event=Event;})();(function(){var timer;function fireContentLoadedEvent(){if(document.loaded)return;if(timer)window.clearTimeout(timer);document.loaded=true;document.fire('dom:loaded');}
+function checkReadyState(){if(document.readyState==='complete'){document.stopObserving('readystatechange',checkReadyState);fireContentLoadedEvent();}}
+function pollDoScroll(){try{document.documentElement.doScroll('left');}
+catch(e){timer=pollDoScroll.defer();return;}
+fireContentLoadedEvent();}
+if(document.addEventListener){document.addEventListener('DOMContentLoaded',fireContentLoadedEvent,false);}else{document.observe('readystatechange',checkReadyState);if(window==top)
+timer=pollDoScroll.defer();}
+Event.observe(window,'load',fireContentLoadedEvent);})();Element.addMethods();Hash.toQueryString=Object.toQueryString;var Toggle={display:Element.toggle};Element.Methods.childOf=Element.Methods.descendantOf;var Insertion={Before:function(element,content){return Element.insert(element,{before:content});},Top:function(element,content){return Element.insert(element,{top:content});},Bottom:function(element,content){return Element.insert(element,{bottom:content});},After:function(element,content){return Element.insert(element,{after:content});}};var $continue=new Error('"throw $continue" is deprecated, use "return" instead');var Position={includeScrollOffsets:false,prepare:function(){this.deltaX=window.pageXOffset||document.documentElement.scrollLeft||document.body.scrollLeft||0;this.deltaY=window.pageYOffset||document.documentElement.scrollTop||document.body.scrollTop||0;},within:function(element,x,y){if(this.includeScrollOffsets)
+return this.withinIncludingScrolloffsets(element,x,y);this.xcomp=x;this.ycomp=y;this.offset=Element.cumulativeOffset(element);return(y>=this.offset[1]&&y<this.offset[1]+element.offsetHeight&&x>=this.offset[0]&&x<this.offset[0]+element.offsetWidth);},withinIncludingScrolloffsets:function(element,x,y){var offsetcache=Element.cumulativeScrollOffset(element);this.xcomp=x+offsetcache[0]-this.deltaX;this.ycomp=y+offsetcache[1]-this.deltaY;this.offset=Element.cumulativeOffset(element);return(this.ycomp>=this.offset[1]&&this.ycomp<this.offset[1]+element.offsetHeight&&this.xcomp>=this.offset[0]&&this.xcomp<this.offset[0]+element.offsetWidth);},overlap:function(mode,element){if(!mode)return 0;if(mode=='vertical')
+return((this.offset[1]+element.offsetHeight)-this.ycomp)/element.offsetHeight;if(mode=='horizontal')
+return((this.offset[0]+element.offsetWidth)-this.xcomp)/element.offsetWidth;},cumulativeOffset:Element.Methods.cumulativeOffset,positionedOffset:Element.Methods.positionedOffset,absolutize:function(element){Position.prepare();return Element.absolutize(element);},relativize:function(element){Position.prepare();return Element.relativize(element);},realOffset:Element.Methods.cumulativeScrollOffset,offsetParent:Element.Methods.getOffsetParent,page:Element.Methods.viewportOffset,clone:function(source,target,options){options=options||{};return Element.clonePosition(target,source,options);}};if(!document.getElementsByClassName)document.getElementsByClassName=function(instanceMethods){function iter(name){return name.blank()?null:"[contains(concat(' ', @class, ' '), ' "+name+" ')]";}
+instanceMethods.getElementsByClassName=Prototype.BrowserFeatures.XPath?function(element,className){className=className.toString().strip();var cond=/\s/.test(className)?$w(className).map(iter).join(''):iter(className);return cond?document._getElementsByXPath('.//*'+cond,element):[];}:function(element,className){className=className.toString().strip();var elements=[],classNames=(/\s/.test(className)?$w(className):null);if(!classNames&&!className)return elements;var nodes=$(element).getElementsByTagName('*');className=' '+className+' ';for(var i=0,child,cn;child=nodes[i];i++){if(child.className&&(cn=' '+child.className+' ')&&(cn.include(className)||(classNames&&classNames.all(function(name){return!name.toString().blank()&&cn.include(' '+name+' ');}))))
+elements.push(Element.extend(child));}
+return elements;};return function(className,parentElement){return $(parentElement||document.body).getElementsByClassName(className);};}(Element.Methods);Element.ClassNames=Class.create();Element.ClassNames.prototype={initialize:function(element){this.element=$(element);},_each:function(iterator){this.element.className.split(/\s+/).select(function(name){return name.length>0;})._each(iterator);},set:function(className){this.element.className=className;},add:function(classNameToAdd){if(this.include(classNameToAdd))return;this.set($A(this).concat(classNameToAdd).join(' '));},remove:function(classNameToRemove){if(!this.include(classNameToRemove))return;this.set($A(this).without(classNameToRemove).join(' '));},toString:function(){return $A(this).join(' ');}};Object.extend(Element.ClassNames.prototype,Enumerable);
+var TrimPath;(function(){if(TrimPath==null)
+TrimPath=new Object();if(TrimPath.evalEx==null)
+TrimPath.evalEx=function(src){return eval(src);};var UNDEFINED;if(Array.prototype.pop==null)
+Array.prototype.pop=function(){if(this.length===0){return UNDEFINED;}
+return this[--this.length];};if(Array.prototype.push==null)
+Array.prototype.push=function(){for(var i=0;i<arguments.length;++i){this[this.length]=arguments[i];}
+return this.length;};TrimPath.parseTemplate=function(tmplContent,optTmplName,optEtc){if(optEtc==null)
+optEtc=TrimPath.parseTemplate_etc;var funcSrc=parse(tmplContent,optTmplName,optEtc);var func=TrimPath.evalEx(funcSrc,optTmplName,1);if(func!=null)
+return new optEtc.Template(optTmplName,tmplContent,funcSrc,func,optEtc);return null;}
+try{String.prototype.process=function(context,optFlags){var template=TrimPath.parseTemplate(this,null);if(template!=null)
+return template.process(context,optFlags);return this;}}catch(e){}
+TrimPath.parseTemplate_etc={};TrimPath.parseTemplate_etc.statementTag="forelse|for|if|elseif|else|var|macro";TrimPath.parseTemplate_etc.statementDef={"if":{delta:1,prefix:"if (",suffix:") {",paramMin:1},"else":{delta:0,prefix:"} else {"},"elseif":{delta:0,prefix:"} else if (",suffix:") {",paramDefault:"true"},"/if":{delta:-1,prefix:"}"},"for":{delta:1,paramMin:3,prefixFunc:function(stmtParts,state,tmplName,etc){if(stmtParts[2]!="in")
+throw new etc.ParseError(tmplName,state.line,"bad for loop statement: "+stmtParts.join(' '));var iterVar=stmtParts[1];var listVar="__LIST__"+iterVar;return["var ",listVar," = ",stmtParts[3],";","var __LENGTH_STACK__;","if (typeof(__LENGTH_STACK__) == 'undefined' || !__LENGTH_STACK__.length) __LENGTH_STACK__ = new Array();","__LENGTH_STACK__[__LENGTH_STACK__.length] = 0;","if ((",listVar,") != null) { ","var ",iterVar,"_ct = 0;","for (var ",iterVar,"_index in ",listVar,") { ",iterVar,"_ct++;","if (typeof(",listVar,"[",iterVar,"_index]) == 'function') {continue;}","__LENGTH_STACK__[__LENGTH_STACK__.length - 1]++;","var ",iterVar," = ",listVar,"[",iterVar,"_index];"].join("");}},"forelse":{delta:0,prefix:"} } if (__LENGTH_STACK__[__LENGTH_STACK__.length - 1] == 0) { if (",suffix:") {",paramDefault:"true"},"/for":{delta:-1,prefix:"} }; delete __LENGTH_STACK__[__LENGTH_STACK__.length - 1];"},"var":{delta:0,prefix:"var ",suffix:";"},"macro":{delta:1,prefixFunc:function(stmtParts,state,tmplName,etc){var macroName=stmtParts[1].split('(')[0];return["var ",macroName," = function",stmtParts.slice(1).join(' ').substring(macroName.length),"{ var _OUT_arr = []; var _OUT = { write: function(m) { if (m) _OUT_arr.push(m); } }; "].join('');}},"/macro":{delta:-1,prefix:" return _OUT_arr.join(''); };"}}
+TrimPath.parseTemplate_etc.modifierDef={"eat":function(v){return"";},"escape":function(s){return String(s).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;");},"capitalize":function(s){return String(s).toUpperCase();},"default":function(s,d){return s!=null?s:d;}}
+TrimPath.parseTemplate_etc.modifierDef.h=TrimPath.parseTemplate_etc.modifierDef.escape;TrimPath.parseTemplate_etc.Template=function(tmplName,tmplContent,funcSrc,func,etc){this.process=function(context,flags){if(context==null)
+context={};if(context._MODIFIERS==null)
+context._MODIFIERS={};if(context.defined==null)
+context.defined=function(str){return(context[str]!=undefined);};for(var k in etc.modifierDef){if(context._MODIFIERS[k]==null)
+context._MODIFIERS[k]=etc.modifierDef[k];}
+if(flags==null)
+flags={};var resultArr=[];var resultOut={write:function(m){resultArr.push(m);}};try{func(resultOut,context,flags);}catch(e){if(flags.throwExceptions==true)
+throw e;var result=new String(resultArr.join("")+"[ERROR: "+e.toString()+(e.message?'; '+e.message:'')+"]");result["exception"]=e;return result;}
+return resultArr.join("");}
+this.name=tmplName;this.source=tmplContent;this.sourceFunc=funcSrc;this.toString=function(){return"TrimPath.Template ["+tmplName+"]";}}
+TrimPath.parseTemplate_etc.ParseError=function(name,line,message){this.name=name;this.line=line;this.message=message;}
+TrimPath.parseTemplate_etc.ParseError.prototype.toString=function(){return("TrimPath template ParseError in "+this.name+": line "+this.line+", "+this.message);}
+var parse=function(body,tmplName,etc){body=cleanWhiteSpace(body);var funcText=["var TrimPath_Template_TEMP = function(_OUT, _CONTEXT, _FLAGS) { with (_CONTEXT) {"];var state={stack:[],line:1};var endStmtPrev=-1;while(endStmtPrev+1<body.length){var begStmt=endStmtPrev;begStmt=body.indexOf("{",begStmt+1);while(begStmt>=0){var endStmt=body.indexOf('}',begStmt+1);var stmt=body.substring(begStmt,endStmt);var blockrx=stmt.match(/^\{(cdata|minify|eval)/);if(blockrx){var blockType=blockrx[1];var blockMarkerBeg=begStmt+blockType.length+1;var blockMarkerEnd=body.indexOf('}',blockMarkerBeg);if(blockMarkerEnd>=0){var blockMarker;if(blockMarkerEnd-blockMarkerBeg<=0){blockMarker="{/"+blockType+"}";}else{blockMarker=body.substring(blockMarkerBeg+1,blockMarkerEnd);}
+var blockEnd=body.indexOf(blockMarker,blockMarkerEnd+1);if(blockEnd>=0){emitSectionText(body.substring(endStmtPrev+1,begStmt),funcText);var blockText=body.substring(blockMarkerEnd+1,blockEnd);if(blockType=='cdata'){emitText(blockText,funcText);}else if(blockType=='minify'){emitText(scrubWhiteSpace(blockText),funcText);}else if(blockType=='eval'){if(blockText!=null&&blockText.length>0)
+funcText.push('_OUT.write( (function() { '+blockText+' })() );');}
+begStmt=endStmtPrev=blockEnd+blockMarker.length-1;}}}else if(body.charAt(begStmt-1)!='$'&&body.charAt(begStmt-1)!='\\'){var offset=(body.charAt(begStmt+1)=='/'?2:1);if(body.substring(begStmt+offset,begStmt+10+offset).search(TrimPath.parseTemplate_etc.statementTag)==0)
+break;}
+begStmt=body.indexOf("{",begStmt+1);}
+if(begStmt<0)
+break;var endStmt=body.indexOf("}",begStmt+1);if(endStmt<0)
+break;emitSectionText(body.substring(endStmtPrev+1,begStmt),funcText);emitStatement(body.substring(begStmt,endStmt+1),state,funcText,tmplName,etc);endStmtPrev=endStmt;}
+emitSectionText(body.substring(endStmtPrev+1),funcText);if(state.stack.length!=0)
+throw new etc.ParseError(tmplName,state.line,"unclosed, unmatched statement(s): "+state.stack.join(","));funcText.push("}}; TrimPath_Template_TEMP");return funcText.join("");}
+var emitStatement=function(stmtStr,state,funcText,tmplName,etc){var parts=stmtStr.slice(1,-1).split(' ');var stmt=etc.statementDef[parts[0]];if(stmt==null){emitSectionText(stmtStr,funcText);return;}
+if(stmt.delta<0){if(state.stack.length<=0)
+throw new etc.ParseError(tmplName,state.line,"close tag does not match any previous statement: "+stmtStr);state.stack.pop();}
+if(stmt.delta>0)
+state.stack.push(stmtStr);if(stmt.paramMin!=null&&stmt.paramMin>=parts.length)
+throw new etc.ParseError(tmplName,state.line,"statement needs more parameters: "+stmtStr);if(stmt.prefixFunc!=null)
+funcText.push(stmt.prefixFunc(parts,state,tmplName,etc));else
+funcText.push(stmt.prefix);if(stmt.suffix!=null){if(parts.length<=1){if(stmt.paramDefault!=null)
+funcText.push(stmt.paramDefault);}else{for(var i=1;i<parts.length;i++){if(i>1)
+funcText.push(' ');funcText.push(parts[i]);}}
+funcText.push(stmt.suffix);}}
+var emitSectionText=function(text,funcText){if(text.length<=0)
+return;var nlPrefix=0;var nlSuffix=text.length-1;while(nlPrefix<text.length&&(text.charAt(nlPrefix)=='\n'))
+nlPrefix++;while(nlSuffix>=0&&(text.charAt(nlSuffix)==' '||text.charAt(nlSuffix)=='\t'))
+nlSuffix--;if(nlSuffix<nlPrefix)
+nlSuffix=nlPrefix;if(nlPrefix>0){funcText.push('if (_FLAGS.keepWhitespace == true) _OUT.write("');var s=text.substring(0,nlPrefix).replace('\n','\\n');if(s.charAt(s.length-1)=='\n')
+s=s.substring(0,s.length-1);funcText.push(s);funcText.push('");');}
+var lines=text.substring(nlPrefix,nlSuffix+1).split('\n');for(var i=0;i<lines.length;i++){emitSectionTextLine(lines[i],funcText);if(i<lines.length-1)
+funcText.push('_OUT.write("\\n");\n');}
+if(nlSuffix+1<text.length){funcText.push('if (_FLAGS.keepWhitespace == true) _OUT.write("');var s=text.substring(nlSuffix+1).replace('\n','\\n');if(s.charAt(s.length-1)=='\n')
+s=s.substring(0,s.length-1);funcText.push(s);funcText.push('");');}}
+var emitSectionTextLine=function(line,funcText){var endMarkPrev='}';var endExprPrev=-1;while(endExprPrev+endMarkPrev.length<line.length){var begMark="${",endMark="}";var begExpr=line.indexOf(begMark,endExprPrev+endMarkPrev.length);if(begExpr<0)
+break;if(line.charAt(begExpr+2)=='%'){begMark="${%";endMark="%}";}
+var endExpr=line.indexOf(endMark,begExpr+begMark.length);if(endExpr<0)
+break;emitText(line.substring(endExprPrev+endMarkPrev.length,begExpr),funcText);var exprArr=line.substring(begExpr+begMark.length,endExpr).replace(/\|\|/g,"#@@#").split('|');for(var k in exprArr){if(exprArr[k].replace)
+exprArr[k]=exprArr[k].replace(/#@@#/g,'||');}
+funcText.push('_OUT.write(');emitExpression(exprArr,exprArr.length-1,funcText);funcText.push(');');endExprPrev=endExpr;endMarkPrev=endMark;}
+emitText(line.substring(endExprPrev+endMarkPrev.length),funcText);}
+var emitText=function(text,funcText){if(text==null||text.length<=0)
+return;text=text.replace(/\\/g,'\\\\');text=text.replace(/\n/g,'\\n');text=text.replace(/"/g,'\\"');funcText.push('_OUT.write("');funcText.push(text);funcText.push('");');}
+var emitExpression=function(exprArr,index,funcText){var expr=exprArr[index];if(index<=0){funcText.push(expr);return;}
+var parts=expr.split(':');funcText.push('_MODIFIERS["');funcText.push(parts[0]);funcText.push('"](');emitExpression(exprArr,index-1,funcText);if(parts.length>1){funcText.push(',');funcText.push(parts[1]);}
+funcText.push(')');}
+var cleanWhiteSpace=function(result){result=result.replace(/\t/g,"    ");result=result.replace(/\r\n/g,"\n");result=result.replace(/\r/g,"\n");result=result.replace(/^(\s*\S*(\s+\S+)*)\s*$/,'$1');return result;}
+var scrubWhiteSpace=function(result){result=result.replace(/^\s+/g,"");result=result.replace(/\s+$/g,"");result=result.replace(/\s+/g," ");result=result.replace(/^(\s*\S*(\s+\S+)*)\s*$/,'$1');return result;}
+TrimPath.parseDOMTemplate=function(elementId,optDocument,optEtc){if(optDocument==null)
+optDocument=document;var element=optDocument.getElementById(elementId);var content=element.value;if(content==null)
+content=element.innerHTML;content=content.replace(/&lt;/g,"<").replace(/&gt;/g,">");return TrimPath.parseTemplate(content,elementId,optEtc);}
+TrimPath.processDOMTemplate=function(elementId,context,optFlags,optDocument,optEtc){return TrimPath.parseDOMTemplate(elementId,optDocument,optEtc).process(context,optFlags);}})();
+var Scriptaculous={Version:'1.8.2',require:function(libraryName){document.write('<script type="text/javascript" src="'+libraryName+'"><\/script>');},REQUIRED_PROTOTYPE:'1.6.0.3',load:function(){function convertVersionString(versionString){var v=versionString.replace(/_.*|\./g,'');v=parseInt(v+'0'.times(4-v.length));return versionString.indexOf('_')>-1?v-1:v;}
+if((typeof Prototype=='undefined')||(typeof Element=='undefined')||(typeof Element.Methods=='undefined')||(convertVersionString(Prototype.Version)<convertVersionString(Scriptaculous.REQUIRED_PROTOTYPE)))
+throw("script.aculo.us requires the Prototype JavaScript framework >= "+
+Scriptaculous.REQUIRED_PROTOTYPE);var js=/scriptaculous\.js(\?.*)?$/;$$('head script[src]').findAll(function(s){return s.src.match(js);}).each(function(s){var path=s.src.replace(js,''),includes=s.src.match(/\?.*load=([a-z,]*)/);(includes?includes[1]:'builder,effects,dragdrop,controls,slider,sound').split(',').each(function(include){Scriptaculous.require(path+include+'.js')});});}};Scriptaculous.load();String.prototype.parseColor=function(){var color='#';if(this.slice(0,4)=='rgb('){var cols=this.slice(4,this.length-1).split(',');var i=0;do{color+=parseInt(cols[i]).toColorPart()}while(++i<3);}else{if(this.slice(0,1)=='#'){if(this.length==4)for(var i=1;i<4;i++)color+=(this.charAt(i)+this.charAt(i)).toLowerCase();if(this.length==7)color=this.toLowerCase();}}
+return(color.length==7?color:(arguments[0]||this));};Element.collectTextNodes=function(element){return $A($(element).childNodes).collect(function(node){return(node.nodeType==3?node.nodeValue:(node.hasChildNodes()?Element.collectTextNodes(node):''));}).flatten().join('');};Element.collectTextNodesIgnoreClass=function(element,className){return $A($(element).childNodes).collect(function(node){return(node.nodeType==3?node.nodeValue:((node.hasChildNodes()&&!Element.hasClassName(node,className))?Element.collectTextNodesIgnoreClass(node,className):''));}).flatten().join('');};Element.setContentZoom=function(element,percent){element=$(element);element.setStyle({fontSize:(percent/100)+'em'});if(Prototype.Browser.WebKit)window.scrollBy(0,0);return element;};Element.getInlineOpacity=function(element){return $(element).style.opacity||'';};Element.forceRerendering=function(element){try{element=$(element);var n=document.createTextNode(' ');element.appendChild(n);element.removeChild(n);}catch(e){}};var Effect={_elementDoesNotExistError:{name:'ElementDoesNotExistError',message:'The specified DOM element does not exist, but is required for this effect to operate'},Transitions:{linear:Prototype.K,sinoidal:function(pos){return(-Math.cos(pos*Math.PI)/2)+.5;},reverse:function(pos){return 1-pos;},flicker:function(pos){var pos=((-Math.cos(pos*Math.PI)/4)+.75)+Math.random()/4;return pos>1?1:pos;},wobble:function(pos){return(-Math.cos(pos*Math.PI*(9*pos))/2)+.5;},pulse:function(pos,pulses){return(-Math.cos((pos*((pulses||5)-.5)*2)*Math.PI)/2)+.5;},spring:function(pos){return 1-(Math.cos(pos*4.5*Math.PI)*Math.exp(-pos*6));},none:function(pos){return 0;},full:function(pos){return 1;}},DefaultOptions:{duration:1.0,fps:100,sync:false,from:0.0,to:1.0,delay:0.0,queue:'parallel'},tagifyText:function(element){var tagifyStyle='position:relative';if(Prototype.Browser.IE)tagifyStyle+=';zoom:1';element=$(element);$A(element.childNodes).each(function(child){if(child.nodeType==3){child.nodeValue.toArray().each(function(character){element.insertBefore(new Element('span',{style:tagifyStyle}).update(character==' '?String.fromCharCode(160):character),child);});Element.remove(child);}});},multiple:function(element,effect){var elements;if(((typeof element=='object')||Object.isFunction(element))&&(element.length))
+elements=element;else
+elements=$(element).childNodes;var options=Object.extend({speed:0.1,delay:0.0},arguments[2]||{});var masterDelay=options.delay;$A(elements).each(function(element,index){new effect(element,Object.extend(options,{delay:index*options.speed+masterDelay}));});},PAIRS:{'slide':['SlideDown','SlideUp'],'blind':['BlindDown','BlindUp'],'appear':['Appear','Fade']},toggle:function(element,effect){element=$(element);effect=(effect||'appear').toLowerCase();var options=Object.extend({queue:{position:'end',scope:(element.id||'global'),limit:1}},arguments[2]||{});Effect[element.visible()?Effect.PAIRS[effect][1]:Effect.PAIRS[effect][0]](element,options);}};Effect.DefaultOptions.transition=Effect.Transitions.sinoidal;Effect.ScopedQueue=Class.create(Enumerable,{initialize:function(){this.effects=[];this.interval=null;},_each:function(iterator){this.effects._each(iterator);},add:function(effect){var timestamp=new Date().getTime();var position=Object.isString(effect.options.queue)?effect.options.queue:effect.options.queue.position;switch(position){case'front':this.effects.findAll(function(e){return e.state=='idle'}).each(function(e){e.startOn+=effect.finishOn;e.finishOn+=effect.finishOn;});break;case'with-last':timestamp=this.effects.pluck('startOn').max()||timestamp;break;case'end':timestamp=this.effects.pluck('finishOn').max()||timestamp;break;}
+effect.startOn+=timestamp;effect.finishOn+=timestamp;if(!effect.options.queue.limit||(this.effects.length<effect.options.queue.limit))
+this.effects.push(effect);if(!this.interval)
+this.interval=setInterval(this.loop.bind(this),15);},remove:function(effect){this.effects=this.effects.reject(function(e){return e==effect});if(this.effects.length==0){clearInterval(this.interval);this.interval=null;}},loop:function(){var timePos=new Date().getTime();for(var i=0,len=this.effects.length;i<len;i++)
+this.effects[i]&&this.effects[i].loop(timePos);}});Effect.Queues={instances:$H(),get:function(queueName){if(!Object.isString(queueName))return queueName;return this.instances.get(queueName)||this.instances.set(queueName,new Effect.ScopedQueue());}};Effect.Queue=Effect.Queues.get('global');Effect.Base=Class.create({position:null,start:function(options){function codeForEvent(options,eventName){return((options[eventName+'Internal']?'this.options.'+eventName+'Internal(this);':'')+
+(options[eventName]?'this.options.'+eventName+'(this);':''));}
+if(options&&options.transition===false)options.transition=Effect.Transitions.linear;this.options=Object.extend(Object.extend({},Effect.DefaultOptions),options||{});this.currentFrame=0;this.state='idle';this.startOn=this.options.delay*1000;this.finishOn=this.startOn+(this.options.duration*1000);this.fromToDelta=this.options.to-this.options.from;this.totalTime=this.finishOn-this.startOn;this.totalFrames=this.options.fps*this.options.duration;this.render=(function(){function dispatch(effect,eventName){if(effect.options[eventName+'Internal'])
+effect.options[eventName+'Internal'](effect);if(effect.options[eventName])
+effect.options[eventName](effect);}
+return function(pos){if(this.state==="idle"){this.state="running";dispatch(this,'beforeSetup');if(this.setup)this.setup();dispatch(this,'afterSetup');}
+if(this.state==="running"){pos=(this.options.transition(pos)*this.fromToDelta)+this.options.from;this.position=pos;dispatch(this,'beforeUpdate');if(this.update)this.update(pos);dispatch(this,'afterUpdate');}};})();this.event('beforeStart');if(!this.options.sync)
+Effect.Queues.get(Object.isString(this.options.queue)?'global':this.options.queue.scope).add(this);},loop:function(timePos){if(timePos>=this.startOn){if(timePos>=this.finishOn){this.render(1.0);this.cancel();this.event('beforeFinish');if(this.finish)this.finish();this.event('afterFinish');return;}
+var pos=(timePos-this.startOn)/this.totalTime,frame=(pos*this.totalFrames).round();if(frame>this.currentFrame){this.render(pos);this.currentFrame=frame;}}},cancel:function(){if(!this.options.sync)
+Effect.Queues.get(Object.isString(this.options.queue)?'global':this.options.queue.scope).remove(this);this.state='finished';},event:function(eventName){if(this.options[eventName+'Internal'])this.options[eventName+'Internal'](this);if(this.options[eventName])this.options[eventName](this);},inspect:function(){var data=$H();for(property in this)
+if(!Object.isFunction(this[property]))data.set(property,this[property]);return'#<Effect:'+data.inspect()+',options:'+$H(this.options).inspect()+'>';}});Effect.Parallel=Class.create(Effect.Base,{initialize:function(effects){this.effects=effects||[];this.start(arguments[1]);},update:function(position){this.effects.invoke('render',position);},finish:function(position){this.effects.each(function(effect){effect.render(1.0);effect.cancel();effect.event('beforeFinish');if(effect.finish)effect.finish(position);effect.event('afterFinish');});}});Effect.Tween=Class.create(Effect.Base,{initialize:function(object,from,to){object=Object.isString(object)?$(object):object;var args=$A(arguments),method=args.last(),options=args.length==5?args[3]:null;this.method=Object.isFunction(method)?method.bind(object):Object.isFunction(object[method])?object[method].bind(object):function(value){object[method]=value};this.start(Object.extend({from:from,to:to},options||{}));},update:function(position){this.method(position);}});Effect.Event=Class.create(Effect.Base,{initialize:function(){this.start(Object.extend({duration:0},arguments[0]||{}));},update:Prototype.emptyFunction});Effect.Opacity=Class.create(Effect.Base,{initialize:function(element){this.element=$(element);if(!this.element)throw(Effect._elementDoesNotExistError);if(Prototype.Browser.IE&&(!this.element.currentStyle.hasLayout))
+this.element.setStyle({zoom:1});var options=Object.extend({from:this.element.getOpacity()||0.0,to:1.0},arguments[1]||{});this.start(options);},update:function(position){this.element.setOpacity(position);}});Effect.Move=Class.create(Effect.Base,{initialize:function(element){this.element=$(element);if(!this.element)throw(Effect._elementDoesNotExistError);var options=Object.extend({x:0,y:0,mode:'relative'},arguments[1]||{});this.start(options);},setup:function(){this.element.makePositioned();this.originalLeft=parseFloat(this.element.getStyle('left')||'0');this.originalTop=parseFloat(this.element.getStyle('top')||'0');if(this.options.mode=='absolute'){this.options.x=this.options.x-this.originalLeft;this.options.y=this.options.y-this.originalTop;}},update:function(position){this.element.setStyle({left:(this.options.x*position+this.originalLeft).round()+'px',top:(this.options.y*position+this.originalTop).round()+'px'});}});Effect.MoveBy=function(element,toTop,toLeft){return new Effect.Move(element,Object.extend({x:toLeft,y:toTop},arguments[3]||{}));};Effect.Scale=Class.create(Effect.Base,{initialize:function(element,percent){this.element=$(element);if(!this.element)throw(Effect._elementDoesNotExistError);var options=Object.extend({scaleX:true,scaleY:true,scaleContent:true,scaleFromCenter:false,scaleMode:'box',scaleFrom:100.0,scaleTo:percent},arguments[2]||{});this.start(options);},setup:function(){this.restoreAfterFinish=this.options.restoreAfterFinish||false;this.elementPositioning=this.element.getStyle('position');this.originalStyle={};['top','left','width','height','fontSize'].each(function(k){this.originalStyle[k]=this.element.style[k];}.bind(this));this.originalTop=this.element.offsetTop;this.originalLeft=this.element.offsetLeft;var fontSize=this.element.getStyle('font-size')||'100%';['em','px','%','pt'].each(function(fontSizeType){if(fontSize.indexOf(fontSizeType)>0){this.fontSize=parseFloat(fontSize);this.fontSizeType=fontSizeType;}}.bind(this));this.factor=(this.options.scaleTo-this.options.scaleFrom)/100;this.dims=null;if(this.options.scaleMode=='box')
+this.dims=[this.element.offsetHeight,this.element.offsetWidth];if(/^content/.test(this.options.scaleMode))
+this.dims=[this.element.scrollHeight,this.element.scrollWidth];if(!this.dims)
+this.dims=[this.options.scaleMode.originalHeight,this.options.scaleMode.originalWidth];},update:function(position){var currentScale=(this.options.scaleFrom/100.0)+(this.factor*position);if(this.options.scaleContent&&this.fontSize)
+this.element.setStyle({fontSize:this.fontSize*currentScale+this.fontSizeType});this.setDimensions(this.dims[0]*currentScale,this.dims[1]*currentScale);},finish:function(position){if(this.restoreAfterFinish)this.element.setStyle(this.originalStyle);},setDimensions:function(height,width){var d={};if(this.options.scaleX)d.width=width.round()+'px';if(this.options.scaleY)d.height=height.round()+'px';if(this.options.scaleFromCenter){var topd=(height-this.dims[0])/2;var leftd=(width-this.dims[1])/2;if(this.elementPositioning=='absolute'){if(this.options.scaleY)d.top=this.originalTop-topd+'px';if(this.options.scaleX)d.left=this.originalLeft-leftd+'px';}else{if(this.options.scaleY)d.top=-topd+'px';if(this.options.scaleX)d.left=-leftd+'px';}}
+this.element.setStyle(d);}});Effect.Highlight=Class.create(Effect.Base,{initialize:function(element){this.element=$(element);if(!this.element)throw(Effect._elementDoesNotExistError);var options=Object.extend({startcolor:'#ffff99'},arguments[1]||{});this.start(options);},setup:function(){if(this.element.getStyle('display')=='none'){this.cancel();return;}
+this.oldStyle={};if(!this.options.keepBackgroundImage){this.oldStyle.backgroundImage=this.element.getStyle('background-image');this.element.setStyle({backgroundImage:'none'});}
+if(!this.options.endcolor)
+this.options.endcolor=this.element.getStyle('background-color').parseColor('#ffffff');if(!this.options.restorecolor)
+this.options.restorecolor=this.element.getStyle('background-color');this._base=$R(0,2).map(function(i){return parseInt(this.options.startcolor.slice(i*2+1,i*2+3),16)}.bind(this));this._delta=$R(0,2).map(function(i){return parseInt(this.options.endcolor.slice(i*2+1,i*2+3),16)-this._base[i]}.bind(this));},update:function(position){this.element.setStyle({backgroundColor:$R(0,2).inject('#',function(m,v,i){return m+((this._base[i]+(this._delta[i]*position)).round().toColorPart());}.bind(this))});},finish:function(){this.element.setStyle(Object.extend(this.oldStyle,{backgroundColor:this.options.restorecolor}));}});Effect.ScrollTo=function(element){var options=arguments[1]||{},scrollOffsets=document.viewport.getScrollOffsets(),elementOffsets=$(element).cumulativeOffset();if(options.offset)elementOffsets[1]+=options.offset;return new Effect.Tween(null,scrollOffsets.top,elementOffsets[1],options,function(p){scrollTo(scrollOffsets.left,p.round());});};Effect.Fade=function(element){element=$(element);var oldOpacity=element.getInlineOpacity();var options=Object.extend({from:element.getOpacity()||1.0,to:0.0,afterFinishInternal:function(effect){if(effect.options.to!=0)return;effect.element.hide().setStyle({opacity:oldOpacity});}},arguments[1]||{});return new Effect.Opacity(element,options);};Effect.Appear=function(element){element=$(element);var options=Object.extend({from:(element.getStyle('display')=='none'?0.0:element.getOpacity()||0.0),to:1.0,afterFinishInternal:function(effect){effect.element.forceRerendering();},beforeSetup:function(effect){effect.element.setOpacity(effect.options.from).show();}},arguments[1]||{});return new Effect.Opacity(element,options);};Effect.Puff=function(element){element=$(element);var oldStyle={opacity:element.getInlineOpacity(),position:element.getStyle('position'),top:element.style.top,left:element.style.left,width:element.style.width,height:element.style.height};return new Effect.Parallel([new Effect.Scale(element,200,{sync:true,scaleFromCenter:true,scaleContent:true,restoreAfterFinish:true}),new Effect.Opacity(element,{sync:true,to:0.0})],Object.extend({duration:1.0,beforeSetupInternal:function(effect){Position.absolutize(effect.effects[0].element);},afterFinishInternal:function(effect){effect.effects[0].element.hide().setStyle(oldStyle);}},arguments[1]||{}));};Effect.BlindUp=function(element){element=$(element);element.makeClipping();return new Effect.Scale(element,0,Object.extend({scaleContent:false,scaleX:false,restoreAfterFinish:true,afterFinishInternal:function(effect){effect.element.hide().undoClipping();}},arguments[1]||{}));};Effect.BlindDown=function(element){element=$(element);var elementDimensions=element.getDimensions();return new Effect.Scale(element,100,Object.extend({scaleContent:false,scaleX:false,scaleFrom:0,scaleMode:{originalHeight:elementDimensions.height,originalWidth:elementDimensions.width},restoreAfterFinish:true,afterSetup:function(effect){effect.element.makeClipping().setStyle({height:'0px'}).show();},afterFinishInternal:function(effect){effect.element.undoClipping();}},arguments[1]||{}));};Effect.SwitchOff=function(element){element=$(element);var oldOpacity=element.getInlineOpacity();return new Effect.Appear(element,Object.extend({duration:0.4,from:0,transition:Effect.Transitions.flicker,afterFinishInternal:function(effect){new Effect.Scale(effect.element,1,{duration:0.3,scaleFromCenter:true,scaleX:false,scaleContent:false,restoreAfterFinish:true,beforeSetup:function(effect){effect.element.makePositioned().makeClipping();},afterFinishInternal:function(effect){effect.element.hide().undoClipping().undoPositioned().setStyle({opacity:oldOpacity});}});}},arguments[1]||{}));};Effect.DropOut=function(element){element=$(element);var oldStyle={top:element.getStyle('top'),left:element.getStyle('left'),opacity:element.getInlineOpacity()};return new Effect.Parallel([new Effect.Move(element,{x:0,y:100,sync:true}),new Effect.Opacity(element,{sync:true,to:0.0})],Object.extend({duration:0.5,beforeSetup:function(effect){effect.effects[0].element.makePositioned();},afterFinishInternal:function(effect){effect.effects[0].element.hide().undoPositioned().setStyle(oldStyle);}},arguments[1]||{}));};Effect.Shake=function(element){element=$(element);var options=Object.extend({distance:20,duration:0.5},arguments[1]||{});var distance=parseFloat(options.distance);var split=parseFloat(options.duration)/10.0;var oldStyle={top:element.getStyle('top'),left:element.getStyle('left')};return new Effect.Move(element,{x:distance,y:0,duration:split,afterFinishInternal:function(effect){new Effect.Move(effect.element,{x:-distance*2,y:0,duration:split*2,afterFinishInternal:function(effect){new Effect.Move(effect.element,{x:distance*2,y:0,duration:split*2,afterFinishInternal:function(effect){new Effect.Move(effect.element,{x:-distance*2,y:0,duration:split*2,afterFinishInternal:function(effect){new Effect.Move(effect.element,{x:distance*2,y:0,duration:split*2,afterFinishInternal:function(effect){new Effect.Move(effect.element,{x:-distance,y:0,duration:split,afterFinishInternal:function(effect){effect.element.undoPositioned().setStyle(oldStyle);}});}});}});}});}});}});};Effect.SlideDown=function(element){element=$(element).cleanWhitespace();var oldInnerBottom=element.down().getStyle('bottom');var elementDimensions=element.getDimensions();return new Effect.Scale(element,100,Object.extend({scaleContent:false,scaleX:false,scaleFrom:window.opera?0:1,scaleMode:{originalHeight:elementDimensions.height,originalWidth:elementDimensions.width},restoreAfterFinish:true,afterSetup:function(effect){effect.element.makePositioned();effect.element.down().makePositioned();if(window.opera)effect.element.setStyle({top:''});effect.element.makeClipping().setStyle({height:'0px'}).show();},afterUpdateInternal:function(effect){effect.element.down().setStyle({bottom:(effect.dims[0]-effect.element.clientHeight)+'px'});},afterFinishInternal:function(effect){effect.element.undoClipping().undoPositioned();effect.element.down().undoPositioned().setStyle({bottom:oldInnerBottom});}},arguments[1]||{}));};Effect.SlideUp=function(element){element=$(element).cleanWhitespace();var oldInnerBottom=element.down().getStyle('bottom');var elementDimensions=element.getDimensions();return new Effect.Scale(element,window.opera?0:1,Object.extend({scaleContent:false,scaleX:false,scaleMode:'box',scaleFrom:100,scaleMode:{originalHeight:elementDimensions.height,originalWidth:elementDimensions.width},restoreAfterFinish:true,afterSetup:function(effect){effect.element.makePositioned();effect.element.down().makePositioned();if(window.opera)effect.element.setStyle({top:''});effect.element.makeClipping().show();},afterUpdateInternal:function(effect){effect.element.down().setStyle({bottom:(effect.dims[0]-effect.element.clientHeight)+'px'});},afterFinishInternal:function(effect){effect.element.hide().undoClipping().undoPositioned();effect.element.down().undoPositioned().setStyle({bottom:oldInnerBottom});}},arguments[1]||{}));};Effect.Squish=function(element){return new Effect.Scale(element,window.opera?1:0,{restoreAfterFinish:true,beforeSetup:function(effect){effect.element.makeClipping();},afterFinishInternal:function(effect){effect.element.hide().undoClipping();}});};Effect.Grow=function(element){element=$(element);var options=Object.extend({direction:'center',moveTransition:Effect.Transitions.sinoidal,scaleTransition:Effect.Transitions.sinoidal,opacityTransition:Effect.Transitions.full},arguments[1]||{});var oldStyle={top:element.style.top,left:element.style.left,height:element.style.height,width:element.style.width,opacity:element.getInlineOpacity()};var dims=element.getDimensions();var initialMoveX,initialMoveY;var moveX,moveY;switch(options.direction){case'top-left':initialMoveX=initialMoveY=moveX=moveY=0;break;case'top-right':initialMoveX=dims.width;initialMoveY=moveY=0;moveX=-dims.width;break;case'bottom-left':initialMoveX=moveX=0;initialMoveY=dims.height;moveY=-dims.height;break;case'bottom-right':initialMoveX=dims.width;initialMoveY=dims.height;moveX=-dims.width;moveY=-dims.height;break;case'center':initialMoveX=dims.width/2;initialMoveY=dims.height/2;moveX=-dims.width/2;moveY=-dims.height/2;break;}
+return new Effect.Move(element,{x:initialMoveX,y:initialMoveY,duration:0.01,beforeSetup:function(effect){effect.element.hide().makeClipping().makePositioned();},afterFinishInternal:function(effect){new Effect.Parallel([new Effect.Opacity(effect.element,{sync:true,to:1.0,from:0.0,transition:options.opacityTransition}),new Effect.Move(effect.element,{x:moveX,y:moveY,sync:true,transition:options.moveTransition}),new Effect.Scale(effect.element,100,{scaleMode:{originalHeight:dims.height,originalWidth:dims.width},sync:true,scaleFrom:window.opera?1:0,transition:options.scaleTransition,restoreAfterFinish:true})],Object.extend({beforeSetup:function(effect){effect.effects[0].element.setStyle({height:'0px'}).show();},afterFinishInternal:function(effect){effect.effects[0].element.undoClipping().undoPositioned().setStyle(oldStyle);}},options));}});};Effect.Shrink=function(element){element=$(element);var options=Object.extend({direction:'center',moveTransition:Effect.Transitions.sinoidal,scaleTransition:Effect.Transitions.sinoidal,opacityTransition:Effect.Transitions.none},arguments[1]||{});var oldStyle={top:element.style.top,left:element.style.left,height:element.style.height,width:element.style.width,opacity:element.getInlineOpacity()};var dims=element.getDimensions();var moveX,moveY;switch(options.direction){case'top-left':moveX=moveY=0;break;case'top-right':moveX=dims.width;moveY=0;break;case'bottom-left':moveX=0;moveY=dims.height;break;case'bottom-right':moveX=dims.width;moveY=dims.height;break;case'center':moveX=dims.width/2;moveY=dims.height/2;break;}
+return new Effect.Parallel([new Effect.Opacity(element,{sync:true,to:0.0,from:1.0,transition:options.opacityTransition}),new Effect.Scale(element,window.opera?1:0,{sync:true,transition:options.scaleTransition,restoreAfterFinish:true}),new Effect.Move(element,{x:moveX,y:moveY,sync:true,transition:options.moveTransition})],Object.extend({beforeStartInternal:function(effect){effect.effects[0].element.makePositioned().makeClipping();},afterFinishInternal:function(effect){effect.effects[0].element.hide().undoClipping().undoPositioned().setStyle(oldStyle);}},options));};Effect.Pulsate=function(element){element=$(element);var options=arguments[1]||{},oldOpacity=element.getInlineOpacity(),transition=options.transition||Effect.Transitions.linear,reverser=function(pos){return 1-transition((-Math.cos((pos*(options.pulses||5)*2)*Math.PI)/2)+.5);};return new Effect.Opacity(element,Object.extend(Object.extend({duration:2.0,from:0,afterFinishInternal:function(effect){effect.element.setStyle({opacity:oldOpacity});}},options),{transition:reverser}));};Effect.Fold=function(element){element=$(element);var oldStyle={top:element.style.top,left:element.style.left,width:element.style.width,height:element.style.height};element.makeClipping();return new Effect.Scale(element,5,Object.extend({scaleContent:false,scaleX:false,afterFinishInternal:function(effect){new Effect.Scale(element,1,{scaleContent:false,scaleY:false,afterFinishInternal:function(effect){effect.element.hide().undoClipping().setStyle(oldStyle);}});}},arguments[1]||{}));};Effect.Morph=Class.create(Effect.Base,{initialize:function(element){this.element=$(element);if(!this.element)throw(Effect._elementDoesNotExistError);var options=Object.extend({style:{}},arguments[1]||{});if(!Object.isString(options.style))this.style=$H(options.style);else{if(options.style.include(':'))
+this.style=options.style.parseStyle();else{this.element.addClassName(options.style);this.style=$H(this.element.getStyles());this.element.removeClassName(options.style);var css=this.element.getStyles();this.style=this.style.reject(function(style){return style.value==css[style.key];});options.afterFinishInternal=function(effect){effect.element.addClassName(effect.options.style);effect.transforms.each(function(transform){effect.element.style[transform.style]='';});};}}
+this.start(options);},setup:function(){function parseColor(color){if(!color||['rgba(0, 0, 0, 0)','transparent'].include(color))color='#ffffff';color=color.parseColor();return $R(0,2).map(function(i){return parseInt(color.slice(i*2+1,i*2+3),16);});}
+this.transforms=this.style.map(function(pair){var property=pair[0],value=pair[1],unit=null;if(value.parseColor('#zzzzzz')!='#zzzzzz'){value=value.parseColor();unit='color';}else if(property=='opacity'){value=parseFloat(value);if(Prototype.Browser.IE&&(!this.element.currentStyle.hasLayout))
+this.element.setStyle({zoom:1});}else if(Element.CSS_LENGTH.test(value)){var components=value.match(/^([\+\-]?[0-9\.]+)(.*)$/);value=parseFloat(components[1]);unit=(components.length==3)?components[2]:null;}
+var originalValue=this.element.getStyle(property);return{style:property.camelize(),originalValue:unit=='color'?parseColor(originalValue):parseFloat(originalValue||0),targetValue:unit=='color'?parseColor(value):value,unit:unit};}.bind(this)).reject(function(transform){return((transform.originalValue==transform.targetValue)||(transform.unit!='color'&&(isNaN(transform.originalValue)||isNaN(transform.targetValue))));});},update:function(position){var style={},transform,i=this.transforms.length;while(i--)
+style[(transform=this.transforms[i]).style]=transform.unit=='color'?'#'+
+(Math.round(transform.originalValue[0]+
+(transform.targetValue[0]-transform.originalValue[0])*position)).toColorPart()+
+(Math.round(transform.originalValue[1]+
+(transform.targetValue[1]-transform.originalValue[1])*position)).toColorPart()+
+(Math.round(transform.originalValue[2]+
+(transform.targetValue[2]-transform.originalValue[2])*position)).toColorPart():(transform.originalValue+
+(transform.targetValue-transform.originalValue)*position).toFixed(3)+
+(transform.unit===null?'':transform.unit);this.element.setStyle(style,true);}});Effect.Transform=Class.create({initialize:function(tracks){this.tracks=[];this.options=arguments[1]||{};this.addTracks(tracks);},addTracks:function(tracks){tracks.each(function(track){track=$H(track);var data=track.values().first();this.tracks.push($H({ids:track.keys().first(),effect:Effect.Morph,options:{style:data}}));}.bind(this));return this;},play:function(){return new Effect.Parallel(this.tracks.map(function(track){var ids=track.get('ids'),effect=track.get('effect'),options=track.get('options');var elements=[$(ids)||$$(ids)].flatten();return elements.map(function(e){return new effect(e,Object.extend({sync:true},options))});}).flatten(),this.options);}});Element.CSS_PROPERTIES=$w('backgroundColor backgroundPosition borderBottomColor borderBottomStyle '+'borderBottomWidth borderLeftColor borderLeftStyle borderLeftWidth '+'borderRightColor borderRightStyle borderRightWidth borderSpacing '+'borderTopColor borderTopStyle borderTopWidth bottom clip color '+'fontSize fontWeight height left letterSpacing lineHeight '+'marginBottom marginLeft marginRight marginTop markerOffset maxHeight '+'maxWidth minHeight minWidth opacity outlineColor outlineOffset '+'outlineWidth paddingBottom paddingLeft paddingRight paddingTop '+'right textIndent top width wordSpacing zIndex');Element.CSS_LENGTH=/^(([\+\-]?[0-9\.]+)(em|ex|px|in|cm|mm|pt|pc|\%))|0$/;String.__parseStyleElement=document.createElement('div');String.prototype.parseStyle=function(){var style,styleRules=$H();if(Prototype.Browser.WebKit)
+style=new Element('div',{style:this}).style;else{String.__parseStyleElement.innerHTML='<div style="'+this+'"></div>';style=String.__parseStyleElement.childNodes[0].style;}
+Element.CSS_PROPERTIES.each(function(property){if(style[property])styleRules.set(property,style[property]);});if(Prototype.Browser.IE&&this.include('opacity'))
+styleRules.set('opacity',this.match(/opacity:\s*((?:0|1)?(?:\.\d*)?)/)[1]);return styleRules;};if(document.defaultView&&document.defaultView.getComputedStyle){Element.getStyles=function(element){var css=document.defaultView.getComputedStyle($(element),null);return Element.CSS_PROPERTIES.inject({},function(styles,property){styles[property]=css[property];return styles;});};}else{Element.getStyles=function(element){element=$(element);var css=element.currentStyle,styles;styles=Element.CSS_PROPERTIES.inject({},function(results,property){results[property]=css[property];return results;});if(!styles.opacity)styles.opacity=element.getOpacity();return styles;};}
+Effect.Methods={morph:function(element,style){element=$(element);new Effect.Morph(element,Object.extend({style:style},arguments[2]||{}));return element;},visualEffect:function(element,effect,options){element=$(element);var s=effect.dasherize().camelize(),klass=s.charAt(0).toUpperCase()+s.substring(1);new Effect[klass](element,options);return element;},highlight:function(element,options){element=$(element);new Effect.Highlight(element,options);return element;}};$w('fade appear grow shrink fold blindUp blindDown slideUp slideDown '+'pulsate shake puff squish switchOff dropOut').each(function(effect){Effect.Methods[effect]=function(element,options){element=$(element);Effect[effect.charAt(0).toUpperCase()+effect.substring(1)](element,options);return element;};});$w('getInlineOpacity forceRerendering setContentZoom collectTextNodes collectTextNodesIgnoreClass getStyles').each(function(f){Effect.Methods[f]=Element[f];});Element.addMethods(Effect.Methods);
+function browserdetect(){var agent=navigator.userAgent.toLowerCase();this.isIE=agent.indexOf("msie")>-1;if(this.isIE){this.ieVer=/msie\s(\d\.\d)/.exec(agent)[1];this.quirksMode=!document.compatMode||document.compatMode.indexOf("BackCompat")>-1;this.get_style=function(obj,prop){if(!(prop in obj.currentStyle))return"";var matches=/^([\d.]+)(\w*)/.exec(obj.currentStyle[prop]);if(!matches)return obj.currentStyle[prop];if(matches[1]==0)return'0';if(matches[2]&&matches[2]!=='px'){var style=obj.style.left;var rtStyle=obj.runtimeStyle.left;obj.runtimeStyle.left=obj.currentStyle.left;obj.style.left=matches[1]+matches[2];matches[0]=obj.style.pixelLeft;obj.style.left=style;obj.runtimeStyle.left=rtStyle;}
+return matches[0];};}
+else{this.ieVer=this.quirksMode=0;this.isMoz=agent.indexOf('firefox')!==-1||('style'in document.childNodes[1]&&'MozBorderRadius'in document.childNodes[1].style);this.isSafari=agent.indexOf('safari')!=-1;this.isOp='opera'in window;this.isWebKit=agent.indexOf('webkit')!=-1;this.get_style=function(obj,prop){prop=prop.replace(/([a-z])([A-Z])/g,'$1-$2').toLowerCase();return document.defaultView.getComputedStyle(obj,'').getPropertyValue(prop);};}}
+var curvyBrowser=new browserdetect;if(curvyBrowser.isIE){try{document.execCommand("BackgroundImageCache",false,true);}
+catch(e){};}
+function curvyCnrSpec(selText){this.selectorText=selText;this.tlR=this.trR=this.blR=this.brR=0;this.tlu=this.tru=this.blu=this.bru="";this.antiAlias=true;}
+curvyCnrSpec.prototype.setcorner=function(tb,lr,radius,unit){if(!tb){this.tlR=this.trR=this.blR=this.brR=parseInt(radius);this.tlu=this.tru=this.blu=this.bru=unit;}
+else{propname=tb.charAt(0)+lr.charAt(0);this[propname+'R']=parseInt(radius);this[propname+'u']=unit;}}
+curvyCnrSpec.prototype.get=function(prop){if(/^(t|b)(l|r)(R|u)$/.test(prop))return this[prop];if(/^(t|b)(l|r)Ru$/.test(prop)){var pname=prop.charAt(0)+prop.charAt(1);return this[pname+'R']+this[pname+'u'];}
+if(/^(t|b)Ru?$/.test(prop)){var tb=prop.charAt(0);tb+=this[tb+'lR']>this[tb+'rR']?'l':'r';var retval=this[tb+'R'];if(prop.length===3&&prop.charAt(2)==='u')
+retval+=this[tb='u'];return retval;}
+throw new Error('Don\'t recognize property '+prop);}
+curvyCnrSpec.prototype.radiusdiff=function(tb){if(tb!=='t'&&tb!=='b')throw new Error("Param must be 't' or 'b'");return Math.abs(this[tb+'lR']-this[tb+'rR']);}
+curvyCnrSpec.prototype.setfrom=function(obj){this.tlu=this.tru=this.blu=this.bru='px';if('tl'in obj)this.tlR=obj.tl.radius;if('tr'in obj)this.trR=obj.tr.radius;if('bl'in obj)this.blR=obj.bl.radius;if('br'in obj)this.brR=obj.br.radius;if('antiAlias'in obj)this.antiAlias=obj.antiAlias;};curvyCnrSpec.prototype.cloneOn=function(box){var props=['tl','tr','bl','br'];var converted=0;var i,propu;for(i in props)if(!isNaN(i)){propu=this[props[i]+'u'];if(propu!==''&&propu!=='px'){converted=new curvyCnrSpec;break;}}
+if(!converted)
+converted=this;else{var propi,propR,save=curvyBrowser.get_style(box,'left');for(i in props)if(!isNaN(i)){propi=props[i];propu=this[propi+'u'];propR=this[propi+'R'];if(propu!=='px'){var save=box.style.left;box.style.left=propR+propu;propR=box.style.pixelLeft;box.style.left=save;}
+converted[propi+'R']=propR;converted[propi+'u']='px';}
+box.style.left=save;}
+return converted;}
+curvyCnrSpec.prototype.radiusSum=function(tb){if(tb!=='t'&&tb!=='b')throw new Error("Param must be 't' or 'b'");return this[tb+'lR']+this[tb+'rR'];}
+curvyCnrSpec.prototype.radiusCount=function(tb){var count=0;if(this[tb+'lR'])++count;if(this[tb+'rR'])++count;return count;}
+curvyCnrSpec.prototype.cornerNames=function(){var ret=[];if(this.tlR)ret.push('tl');if(this.trR)ret.push('tr');if(this.blR)ret.push('bl');if(this.brR)ret.push('br');return ret;}
+function operasheet(sheetnumber){var txt=document.styleSheets.item(sheetnumber).ownerNode.text;txt=txt.replace(/\/\*(\n|\r|.)*?\*\//g,'');var pat=new RegExp("^\\s*([\\w.#][-\\w.#, ]+)[\\n\\s]*\\{([^}]+border-((top|bottom)-(left|right)-)?radius[^}]*)\\}","mg");var matches;this.rules=[];while((matches=pat.exec(txt))!==null){var pat2=new RegExp("(..)border-((top|bottom)-(left|right)-)?radius:\\s*([\\d.]+)(in|em|px|ex|pt)","g");var submatches,cornerspec=new curvyCnrSpec(matches[1]);while((submatches=pat2.exec(matches[2]))!==null)
+if(submatches[1]!=="z-")
+cornerspec.setcorner(submatches[3],submatches[4],submatches[5],submatches[6]);this.rules.push(cornerspec);}}
+operasheet.contains_border_radius=function(sheetnumber){return/border-((top|bottom)-(left|right)-)?radius/.test(document.styleSheets.item(sheetnumber).ownerNode.text);}
+function curvyCorners(){var i,j,boxCol,settings,startIndex;if(typeof arguments[0]!=="object")throw curvyCorners.newError("First parameter of curvyCorners() must be an object.");if(arguments[0]instanceof curvyCnrSpec){settings=arguments[0];if(!settings.selectorText&&typeof arguments[1]==='string')
+settings.selectorText=arguments[1];}
+else{if(typeof arguments[1]!=="object"&&typeof arguments[1]!=="string")throw curvyCorners.newError("Second parameter of curvyCorners() must be an object or a class name.");j=arguments[1];if(typeof j!=='string')j='';if(j!==''&&j.charAt(0)!=='.'&&'autoPad'in arguments[0])j='.'+j;settings=new curvyCnrSpec(j);settings.setfrom(arguments[0]);}
+if(settings.selectorText){startIndex=0;var args=settings.selectorText.replace(/\s+$/,'').split(/,\s*/);boxCol=new Array;function idof(str){var ret=str.split('#');return(ret.length===2?"#":"")+ret.pop();}
+for(i=0;i<args.length;++i){var arg=idof(args[i]);var argbits=arg.split(' ');switch(arg.charAt(0)){case'#':j=argbits.length===1?arg:argbits[0];j=document.getElementById(j.substr(1));if(j===null)
+curvyCorners.alert("No object with ID "+arg+" exists yet.\nCall curvyCorners(settings, obj) when it is created.");else if(argbits.length===1)
+boxCol.push(j);else
+boxCol=boxCol.concat(curvyCorners.getElementsByClass(argbits[1],j));break;default:if(argbits.length===1)
+boxCol=boxCol.concat(curvyCorners.getElementsByClass(arg));else{var encloser=curvyCorners.getElementsByClass(argbits[0]);for(j=0;j<encloser.length;++j){boxCol=boxCol.concat(curvyCorners.getElementsByClass(argbits[1],encloser[j]));}}}}}
+else{startIndex=1;boxCol=arguments;}
+for(i=startIndex,j=boxCol.length;i<j;++i){if(boxCol[i]&&(!('IEborderRadius'in boxCol[i].style)||boxCol[i].style.IEborderRadius!='set')){if(boxCol[i].className&&boxCol[i].className.indexOf('curvyRedraw')!==-1){if(typeof curvyCorners.redrawList==='undefined')curvyCorners.redrawList=new Array;curvyCorners.redrawList.push({node:boxCol[i],spec:settings,copy:boxCol[i].cloneNode(false)});}
+boxCol[i].style.IEborderRadius='set';var obj=new curvyObject(settings,boxCol[i]);obj.applyCorners();}}}
+curvyCorners.prototype.applyCornersToAll=function(){throw curvyCorners.newError('This function is now redundant. Just call curvyCorners(). See documentation.');};curvyCorners.redraw=function(){if(!curvyBrowser.isOp&&!curvyBrowser.isIE)return;if(!curvyCorners.redrawList)throw curvyCorners.newError('curvyCorners.redraw() has nothing to redraw.');var old_block_value=curvyCorners.block_redraw;curvyCorners.block_redraw=true;for(var i in curvyCorners.redrawList){if(isNaN(i))continue;var o=curvyCorners.redrawList[i];if(!o.node.clientWidth)continue;var newchild=o.copy.cloneNode(false);for(var contents=o.node.firstChild;contents!=null;contents=contents.nextSibling)
+if(contents.className==='autoPadDiv')break;if(!contents){curvyCorners.alert('Couldn\'t find autoPad DIV');break;}
+o.node.parentNode.replaceChild(newchild,o.node);var scripts=contents.getElementsByTagName('script');for(var j=scripts.length-1;j>=0;--j)
+scripts[j].parentNode.removeChild(scripts[j]);while(contents.firstChild)newchild.appendChild(contents.removeChild(contents.firstChild));o=new curvyObject(o.spec,o.node=newchild);o.applyCorners();}
+curvyCorners.block_redraw=old_block_value;}
+curvyCorners.adjust=function(obj,prop,newval){if(curvyBrowser.isOp||curvyBrowser.isIE){if(!curvyCorners.redrawList)throw curvyCorners.newError('curvyCorners.adjust() has nothing to adjust.');var i,j=curvyCorners.redrawList.length;for(i=0;i<j;++i)if(curvyCorners.redrawList[i].node===obj)break;if(i===j)throw curvyCorners.newError('Object not redrawable');obj=curvyCorners.redrawList[i].copy;}
+if(prop.indexOf('.')===-1)
+obj[prop]=newval;else eval('obj.'+prop+"='"+newval+"'");}
+curvyCorners.handleWinResize=function(){if(!curvyCorners.block_redraw)curvyCorners.redraw();}
+curvyCorners.setWinResize=function(onoff){curvyCorners.block_redraw=!onoff;}
+curvyCorners.newError=function(errorMessage){return new Error("curvyCorners Error:\n"+errorMessage)}
+curvyCorners.alert=function(errorMessage){if(typeof curvyCornersVerbose==='undefined'||curvyCornersVerbose)alert(errorMessage);}
+function curvyObject(){var boxDisp;this.box=arguments[1];this.settings=arguments[0];this.topContainer=this.bottomContainer=this.shell=boxDisp=null;var boxWidth=this.box.clientWidth;if(('canHaveChildren'in this.box&&!this.box.canHaveChildren)||this.box.tagName==='TABLE')
+throw new Error(this.errmsg("You cannot apply corners to "+this.box.tagName+" elements.","Error"));if(!boxWidth&&curvyBrowser.isIE){this.box.style.zoom=1;boxWidth=this.box.clientWidth;}
+if(!boxWidth&&curvyBrowser.get_style(this.box,'display')==='inline'){this.box.style.display='inline-block';curvyCorners.alert(this.errmsg("Converting inline element to inline-block","warning"));boxWidth=this.box.clientWidth;}
+if(!boxWidth){if(!this.box.parentNode)throw this.newError("box has no parent!");for(boxDisp=this.box;;boxDisp=boxDisp.parentNode){if(!boxDisp||boxDisp.tagName==='BODY'){this.applyCorners=function(){}
+curvyCorners.alert(this.errmsg("zero-width box with no accountable parent","warning"));return;}
+if(curvyBrowser.get_style(boxDisp,'display')==='none')break;}
+var boxDispSave=boxDisp.style.display;boxDisp.style.display='block';boxWidth=this.box.clientWidth;}
+if(!boxWidth){curvyCorners.alert(this.errmsg("zero-width box, cannot display","error"));this.applyCorners=function(){}
+return;}
+if(arguments[0]instanceof curvyCnrSpec)
+this.spec=arguments[0].cloneOn(this.box);else{this.spec=new curvyCnrSpec('');this.spec.setfrom(this.settings);}
+var borderWidth=curvyBrowser.get_style(this.box,"borderTopWidth");var borderWidthB=curvyBrowser.get_style(this.box,"borderBottomWidth");var borderWidthL=curvyBrowser.get_style(this.box,"borderLeftWidth");var borderWidthR=curvyBrowser.get_style(this.box,"borderRightWidth");var borderColour=curvyBrowser.get_style(this.box,"borderTopColor");var borderColourB=curvyBrowser.get_style(this.box,"borderBottomColor");var borderColourL=curvyBrowser.get_style(this.box,"borderLeftColor");var borderColourR=curvyBrowser.get_style(this.box,"borderRightColor");var borderStyle=curvyBrowser.get_style(this.box,"borderTopStyle");var borderStyleB=curvyBrowser.get_style(this.box,"borderBottomStyle");var borderStyleL=curvyBrowser.get_style(this.box,"borderLeftStyle");var borderStyleR=curvyBrowser.get_style(this.box,"borderRightStyle");var boxColour=curvyBrowser.get_style(this.box,"backgroundColor");var backgroundImage=curvyBrowser.get_style(this.box,"backgroundImage");var backgroundRepeat=curvyBrowser.get_style(this.box,"backgroundRepeat");if(this.box.currentStyle&&this.box.currentStyle.backgroundPositionX){var backgroundPosX=curvyBrowser.get_style(this.box,"backgroundPositionX");var backgroundPosY=curvyBrowser.get_style(this.box,"backgroundPositionY");}
+else{var backgroundPosX=curvyBrowser.get_style(this.box,'backgroundPosition');backgroundPosX=backgroundPosX.split(' ');var backgroundPosY=backgroundPosX[1];backgroundPosX=backgroundPosX[0];}
+var boxPosition=curvyBrowser.get_style(this.box,"position");var topPadding=curvyBrowser.get_style(this.box,"paddingTop");var bottomPadding=curvyBrowser.get_style(this.box,"paddingBottom");var leftPadding=curvyBrowser.get_style(this.box,"paddingLeft");var rightPadding=curvyBrowser.get_style(this.box,"paddingRight");var border=curvyBrowser.get_style(this.box,"border");var filter=curvyBrowser.ieVer>7?curvyBrowser.get_style(this.box,'filter'):null;var topMaxRadius=this.spec.get('tR');var botMaxRadius=this.spec.get('bR');var styleToNPx=function(val){if(typeof val==='number')return val;if(typeof val!=='string')throw new Error('unexpected styleToNPx type '+typeof val);var matches=/^[-\d.]([a-z]+)$/.exec(val);if(matches&&matches[1]!='px')throw new Error('Unexpected unit '+matches[1]);if(isNaN(val=parseInt(val)))val=0;return val;}
+var min0Px=function(val){return val<=0?"0":val+"px";}
+try{this.borderWidth=styleToNPx(borderWidth);this.borderWidthB=styleToNPx(borderWidthB);this.borderWidthL=styleToNPx(borderWidthL);this.borderWidthR=styleToNPx(borderWidthR);this.boxColour=curvyObject.format_colour(boxColour);this.topPadding=styleToNPx(topPadding);this.bottomPadding=styleToNPx(bottomPadding);this.leftPadding=styleToNPx(leftPadding);this.rightPadding=styleToNPx(rightPadding);this.boxWidth=boxWidth;this.boxHeight=this.box.clientHeight;this.borderColour=curvyObject.format_colour(borderColour);this.borderColourB=curvyObject.format_colour(borderColourB);this.borderColourL=curvyObject.format_colour(borderColourL);this.borderColourR=curvyObject.format_colour(borderColourR);this.borderString=this.borderWidth+"px"+" "+borderStyle+" "+this.borderColour;this.borderStringB=this.borderWidthB+"px"+" "+borderStyleB+" "+this.borderColourB;this.borderStringL=this.borderWidthL+"px"+" "+borderStyleL+" "+this.borderColourL;this.borderStringR=this.borderWidthR+"px"+" "+borderStyleR+" "+this.borderColourR;this.backgroundImage=((backgroundImage!="none")?backgroundImage:"");this.backgroundRepeat=backgroundRepeat;}
+catch(e){throw this.newError(e.message);}
+var clientHeight=this.boxHeight;var clientWidth=boxWidth;if(curvyBrowser.isOp){backgroundPosX=styleToNPx(backgroundPosX);backgroundPosY=styleToNPx(backgroundPosY);if(backgroundPosX){var t=clientWidth+this.borderWidthL+this.borderWidthR;if(backgroundPosX>t)backgroundPosX=t;backgroundPosX=(t/backgroundPosX*100)+'%';}
+if(backgroundPosY){var t=clientHeight+this.borderWidth+this.borderWidthB;if(backgroundPosY>t)backgroundPosY=t;backgroundPosY=(t/backgroundPosY*100)+'%';}}
+if(curvyBrowser.quirksMode){}
+else{this.boxWidth-=this.leftPadding+this.rightPadding;this.boxHeight-=this.topPadding+this.bottomPadding;}
+this.contentContainer=document.createElement("div");if(filter)this.contentContainer.style.filter=filter;while(this.box.firstChild)this.contentContainer.appendChild(this.box.removeChild(this.box.firstChild));if(boxPosition!="absolute")this.box.style.position="relative";this.box.style.padding='0';this.box.style.border=this.box.style.backgroundImage='none';this.box.style.backgroundColor='transparent';this.box.style.width=(clientWidth+this.borderWidthL+this.borderWidthR)+'px';this.box.style.height=(clientHeight+this.borderWidth+this.borderWidthB)+'px';var newMainContainer=document.createElement("div");newMainContainer.style.position="absolute";if(filter)newMainContainer.style.filter=filter;if(curvyBrowser.quirksMode){newMainContainer.style.width=(clientWidth+this.borderWidthL+this.borderWidthR)+'px';}else{newMainContainer.style.width=clientWidth+'px';}
+newMainContainer.style.height=min0Px(clientHeight+this.borderWidth+this.borderWidthB-topMaxRadius-botMaxRadius);newMainContainer.style.padding="0";newMainContainer.style.top=topMaxRadius+"px";newMainContainer.style.left="0";if(this.borderWidthL)
+newMainContainer.style.borderLeft=this.borderStringL;if(this.borderWidth&&!topMaxRadius)
+newMainContainer.style.borderTop=this.borderString;if(this.borderWidthR)
+newMainContainer.style.borderRight=this.borderStringR;if(this.borderWidthB&&!botMaxRadius)
+newMainContainer.style.borderBottom=this.borderStringB;newMainContainer.style.backgroundColor=boxColour;newMainContainer.style.backgroundImage=this.backgroundImage;newMainContainer.style.backgroundRepeat=this.backgroundRepeat;newMainContainer.style.direction='ltr';this.shell=this.box.appendChild(newMainContainer);boxWidth=curvyBrowser.get_style(this.shell,"width");if(boxWidth===""||boxWidth==="auto"||boxWidth.indexOf("%")!==-1)throw this.newError('Shell width is '+boxWidth);this.boxWidth=(boxWidth!=""&&boxWidth!="auto"&&boxWidth.indexOf("%")==-1)?parseInt(boxWidth):this.shell.clientWidth;this.applyCorners=function(){this.backgroundPosX=this.backgroundPosY=0;if(this.backgroundObject){var bgOffset=function(style,imglen,boxlen){if(style===0)return 0;var retval;if(style==='right'||style==='bottom')return boxlen-imglen;if(style==='center')return(boxlen-imglen)/2;if(style.indexOf('%')>0)return(boxlen-imglen)*100/parseInt(style);return styleToNPx(style);}
+this.backgroundPosX=bgOffset(backgroundPosX,this.backgroundObject.width,clientWidth);this.backgroundPosY=bgOffset(backgroundPosY,this.backgroundObject.height,clientHeight);}
+else if(this.backgroundImage){this.backgroundPosX=styleToNPx(backgroundPosX);this.backgroundPosY=styleToNPx(backgroundPosY);}
+if(topMaxRadius){newMainContainer=document.createElement("div");newMainContainer.style.width=this.boxWidth+"px";newMainContainer.style.fontSize="1px";newMainContainer.style.overflow="hidden";newMainContainer.style.position="absolute";newMainContainer.style.paddingLeft=this.borderWidth+"px";newMainContainer.style.paddingRight=this.borderWidth+"px";newMainContainer.style.height=topMaxRadius+"px";newMainContainer.style.top=-topMaxRadius+"px";newMainContainer.style.left=-this.borderWidthL+"px";this.topContainer=this.shell.appendChild(newMainContainer);}
+if(botMaxRadius){var newMainContainer=document.createElement("div");newMainContainer.style.width=this.boxWidth+"px";newMainContainer.style.fontSize="1px";newMainContainer.style.overflow="hidden";newMainContainer.style.position="absolute";newMainContainer.style.paddingLeft=this.borderWidthB+"px";newMainContainer.style.paddingRight=this.borderWidthB+"px";newMainContainer.style.height=botMaxRadius+"px";newMainContainer.style.bottom=-botMaxRadius+"px";newMainContainer.style.left=-this.borderWidthL+"px";this.bottomContainer=this.shell.appendChild(newMainContainer);}
+var corners=this.spec.cornerNames();for(var i in corners)if(!isNaN(i)){var cc=corners[i];var specRadius=this.spec[cc+'R'];var bwidth,bcolor,borderRadius,borderWidthTB;if(cc=="tr"||cc=="tl"){bwidth=this.borderWidth;bcolor=this.borderColour;borderWidthTB=this.borderWidth;}else{bwidth=this.borderWidthB;bcolor=this.borderColourB;borderWidthTB=this.borderWidthB;}
+borderRadius=specRadius-borderWidthTB;var newCorner=document.createElement("div");newCorner.style.height=this.spec.get(cc+'Ru');newCorner.style.width=this.spec.get(cc+'Ru');newCorner.style.position="absolute";newCorner.style.fontSize="1px";newCorner.style.overflow="hidden";var intx,inty,outsideColour;var trans=filter?parseInt(/alpha\(opacity.(\d+)\)/.exec(filter)[1]):100;for(intx=0;intx<specRadius;++intx){var y1=(intx+1>=borderRadius)?-1:Math.floor(Math.sqrt(Math.pow(borderRadius,2)-Math.pow(intx+1,2)))-1;if(borderRadius!=specRadius){var y2=(intx>=borderRadius)?-1:Math.ceil(Math.sqrt(Math.pow(borderRadius,2)-Math.pow(intx,2)));var y3=(intx+1>=specRadius)?-1:Math.floor(Math.sqrt(Math.pow(specRadius,2)-Math.pow((intx+1),2)))-1;}
+var y4=(intx>=specRadius)?-1:Math.ceil(Math.sqrt(Math.pow(specRadius,2)-Math.pow(intx,2)));if(y1>-1)this.drawPixel(intx,0,this.boxColour,trans,(y1+1),newCorner,true,specRadius);if(borderRadius!=specRadius){if(this.spec.antiAlias){for(inty=y1+1;inty<y2;++inty){if(this.backgroundImage!=""){var borderFract=curvyObject.pixelFraction(intx,inty,borderRadius)*100;this.drawPixel(intx,inty,bcolor,trans,1,newCorner,borderFract>=30,specRadius);}
+else if(this.boxColour!=='transparent'){var pixelcolour=curvyObject.BlendColour(this.boxColour,bcolor,curvyObject.pixelFraction(intx,inty,borderRadius));this.drawPixel(intx,inty,pixelcolour,trans,1,newCorner,false,specRadius);}
+else this.drawPixel(intx,inty,bcolor,trans>>1,1,newCorner,false,specRadius);}
+if(y3>=y2){if(y2==-1)y2=0;this.drawPixel(intx,y2,bcolor,trans,(y3-y2+1),newCorner,false,0);}
+outsideColour=bcolor;inty=y3;}
+else{if(y3>y1){this.drawPixel(intx,(y1+1),bcolor,trans,(y3-y1),newCorner,false,0);}}}
+else{outsideColour=this.boxColour;inty=y1;}
+if(this.spec.antiAlias){while(++inty<y4){this.drawPixel(intx,inty,outsideColour,(curvyObject.pixelFraction(intx,inty,specRadius)*trans),1,newCorner,borderWidthTB<=0,specRadius);}}}
+for(var t=0,k=newCorner.childNodes.length;t<k;++t){var pixelBar=newCorner.childNodes[t];var pixelBarTop=parseInt(pixelBar.style.top);var pixelBarLeft=parseInt(pixelBar.style.left);var pixelBarHeight=parseInt(pixelBar.style.height);if(cc=="tl"||cc=="bl"){pixelBar.style.left=(specRadius-pixelBarLeft-1)+"px";}
+if(cc=="tr"||cc=="tl"){pixelBar.style.top=(specRadius-pixelBarHeight-pixelBarTop)+"px";}
+pixelBar.style.backgroundRepeat=this.backgroundRepeat;if(this.backgroundImage)switch(cc){case"tr":pixelBar.style.backgroundPosition=(this.backgroundPosX-this.borderWidthL+specRadius-clientWidth-pixelBarLeft)+"px "+(this.backgroundPosY+pixelBarHeight+pixelBarTop+this.borderWidth-specRadius)+"px";break;case"tl":pixelBar.style.backgroundPosition=(this.backgroundPosX-specRadius+pixelBarLeft+1+this.borderWidthL)+"px "+(this.backgroundPosY-specRadius+pixelBarHeight+pixelBarTop+this.borderWidth)+"px";break;case"bl":pixelBar.style.backgroundPosition=(this.backgroundPosX-specRadius+pixelBarLeft+1+this.borderWidthL)+"px "+(this.backgroundPosY-clientHeight-this.borderWidth+(curvyBrowser.quirksMode?pixelBarTop:-pixelBarTop)+specRadius)+"px";break;case"br":if(curvyBrowser.quirksMode){pixelBar.style.backgroundPosition=(this.backgroundPosX-this.borderWidthL-clientWidth+specRadius-pixelBarLeft)+"px "+(this.backgroundPosY-clientHeight-this.borderWidth+pixelBarTop+specRadius)+"px";}else{pixelBar.style.backgroundPosition=(this.backgroundPosX-this.borderWidthL-clientWidth+specRadius-pixelBarLeft)+"px "+(this.backgroundPosY-clientHeight-this.borderWidth+specRadius-pixelBarTop)+"px";}}}
+switch(cc){case"tl":newCorner.style.top=newCorner.style.left="0";this.topContainer.appendChild(newCorner);break;case"tr":newCorner.style.top=newCorner.style.right="0";this.topContainer.appendChild(newCorner);break;case"bl":newCorner.style.bottom=newCorner.style.left="0";this.bottomContainer.appendChild(newCorner);break;case"br":newCorner.style.bottom=newCorner.style.right="0";this.bottomContainer.appendChild(newCorner);}}
+var radiusDiff={t:this.spec.radiusdiff('t'),b:this.spec.radiusdiff('b')};for(z in radiusDiff){if(typeof z==='function')continue;if(!this.spec.get(z+'R'))continue;if(radiusDiff[z]){var smallerCornerType=(this.spec[z+"lR"]<this.spec[z+"rR"])?z+"l":z+"r";var newFiller=document.createElement("div");newFiller.style.height=radiusDiff[z]+"px";newFiller.style.width=this.spec.get(smallerCornerType+'Ru');newFiller.style.position="absolute";newFiller.style.fontSize="1px";newFiller.style.overflow="hidden";newFiller.style.backgroundColor=this.boxColour;if(filter)newFiller.style.filter=filter;newFiller.style.backgroundImage=this.backgroundImage;newFiller.style.backgroundRepeat=this.backgroundRepeat;switch(smallerCornerType){case"tl":newFiller.style.bottom=newFiller.style.left="0";newFiller.style.borderLeft=this.borderStringL;newFiller.style.backgroundPosition=this.backgroundPosX+"px "+(this.borderWidth+this.backgroundPosY-this.spec.tlR)+"px";this.topContainer.appendChild(newFiller);break;case"tr":newFiller.style.bottom=newFiller.style.right="0";newFiller.style.borderRight=this.borderStringR;newFiller.style.backgroundPosition=(this.backgroundPosX-this.boxWidth+this.spec.trR)+"px "+(this.borderWidth+this.backgroundPosY-this.spec.trR)+"px";this.topContainer.appendChild(newFiller);break;case"bl":newFiller.style.top=newFiller.style.left="0";newFiller.style.borderLeft=this.borderStringL;newFiller.style.backgroundPosition=this.backgroundPosX+"px "+(this.backgroundPosY-this.borderWidth-this.boxHeight+radiusDiff[z]+this.spec.blR)+"px";this.bottomContainer.appendChild(newFiller);break;case"br":newFiller.style.top=newFiller.style.right="0";newFiller.style.borderRight=this.borderStringR;newFiller.style.backgroundPosition=(this.borderWidthL+this.backgroundPosX-this.boxWidth+this.spec.brR)+"px "+(this.backgroundPosY-this.borderWidth-this.boxHeight+radiusDiff[z]+this.spec.brR)+"px";this.bottomContainer.appendChild(newFiller);}}
+var newFillerBar=document.createElement("div");if(filter)newFillerBar.style.filter=filter;newFillerBar.style.position="relative";newFillerBar.style.fontSize="1px";newFillerBar.style.overflow="hidden";newFillerBar.style.width=this.fillerWidth(z);newFillerBar.style.backgroundColor=this.boxColour;newFillerBar.style.backgroundImage=this.backgroundImage;newFillerBar.style.backgroundRepeat=this.backgroundRepeat;switch(z){case"t":if(this.topContainer){if(curvyBrowser.quirksMode){newFillerBar.style.height=100+topMaxRadius+"px";}else{newFillerBar.style.height=100+topMaxRadius-this.borderWidth+"px";}
+newFillerBar.style.marginLeft=this.spec.tlR?(this.spec.tlR-this.borderWidthL)+"px":"0";newFillerBar.style.borderTop=this.borderString;if(this.backgroundImage){var x_offset=this.spec.tlR?(this.borderWidthL+this.backgroundPosX-this.spec.tlR)+"px ":this.backgroundPosX+"px ";newFillerBar.style.backgroundPosition=x_offset+this.backgroundPosY+"px";this.shell.style.backgroundPosition=this.backgroundPosX+"px "+(this.backgroundPosY-topMaxRadius+this.borderWidthL)+"px";}
+this.topContainer.appendChild(newFillerBar);}
+break;case"b":if(this.bottomContainer){if(curvyBrowser.quirksMode){newFillerBar.style.height=botMaxRadius+"px";}else{newFillerBar.style.height=botMaxRadius-this.borderWidthB+"px";}
+newFillerBar.style.marginLeft=this.spec.blR?(this.spec.blR-this.borderWidthL)+"px":"0";newFillerBar.style.borderBottom=this.borderStringB;if(this.backgroundImage){var x_offset=this.spec.blR?(this.backgroundPosX+this.borderWidthL-this.spec.blR)+"px ":this.backgroundPosX+"px ";newFillerBar.style.backgroundPosition=x_offset+(this.backgroundPosY-clientHeight-this.borderWidth+botMaxRadius)+"px";}
+this.bottomContainer.appendChild(newFillerBar);}}}
+this.contentContainer.style.position="absolute";this.contentContainer.className="autoPadDiv";this.contentContainer.style.left=this.borderWidthL+"px";this.contentContainer.style.paddingTop=this.topPadding+"px";this.contentContainer.style.top=this.borderWidth+"px";this.contentContainer.style.paddingLeft=this.leftPadding+"px";this.contentContainer.style.paddingRight=this.rightPadding+"px";z=clientWidth;if(!curvyBrowser.quirksMode)z-=this.leftPadding+this.rightPadding;this.contentContainer.style.width=z+"px";this.contentContainer.style.textAlign=curvyBrowser.get_style(this.box,'textAlign');this.box.style.textAlign='left';this.box.appendChild(this.contentContainer);if(boxDisp)boxDisp.style.display=boxDispSave;}
+if(this.backgroundImage){backgroundPosX=this.backgroundCheck(backgroundPosX);backgroundPosY=this.backgroundCheck(backgroundPosY);if(this.backgroundObject){this.backgroundObject.holdingElement=this;this.dispatch=this.applyCorners;this.applyCorners=function(){if(this.backgroundObject.complete)
+this.dispatch();else this.backgroundObject.onload=new Function('curvyObject.dispatch(this.holdingElement);');}}}}
+curvyObject.prototype.backgroundCheck=function(style){if(style==='top'||style==='left'||parseInt(style)===0)return 0;if(!(/^[-\d.]+px$/.test(style))&&!this.backgroundObject){this.backgroundObject=new Image;var imgName=function(str){var matches=/url\("?([^'"]+)"?\)/.exec(str);return(matches?matches[1]:str);}
+this.backgroundObject.src=imgName(this.backgroundImage);}
+return style;}
+curvyObject.dispatch=function(obj){if('dispatch'in obj)
+obj.dispatch();else throw obj.newError('No dispatch function');}
+curvyObject.prototype.drawPixel=function(intx,inty,colour,transAmount,height,newCorner,image,cornerRadius){var pixel=document.createElement("div");pixel.style.height=height+"px";pixel.style.width="1px";pixel.style.position="absolute";pixel.style.fontSize="1px";pixel.style.overflow="hidden";var topMaxRadius=this.spec.get('tR');pixel.style.backgroundColor=colour;if(image&&this.backgroundImage!=""){pixel.style.backgroundImage=this.backgroundImage;pixel.style.backgroundPosition="-"+(this.boxWidth-(cornerRadius-intx)+this.borderWidth)+"px -"+((this.boxHeight+topMaxRadius+inty)-this.borderWidth)+"px";}
+if(transAmount!=100)curvyObject.setOpacity(pixel,transAmount);pixel.style.top=inty+"px";pixel.style.left=intx+"px";newCorner.appendChild(pixel);}
+curvyObject.prototype.fillerWidth=function(tb){var b_width,f_width;b_width=curvyBrowser.quirksMode?0:this.spec.radiusCount(tb)*this.borderWidthL;if((f_width=this.boxWidth-this.spec.radiusSum(tb)+b_width)<0)
+throw this.newError("Radius exceeds box width");return f_width+'px';}
+curvyObject.prototype.errmsg=function(msg,gravity){var extradata="\ntag: "+this.box.tagName;if(this.box.id)extradata+="\nid: "+this.box.id;if(this.box.className)extradata+="\nclass: "+this.box.className;var parent;if((parent=this.box.parentNode)===null)
+extradata+="\n(box has no parent)";else{extradata+="\nParent tag: "+parent.tagName;if(parent.id)extradata+="\nParent ID: "+parent.id;if(parent.className)extradata+="\nParent class: "+parent.className;}
+if(gravity===undefined)gravity='warning';return'curvyObject '+gravity+":\n"+msg+extradata;}
+curvyObject.prototype.newError=function(msg){return new Error(this.errmsg(msg,'exception'));}
+curvyObject.IntToHex=function(strNum){var hexdig=['0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'];return hexdig[strNum>>>4]+''+hexdig[strNum&15];}
+curvyObject.BlendColour=function(Col1,Col2,Col1Fraction){if(Col1==='transparent'||Col2==='transparent')throw this.newError('Cannot blend with transparent');if(Col1.charAt(0)!=='#'){Col1=curvyObject.format_colour(Col1);}
+if(Col2.charAt(0)!=='#'){Col2=curvyObject.format_colour(Col2);}
+var red1=parseInt(Col1.substr(1,2),16);var green1=parseInt(Col1.substr(3,2),16);var blue1=parseInt(Col1.substr(5,2),16);var red2=parseInt(Col2.substr(1,2),16);var green2=parseInt(Col2.substr(3,2),16);var blue2=parseInt(Col2.substr(5,2),16);if(Col1Fraction>1||Col1Fraction<0)Col1Fraction=1;var endRed=Math.round((red1*Col1Fraction)+(red2*(1-Col1Fraction)));if(endRed>255)endRed=255;if(endRed<0)endRed=0;var endGreen=Math.round((green1*Col1Fraction)+(green2*(1-Col1Fraction)));if(endGreen>255)endGreen=255;if(endGreen<0)endGreen=0;var endBlue=Math.round((blue1*Col1Fraction)+(blue2*(1-Col1Fraction)));if(endBlue>255)endBlue=255;if(endBlue<0)endBlue=0;return"#"+curvyObject.IntToHex(endRed)+curvyObject.IntToHex(endGreen)+curvyObject.IntToHex(endBlue);}
+curvyObject.pixelFraction=function(x,y,r){var fraction;var rsquared=r*r;var xvalues=new Array(2);var yvalues=new Array(2);var point=0;var whatsides="";var intersect=Math.sqrt(rsquared-Math.pow(x,2));if(intersect>=y&&intersect<(y+1)){whatsides="Left";xvalues[point]=0;yvalues[point]=intersect-y;++point;}
+intersect=Math.sqrt(rsquared-Math.pow(y+1,2));if(intersect>=x&&intersect<(x+1)){whatsides+="Top";xvalues[point]=intersect-x;yvalues[point]=1;++point;}
+intersect=Math.sqrt(rsquared-Math.pow(x+1,2));if(intersect>=y&&intersect<(y+1)){whatsides+="Right";xvalues[point]=1;yvalues[point]=intersect-y;++point;}
+intersect=Math.sqrt(rsquared-Math.pow(y,2));if(intersect>=x&&intersect<(x+1)){whatsides+="Bottom";xvalues[point]=intersect-x;yvalues[point]=0;}
+switch(whatsides){case"LeftRight":fraction=Math.min(yvalues[0],yvalues[1])+((Math.max(yvalues[0],yvalues[1])-Math.min(yvalues[0],yvalues[1]))/2);break;case"TopRight":fraction=1-(((1-xvalues[0])*(1-yvalues[1]))/2);break;case"TopBottom":fraction=Math.min(xvalues[0],xvalues[1])+((Math.max(xvalues[0],xvalues[1])-Math.min(xvalues[0],xvalues[1]))/2);break;case"LeftBottom":fraction=yvalues[0]*xvalues[1]/2;break;default:fraction=1;}
+return fraction;}
+curvyObject.rgb2Array=function(rgbColour){var rgbValues=rgbColour.substring(4,rgbColour.indexOf(")"));return rgbValues.split(", ");}
+curvyObject.rgb2Hex=function(rgbColour){try{var rgbArray=curvyObject.rgb2Array(rgbColour);var red=parseInt(rgbArray[0]);var green=parseInt(rgbArray[1]);var blue=parseInt(rgbArray[2]);var hexColour="#"+curvyObject.IntToHex(red)+curvyObject.IntToHex(green)+curvyObject.IntToHex(blue);}
+catch(e){var msg='getMessage'in e?e.getMessage():e.message;throw new Error("Error ("+msg+") converting RGB value to Hex in rgb2Hex");}
+return hexColour;}
+curvyObject.setOpacity=function(obj,opacity){opacity=(opacity==100)?99.999:opacity;if(curvyBrowser.isSafari&&obj.tagName!="IFRAME"){var rgbArray=curvyObject.rgb2Array(obj.style.backgroundColor);var red=parseInt(rgbArray[0]);var green=parseInt(rgbArray[1]);var blue=parseInt(rgbArray[2]);obj.style.backgroundColor="rgba("+red+", "+green+", "+blue+", "+opacity/100+")";}
+else if(typeof obj.style.opacity!=="undefined"){obj.style.opacity=opacity/100;}
+else if(typeof obj.style.MozOpacity!=="undefined"){obj.style.MozOpacity=opacity/100;}
+else if(typeof obj.style.filter!=="undefined"){obj.style.filter="alpha(opacity="+opacity+")";}
+else if(typeof obj.style.KHTMLOpacity!=="undefined"){obj.style.KHTMLOpacity=opacity/100;}}
+curvyCorners.addEvent=function(elm,evType,fn,useCapture){if(elm.addEventListener){elm.addEventListener(evType,fn,useCapture);return true;}
+if(elm.attachEvent)return elm.attachEvent('on'+evType,fn);elm['on'+evType]=fn;return false;}
+if(typeof addEvent==='undefined')addEvent=curvyCorners.addEvent;curvyObject.getComputedColour=function(colour){var d=document.createElement('DIV');d.style.backgroundColor=colour;document.body.appendChild(d);if(window.getComputedStyle){var rtn=document.defaultView.getComputedStyle(d,null).getPropertyValue('background-color');d.parentNode.removeChild(d);if(rtn.substr(0,3)==="rgb")rtn=curvyObject.rgb2Hex(rtn);return rtn;}
+else{var rng=document.body.createTextRange();rng.moveToElementText(d);rng.execCommand('ForeColor',false,colour);var iClr=rng.queryCommandValue('ForeColor');var rgb="rgb("+(iClr&0xFF)+", "+((iClr&0xFF00)>>8)+", "+((iClr&0xFF0000)>>16)+")";d.parentNode.removeChild(d);rng=null;return curvyObject.rgb2Hex(rgb);}}
+curvyObject.format_colour=function(colour){if(colour!=""&&colour!="transparent"){if(colour.substr(0,3)==="rgb"){colour=curvyObject.rgb2Hex(colour);}
+else if(colour.charAt(0)!=='#'){colour=curvyObject.getComputedColour(colour);}
+else if(colour.length===4){colour="#"+colour.charAt(1)+colour.charAt(1)+colour.charAt(2)+colour.charAt(2)+colour.charAt(3)+colour.charAt(3);}}
+return colour;}
+curvyCorners.getElementsByClass=function(searchClass,node){var classElements=new Array;if(node===undefined)node=document;searchClass=searchClass.split('.');var tag='*';if(searchClass.length===1){tag=searchClass[0];searchClass=false;}
+else{if(searchClass[0])tag=searchClass[0];searchClass=searchClass[1];}
+var i,els,elsLen;if(tag.charAt(0)==='#'){els=document.getElementById(tag.substr(1));if(els)classElements.push(els);}
+else{els=node.getElementsByTagName(tag);elsLen=els.length;if(searchClass){var pattern=new RegExp("(^|\\s)"+searchClass+"(\\s|$)");for(i=0;i<elsLen;++i){if(pattern.test(els[i].className))classElements.push(els[i]);}}
+else for(i=0;i<elsLen;++i)classElements.push(els[i]);}
+return classElements;}
+if(curvyBrowser.isMoz||curvyBrowser.isWebKit){var curvyCornersNoAutoScan=true;curvyCorners.init=function(){};}
+else{curvyCorners.scanStyles=function(){function units(num){if(!parseInt(num))return'px';var matches=/^[\d.]+(\w+)$/.exec(num);return matches[1];}
+var t,i,j;if(curvyBrowser.isIE){function procIEStyles(rule){var style=rule.style;if(curvyBrowser.ieVer>6.0){var allR=style['-webkit-border-radius']||0;var tR=style['-webkit-border-top-right-radius']||0;var tL=style['-webkit-border-top-left-radius']||0;var bR=style['-webkit-border-bottom-right-radius']||0;var bL=style['-webkit-border-bottom-left-radius']||0;}
+else{var allR=style['webkit-border-radius']||0;var tR=style['webkit-border-top-right-radius']||0;var tL=style['webkit-border-top-left-radius']||0;var bR=style['webkit-border-bottom-right-radius']||0;var bL=style['webkit-border-bottom-left-radius']||0;}
+if(allR||tL||tR||bR||bL){var settings=new curvyCnrSpec(rule.selectorText);if(allR)
+settings.setcorner(null,null,parseInt(allR),units(allR));else{if(tR)settings.setcorner('t','r',parseInt(tR),units(tR));if(tL)settings.setcorner('t','l',parseInt(tL),units(tL));if(bL)settings.setcorner('b','l',parseInt(bL),units(bL));if(bR)settings.setcorner('b','r',parseInt(bR),units(bR));}
+curvyCorners(settings);}}
+for(t=0;t<document.styleSheets.length;++t){try{if(document.styleSheets[t].imports){for(i=0;i<document.styleSheets[t].imports.length;++i)
+for(j=0;j<document.styleSheets[t].imports[i].rules.length;++j)
+procIEStyles(document.styleSheets[t].imports[i].rules[j]);}
+for(i=0;i<document.styleSheets[t].rules.length;++i)
+procIEStyles(document.styleSheets[t].rules[i]);}
+catch(e){if(typeof curvyCornersVerbose!=='undefined'&&curvyCornersVerbose)
+alert(e.message+" - ignored");}}}
+else if(curvyBrowser.isOp){for(t=0;t<document.styleSheets.length;++t){if(operasheet.contains_border_radius(t)){j=new operasheet(t);for(i in j.rules)if(!isNaN(i))
+curvyCorners(j.rules[i]);}}}
+else curvyCorners.alert('Scanstyles does nothing in Webkit/Firefox');};curvyCorners.init=function(){if(arguments.callee.done)return;arguments.callee.done=true;if(curvyBrowser.isWebKit&&curvyCorners.init.timer){clearInterval(curvyCorners.init.timer);curvyCorners.init.timer=null;}
+curvyCorners.scanStyles();};}
+if(typeof curvyCornersNoAutoScan==='undefined'||curvyCornersNoAutoScan===false){if(curvyBrowser.isOp)
+document.addEventListener("DOMContentLoaded",curvyCorners.init,false);else curvyCorners.addEvent(window,'load',curvyCorners.init,false);}
Index: ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web-data/lib/prototype-1.6.1.js
===================================================================
--- ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web-data/lib/prototype-1.6.1.js	(revision 14969)
+++ ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web-data/lib/prototype-1.6.1.js	(revision 14969)
@@ -0,0 +1,4874 @@
+/*  Prototype JavaScript framework, version 1.6.1
+ *  (c) 2005-2009 Sam Stephenson
+ *
+ *  Prototype is freely distributable under the terms of an MIT-style license.
+ *  For details, see the Prototype web site: http://www.prototypejs.org/
+ *
+ *--------------------------------------------------------------------------*/
+
+var Prototype = {
+  Version: '1.6.1',
+
+  Browser: (function(){
+    var ua = navigator.userAgent;
+    var isOpera = Object.prototype.toString.call(window.opera) == '[object Opera]';
+    return {
+      IE:             !!window.attachEvent && !isOpera,
+      Opera:          isOpera,
+      WebKit:         ua.indexOf('AppleWebKit/') > -1,
+      Gecko:          ua.indexOf('Gecko') > -1 && ua.indexOf('KHTML') === -1,
+      MobileSafari:   /Apple.*Mobile.*Safari/.test(ua)
+    }
+  })(),
+
+  BrowserFeatures: {
+    XPath: !!document.evaluate,
+    SelectorsAPI: !!document.querySelector,
+    ElementExtensions: (function() {
+      var constructor = window.Element || window.HTMLElement;
+      return !!(constructor && constructor.prototype);
+    })(),
+    SpecificElementExtensions: (function() {
+      if (typeof window.HTMLDivElement !== 'undefined')
+        return true;
+
+      var div = document.createElement('div');
+      var form = document.createElement('form');
+      var isSupported = false;
+
+      if (div['__proto__'] && (div['__proto__'] !== form['__proto__'])) {
+        isSupported = true;
+      }
+
+      div = form = null;
+
+      return isSupported;
+    })()
+  },
+
+  ScriptFragment: '<script[^>]*>([\\S\\s]*?)<\/script>',
+  JSONFilter: /^\/\*-secure-([\s\S]*)\*\/\s*$/,
+
+  emptyFunction: function() { },
+  K: function(x) { return x }
+};
+
+if (Prototype.Browser.MobileSafari)
+  Prototype.BrowserFeatures.SpecificElementExtensions = false;
+
+
+var Abstract = { };
+
+
+var Try = {
+  these: function() {
+    var returnValue;
+
+    for (var i = 0, length = arguments.length; i < length; i++) {
+      var lambda = arguments[i];
+      try {
+        returnValue = lambda();
+        break;
+      } catch (e) { }
+    }
+
+    return returnValue;
+  }
+};
+
+/* Based on Alex Arnell's inheritance implementation. */
+
+var Class = (function() {
+  function subclass() {};
+  function create() {
+    var parent = null, properties = $A(arguments);
+    if (Object.isFunction(properties[0]))
+      parent = properties.shift();
+
+    function klass() {
+      this.initialize.apply(this, arguments);
+    }
+
+    Object.extend(klass, Class.Methods);
+    klass.superclass = parent;
+    klass.subclasses = [];
+
+    if (parent) {
+      subclass.prototype = parent.prototype;
+      klass.prototype = new subclass;
+      parent.subclasses.push(klass);
+    }
+
+    for (var i = 0; i < properties.length; i++)
+      klass.addMethods(properties[i]);
+
+    if (!klass.prototype.initialize)
+      klass.prototype.initialize = Prototype.emptyFunction;
+
+    klass.prototype.constructor = klass;
+    return klass;
+  }
+
+  function addMethods(source) {
+    var ancestor   = this.superclass && this.superclass.prototype;
+    var properties = Object.keys(source);
+
+    if (!Object.keys({ toString: true }).length) {
+      if (source.toString != Object.prototype.toString)
+        properties.push("toString");
+      if (source.valueOf != Object.prototype.valueOf)
+        properties.push("valueOf");
+    }
+
+    for (var i = 0, length = properties.length; i < length; i++) {
+      var property = properties[i], value = source[property];
+      if (ancestor && Object.isFunction(value) &&
+          value.argumentNames().first() == "$super") {
+        var method = value;
+        value = (function(m) {
+          return function() { return ancestor[m].apply(this, arguments); };
+        })(property).wrap(method);
+
+        value.valueOf = method.valueOf.bind(method);
+        value.toString = method.toString.bind(method);
+      }
+      this.prototype[property] = value;
+    }
+
+    return this;
+  }
+
+  return {
+    create: create,
+    Methods: {
+      addMethods: addMethods
+    }
+  };
+})();
+(function() {
+
+  var _toString = Object.prototype.toString;
+
+  function extend(destination, source) {
+    for (var property in source)
+      destination[property] = source[property];
+    return destination;
+  }
+
+  function inspect(object) {
+    try {
+      if (isUndefined(object)) return 'undefined';
+      if (object === null) return 'null';
+      return object.inspect ? object.inspect() : String(object);
+    } catch (e) {
+      if (e instanceof RangeError) return '...';
+      throw e;
+    }
+  }
+
+  function toJSON(object) {
+    var type = typeof object;
+    switch (type) {
+      case 'undefined':
+      case 'function':
+      case 'unknown': return;
+      case 'boolean': return object.toString();
+    }
+
+    if (object === null) return 'null';
+    if (object.toJSON) return object.toJSON();
+    if (isElement(object)) return;
+
+    var results = [];
+    for (var property in object) {
+      var value = toJSON(object[property]);
+      if (!isUndefined(value))
+        results.push(property.toJSON() + ': ' + value);
+    }
+
+    return '{' + results.join(', ') + '}';
+  }
+
+  function toQueryString(object) {
+    return $H(object).toQueryString();
+  }
+
+  function toHTML(object) {
+    return object && object.toHTML ? object.toHTML() : String.interpret(object);
+  }
+
+  function keys(object) {
+    var results = [];
+    for (var property in object)
+      results.push(property);
+    return results;
+  }
+
+  function values(object) {
+    var results = [];
+    for (var property in object)
+      results.push(object[property]);
+    return results;
+  }
+
+  function clone(object) {
+    return extend({ }, object);
+  }
+
+  function isElement(object) {
+    return !!(object && object.nodeType == 1);
+  }
+
+  function isArray(object) {
+    return _toString.call(object) == "[object Array]";
+  }
+
+
+  function isHash(object) {
+    return object instanceof Hash;
+  }
+
+  function isFunction(object) {
+    return typeof object === "function";
+  }
+
+  function isString(object) {
+    return _toString.call(object) == "[object String]";
+  }
+
+  function isNumber(object) {
+    return _toString.call(object) == "[object Number]";
+  }
+
+  function isUndefined(object) {
+    return typeof object === "undefined";
+  }
+
+  extend(Object, {
+    extend:        extend,
+    inspect:       inspect,
+    toJSON:        toJSON,
+    toQueryString: toQueryString,
+    toHTML:        toHTML,
+    keys:          keys,
+    values:        values,
+    clone:         clone,
+    isElement:     isElement,
+    isArray:       isArray,
+    isHash:        isHash,
+    isFunction:    isFunction,
+    isString:      isString,
+    isNumber:      isNumber,
+    isUndefined:   isUndefined
+  });
+})();
+Object.extend(Function.prototype, (function() {
+  var slice = Array.prototype.slice;
+
+  function update(array, args) {
+    var arrayLength = array.length, length = args.length;
+    while (length--) array[arrayLength + length] = args[length];
+    return array;
+  }
+
+  function merge(array, args) {
+    array = slice.call(array, 0);
+    return update(array, args);
+  }
+
+  function argumentNames() {
+    var names = this.toString().match(/^[\s\(]*function[^(]*\(([^)]*)\)/)[1]
+      .replace(/\/\/.*?[\r\n]|\/\*(?:.|[\r\n])*?\*\//g, '')
+      .replace(/\s+/g, '').split(',');
+    return names.length == 1 && !names[0] ? [] : names;
+  }
+
+  function bind(context) {
+    if (arguments.length < 2 && Object.isUndefined(arguments[0])) return this;
+    var __method = this, args = slice.call(arguments, 1);
+    return function() {
+      var a = merge(args, arguments);
+      return __method.apply(context, a);
+    }
+  }
+
+  function bindAsEventListener(context) {
+    var __method = this, args = slice.call(arguments, 1);
+    return function(event) {
+      var a = update([event || window.event], args);
+      return __method.apply(context, a);
+    }
+  }
+
+  function curry() {
+    if (!arguments.length) return this;
+    var __method = this, args = slice.call(arguments, 0);
+    return function() {
+      var a = merge(args, arguments);
+      return __method.apply(this, a);
+    }
+  }
+
+  function delay(timeout) {
+    var __method = this, args = slice.call(arguments, 1);
+    timeout = timeout * 1000
+    return window.setTimeout(function() {
+      return __method.apply(__method, args);
+    }, timeout);
+  }
+
+  function defer() {
+    var args = update([0.01], arguments);
+    return this.delay.apply(this, args);
+  }
+
+  function wrap(wrapper) {
+    var __method = this;
+    return function() {
+      var a = update([__method.bind(this)], arguments);
+      return wrapper.apply(this, a);
+    }
+  }
+
+  function methodize() {
+    if (this._methodized) return this._methodized;
+    var __method = this;
+    return this._methodized = function() {
+      var a = update([this], arguments);
+      return __method.apply(null, a);
+    };
+  }
+
+  return {
+    argumentNames:       argumentNames,
+    bind:                bind,
+    bindAsEventListener: bindAsEventListener,
+    curry:               curry,
+    delay:               delay,
+    defer:               defer,
+    wrap:                wrap,
+    methodize:           methodize
+  }
+})());
+
+
+Date.prototype.toJSON = function() {
+  return '"' + this.getUTCFullYear() + '-' +
+    (this.getUTCMonth() + 1).toPaddedString(2) + '-' +
+    this.getUTCDate().toPaddedString(2) + 'T' +
+    this.getUTCHours().toPaddedString(2) + ':' +
+    this.getUTCMinutes().toPaddedString(2) + ':' +
+    this.getUTCSeconds().toPaddedString(2) + 'Z"';
+};
+
+
+RegExp.prototype.match = RegExp.prototype.test;
+
+RegExp.escape = function(str) {
+  return String(str).replace(/([.*+?^=!:${}()|[\]\/\\])/g, '\\$1');
+};
+var PeriodicalExecuter = Class.create({
+  initialize: function(callback, frequency) {
+    this.callback = callback;
+    this.frequency = frequency;
+    this.currentlyExecuting = false;
+
+    this.registerCallback();
+  },
+
+  registerCallback: function() {
+    this.timer = setInterval(this.onTimerEvent.bind(this), this.frequency * 1000);
+  },
+
+  execute: function() {
+    this.callback(this);
+  },
+
+  stop: function() {
+    if (!this.timer) return;
+    clearInterval(this.timer);
+    this.timer = null;
+  },
+
+  onTimerEvent: function() {
+    if (!this.currentlyExecuting) {
+      try {
+        this.currentlyExecuting = true;
+        this.execute();
+        this.currentlyExecuting = false;
+      } catch(e) {
+        this.currentlyExecuting = false;
+        throw e;
+      }
+    }
+  }
+});
+Object.extend(String, {
+  interpret: function(value) {
+    return value == null ? '' : String(value);
+  },
+  specialChar: {
+    '\b': '\\b',
+    '\t': '\\t',
+    '\n': '\\n',
+    '\f': '\\f',
+    '\r': '\\r',
+    '\\': '\\\\'
+  }
+});
+
+Object.extend(String.prototype, (function() {
+
+  function prepareReplacement(replacement) {
+    if (Object.isFunction(replacement)) return replacement;
+    var template = new Template(replacement);
+    return function(match) { return template.evaluate(match) };
+  }
+
+  function gsub(pattern, replacement) {
+    var result = '', source = this, match;
+    replacement = prepareReplacement(replacement);
+
+    if (Object.isString(pattern))
+      pattern = RegExp.escape(pattern);
+
+    if (!(pattern.length || pattern.source)) {
+      replacement = replacement('');
+      return replacement + source.split('').join(replacement) + replacement;
+    }
+
+    while (source.length > 0) {
+      if (match = source.match(pattern)) {
+        result += source.slice(0, match.index);
+        result += String.interpret(replacement(match));
+        source  = source.slice(match.index + match[0].length);
+      } else {
+        result += source, source = '';
+      }
+    }
+    return result;
+  }
+
+  function sub(pattern, replacement, count) {
+    replacement = prepareReplacement(replacement);
+    count = Object.isUndefined(count) ? 1 : count;
+
+    return this.gsub(pattern, function(match) {
+      if (--count < 0) return match[0];
+      return replacement(match);
+    });
+  }
+
+  function scan(pattern, iterator) {
+    this.gsub(pattern, iterator);
+    return String(this);
+  }
+
+  function truncate(length, truncation) {
+    length = length || 30;
+    truncation = Object.isUndefined(truncation) ? '...' : truncation;
+    return this.length > length ?
+      this.slice(0, length - truncation.length) + truncation : String(this);
+  }
+
+  function strip() {
+    return this.replace(/^\s+/, '').replace(/\s+$/, '');
+  }
+
+  function stripTags() {
+    return this.replace(/<\w+(\s+("[^"]*"|'[^']*'|[^>])+)?>|<\/\w+>/gi, '');
+  }
+
+  function stripScripts() {
+    return this.replace(new RegExp(Prototype.ScriptFragment, 'img'), '');
+  }
+
+  function extractScripts() {
+    var matchAll = new RegExp(Prototype.ScriptFragment, 'img');
+    var matchOne = new RegExp(Prototype.ScriptFragment, 'im');
+    return (this.match(matchAll) || []).map(function(scriptTag) {
+      return (scriptTag.match(matchOne) || ['', ''])[1];
+    });
+  }
+
+  function evalScripts() {
+    return this.extractScripts().map(function(script) { return eval(script) });
+  }
+
+  function escapeHTML() {
+    return this.replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;');
+  }
+
+  function unescapeHTML() {
+    return this.stripTags().replace(/&lt;/g,'<').replace(/&gt;/g,'>').replace(/&amp;/g,'&');
+  }
+
+
+  function toQueryParams(separator) {
+    var match = this.strip().match(/([^?#]*)(#.*)?$/);
+    if (!match) return { };
+
+    return match[1].split(separator || '&').inject({ }, function(hash, pair) {
+      if ((pair = pair.split('='))[0]) {
+        var key = decodeURIComponent(pair.shift());
+        var value = pair.length > 1 ? pair.join('=') : pair[0];
+        if (value != undefined) value = decodeURIComponent(value);
+
+        if (key in hash) {
+          if (!Object.isArray(hash[key])) hash[key] = [hash[key]];
+          hash[key].push(value);
+        }
+        else hash[key] = value;
+      }
+      return hash;
+    });
+  }
+
+  function toArray() {
+    return this.split('');
+  }
+
+  function succ() {
+    return this.slice(0, this.length - 1) +
+      String.fromCharCode(this.charCodeAt(this.length - 1) + 1);
+  }
+
+  function times(count) {
+    return count < 1 ? '' : new Array(count + 1).join(this);
+  }
+
+  function camelize() {
+    var parts = this.split('-'), len = parts.length;
+    if (len == 1) return parts[0];
+
+    var camelized = this.charAt(0) == '-'
+      ? parts[0].charAt(0).toUpperCase() + parts[0].substring(1)
+      : parts[0];
+
+    for (var i = 1; i < len; i++)
+      camelized += parts[i].charAt(0).toUpperCase() + parts[i].substring(1);
+
+    return camelized;
+  }
+
+  function capitalize() {
+    return this.charAt(0).toUpperCase() + this.substring(1).toLowerCase();
+  }
+
+  function underscore() {
+    return this.replace(/::/g, '/')
+               .replace(/([A-Z]+)([A-Z][a-z])/g, '$1_$2')
+               .replace(/([a-z\d])([A-Z])/g, '$1_$2')
+               .replace(/-/g, '_')
+               .toLowerCase();
+  }
+
+  function dasherize() {
+    return this.replace(/_/g, '-');
+  }
+
+  function inspect(useDoubleQuotes) {
+    var escapedString = this.replace(/[\x00-\x1f\\]/g, function(character) {
+      if (character in String.specialChar) {
+        return String.specialChar[character];
+      }
+      return '\\u00' + character.charCodeAt().toPaddedString(2, 16);
+    });
+    if (useDoubleQuotes) return '"' + escapedString.replace(/"/g, '\\"') + '"';
+    return "'" + escapedString.replace(/'/g, '\\\'') + "'";
+  }
+
+  function toJSON() {
+    return this.inspect(true);
+  }
+
+  function unfilterJSON(filter) {
+    return this.replace(filter || Prototype.JSONFilter, '$1');
+  }
+
+  function isJSON() {
+    var str = this;
+    if (str.blank()) return false;
+    str = this.replace(/\\./g, '@').replace(/"[^"\\\n\r]*"/g, '');
+    return (/^[,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t]*$/).test(str);
+  }
+
+  function evalJSON(sanitize) {
+    var json = this.unfilterJSON();
+    try {
+      if (!sanitize || json.isJSON()) return eval('(' + json + ')');
+    } catch (e) { }
+    throw new SyntaxError('Badly formed JSON string: ' + this.inspect());
+  }
+
+  function include(pattern) {
+    return this.indexOf(pattern) > -1;
+  }
+
+  function startsWith(pattern) {
+    return this.indexOf(pattern) === 0;
+  }
+
+  function endsWith(pattern) {
+    var d = this.length - pattern.length;
+    return d >= 0 && this.lastIndexOf(pattern) === d;
+  }
+
+  function empty() {
+    return this == '';
+  }
+
+  function blank() {
+    return /^\s*$/.test(this);
+  }
+
+  function interpolate(object, pattern) {
+    return new Template(this, pattern).evaluate(object);
+  }
+
+  return {
+    gsub:           gsub,
+    sub:            sub,
+    scan:           scan,
+    truncate:       truncate,
+    strip:          String.prototype.trim ? String.prototype.trim : strip,
+    stripTags:      stripTags,
+    stripScripts:   stripScripts,
+    extractScripts: extractScripts,
+    evalScripts:    evalScripts,
+    escapeHTML:     escapeHTML,
+    unescapeHTML:   unescapeHTML,
+    toQueryParams:  toQueryParams,
+    parseQuery:     toQueryParams,
+    toArray:        toArray,
+    succ:           succ,
+    times:          times,
+    camelize:       camelize,
+    capitalize:     capitalize,
+    underscore:     underscore,
+    dasherize:      dasherize,
+    inspect:        inspect,
+    toJSON:         toJSON,
+    unfilterJSON:   unfilterJSON,
+    isJSON:         isJSON,
+    evalJSON:       evalJSON,
+    include:        include,
+    startsWith:     startsWith,
+    endsWith:       endsWith,
+    empty:          empty,
+    blank:          blank,
+    interpolate:    interpolate
+  };
+})());
+
+var Template = Class.create({
+  initialize: function(template, pattern) {
+    this.template = template.toString();
+    this.pattern = pattern || Template.Pattern;
+  },
+
+  evaluate: function(object) {
+    if (object && Object.isFunction(object.toTemplateReplacements))
+      object = object.toTemplateReplacements();
+
+    return this.template.gsub(this.pattern, function(match) {
+      if (object == null) return (match[1] + '');
+
+      var before = match[1] || '';
+      if (before == '\\') return match[2];
+
+      var ctx = object, expr = match[3];
+      var pattern = /^([^.[]+|\[((?:.*?[^\\])?)\])(\.|\[|$)/;
+      match = pattern.exec(expr);
+      if (match == null) return before;
+
+      while (match != null) {
+        var comp = match[1].startsWith('[') ? match[2].replace(/\\\\]/g, ']') : match[1];
+        ctx = ctx[comp];
+        if (null == ctx || '' == match[3]) break;
+        expr = expr.substring('[' == match[3] ? match[1].length : match[0].length);
+        match = pattern.exec(expr);
+      }
+
+      return before + String.interpret(ctx);
+    });
+  }
+});
+Template.Pattern = /(^|.|\r|\n)(#\{(.*?)\})/;
+
+var $break = { };
+
+var Enumerable = (function() {
+  function each(iterator, context) {
+    var index = 0;
+    try {
+      this._each(function(value) {
+        iterator.call(context, value, index++);
+      });
+    } catch (e) {
+      if (e != $break) throw e;
+    }
+    return this;
+  }
+
+  function eachSlice(number, iterator, context) {
+    var index = -number, slices = [], array = this.toArray();
+    if (number < 1) return array;
+    while ((index += number) < array.length)
+      slices.push(array.slice(index, index+number));
+    return slices.collect(iterator, context);
+  }
+
+  function all(iterator, context) {
+    iterator = iterator || Prototype.K;
+    var result = true;
+    this.each(function(value, index) {
+      result = result && !!iterator.call(context, value, index);
+      if (!result) throw $break;
+    });
+    return result;
+  }
+
+  function any(iterator, context) {
+    iterator = iterator || Prototype.K;
+    var result = false;
+    this.each(function(value, index) {
+      if (result = !!iterator.call(context, value, index))
+        throw $break;
+    });
+    return result;
+  }
+
+  function collect(iterator, context) {
+    iterator = iterator || Prototype.K;
+    var results = [];
+    this.each(function(value, index) {
+      results.push(iterator.call(context, value, index));
+    });
+    return results;
+  }
+
+  function detect(iterator, context) {
+    var result;
+    this.each(function(value, index) {
+      if (iterator.call(context, value, index)) {
+        result = value;
+        throw $break;
+      }
+    });
+    return result;
+  }
+
+  function findAll(iterator, context) {
+    var results = [];
+    this.each(function(value, index) {
+      if (iterator.call(context, value, index))
+        results.push(value);
+    });
+    return results;
+  }
+
+  function grep(filter, iterator, context) {
+    iterator = iterator || Prototype.K;
+    var results = [];
+
+    if (Object.isString(filter))
+      filter = new RegExp(RegExp.escape(filter));
+
+    this.each(function(value, index) {
+      if (filter.match(value))
+        results.push(iterator.call(context, value, index));
+    });
+    return results;
+  }
+
+  function include(object) {
+    if (Object.isFunction(this.indexOf))
+      if (this.indexOf(object) != -1) return true;
+
+    var found = false;
+    this.each(function(value) {
+      if (value == object) {
+        found = true;
+        throw $break;
+      }
+    });
+    return found;
+  }
+
+  function inGroupsOf(number, fillWith) {
+    fillWith = Object.isUndefined(fillWith) ? null : fillWith;
+    return this.eachSlice(number, function(slice) {
+      while(slice.length < number) slice.push(fillWith);
+      return slice;
+    });
+  }
+
+  function inject(memo, iterator, context) {
+    this.each(function(value, index) {
+      memo = iterator.call(context, memo, value, index);
+    });
+    return memo;
+  }
+
+  function invoke(method) {
+    var args = $A(arguments).slice(1);
+    return this.map(function(value) {
+      return value[method].apply(value, args);
+    });
+  }
+
+  function max(iterator, context) {
+    iterator = iterator || Prototype.K;
+    var result;
+    this.each(function(value, index) {
+      value = iterator.call(context, value, index);
+      if (result == null || value >= result)
+        result = value;
+    });
+    return result;
+  }
+
+  function min(iterator, context) {
+    iterator = iterator || Prototype.K;
+    var result;
+    this.each(function(value, index) {
+      value = iterator.call(context, value, index);
+      if (result == null || value < result)
+        result = value;
+    });
+    return result;
+  }
+
+  function partition(iterator, context) {
+    iterator = iterator || Prototype.K;
+    var trues = [], falses = [];
+    this.each(function(value, index) {
+      (iterator.call(context, value, index) ?
+        trues : falses).push(value);
+    });
+    return [trues, falses];
+  }
+
+  function pluck(property) {
+    var results = [];
+    this.each(function(value) {
+      results.push(value[property]);
+    });
+    return results;
+  }
+
+  function reject(iterator, context) {
+    var results = [];
+    this.each(function(value, index) {
+      if (!iterator.call(context, value, index))
+        results.push(value);
+    });
+    return results;
+  }
+
+  function sortBy(iterator, context) {
+    return this.map(function(value, index) {
+      return {
+        value: value,
+        criteria: iterator.call(context, value, index)
+      };
+    }).sort(function(left, right) {
+      var a = left.criteria, b = right.criteria;
+      return a < b ? -1 : a > b ? 1 : 0;
+    }).pluck('value');
+  }
+
+  function toArray() {
+    return this.map();
+  }
+
+  function zip() {
+    var iterator = Prototype.K, args = $A(arguments);
+    if (Object.isFunction(args.last()))
+      iterator = args.pop();
+
+    var collections = [this].concat(args).map($A);
+    return this.map(function(value, index) {
+      return iterator(collections.pluck(index));
+    });
+  }
+
+  function size() {
+    return this.toArray().length;
+  }
+
+  function inspect() {
+    return '#<Enumerable:' + this.toArray().inspect() + '>';
+  }
+
+
+
+
+
+
+
+
+
+  return {
+    each:       each,
+    eachSlice:  eachSlice,
+    all:        all,
+    every:      all,
+    any:        any,
+    some:       any,
+    collect:    collect,
+    map:        collect,
+    detect:     detect,
+    findAll:    findAll,
+    select:     findAll,
+    filter:     findAll,
+    grep:       grep,
+    include:    include,
+    member:     include,
+    inGroupsOf: inGroupsOf,
+    inject:     inject,
+    invoke:     invoke,
+    max:        max,
+    min:        min,
+    partition:  partition,
+    pluck:      pluck,
+    reject:     reject,
+    sortBy:     sortBy,
+    toArray:    toArray,
+    entries:    toArray,
+    zip:        zip,
+    size:       size,
+    inspect:    inspect,
+    find:       detect
+  };
+})();
+function $A(iterable) {
+  if (!iterable) return [];
+  if ('toArray' in Object(iterable)) return iterable.toArray();
+  var length = iterable.length || 0, results = new Array(length);
+  while (length--) results[length] = iterable[length];
+  return results;
+}
+
+function $w(string) {
+  if (!Object.isString(string)) return [];
+  string = string.strip();
+  return string ? string.split(/\s+/) : [];
+}
+
+Array.from = $A;
+
+
+(function() {
+  var arrayProto = Array.prototype,
+      slice = arrayProto.slice,
+      _each = arrayProto.forEach; // use native browser JS 1.6 implementation if available
+
+  function each(iterator) {
+    for (var i = 0, length = this.length; i < length; i++)
+      iterator(this[i]);
+  }
+  if (!_each) _each = each;
+
+  function clear() {
+    this.length = 0;
+    return this;
+  }
+
+  function first() {
+    return this[0];
+  }
+
+  function last() {
+    return this[this.length - 1];
+  }
+
+  function compact() {
+    return this.select(function(value) {
+      return value != null;
+    });
+  }
+
+  function flatten() {
+    return this.inject([], function(array, value) {
+      if (Object.isArray(value))
+        return array.concat(value.flatten());
+      array.push(value);
+      return array;
+    });
+  }
+
+  function without() {
+    var values = slice.call(arguments, 0);
+    return this.select(function(value) {
+      return !values.include(value);
+    });
+  }
+
+  function reverse(inline) {
+    return (inline !== false ? this : this.toArray())._reverse();
+  }
+
+  function uniq(sorted) {
+    return this.inject([], function(array, value, index) {
+      if (0 == index || (sorted ? array.last() != value : !array.include(value)))
+        array.push(value);
+      return array;
+    });
+  }
+
+  function intersect(array) {
+    return this.uniq().findAll(function(item) {
+      return array.detect(function(value) { return item === value });
+    });
+  }
+
+
+  function clone() {
+    return slice.call(this, 0);
+  }
+
+  function size() {
+    return this.length;
+  }
+
+  function inspect() {
+    return '[' + this.map(Object.inspect).join(', ') + ']';
+  }
+
+  function toJSON() {
+    var results = [];
+    this.each(function(object) {
+      var value = Object.toJSON(object);
+      if (!Object.isUndefined(value)) results.push(value);
+    });
+    return '[' + results.join(', ') + ']';
+  }
+
+  function indexOf(item, i) {
+    i || (i = 0);
+    var length = this.length;
+    if (i < 0) i = length + i;
+    for (; i < length; i++)
+      if (this[i] === item) return i;
+    return -1;
+  }
+
+  function lastIndexOf(item, i) {
+    i = isNaN(i) ? this.length : (i < 0 ? this.length + i : i) + 1;
+    var n = this.slice(0, i).reverse().indexOf(item);
+    return (n < 0) ? n : i - n - 1;
+  }
+
+  function concat() {
+    var array = slice.call(this, 0), item;
+    for (var i = 0, length = arguments.length; i < length; i++) {
+      item = arguments[i];
+      if (Object.isArray(item) && !('callee' in item)) {
+        for (var j = 0, arrayLength = item.length; j < arrayLength; j++)
+          array.push(item[j]);
+      } else {
+        array.push(item);
+      }
+    }
+    return array;
+  }
+
+  Object.extend(arrayProto, Enumerable);
+
+  if (!arrayProto._reverse)
+    arrayProto._reverse = arrayProto.reverse;
+
+  Object.extend(arrayProto, {
+    _each:     _each,
+    clear:     clear,
+    first:     first,
+    last:      last,
+    compact:   compact,
+    flatten:   flatten,
+    without:   without,
+    reverse:   reverse,
+    uniq:      uniq,
+    intersect: intersect,
+    clone:     clone,
+    toArray:   clone,
+    size:      size,
+    inspect:   inspect,
+    toJSON:    toJSON
+  });
+
+  var CONCAT_ARGUMENTS_BUGGY = (function() {
+    return [].concat(arguments)[0][0] !== 1;
+  })(1,2)
+
+  if (CONCAT_ARGUMENTS_BUGGY) arrayProto.concat = concat;
+
+  if (!arrayProto.indexOf) arrayProto.indexOf = indexOf;
+  if (!arrayProto.lastIndexOf) arrayProto.lastIndexOf = lastIndexOf;
+})();
+function $H(object) {
+  return new Hash(object);
+};
+
+var Hash = Class.create(Enumerable, (function() {
+  function initialize(object) {
+    this._object = Object.isHash(object) ? object.toObject() : Object.clone(object);
+  }
+
+  function _each(iterator) {
+    for (var key in this._object) {
+      var value = this._object[key], pair = [key, value];
+      pair.key = key;
+      pair.value = value;
+      iterator(pair);
+    }
+  }
+
+  function set(key, value) {
+    return this._object[key] = value;
+  }
+
+  function get(key) {
+    if (this._object[key] !== Object.prototype[key])
+      return this._object[key];
+  }
+
+  function unset(key) {
+    var value = this._object[key];
+    delete this._object[key];
+    return value;
+  }
+
+  function toObject() {
+    return Object.clone(this._object);
+  }
+
+  function keys() {
+    return this.pluck('key');
+  }
+
+  function values() {
+    return this.pluck('value');
+  }
+
+  function index(value) {
+    var match = this.detect(function(pair) {
+      return pair.value === value;
+    });
+    return match && match.key;
+  }
+
+  function merge(object) {
+    return this.clone().update(object);
+  }
+
+  function update(object) {
+    return new Hash(object).inject(this, function(result, pair) {
+      result.set(pair.key, pair.value);
+      return result;
+    });
+  }
+
+  function toQueryPair(key, value) {
+    if (Object.isUndefined(value)) return key;
+    return key + '=' + encodeURIComponent(String.interpret(value));
+  }
+
+  function toQueryString() {
+    return this.inject([], function(results, pair) {
+      var key = encodeURIComponent(pair.key), values = pair.value;
+
+      if (values && typeof values == 'object') {
+        if (Object.isArray(values))
+          return results.concat(values.map(toQueryPair.curry(key)));
+      } else results.push(toQueryPair(key, values));
+      return results;
+    }).join('&');
+  }
+
+  function inspect() {
+    return '#<Hash:{' + this.map(function(pair) {
+      return pair.map(Object.inspect).join(': ');
+    }).join(', ') + '}>';
+  }
+
+  function toJSON() {
+    return Object.toJSON(this.toObject());
+  }
+
+  function clone() {
+    return new Hash(this);
+  }
+
+  return {
+    initialize:             initialize,
+    _each:                  _each,
+    set:                    set,
+    get:                    get,
+    unset:                  unset,
+    toObject:               toObject,
+    toTemplateReplacements: toObject,
+    keys:                   keys,
+    values:                 values,
+    index:                  index,
+    merge:                  merge,
+    update:                 update,
+    toQueryString:          toQueryString,
+    inspect:                inspect,
+    toJSON:                 toJSON,
+    clone:                  clone
+  };
+})());
+
+Hash.from = $H;
+Object.extend(Number.prototype, (function() {
+  function toColorPart() {
+    return this.toPaddedString(2, 16);
+  }
+
+  function succ() {
+    return this + 1;
+  }
+
+  function times(iterator, context) {
+    $R(0, this, true).each(iterator, context);
+    return this;
+  }
+
+  function toPaddedString(length, radix) {
+    var string = this.toString(radix || 10);
+    return '0'.times(length - string.length) + string;
+  }
+
+  function toJSON() {
+    return isFinite(this) ? this.toString() : 'null';
+  }
+
+  function abs() {
+    return Math.abs(this);
+  }
+
+  function round() {
+    return Math.round(this);
+  }
+
+  function ceil() {
+    return Math.ceil(this);
+  }
+
+  function floor() {
+    return Math.floor(this);
+  }
+
+  return {
+    toColorPart:    toColorPart,
+    succ:           succ,
+    times:          times,
+    toPaddedString: toPaddedString,
+    toJSON:         toJSON,
+    abs:            abs,
+    round:          round,
+    ceil:           ceil,
+    floor:          floor
+  };
+})());
+
+function $R(start, end, exclusive) {
+  return new ObjectRange(start, end, exclusive);
+}
+
+var ObjectRange = Class.create(Enumerable, (function() {
+  function initialize(start, end, exclusive) {
+    this.start = start;
+    this.end = end;
+    this.exclusive = exclusive;
+  }
+
+  function _each(iterator) {
+    var value = this.start;
+    while (this.include(value)) {
+      iterator(value);
+      value = value.succ();
+    }
+  }
+
+  function include(value) {
+    if (value < this.start)
+      return false;
+    if (this.exclusive)
+      return value < this.end;
+    return value <= this.end;
+  }
+
+  return {
+    initialize: initialize,
+    _each:      _each,
+    include:    include
+  };
+})());
+
+
+
+var Ajax = {
+  getTransport: function() {
+    return Try.these(
+      function() {return new XMLHttpRequest()},
+      function() {return new ActiveXObject('Msxml2.XMLHTTP')},
+      function() {return new ActiveXObject('Microsoft.XMLHTTP')}
+    ) || false;
+  },
+
+  activeRequestCount: 0
+};
+
+Ajax.Responders = {
+  responders: [],
+
+  _each: function(iterator) {
+    this.responders._each(iterator);
+  },
+
+  register: function(responder) {
+    if (!this.include(responder))
+      this.responders.push(responder);
+  },
+
+  unregister: function(responder) {
+    this.responders = this.responders.without(responder);
+  },
+
+  dispatch: function(callback, request, transport, json) {
+    this.each(function(responder) {
+      if (Object.isFunction(responder[callback])) {
+        try {
+          responder[callback].apply(responder, [request, transport, json]);
+        } catch (e) { }
+      }
+    });
+  }
+};
+
+Object.extend(Ajax.Responders, Enumerable);
+
+Ajax.Responders.register({
+  onCreate:   function() { Ajax.activeRequestCount++ },
+  onComplete: function() { Ajax.activeRequestCount-- }
+});
+Ajax.Base = Class.create({
+  initialize: function(options) {
+    this.options = {
+      method:       'post',
+      asynchronous: true,
+      contentType:  'application/x-www-form-urlencoded',
+      encoding:     'UTF-8',
+      parameters:   '',
+      evalJSON:     true,
+      evalJS:       true
+    };
+    Object.extend(this.options, options || { });
+
+    this.options.method = this.options.method.toLowerCase();
+
+    if (Object.isString(this.options.parameters))
+      this.options.parameters = this.options.parameters.toQueryParams();
+    else if (Object.isHash(this.options.parameters))
+      this.options.parameters = this.options.parameters.toObject();
+  }
+});
+Ajax.Request = Class.create(Ajax.Base, {
+  _complete: false,
+
+  initialize: function($super, url, options) {
+    $super(options);
+    this.transport = Ajax.getTransport();
+    this.request(url);
+  },
+
+  request: function(url) {
+    this.url = url;
+    this.method = this.options.method;
+    var params = Object.clone(this.options.parameters);
+
+    if (!['get', 'post'].include(this.method)) {
+      params['_method'] = this.method;
+      this.method = 'post';
+    }
+
+    this.parameters = params;
+
+    if (params = Object.toQueryString(params)) {
+      if (this.method == 'get')
+        this.url += (this.url.include('?') ? '&' : '?') + params;
+      else if (/Konqueror|Safari|KHTML/.test(navigator.userAgent))
+        params += '&_=';
+    }
+
+    try {
+      var response = new Ajax.Response(this);
+      if (this.options.onCreate) this.options.onCreate(response);
+      Ajax.Responders.dispatch('onCreate', this, response);
+
+      this.transport.open(this.method.toUpperCase(), this.url,
+        this.options.asynchronous);
+
+      if (this.options.asynchronous) this.respondToReadyState.bind(this).defer(1);
+
+      this.transport.onreadystatechange = this.onStateChange.bind(this);
+      this.setRequestHeaders();
+
+      this.body = this.method == 'post' ? (this.options.postBody || params) : null;
+      this.transport.send(this.body);
+
+      /* Force Firefox to handle ready state 4 for synchronous requests */
+      if (!this.options.asynchronous && this.transport.overrideMimeType)
+        this.onStateChange();
+
+    }
+    catch (e) {
+      this.dispatchException(e);
+    }
+  },
+
+  onStateChange: function() {
+    var readyState = this.transport.readyState;
+    if (readyState > 1 && !((readyState == 4) && this._complete))
+      this.respondToReadyState(this.transport.readyState);
+  },
+
+  setRequestHeaders: function() {
+    var headers = {
+      'X-Requested-With': 'XMLHttpRequest',
+      'X-Prototype-Version': Prototype.Version,
+      'Accept': 'text/javascript, text/html, application/xml, text/xml, */*'
+    };
+
+    if (this.method == 'post') {
+      headers['Content-type'] = this.options.contentType +
+        (this.options.encoding ? '; charset=' + this.options.encoding : '');
+
+      /* Force "Connection: close" for older Mozilla browsers to work
+       * around a bug where XMLHttpRequest sends an incorrect
+       * Content-length header. See Mozilla Bugzilla #246651.
+       */
+      if (this.transport.overrideMimeType &&
+          (navigator.userAgent.match(/Gecko\/(\d{4})/) || [0,2005])[1] < 2005)
+            headers['Connection'] = 'close';
+    }
+
+    if (typeof this.options.requestHeaders == 'object') {
+      var extras = this.options.requestHeaders;
+
+      if (Object.isFunction(extras.push))
+        for (var i = 0, length = extras.length; i < length; i += 2)
+          headers[extras[i]] = extras[i+1];
+      else
+        $H(extras).each(function(pair) { headers[pair.key] = pair.value });
+    }
+
+    for (var name in headers)
+      this.transport.setRequestHeader(name, headers[name]);
+  },
+
+  success: function() {
+    var status = this.getStatus();
+    return !status || (status >= 200 && status < 300);
+  },
+
+  getStatus: function() {
+    try {
+      return this.transport.status || 0;
+    } catch (e) { return 0 }
+  },
+
+  respondToReadyState: function(readyState) {
+    var state = Ajax.Request.Events[readyState], response = new Ajax.Response(this);
+
+    if (state == 'Complete') {
+      try {
+        this._complete = true;
+        (this.options['on' + response.status]
+         || this.options['on' + (this.success() ? 'Success' : 'Failure')]
+         || Prototype.emptyFunction)(response, response.headerJSON);
+      } catch (e) {
+        this.dispatchException(e);
+      }
+
+      var contentType = response.getHeader('Content-type');
+      if (this.options.evalJS == 'force'
+          || (this.options.evalJS && this.isSameOrigin() && contentType
+          && contentType.match(/^\s*(text|application)\/(x-)?(java|ecma)script(;.*)?\s*$/i)))
+        this.evalResponse();
+    }
+
+    try {
+      (this.options['on' + state] || Prototype.emptyFunction)(response, response.headerJSON);
+      Ajax.Responders.dispatch('on' + state, this, response, response.headerJSON);
+    } catch (e) {
+      this.dispatchException(e);
+    }
+
+    if (state == 'Complete') {
+      this.transport.onreadystatechange = Prototype.emptyFunction;
+    }
+  },
+
+  isSameOrigin: function() {
+    var m = this.url.match(/^\s*https?:\/\/[^\/]*/);
+    return !m || (m[0] == '#{protocol}//#{domain}#{port}'.interpolate({
+      protocol: location.protocol,
+      domain: document.domain,
+      port: location.port ? ':' + location.port : ''
+    }));
+  },
+
+  getHeader: function(name) {
+    try {
+      return this.transport.getResponseHeader(name) || null;
+    } catch (e) { return null; }
+  },
+
+  evalResponse: function() {
+    try {
+      return eval((this.transport.responseText || '').unfilterJSON());
+    } catch (e) {
+      this.dispatchException(e);
+    }
+  },
+
+  dispatchException: function(exception) {
+    (this.options.onException || Prototype.emptyFunction)(this, exception);
+    Ajax.Responders.dispatch('onException', this, exception);
+  }
+});
+
+Ajax.Request.Events =
+  ['Uninitialized', 'Loading', 'Loaded', 'Interactive', 'Complete'];
+
+
+
+
+
+
+
+
+Ajax.Response = Class.create({
+  initialize: function(request){
+    this.request = request;
+    var transport  = this.transport  = request.transport,
+        readyState = this.readyState = transport.readyState;
+
+    if((readyState > 2 && !Prototype.Browser.IE) || readyState == 4) {
+      this.status       = this.getStatus();
+      this.statusText   = this.getStatusText();
+      this.responseText = String.interpret(transport.responseText);
+      this.headerJSON   = this._getHeaderJSON();
+    }
+
+    if(readyState == 4) {
+      var xml = transport.responseXML;
+      this.responseXML  = Object.isUndefined(xml) ? null : xml;
+      this.responseJSON = this._getResponseJSON();
+    }
+  },
+
+  status:      0,
+
+  statusText: '',
+
+  getStatus: Ajax.Request.prototype.getStatus,
+
+  getStatusText: function() {
+    try {
+      return this.transport.statusText || '';
+    } catch (e) { return '' }
+  },
+
+  getHeader: Ajax.Request.prototype.getHeader,
+
+  getAllHeaders: function() {
+    try {
+      return this.getAllResponseHeaders();
+    } catch (e) { return null }
+  },
+
+  getResponseHeader: function(name) {
+    return this.transport.getResponseHeader(name);
+  },
+
+  getAllResponseHeaders: function() {
+    return this.transport.getAllResponseHeaders();
+  },
+
+  _getHeaderJSON: function() {
+    var json = this.getHeader('X-JSON');
+    if (!json) return null;
+    json = decodeURIComponent(escape(json));
+    try {
+      return json.evalJSON(this.request.options.sanitizeJSON ||
+        !this.request.isSameOrigin());
+    } catch (e) {
+      this.request.dispatchException(e);
+    }
+  },
+
+  _getResponseJSON: function() {
+    var options = this.request.options;
+    if (!options.evalJSON || (options.evalJSON != 'force' &&
+      !(this.getHeader('Content-type') || '').include('application/json')) ||
+        this.responseText.blank())
+          return null;
+    try {
+      return this.responseText.evalJSON(options.sanitizeJSON ||
+        !this.request.isSameOrigin());
+    } catch (e) {
+      this.request.dispatchException(e);
+    }
+  }
+});
+
+Ajax.Updater = Class.create(Ajax.Request, {
+  initialize: function($super, container, url, options) {
+    this.container = {
+      success: (container.success || container),
+      failure: (container.failure || (container.success ? null : container))
+    };
+
+    options = Object.clone(options);
+    var onComplete = options.onComplete;
+    options.onComplete = (function(response, json) {
+      this.updateContent(response.responseText);
+      if (Object.isFunction(onComplete)) onComplete(response, json);
+    }).bind(this);
+
+    $super(url, options);
+  },
+
+  updateContent: function(responseText) {
+    var receiver = this.container[this.success() ? 'success' : 'failure'],
+        options = this.options;
+
+    if (!options.evalScripts) responseText = responseText.stripScripts();
+
+    if (receiver = $(receiver)) {
+      if (options.insertion) {
+        if (Object.isString(options.insertion)) {
+          var insertion = { }; insertion[options.insertion] = responseText;
+          receiver.insert(insertion);
+        }
+        else options.insertion(receiver, responseText);
+      }
+      else receiver.update(responseText);
+    }
+  }
+});
+
+Ajax.PeriodicalUpdater = Class.create(Ajax.Base, {
+  initialize: function($super, container, url, options) {
+    $super(options);
+    this.onComplete = this.options.onComplete;
+
+    this.frequency = (this.options.frequency || 2);
+    this.decay = (this.options.decay || 1);
+
+    this.updater = { };
+    this.container = container;
+    this.url = url;
+
+    this.start();
+  },
+
+  start: function() {
+    this.options.onComplete = this.updateComplete.bind(this);
+    this.onTimerEvent();
+  },
+
+  stop: function() {
+    this.updater.options.onComplete = undefined;
+    clearTimeout(this.timer);
+    (this.onComplete || Prototype.emptyFunction).apply(this, arguments);
+  },
+
+  updateComplete: function(response) {
+    if (this.options.decay) {
+      this.decay = (response.responseText == this.lastText ?
+        this.decay * this.options.decay : 1);
+
+      this.lastText = response.responseText;
+    }
+    this.timer = this.onTimerEvent.bind(this).delay(this.decay * this.frequency);
+  },
+
+  onTimerEvent: function() {
+    this.updater = new Ajax.Updater(this.container, this.url, this.options);
+  }
+});
+
+
+
+function $(element) {
+  if (arguments.length > 1) {
+    for (var i = 0, elements = [], length = arguments.length; i < length; i++)
+      elements.push($(arguments[i]));
+    return elements;
+  }
+  if (Object.isString(element))
+    element = document.getElementById(element);
+  return Element.extend(element);
+}
+
+if (Prototype.BrowserFeatures.XPath) {
+  document._getElementsByXPath = function(expression, parentElement) {
+    var results = [];
+    var query = document.evaluate(expression, $(parentElement) || document,
+      null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
+    for (var i = 0, length = query.snapshotLength; i < length; i++)
+      results.push(Element.extend(query.snapshotItem(i)));
+    return results;
+  };
+}
+
+/*--------------------------------------------------------------------------*/
+
+if (!window.Node) var Node = { };
+
+if (!Node.ELEMENT_NODE) {
+  Object.extend(Node, {
+    ELEMENT_NODE: 1,
+    ATTRIBUTE_NODE: 2,
+    TEXT_NODE: 3,
+    CDATA_SECTION_NODE: 4,
+    ENTITY_REFERENCE_NODE: 5,
+    ENTITY_NODE: 6,
+    PROCESSING_INSTRUCTION_NODE: 7,
+    COMMENT_NODE: 8,
+    DOCUMENT_NODE: 9,
+    DOCUMENT_TYPE_NODE: 10,
+    DOCUMENT_FRAGMENT_NODE: 11,
+    NOTATION_NODE: 12
+  });
+}
+
+
+(function(global) {
+
+  var SETATTRIBUTE_IGNORES_NAME = (function(){
+    var elForm = document.createElement("form");
+    var elInput = document.createElement("input");
+    var root = document.documentElement;
+    elInput.setAttribute("name", "test");
+    elForm.appendChild(elInput);
+    root.appendChild(elForm);
+    var isBuggy = elForm.elements
+      ? (typeof elForm.elements.test == "undefined")
+      : null;
+    root.removeChild(elForm);
+    elForm = elInput = null;
+    return isBuggy;
+  })();
+
+  var element = global.Element;
+  global.Element = function(tagName, attributes) {
+    attributes = attributes || { };
+    tagName = tagName.toLowerCase();
+    var cache = Element.cache;
+    if (SETATTRIBUTE_IGNORES_NAME && attributes.name) {
+      tagName = '<' + tagName + ' name="' + attributes.name + '">';
+      delete attributes.name;
+      return Element.writeAttribute(document.createElement(tagName), attributes);
+    }
+    if (!cache[tagName]) cache[tagName] = Element.extend(document.createElement(tagName));
+    return Element.writeAttribute(cache[tagName].cloneNode(false), attributes);
+  };
+  Object.extend(global.Element, element || { });
+  if (element) global.Element.prototype = element.prototype;
+})(this);
+
+Element.cache = { };
+Element.idCounter = 1;
+
+Element.Methods = {
+  visible: function(element) {
+    return $(element).style.display != 'none';
+  },
+
+  toggle: function(element) {
+    element = $(element);
+    Element[Element.visible(element) ? 'hide' : 'show'](element);
+    return element;
+  },
+
+
+  hide: function(element) {
+    element = $(element);
+    element.style.display = 'none';
+    return element;
+  },
+
+  show: function(element) {
+    element = $(element);
+    element.style.display = '';
+    return element;
+  },
+
+  remove: function(element) {
+    element = $(element);
+    element.parentNode.removeChild(element);
+    return element;
+  },
+
+  update: (function(){
+
+    var SELECT_ELEMENT_INNERHTML_BUGGY = (function(){
+      var el = document.createElement("select"),
+          isBuggy = true;
+      el.innerHTML = "<option value=\"test\">test</option>";
+      if (el.options && el.options[0]) {
+        isBuggy = el.options[0].nodeName.toUpperCase() !== "OPTION";
+      }
+      el = null;
+      return isBuggy;
+    })();
+
+    var TABLE_ELEMENT_INNERHTML_BUGGY = (function(){
+      try {
+        var el = document.createElement("table");
+        if (el && el.tBodies) {
+          el.innerHTML = "<tbody><tr><td>test</td></tr></tbody>";
+          var isBuggy = typeof el.tBodies[0] == "undefined";
+          el = null;
+          return isBuggy;
+        }
+      } catch (e) {
+        return true;
+      }
+    })();
+
+    var SCRIPT_ELEMENT_REJECTS_TEXTNODE_APPENDING = (function () {
+      var s = document.createElement("script"),
+          isBuggy = false;
+      try {
+        s.appendChild(document.createTextNode(""));
+        isBuggy = !s.firstChild ||
+          s.firstChild && s.firstChild.nodeType !== 3;
+      } catch (e) {
+        isBuggy = true;
+      }
+      s = null;
+      return isBuggy;
+    })();
+
+    function update(element, content) {
+      element = $(element);
+
+      if (content && content.toElement)
+        content = content.toElement();
+
+      if (Object.isElement(content))
+        return element.update().insert(content);
+
+      content = Object.toHTML(content);
+
+      var tagName = element.tagName.toUpperCase();
+
+      if (tagName === 'SCRIPT' && SCRIPT_ELEMENT_REJECTS_TEXTNODE_APPENDING) {
+        element.text = content;
+        return element;
+      }
+
+      if (SELECT_ELEMENT_INNERHTML_BUGGY || TABLE_ELEMENT_INNERHTML_BUGGY) {
+        if (tagName in Element._insertionTranslations.tags) {
+          while (element.firstChild) {
+            element.removeChild(element.firstChild);
+          }
+          Element._getContentFromAnonymousElement(tagName, content.stripScripts())
+            .each(function(node) {
+              element.appendChild(node)
+            });
+        }
+        else {
+          element.innerHTML = content.stripScripts();
+        }
+      }
+      else {
+        element.innerHTML = content.stripScripts();
+      }
+
+      content.evalScripts.bind(content).defer();
+      return element;
+    }
+
+    return update;
+  })(),
+
+  replace: function(element, content) {
+    element = $(element);
+    if (content && content.toElement) content = content.toElement();
+    else if (!Object.isElement(content)) {
+      content = Object.toHTML(content);
+      var range = element.ownerDocument.createRange();
+      range.selectNode(element);
+      content.evalScripts.bind(content).defer();
+      content = range.createContextualFragment(content.stripScripts());
+    }
+    element.parentNode.replaceChild(content, element);
+    return element;
+  },
+
+  insert: function(element, insertions) {
+    element = $(element);
+
+    if (Object.isString(insertions) || Object.isNumber(insertions) ||
+        Object.isElement(insertions) || (insertions && (insertions.toElement || insertions.toHTML)))
+          insertions = {bottom:insertions};
+
+    var content, insert, tagName, childNodes;
+
+    for (var position in insertions) {
+      content  = insertions[position];
+      position = position.toLowerCase();
+      insert = Element._insertionTranslations[position];
+
+      if (content && content.toElement) content = content.toElement();
+      if (Object.isElement(content)) {
+        insert(element, content);
+        continue;
+      }
+
+      content = Object.toHTML(content);
+
+      tagName = ((position == 'before' || position == 'after')
+        ? element.parentNode : element).tagName.toUpperCase();
+
+      childNodes = Element._getContentFromAnonymousElement(tagName, content.stripScripts());
+
+      if (position == 'top' || position == 'after') childNodes.reverse();
+      childNodes.each(insert.curry(element));
+
+      content.evalScripts.bind(content).defer();
+    }
+
+    return element;
+  },
+
+  wrap: function(element, wrapper, attributes) {
+    element = $(element);
+    if (Object.isElement(wrapper))
+      $(wrapper).writeAttribute(attributes || { });
+    else if (Object.isString(wrapper)) wrapper = new Element(wrapper, attributes);
+    else wrapper = new Element('div', wrapper);
+    if (element.parentNode)
+      element.parentNode.replaceChild(wrapper, element);
+    wrapper.appendChild(element);
+    return wrapper;
+  },
+
+  inspect: function(element) {
+    element = $(element);
+    var result = '<' + element.tagName.toLowerCase();
+    $H({'id': 'id', 'className': 'class'}).each(function(pair) {
+      var property = pair.first(), attribute = pair.last();
+      var value = (element[property] || '').toString();
+      if (value) result += ' ' + attribute + '=' + value.inspect(true);
+    });
+    return result + '>';
+  },
+
+  recursivelyCollect: function(element, property) {
+    element = $(element);
+    var elements = [];
+    while (element = element[property])
+      if (element.nodeType == 1)
+        elements.push(Element.extend(element));
+    return elements;
+  },
+
+  ancestors: function(element) {
+    return Element.recursivelyCollect(element, 'parentNode');
+  },
+
+  descendants: function(element) {
+    return Element.select(element, "*");
+  },
+
+  firstDescendant: function(element) {
+    element = $(element).firstChild;
+    while (element && element.nodeType != 1) element = element.nextSibling;
+    return $(element);
+  },
+
+  immediateDescendants: function(element) {
+    if (!(element = $(element).firstChild)) return [];
+    while (element && element.nodeType != 1) element = element.nextSibling;
+    if (element) return [element].concat($(element).nextSiblings());
+    return [];
+  },
+
+  previousSiblings: function(element) {
+    return Element.recursivelyCollect(element, 'previousSibling');
+  },
+
+  nextSiblings: function(element) {
+    return Element.recursivelyCollect(element, 'nextSibling');
+  },
+
+  siblings: function(element) {
+    element = $(element);
+    return Element.previousSiblings(element).reverse()
+      .concat(Element.nextSiblings(element));
+  },
+
+  match: function(element, selector) {
+    if (Object.isString(selector))
+      selector = new Selector(selector);
+    return selector.match($(element));
+  },
+
+  up: function(element, expression, index) {
+    element = $(element);
+    if (arguments.length == 1) return $(element.parentNode);
+    var ancestors = Element.ancestors(element);
+    return Object.isNumber(expression) ? ancestors[expression] :
+      Selector.findElement(ancestors, expression, index);
+  },
+
+  down: function(element, expression, index) {
+    element = $(element);
+    if (arguments.length == 1) return Element.firstDescendant(element);
+    return Object.isNumber(expression) ? Element.descendants(element)[expression] :
+      Element.select(element, expression)[index || 0];
+  },
+
+  previous: function(element, expression, index) {
+    element = $(element);
+    if (arguments.length == 1) return $(Selector.handlers.previousElementSibling(element));
+    var previousSiblings = Element.previousSiblings(element);
+    return Object.isNumber(expression) ? previousSiblings[expression] :
+      Selector.findElement(previousSiblings, expression, index);
+  },
+
+  next: function(element, expression, index) {
+    element = $(element);
+    if (arguments.length == 1) return $(Selector.handlers.nextElementSibling(element));
+    var nextSiblings = Element.nextSiblings(element);
+    return Object.isNumber(expression) ? nextSiblings[expression] :
+      Selector.findElement(nextSiblings, expression, index);
+  },
+
+
+  select: function(element) {
+    var args = Array.prototype.slice.call(arguments, 1);
+    return Selector.findChildElements(element, args);
+  },
+
+  adjacent: function(element) {
+    var args = Array.prototype.slice.call(arguments, 1);
+    return Selector.findChildElements(element.parentNode, args).without(element);
+  },
+
+  identify: function(element) {
+    element = $(element);
+    var id = Element.readAttribute(element, 'id');
+    if (id) return id;
+    do { id = 'anonymous_element_' + Element.idCounter++ } while ($(id));
+    Element.writeAttribute(element, 'id', id);
+    return id;
+  },
+
+  readAttribute: function(element, name) {
+    element = $(element);
+    if (Prototype.Browser.IE) {
+      var t = Element._attributeTranslations.read;
+      if (t.values[name]) return t.values[name](element, name);
+      if (t.names[name]) name = t.names[name];
+      if (name.include(':')) {
+        return (!element.attributes || !element.attributes[name]) ? null :
+         element.attributes[name].value;
+      }
+    }
+    return element.getAttribute(name);
+  },
+
+  writeAttribute: function(element, name, value) {
+    element = $(element);
+    var attributes = { }, t = Element._attributeTranslations.write;
+
+    if (typeof name == 'object') attributes = name;
+    else attributes[name] = Object.isUndefined(value) ? true : value;
+
+    for (var attr in attributes) {
+      name = t.names[attr] || attr;
+      value = attributes[attr];
+      if (t.values[attr]) name = t.values[attr](element, value);
+      if (value === false || value === null)
+        element.removeAttribute(name);
+      else if (value === true)
+        element.setAttribute(name, name);
+      else element.setAttribute(name, value);
+    }
+    return element;
+  },
+
+  getHeight: function(element) {
+    return Element.getDimensions(element).height;
+  },
+
+  getWidth: function(element) {
+    return Element.getDimensions(element).width;
+  },
+
+  classNames: function(element) {
+    return new Element.ClassNames(element);
+  },
+
+  hasClassName: function(element, className) {
+    if (!(element = $(element))) return;
+    var elementClassName = element.className;
+    return (elementClassName.length > 0 && (elementClassName == className ||
+      new RegExp("(^|\\s)" + className + "(\\s|$)").test(elementClassName)));
+  },
+
+  addClassName: function(element, className) {
+    if (!(element = $(element))) return;
+    if (!Element.hasClassName(element, className))
+      element.className += (element.className ? ' ' : '') + className;
+    return element;
+  },
+
+  removeClassName: function(element, className) {
+    if (!(element = $(element))) return;
+    element.className = element.className.replace(
+      new RegExp("(^|\\s+)" + className + "(\\s+|$)"), ' ').strip();
+    return element;
+  },
+
+  toggleClassName: function(element, className) {
+    if (!(element = $(element))) return;
+    return Element[Element.hasClassName(element, className) ?
+      'removeClassName' : 'addClassName'](element, className);
+  },
+
+  cleanWhitespace: function(element) {
+    element = $(element);
+    var node = element.firstChild;
+    while (node) {
+      var nextNode = node.nextSibling;
+      if (node.nodeType == 3 && !/\S/.test(node.nodeValue))
+        element.removeChild(node);
+      node = nextNode;
+    }
+    return element;
+  },
+
+  empty: function(element) {
+    return $(element).innerHTML.blank();
+  },
+
+  descendantOf: function(element, ancestor) {
+    element = $(element), ancestor = $(ancestor);
+
+    if (element.compareDocumentPosition)
+      return (element.compareDocumentPosition(ancestor) & 8) === 8;
+
+    if (ancestor.contains)
+      return ancestor.contains(element) && ancestor !== element;
+
+    while (element = element.parentNode)
+      if (element == ancestor) return true;
+
+    return false;
+  },
+
+  scrollTo: function(element) {
+    element = $(element);
+    var pos = Element.cumulativeOffset(element);
+    window.scrollTo(pos[0], pos[1]);
+    return element;
+  },
+
+  getStyle: function(element, style) {
+    element = $(element);
+    style = style == 'float' ? 'cssFloat' : style.camelize();
+    var value = element.style[style];
+    if (!value || value == 'auto') {
+      var css = document.defaultView.getComputedStyle(element, null);
+      value = css ? css[style] : null;
+    }
+    if (style == 'opacity') return value ? parseFloat(value) : 1.0;
+    return value == 'auto' ? null : value;
+  },
+
+  getOpacity: function(element) {
+    return $(element).getStyle('opacity');
+  },
+
+  setStyle: function(element, styles) {
+    element = $(element);
+    var elementStyle = element.style, match;
+    if (Object.isString(styles)) {
+      element.style.cssText += ';' + styles;
+      return styles.include('opacity') ?
+        element.setOpacity(styles.match(/opacity:\s*(\d?\.?\d*)/)[1]) : element;
+    }
+    for (var property in styles)
+      if (property == 'opacity') element.setOpacity(styles[property]);
+      else
+        elementStyle[(property == 'float' || property == 'cssFloat') ?
+          (Object.isUndefined(elementStyle.styleFloat) ? 'cssFloat' : 'styleFloat') :
+            property] = styles[property];
+
+    return element;
+  },
+
+  setOpacity: function(element, value) {
+    element = $(element);
+    element.style.opacity = (value == 1 || value === '') ? '' :
+      (value < 0.00001) ? 0 : value;
+    return element;
+  },
+
+  getDimensions: function(element) {
+    element = $(element);
+    var display = Element.getStyle(element, 'display');
+    if (display != 'none' && display != null) // Safari bug
+      return {width: element.offsetWidth, height: element.offsetHeight};
+
+    var els = element.style;
+    var originalVisibility = els.visibility;
+    var originalPosition = els.position;
+    var originalDisplay = els.display;
+    els.visibility = 'hidden';
+    if (originalPosition != 'fixed') // Switching fixed to absolute causes issues in Safari
+      els.position = 'absolute';
+    els.display = 'block';
+    var originalWidth = element.clientWidth;
+    var originalHeight = element.clientHeight;
+    els.display = originalDisplay;
+    els.position = originalPosition;
+    els.visibility = originalVisibility;
+    return {width: originalWidth, height: originalHeight};
+  },
+
+  makePositioned: function(element) {
+    element = $(element);
+    var pos = Element.getStyle(element, 'position');
+    if (pos == 'static' || !pos) {
+      element._madePositioned = true;
+      element.style.position = 'relative';
+      if (Prototype.Browser.Opera) {
+        element.style.top = 0;
+        element.style.left = 0;
+      }
+    }
+    return element;
+  },
+
+  undoPositioned: function(element) {
+    element = $(element);
+    if (element._madePositioned) {
+      element._madePositioned = undefined;
+      element.style.position =
+        element.style.top =
+        element.style.left =
+        element.style.bottom =
+        element.style.right = '';
+    }
+    return element;
+  },
+
+  makeClipping: function(element) {
+    element = $(element);
+    if (element._overflow) return element;
+    element._overflow = Element.getStyle(element, 'overflow') || 'auto';
+    if (element._overflow !== 'hidden')
+      element.style.overflow = 'hidden';
+    return element;
+  },
+
+  undoClipping: function(element) {
+    element = $(element);
+    if (!element._overflow) return element;
+    element.style.overflow = element._overflow == 'auto' ? '' : element._overflow;
+    element._overflow = null;
+    return element;
+  },
+
+  cumulativeOffset: function(element) {
+    var valueT = 0, valueL = 0;
+    do {
+      valueT += element.offsetTop  || 0;
+      valueL += element.offsetLeft || 0;
+      element = element.offsetParent;
+    } while (element);
+    return Element._returnOffset(valueL, valueT);
+  },
+
+  positionedOffset: function(element) {
+    var valueT = 0, valueL = 0;
+    do {
+      valueT += element.offsetTop  || 0;
+      valueL += element.offsetLeft || 0;
+      element = element.offsetParent;
+      if (element) {
+        if (element.tagName.toUpperCase() == 'BODY') break;
+        var p = Element.getStyle(element, 'position');
+        if (p !== 'static') break;
+      }
+    } while (element);
+    return Element._returnOffset(valueL, valueT);
+  },
+
+  absolutize: function(element) {
+    element = $(element);
+    if (Element.getStyle(element, 'position') == 'absolute') return element;
+
+    var offsets = Element.positionedOffset(element);
+    var top     = offsets[1];
+    var left    = offsets[0];
+    var width   = element.clientWidth;
+    var height  = element.clientHeight;
+
+    element._originalLeft   = left - parseFloat(element.style.left  || 0);
+    element._originalTop    = top  - parseFloat(element.style.top || 0);
+    element._originalWidth  = element.style.width;
+    element._originalHeight = element.style.height;
+
+    element.style.position = 'absolute';
+    element.style.top    = top + 'px';
+    element.style.left   = left + 'px';
+    element.style.width  = width + 'px';
+    element.style.height = height + 'px';
+    return element;
+  },
+
+  relativize: function(element) {
+    element = $(element);
+    if (Element.getStyle(element, 'position') == 'relative') return element;
+
+    element.style.position = 'relative';
+    var top  = parseFloat(element.style.top  || 0) - (element._originalTop || 0);
+    var left = parseFloat(element.style.left || 0) - (element._originalLeft || 0);
+
+    element.style.top    = top + 'px';
+    element.style.left   = left + 'px';
+    element.style.height = element._originalHeight;
+    element.style.width  = element._originalWidth;
+    return element;
+  },
+
+  cumulativeScrollOffset: function(element) {
+    var valueT = 0, valueL = 0;
+    do {
+      valueT += element.scrollTop  || 0;
+      valueL += element.scrollLeft || 0;
+      element = element.parentNode;
+    } while (element);
+    return Element._returnOffset(valueL, valueT);
+  },
+
+  getOffsetParent: function(element) {
+    if (element.offsetParent) return $(element.offsetParent);
+    if (element == document.body) return $(element);
+
+    while ((element = element.parentNode) && element != document.body)
+      if (Element.getStyle(element, 'position') != 'static')
+        return $(element);
+
+    return $(document.body);
+  },
+
+  viewportOffset: function(forElement) {
+    var valueT = 0, valueL = 0;
+
+    var element = forElement;
+    do {
+      valueT += element.offsetTop  || 0;
+      valueL += element.offsetLeft || 0;
+
+      if (element.offsetParent == document.body &&
+        Element.getStyle(element, 'position') == 'absolute') break;
+
+    } while (element = element.offsetParent);
+
+    element = forElement;
+    do {
+      if (!Prototype.Browser.Opera || (element.tagName && (element.tagName.toUpperCase() == 'BODY'))) {
+        valueT -= element.scrollTop  || 0;
+        valueL -= element.scrollLeft || 0;
+      }
+    } while (element = element.parentNode);
+
+    return Element._returnOffset(valueL, valueT);
+  },
+
+  clonePosition: function(element, source) {
+    var options = Object.extend({
+      setLeft:    true,
+      setTop:     true,
+      setWidth:   true,
+      setHeight:  true,
+      offsetTop:  0,
+      offsetLeft: 0
+    }, arguments[2] || { });
+
+    source = $(source);
+    var p = Element.viewportOffset(source);
+
+    element = $(element);
+    var delta = [0, 0];
+    var parent = null;
+    if (Element.getStyle(element, 'position') == 'absolute') {
+      parent = Element.getOffsetParent(element);
+      delta = Element.viewportOffset(parent);
+    }
+
+    if (parent == document.body) {
+      delta[0] -= document.body.offsetLeft;
+      delta[1] -= document.body.offsetTop;
+    }
+
+    if (options.setLeft)   element.style.left  = (p[0] - delta[0] + options.offsetLeft) + 'px';
+    if (options.setTop)    element.style.top   = (p[1] - delta[1] + options.offsetTop) + 'px';
+    if (options.setWidth)  element.style.width = source.offsetWidth + 'px';
+    if (options.setHeight) element.style.height = source.offsetHeight + 'px';
+    return element;
+  }
+};
+
+Object.extend(Element.Methods, {
+  getElementsBySelector: Element.Methods.select,
+
+  childElements: Element.Methods.immediateDescendants
+});
+
+Element._attributeTranslations = {
+  write: {
+    names: {
+      className: 'class',
+      htmlFor:   'for'
+    },
+    values: { }
+  }
+};
+
+if (Prototype.Browser.Opera) {
+  Element.Methods.getStyle = Element.Methods.getStyle.wrap(
+    function(proceed, element, style) {
+      switch (style) {
+        case 'left': case 'top': case 'right': case 'bottom':
+          if (proceed(element, 'position') === 'static') return null;
+        case 'height': case 'width':
+          if (!Element.visible(element)) return null;
+
+          var dim = parseInt(proceed(element, style), 10);
+
+          if (dim !== element['offset' + style.capitalize()])
+            return dim + 'px';
+
+          var properties;
+          if (style === 'height') {
+            properties = ['border-top-width', 'padding-top',
+             'padding-bottom', 'border-bottom-width'];
+          }
+          else {
+            properties = ['border-left-width', 'padding-left',
+             'padding-right', 'border-right-width'];
+          }
+          return properties.inject(dim, function(memo, property) {
+            var val = proceed(element, property);
+            return val === null ? memo : memo - parseInt(val, 10);
+          }) + 'px';
+        default: return proceed(element, style);
+      }
+    }
+  );
+
+  Element.Methods.readAttribute = Element.Methods.readAttribute.wrap(
+    function(proceed, element, attribute) {
+      if (attribute === 'title') return element.title;
+      return proceed(element, attribute);
+    }
+  );
+}
+
+else if (Prototype.Browser.IE) {
+  Element.Methods.getOffsetParent = Element.Methods.getOffsetParent.wrap(
+    function(proceed, element) {
+      element = $(element);
+      try { element.offsetParent }
+      catch(e) { return $(document.body) }
+      var position = element.getStyle('position');
+      if (position !== 'static') return proceed(element);
+      element.setStyle({ position: 'relative' });
+      var value = proceed(element);
+      element.setStyle({ position: position });
+      return value;
+    }
+  );
+
+  $w('positionedOffset viewportOffset').each(function(method) {
+    Element.Methods[method] = Element.Methods[method].wrap(
+      function(proceed, element) {
+        element = $(element);
+        try { element.offsetParent }
+        catch(e) { return Element._returnOffset(0,0) }
+        var position = element.getStyle('position');
+        if (position !== 'static') return proceed(element);
+        var offsetParent = element.getOffsetParent();
+        if (offsetParent && offsetParent.getStyle('position') === 'fixed')
+          offsetParent.setStyle({ zoom: 1 });
+        element.setStyle({ position: 'relative' });
+        var value = proceed(element);
+        element.setStyle({ position: position });
+        return value;
+      }
+    );
+  });
+
+  Element.Methods.cumulativeOffset = Element.Methods.cumulativeOffset.wrap(
+    function(proceed, element) {
+      try { element.offsetParent }
+      catch(e) { return Element._returnOffset(0,0) }
+      return proceed(element);
+    }
+  );
+
+  Element.Methods.getStyle = function(element, style) {
+    element = $(element);
+    style = (style == 'float' || style == 'cssFloat') ? 'styleFloat' : style.camelize();
+    var value = element.style[style];
+    if (!value && element.currentStyle) value = element.currentStyle[style];
+
+    if (style == 'opacity') {
+      if (value = (element.getStyle('filter') || '').match(/alpha\(opacity=(.*)\)/))
+        if (value[1]) return parseFloat(value[1]) / 100;
+      return 1.0;
+    }
+
+    if (value == 'auto') {
+      if ((style == 'width' || style == 'height') && (element.getStyle('display') != 'none'))
+        return element['offset' + style.capitalize()] + 'px';
+      return null;
+    }
+    return value;
+  };
+
+  Element.Methods.setOpacity = function(element, value) {
+    function stripAlpha(filter){
+      return filter.replace(/alpha\([^\)]*\)/gi,'');
+    }
+    element = $(element);
+    var currentStyle = element.currentStyle;
+    if ((currentStyle && !currentStyle.hasLayout) ||
+      (!currentStyle && element.style.zoom == 'normal'))
+        element.style.zoom = 1;
+
+    var filter = element.getStyle('filter'), style = element.style;
+    if (value == 1 || value === '') {
+      (filter = stripAlpha(filter)) ?
+        style.filter = filter : style.removeAttribute('filter');
+      return element;
+    } else if (value < 0.00001) value = 0;
+    style.filter = stripAlpha(filter) +
+      'alpha(opacity=' + (value * 100) + ')';
+    return element;
+  };
+
+  Element._attributeTranslations = (function(){
+
+    var classProp = 'className';
+    var forProp = 'for';
+
+    var el = document.createElement('div');
+
+    el.setAttribute(classProp, 'x');
+
+    if (el.className !== 'x') {
+      el.setAttribute('class', 'x');
+      if (el.className === 'x') {
+        classProp = 'class';
+      }
+    }
+    el = null;
+
+    el = document.createElement('label');
+    el.setAttribute(forProp, 'x');
+    if (el.htmlFor !== 'x') {
+      el.setAttribute('htmlFor', 'x');
+      if (el.htmlFor === 'x') {
+        forProp = 'htmlFor';
+      }
+    }
+    el = null;
+
+    return {
+      read: {
+        names: {
+          'class':      classProp,
+          'className':  classProp,
+          'for':        forProp,
+          'htmlFor':    forProp
+        },
+        values: {
+          _getAttr: function(element, attribute) {
+            return element.getAttribute(attribute);
+          },
+          _getAttr2: function(element, attribute) {
+            return element.getAttribute(attribute, 2);
+          },
+          _getAttrNode: function(element, attribute) {
+            var node = element.getAttributeNode(attribute);
+            return node ? node.value : "";
+          },
+          _getEv: (function(){
+
+            var el = document.createElement('div');
+            el.onclick = Prototype.emptyFunction;
+            var value = el.getAttribute('onclick');
+            var f;
+
+            if (String(value).indexOf('{') > -1) {
+              f = function(element, attribute) {
+                attribute = element.getAttribute(attribute);
+                if (!attribute) return null;
+                attribute = attribute.toString();
+                attribute = attribute.split('{')[1];
+                attribute = attribute.split('}')[0];
+                return attribute.strip();
+              };
+            }
+            else if (value === '') {
+              f = function(element, attribute) {
+                attribute = element.getAttribute(attribute);
+                if (!attribute) return null;
+                return attribute.strip();
+              };
+            }
+            el = null;
+            return f;
+          })(),
+          _flag: function(element, attribute) {
+            return $(element).hasAttribute(attribute) ? attribute : null;
+          },
+          style: function(element) {
+            return element.style.cssText.toLowerCase();
+          },
+          title: function(element) {
+            return element.title;
+          }
+        }
+      }
+    }
+  })();
+
+  Element._attributeTranslations.write = {
+    names: Object.extend({
+      cellpadding: 'cellPadding',
+      cellspacing: 'cellSpacing'
+    }, Element._attributeTranslations.read.names),
+    values: {
+      checked: function(element, value) {
+        element.checked = !!value;
+      },
+
+      style: function(element, value) {
+        element.style.cssText = value ? value : '';
+      }
+    }
+  };
+
+  Element._attributeTranslations.has = {};
+
+  $w('colSpan rowSpan vAlign dateTime accessKey tabIndex ' +
+      'encType maxLength readOnly longDesc frameBorder').each(function(attr) {
+    Element._attributeTranslations.write.names[attr.toLowerCase()] = attr;
+    Element._attributeTranslations.has[attr.toLowerCase()] = attr;
+  });
+
+  (function(v) {
+    Object.extend(v, {
+      href:        v._getAttr2,
+      src:         v._getAttr2,
+      type:        v._getAttr,
+      action:      v._getAttrNode,
+      disabled:    v._flag,
+      checked:     v._flag,
+      readonly:    v._flag,
+      multiple:    v._flag,
+      onload:      v._getEv,
+      onunload:    v._getEv,
+      onclick:     v._getEv,
+      ondblclick:  v._getEv,
+      onmousedown: v._getEv,
+      onmouseup:   v._getEv,
+      onmouseover: v._getEv,
+      onmousemove: v._getEv,
+      onmouseout:  v._getEv,
+      onfocus:     v._getEv,
+      onblur:      v._getEv,
+      onkeypress:  v._getEv,
+      onkeydown:   v._getEv,
+      onkeyup:     v._getEv,
+      onsubmit:    v._getEv,
+      onreset:     v._getEv,
+      onselect:    v._getEv,
+      onchange:    v._getEv
+    });
+  })(Element._attributeTranslations.read.values);
+
+  if (Prototype.BrowserFeatures.ElementExtensions) {
+    (function() {
+      function _descendants(element) {
+        var nodes = element.getElementsByTagName('*'), results = [];
+        for (var i = 0, node; node = nodes[i]; i++)
+          if (node.tagName !== "!") // Filter out comment nodes.
+            results.push(node);
+        return results;
+      }
+
+      Element.Methods.down = function(element, expression, index) {
+        element = $(element);
+        if (arguments.length == 1) return element.firstDescendant();
+        return Object.isNumber(expression) ? _descendants(element)[expression] :
+          Element.select(element, expression)[index || 0];
+      }
+    })();
+  }
+
+}
+
+else if (Prototype.Browser.Gecko && /rv:1\.8\.0/.test(navigator.userAgent)) {
+  Element.Methods.setOpacity = function(element, value) {
+    element = $(element);
+    element.style.opacity = (value == 1) ? 0.999999 :
+      (value === '') ? '' : (value < 0.00001) ? 0 : value;
+    return element;
+  };
+}
+
+else if (Prototype.Browser.WebKit) {
+  Element.Methods.setOpacity = function(element, value) {
+    element = $(element);
+    element.style.opacity = (value == 1 || value === '') ? '' :
+      (value < 0.00001) ? 0 : value;
+
+    if (value == 1)
+      if(element.tagName.toUpperCase() == 'IMG' && element.width) {
+        element.width++; element.width--;
+      } else try {
+        var n = document.createTextNode(' ');
+        element.appendChild(n);
+        element.removeChild(n);
+      } catch (e) { }
+
+    return element;
+  };
+
+  Element.Methods.cumulativeOffset = function(element) {
+    var valueT = 0, valueL = 0;
+    do {
+      valueT += element.offsetTop  || 0;
+      valueL += element.offsetLeft || 0;
+      if (element.offsetParent == document.body)
+        if (Element.getStyle(element, 'position') == 'absolute') break;
+
+      element = element.offsetParent;
+    } while (element);
+
+    return Element._returnOffset(valueL, valueT);
+  };
+}
+
+if ('outerHTML' in document.documentElement) {
+  Element.Methods.replace = function(element, content) {
+    element = $(element);
+
+    if (content && content.toElement) content = content.toElement();
+    if (Object.isElement(content)) {
+      element.parentNode.replaceChild(content, element);
+      return element;
+    }
+
+    content = Object.toHTML(content);
+    var parent = element.parentNode, tagName = parent.tagName.toUpperCase();
+
+    if (Element._insertionTranslations.tags[tagName]) {
+      var nextSibling = element.next();
+      var fragments = Element._getContentFromAnonymousElement(tagName, content.stripScripts());
+      parent.removeChild(element);
+      if (nextSibling)
+        fragments.each(function(node) { parent.insertBefore(node, nextSibling) });
+      else
+        fragments.each(function(node) { parent.appendChild(node) });
+    }
+    else element.outerHTML = content.stripScripts();
+
+    content.evalScripts.bind(content).defer();
+    return element;
+  };
+}
+
+Element._returnOffset = function(l, t) {
+  var result = [l, t];
+  result.left = l;
+  result.top = t;
+  return result;
+};
+
+Element._getContentFromAnonymousElement = function(tagName, html) {
+  var div = new Element('div'), t = Element._insertionTranslations.tags[tagName];
+  if (t) {
+    div.innerHTML = t[0] + html + t[1];
+    t[2].times(function() { div = div.firstChild });
+  } else div.innerHTML = html;
+  return $A(div.childNodes);
+};
+
+Element._insertionTranslations = {
+  before: function(element, node) {
+    element.parentNode.insertBefore(node, element);
+  },
+  top: function(element, node) {
+    element.insertBefore(node, element.firstChild);
+  },
+  bottom: function(element, node) {
+    element.appendChild(node);
+  },
+  after: function(element, node) {
+    element.parentNode.insertBefore(node, element.nextSibling);
+  },
+  tags: {
+    TABLE:  ['<table>',                '</table>',                   1],
+    TBODY:  ['<table><tbody>',         '</tbody></table>',           2],
+    TR:     ['<table><tbody><tr>',     '</tr></tbody></table>',      3],
+    TD:     ['<table><tbody><tr><td>', '</td></tr></tbody></table>', 4],
+    SELECT: ['<select>',               '</select>',                  1]
+  }
+};
+
+(function() {
+  var tags = Element._insertionTranslations.tags;
+  Object.extend(tags, {
+    THEAD: tags.TBODY,
+    TFOOT: tags.TBODY,
+    TH:    tags.TD
+  });
+})();
+
+Element.Methods.Simulated = {
+  hasAttribute: function(element, attribute) {
+    attribute = Element._attributeTranslations.has[attribute] || attribute;
+    var node = $(element).getAttributeNode(attribute);
+    return !!(node && node.specified);
+  }
+};
+
+Element.Methods.ByTag = { };
+
+Object.extend(Element, Element.Methods);
+
+(function(div) {
+
+  if (!Prototype.BrowserFeatures.ElementExtensions && div['__proto__']) {
+    window.HTMLElement = { };
+    window.HTMLElement.prototype = div['__proto__'];
+    Prototype.BrowserFeatures.ElementExtensions = true;
+  }
+
+  div = null;
+
+})(document.createElement('div'))
+
+Element.extend = (function() {
+
+  function checkDeficiency(tagName) {
+    if (typeof window.Element != 'undefined') {
+      var proto = window.Element.prototype;
+      if (proto) {
+        var id = '_' + (Math.random()+'').slice(2);
+        var el = document.createElement(tagName);
+        proto[id] = 'x';
+        var isBuggy = (el[id] !== 'x');
+        delete proto[id];
+        el = null;
+        return isBuggy;
+      }
+    }
+    return false;
+  }
+
+  function extendElementWith(element, methods) {
+    for (var property in methods) {
+      var value = methods[property];
+      if (Object.isFunction(value) && !(property in element))
+        element[property] = value.methodize();
+    }
+  }
+
+  var HTMLOBJECTELEMENT_PROTOTYPE_BUGGY = checkDeficiency('object');
+
+  if (Prototype.BrowserFeatures.SpecificElementExtensions) {
+    if (HTMLOBJECTELEMENT_PROTOTYPE_BUGGY) {
+      return function(element) {
+        if (element && typeof element._extendedByPrototype == 'undefined') {
+          var t = element.tagName;
+          if (t && (/^(?:object|applet|embed)$/i.test(t))) {
+            extendElementWith(element, Element.Methods);
+            extendElementWith(element, Element.Methods.Simulated);
+            extendElementWith(element, Element.Methods.ByTag[t.toUpperCase()]);
+          }
+        }
+        return element;
+      }
+    }
+    return Prototype.K;
+  }
+
+  var Methods = { }, ByTag = Element.Methods.ByTag;
+
+  var extend = Object.extend(function(element) {
+    if (!element || typeof element._extendedByPrototype != 'undefined' ||
+        element.nodeType != 1 || element == window) return element;
+
+    var methods = Object.clone(Methods),
+        tagName = element.tagName.toUpperCase();
+
+    if (ByTag[tagName]) Object.extend(methods, ByTag[tagName]);
+
+    extendElementWith(element, methods);
+
+    element._extendedByPrototype = Prototype.emptyFunction;
+    return element;
+
+  }, {
+    refresh: function() {
+      if (!Prototype.BrowserFeatures.ElementExtensions) {
+        Object.extend(Methods, Element.Methods);
+        Object.extend(Methods, Element.Methods.Simulated);
+      }
+    }
+  });
+
+  extend.refresh();
+  return extend;
+})();
+
+Element.hasAttribute = function(element, attribute) {
+  if (element.hasAttribute) return element.hasAttribute(attribute);
+  return Element.Methods.Simulated.hasAttribute(element, attribute);
+};
+
+Element.addMethods = function(methods) {
+  var F = Prototype.BrowserFeatures, T = Element.Methods.ByTag;
+
+  if (!methods) {
+    Object.extend(Form, Form.Methods);
+    Object.extend(Form.Element, Form.Element.Methods);
+    Object.extend(Element.Methods.ByTag, {
+      "FORM":     Object.clone(Form.Methods),
+      "INPUT":    Object.clone(Form.Element.Methods),
+      "SELECT":   Object.clone(Form.Element.Methods),
+      "TEXTAREA": Object.clone(Form.Element.Methods)
+    });
+  }
+
+  if (arguments.length == 2) {
+    var tagName = methods;
+    methods = arguments[1];
+  }
+
+  if (!tagName) Object.extend(Element.Methods, methods || { });
+  else {
+    if (Object.isArray(tagName)) tagName.each(extend);
+    else extend(tagName);
+  }
+
+  function extend(tagName) {
+    tagName = tagName.toUpperCase();
+    if (!Element.Methods.ByTag[tagName])
+      Element.Methods.ByTag[tagName] = { };
+    Object.extend(Element.Methods.ByTag[tagName], methods);
+  }
+
+  function copy(methods, destination, onlyIfAbsent) {
+    onlyIfAbsent = onlyIfAbsent || false;
+    for (var property in methods) {
+      var value = methods[property];
+      if (!Object.isFunction(value)) continue;
+      if (!onlyIfAbsent || !(property in destination))
+        destination[property] = value.methodize();
+    }
+  }
+
+  function findDOMClass(tagName) {
+    var klass;
+    var trans = {
+      "OPTGROUP": "OptGroup", "TEXTAREA": "TextArea", "P": "Paragraph",
+      "FIELDSET": "FieldSet", "UL": "UList", "OL": "OList", "DL": "DList",
+      "DIR": "Directory", "H1": "Heading", "H2": "Heading", "H3": "Heading",
+      "H4": "Heading", "H5": "Heading", "H6": "Heading", "Q": "Quote",
+      "INS": "Mod", "DEL": "Mod", "A": "Anchor", "IMG": "Image", "CAPTION":
+      "TableCaption", "COL": "TableCol", "COLGROUP": "TableCol", "THEAD":
+      "TableSection", "TFOOT": "TableSection", "TBODY": "TableSection", "TR":
+      "TableRow", "TH": "TableCell", "TD": "TableCell", "FRAMESET":
+      "FrameSet", "IFRAME": "IFrame"
+    };
+    if (trans[tagName]) klass = 'HTML' + trans[tagName] + 'Element';
+    if (window[klass]) return window[klass];
+    klass = 'HTML' + tagName + 'Element';
+    if (window[klass]) return window[klass];
+    klass = 'HTML' + tagName.capitalize() + 'Element';
+    if (window[klass]) return window[klass];
+
+    var element = document.createElement(tagName);
+    var proto = element['__proto__'] || element.constructor.prototype;
+    element = null;
+    return proto;
+  }
+
+  var elementPrototype = window.HTMLElement ? HTMLElement.prototype :
+   Element.prototype;
+
+  if (F.ElementExtensions) {
+    copy(Element.Methods, elementPrototype);
+    copy(Element.Methods.Simulated, elementPrototype, true);
+  }
+
+  if (F.SpecificElementExtensions) {
+    for (var tag in Element.Methods.ByTag) {
+      var klass = findDOMClass(tag);
+      if (Object.isUndefined(klass)) continue;
+      copy(T[tag], klass.prototype);
+    }
+  }
+
+  Object.extend(Element, Element.Methods);
+  delete Element.ByTag;
+
+  if (Element.extend.refresh) Element.extend.refresh();
+  Element.cache = { };
+};
+
+
+document.viewport = {
+
+  getDimensions: function() {
+    return { width: this.getWidth(), height: this.getHeight() };
+  },
+
+  getScrollOffsets: function() {
+    return Element._returnOffset(
+      window.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft,
+      window.pageYOffset || document.documentElement.scrollTop  || document.body.scrollTop);
+  }
+};
+
+(function(viewport) {
+  var B = Prototype.Browser, doc = document, element, property = {};
+
+  function getRootElement() {
+    if (B.WebKit && !doc.evaluate)
+      return document;
+
+    if (B.Opera && window.parseFloat(window.opera.version()) < 9.5)
+      return document.body;
+
+    return document.documentElement;
+  }
+
+  function define(D) {
+    if (!element) element = getRootElement();
+
+    property[D] = 'client' + D;
+
+    viewport['get' + D] = function() { return element[property[D]] };
+    return viewport['get' + D]();
+  }
+
+  viewport.getWidth  = define.curry('Width');
+
+  viewport.getHeight = define.curry('Height');
+})(document.viewport);
+
+
+Element.Storage = {
+  UID: 1
+};
+
+Element.addMethods({
+  getStorage: function(element) {
+    if (!(element = $(element))) return;
+
+    var uid;
+    if (element === window) {
+      uid = 0;
+    } else {
+      if (typeof element._prototypeUID === "undefined")
+        element._prototypeUID = [Element.Storage.UID++];
+      uid = element._prototypeUID[0];
+    }
+
+    if (!Element.Storage[uid])
+      Element.Storage[uid] = $H();
+
+    return Element.Storage[uid];
+  },
+
+  store: function(element, key, value) {
+    if (!(element = $(element))) return;
+
+    if (arguments.length === 2) {
+      Element.getStorage(element).update(key);
+    } else {
+      Element.getStorage(element).set(key, value);
+    }
+
+    return element;
+  },
+
+  retrieve: function(element, key, defaultValue) {
+    if (!(element = $(element))) return;
+    var hash = Element.getStorage(element), value = hash.get(key);
+
+    if (Object.isUndefined(value)) {
+      hash.set(key, defaultValue);
+      value = defaultValue;
+    }
+
+    return value;
+  },
+
+  clone: function(element, deep) {
+    if (!(element = $(element))) return;
+    var clone = element.cloneNode(deep);
+    clone._prototypeUID = void 0;
+    if (deep) {
+      var descendants = Element.select(clone, '*'),
+          i = descendants.length;
+      while (i--) {
+        descendants[i]._prototypeUID = void 0;
+      }
+    }
+    return Element.extend(clone);
+  }
+});
+/* Portions of the Selector class are derived from Jack Slocum's DomQuery,
+ * part of YUI-Ext version 0.40, distributed under the terms of an MIT-style
+ * license.  Please see http://www.yui-ext.com/ for more information. */
+
+var Selector = Class.create({
+  initialize: function(expression) {
+    this.expression = expression.strip();
+
+    if (this.shouldUseSelectorsAPI()) {
+      this.mode = 'selectorsAPI';
+    } else if (this.shouldUseXPath()) {
+      this.mode = 'xpath';
+      this.compileXPathMatcher();
+    } else {
+      this.mode = "normal";
+      this.compileMatcher();
+    }
+
+  },
+
+  shouldUseXPath: (function() {
+
+    var IS_DESCENDANT_SELECTOR_BUGGY = (function(){
+      var isBuggy = false;
+      if (document.evaluate && window.XPathResult) {
+        var el = document.createElement('div');
+        el.innerHTML = '<ul><li></li></ul><div><ul><li></li></ul></div>';
+
+        var xpath = ".//*[local-name()='ul' or local-name()='UL']" +
+          "//*[local-name()='li' or local-name()='LI']";
+
+        var result = document.evaluate(xpath, el, null,
+          XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
+
+        isBuggy = (result.snapshotLength !== 2);
+        el = null;
+      }
+      return isBuggy;
+    })();
+
+    return function() {
+      if (!Prototype.BrowserFeatures.XPath) return false;
+
+      var e = this.expression;
+
+      if (Prototype.Browser.WebKit &&
+       (e.include("-of-type") || e.include(":empty")))
+        return false;
+
+      if ((/(\[[\w-]*?:|:checked)/).test(e))
+        return false;
+
+      if (IS_DESCENDANT_SELECTOR_BUGGY) return false;
+
+      return true;
+    }
+
+  })(),
+
+  shouldUseSelectorsAPI: function() {
+    if (!Prototype.BrowserFeatures.SelectorsAPI) return false;
+
+    if (Selector.CASE_INSENSITIVE_CLASS_NAMES) return false;
+
+    if (!Selector._div) Selector._div = new Element('div');
+
+    try {
+      Selector._div.querySelector(this.expression);
+    } catch(e) {
+      return false;
+    }
+
+    return true;
+  },
+
+  compileMatcher: function() {
+    var e = this.expression, ps = Selector.patterns, h = Selector.handlers,
+        c = Selector.criteria, le, p, m, len = ps.length, name;
+
+    if (Selector._cache[e]) {
+      this.matcher = Selector._cache[e];
+      return;
+    }
+
+    this.matcher = ["this.matcher = function(root) {",
+                    "var r = root, h = Selector.handlers, c = false, n;"];
+
+    while (e && le != e && (/\S/).test(e)) {
+      le = e;
+      for (var i = 0; i<len; i++) {
+        p = ps[i].re;
+        name = ps[i].name;
+        if (m = e.match(p)) {
+          this.matcher.push(Object.isFunction(c[name]) ? c[name](m) :
+            new Template(c[name]).evaluate(m));
+          e = e.replace(m[0], '');
+          break;
+        }
+      }
+    }
+
+    this.matcher.push("return h.unique(n);\n}");
+    eval(this.matcher.join('\n'));
+    Selector._cache[this.expression] = this.matcher;
+  },
+
+  compileXPathMatcher: function() {
+    var e = this.expression, ps = Selector.patterns,
+        x = Selector.xpath, le, m, len = ps.length, name;
+
+    if (Selector._cache[e]) {
+      this.xpath = Selector._cache[e]; return;
+    }
+
+    this.matcher = ['.//*'];
+    while (e && le != e && (/\S/).test(e)) {
+      le = e;
+      for (var i = 0; i<len; i++) {
+        name = ps[i].name;
+        if (m = e.match(ps[i].re)) {
+          this.matcher.push(Object.isFunction(x[name]) ? x[name](m) :
+            new Template(x[name]).evaluate(m));
+          e = e.replace(m[0], '');
+          break;
+        }
+      }
+    }
+
+    this.xpath = this.matcher.join('');
+    Selector._cache[this.expression] = this.xpath;
+  },
+
+  findElements: function(root) {
+    root = root || document;
+    var e = this.expression, results;
+
+    switch (this.mode) {
+      case 'selectorsAPI':
+        if (root !== document) {
+          var oldId = root.id, id = $(root).identify();
+          id = id.replace(/([\.:])/g, "\\$1");
+          e = "#" + id + " " + e;
+        }
+
+        results = $A(root.querySelectorAll(e)).map(Element.extend);
+        root.id = oldId;
+
+        return results;
+      case 'xpath':
+        return document._getElementsByXPath(this.xpath, root);
+      default:
+       return this.matcher(root);
+    }
+  },
+
+  match: function(element) {
+    this.tokens = [];
+
+    var e = this.expression, ps = Selector.patterns, as = Selector.assertions;
+    var le, p, m, len = ps.length, name;
+
+    while (e && le !== e && (/\S/).test(e)) {
+      le = e;
+      for (var i = 0; i<len; i++) {
+        p = ps[i].re;
+        name = ps[i].name;
+        if (m = e.match(p)) {
+          if (as[name]) {
+            this.tokens.push([name, Object.clone(m)]);
+            e = e.replace(m[0], '');
+          } else {
+            return this.findElements(document).include(element);
+          }
+        }
+      }
+    }
+
+    var match = true, name, matches;
+    for (var i = 0, token; token = this.tokens[i]; i++) {
+      name = token[0], matches = token[1];
+      if (!Selector.assertions[name](element, matches)) {
+        match = false; break;
+      }
+    }
+
+    return match;
+  },
+
+  toString: function() {
+    return this.expression;
+  },
+
+  inspect: function() {
+    return "#<Selector:" + this.expression.inspect() + ">";
+  }
+});
+
+if (Prototype.BrowserFeatures.SelectorsAPI &&
+ document.compatMode === 'BackCompat') {
+  Selector.CASE_INSENSITIVE_CLASS_NAMES = (function(){
+    var div = document.createElement('div'),
+     span = document.createElement('span');
+
+    div.id = "prototype_test_id";
+    span.className = 'Test';
+    div.appendChild(span);
+    var isIgnored = (div.querySelector('#prototype_test_id .test') !== null);
+    div = span = null;
+    return isIgnored;
+  })();
+}
+
+Object.extend(Selector, {
+  _cache: { },
+
+  xpath: {
+    descendant:   "//*",
+    child:        "/*",
+    adjacent:     "/following-sibling::*[1]",
+    laterSibling: '/following-sibling::*',
+    tagName:      function(m) {
+      if (m[1] == '*') return '';
+      return "[local-name()='" + m[1].toLowerCase() +
+             "' or local-name()='" + m[1].toUpperCase() + "']";
+    },
+    className:    "[contains(concat(' ', @class, ' '), ' #{1} ')]",
+    id:           "[@id='#{1}']",
+    attrPresence: function(m) {
+      m[1] = m[1].toLowerCase();
+      return new Template("[@#{1}]").evaluate(m);
+    },
+    attr: function(m) {
+      m[1] = m[1].toLowerCase();
+      m[3] = m[5] || m[6];
+      return new Template(Selector.xpath.operators[m[2]]).evaluate(m);
+    },
+    pseudo: function(m) {
+      var h = Selector.xpath.pseudos[m[1]];
+      if (!h) return '';
+      if (Object.isFunction(h)) return h(m);
+      return new Template(Selector.xpath.pseudos[m[1]]).evaluate(m);
+    },
+    operators: {
+      '=':  "[@#{1}='#{3}']",
+      '!=': "[@#{1}!='#{3}']",
+      '^=': "[starts-with(@#{1}, '#{3}')]",
+      '$=': "[substring(@#{1}, (string-length(@#{1}) - string-length('#{3}') + 1))='#{3}']",
+      '*=': "[contains(@#{1}, '#{3}')]",
+      '~=': "[contains(concat(' ', @#{1}, ' '), ' #{3} ')]",
+      '|=': "[contains(concat('-', @#{1}, '-'), '-#{3}-')]"
+    },
+    pseudos: {
+      'first-child': '[not(preceding-sibling::*)]',
+      'last-child':  '[not(following-sibling::*)]',
+      'only-child':  '[not(preceding-sibling::* or following-sibling::*)]',
+      'empty':       "[count(*) = 0 and (count(text()) = 0)]",
+      'checked':     "[@checked]",
+      'disabled':    "[(@disabled) and (@type!='hidden')]",
+      'enabled':     "[not(@disabled) and (@type!='hidden')]",
+      'not': function(m) {
+        var e = m[6], p = Selector.patterns,
+            x = Selector.xpath, le, v, len = p.length, name;
+
+        var exclusion = [];
+        while (e && le != e && (/\S/).test(e)) {
+          le = e;
+          for (var i = 0; i<len; i++) {
+            name = p[i].name
+            if (m = e.match(p[i].re)) {
+              v = Object.isFunction(x[name]) ? x[name](m) : new Template(x[name]).evaluate(m);
+              exclusion.push("(" + v.substring(1, v.length - 1) + ")");
+              e = e.replace(m[0], '');
+              break;
+            }
+          }
+        }
+        return "[not(" + exclusion.join(" and ") + ")]";
+      },
+      'nth-child':      function(m) {
+        return Selector.xpath.pseudos.nth("(count(./preceding-sibling::*) + 1) ", m);
+      },
+      'nth-last-child': function(m) {
+        return Selector.xpath.pseudos.nth("(count(./following-sibling::*) + 1) ", m);
+      },
+      'nth-of-type':    function(m) {
+        return Selector.xpath.pseudos.nth("position() ", m);
+      },
+      'nth-last-of-type': function(m) {
+        return Selector.xpath.pseudos.nth("(last() + 1 - position()) ", m);
+      },
+      'first-of-type':  function(m) {
+        m[6] = "1"; return Selector.xpath.pseudos['nth-of-type'](m);
+      },
+      'last-of-type':   function(m) {
+        m[6] = "1"; return Selector.xpath.pseudos['nth-last-of-type'](m);
+      },
+      'only-of-type':   function(m) {
+        var p = Selector.xpath.pseudos; return p['first-of-type'](m) + p['last-of-type'](m);
+      },
+      nth: function(fragment, m) {
+        var mm, formula = m[6], predicate;
+        if (formula == 'even') formula = '2n+0';
+        if (formula == 'odd')  formula = '2n+1';
+        if (mm = formula.match(/^(\d+)$/)) // digit only
+          return '[' + fragment + "= " + mm[1] + ']';
+        if (mm = formula.match(/^(-?\d*)?n(([+-])(\d+))?/)) { // an+b
+          if (mm[1] == "-") mm[1] = -1;
+          var a = mm[1] ? Number(mm[1]) : 1;
+          var b = mm[2] ? Number(mm[2]) : 0;
+          predicate = "[((#{fragment} - #{b}) mod #{a} = 0) and " +
+          "((#{fragment} - #{b}) div #{a} >= 0)]";
+          return new Template(predicate).evaluate({
+            fragment: fragment, a: a, b: b });
+        }
+      }
+    }
+  },
+
+  criteria: {
+    tagName:      'n = h.tagName(n, r, "#{1}", c);      c = false;',
+    className:    'n = h.className(n, r, "#{1}", c);    c = false;',
+    id:           'n = h.id(n, r, "#{1}", c);           c = false;',
+    attrPresence: 'n = h.attrPresence(n, r, "#{1}", c); c = false;',
+    attr: function(m) {
+      m[3] = (m[5] || m[6]);
+      return new Template('n = h.attr(n, r, "#{1}", "#{3}", "#{2}", c); c = false;').evaluate(m);
+    },
+    pseudo: function(m) {
+      if (m[6]) m[6] = m[6].replace(/"/g, '\\"');
+      return new Template('n = h.pseudo(n, "#{1}", "#{6}", r, c); c = false;').evaluate(m);
+    },
+    descendant:   'c = "descendant";',
+    child:        'c = "child";',
+    adjacent:     'c = "adjacent";',
+    laterSibling: 'c = "laterSibling";'
+  },
+
+  patterns: [
+    { name: 'laterSibling', re: /^\s*~\s*/ },
+    { name: 'child',        re: /^\s*>\s*/ },
+    { name: 'adjacent',     re: /^\s*\+\s*/ },
+    { name: 'descendant',   re: /^\s/ },
+
+    { name: 'tagName',      re: /^\s*(\*|[\w\-]+)(\b|$)?/ },
+    { name: 'id',           re: /^#([\w\-\*]+)(\b|$)/ },
+    { name: 'className',    re: /^\.([\w\-\*]+)(\b|$)/ },
+    { name: 'pseudo',       re: /^:((first|last|nth|nth-last|only)(-child|-of-type)|empty|checked|(en|dis)abled|not)(\((.*?)\))?(\b|$|(?=\s|[:+~>]))/ },
+    { name: 'attrPresence', re: /^\[((?:[\w-]+:)?[\w-]+)\]/ },
+    { name: 'attr',         re: /\[((?:[\w-]*:)?[\w-]+)\s*(?:([!^$*~|]?=)\s*((['"])([^\4]*?)\4|([^'"][^\]]*?)))?\]/ }
+  ],
+
+  assertions: {
+    tagName: function(element, matches) {
+      return matches[1].toUpperCase() == element.tagName.toUpperCase();
+    },
+
+    className: function(element, matches) {
+      return Element.hasClassName(element, matches[1]);
+    },
+
+    id: function(element, matches) {
+      return element.id === matches[1];
+    },
+
+    attrPresence: function(element, matches) {
+      return Element.hasAttribute(element, matches[1]);
+    },
+
+    attr: function(element, matches) {
+      var nodeValue = Element.readAttribute(element, matches[1]);
+      return nodeValue && Selector.operators[matches[2]](nodeValue, matches[5] || matches[6]);
+    }
+  },
+
+  handlers: {
+    concat: function(a, b) {
+      for (var i = 0, node; node = b[i]; i++)
+        a.push(node);
+      return a;
+    },
+
+    mark: function(nodes) {
+      var _true = Prototype.emptyFunction;
+      for (var i = 0, node; node = nodes[i]; i++)
+        node._countedByPrototype = _true;
+      return nodes;
+    },
+
+    unmark: (function(){
+
+      var PROPERTIES_ATTRIBUTES_MAP = (function(){
+        var el = document.createElement('div'),
+            isBuggy = false,
+            propName = '_countedByPrototype',
+            value = 'x'
+        el[propName] = value;
+        isBuggy = (el.getAttribute(propName) === value);
+        el = null;
+        return isBuggy;
+      })();
+
+      return PROPERTIES_ATTRIBUTES_MAP ?
+        function(nodes) {
+          for (var i = 0, node; node = nodes[i]; i++)
+            node.removeAttribute('_countedByPrototype');
+          return nodes;
+        } :
+        function(nodes) {
+          for (var i = 0, node; node = nodes[i]; i++)
+            node._countedByPrototype = void 0;
+          return nodes;
+        }
+    })(),
+
+    index: function(parentNode, reverse, ofType) {
+      parentNode._countedByPrototype = Prototype.emptyFunction;
+      if (reverse) {
+        for (var nodes = parentNode.childNodes, i = nodes.length - 1, j = 1; i >= 0; i--) {
+          var node = nodes[i];
+          if (node.nodeType == 1 && (!ofType || node._countedByPrototype)) node.nodeIndex = j++;
+        }
+      } else {
+        for (var i = 0, j = 1, nodes = parentNode.childNodes; node = nodes[i]; i++)
+          if (node.nodeType == 1 && (!ofType || node._countedByPrototype)) node.nodeIndex = j++;
+      }
+    },
+
+    unique: function(nodes) {
+      if (nodes.length == 0) return nodes;
+      var results = [], n;
+      for (var i = 0, l = nodes.length; i < l; i++)
+        if (typeof (n = nodes[i])._countedByPrototype == 'undefined') {
+          n._countedByPrototype = Prototype.emptyFunction;
+          results.push(Element.extend(n));
+        }
+      return Selector.handlers.unmark(results);
+    },
+
+    descendant: function(nodes) {
+      var h = Selector.handlers;
+      for (var i = 0, results = [], node; node = nodes[i]; i++)
+        h.concat(results, node.getElementsByTagName('*'));
+      return results;
+    },
+
+    child: function(nodes) {
+      var h = Selector.handlers;
+      for (var i = 0, results = [], node; node = nodes[i]; i++) {
+        for (var j = 0, child; child = node.childNodes[j]; j++)
+          if (child.nodeType == 1 && child.tagName != '!') results.push(child);
+      }
+      return results;
+    },
+
+    adjacent: function(nodes) {
+      for (var i = 0, results = [], node; node = nodes[i]; i++) {
+        var next = this.nextElementSibling(node);
+        if (next) results.push(next);
+      }
+      return results;
+    },
+
+    laterSibling: function(nodes) {
+      var h = Selector.handlers;
+      for (var i = 0, results = [], node; node = nodes[i]; i++)
+        h.concat(results, Element.nextSiblings(node));
+      return results;
+    },
+
+    nextElementSibling: function(node) {
+      while (node = node.nextSibling)
+        if (node.nodeType == 1) return node;
+      return null;
+    },
+
+    previousElementSibling: function(node) {
+      while (node = node.previousSibling)
+        if (node.nodeType == 1) return node;
+      return null;
+    },
+
+    tagName: function(nodes, root, tagName, combinator) {
+      var uTagName = tagName.toUpperCase();
+      var results = [], h = Selector.handlers;
+      if (nodes) {
+        if (combinator) {
+          if (combinator == "descendant") {
+            for (var i = 0, node; node = nodes[i]; i++)
+              h.concat(results, node.getElementsByTagName(tagName));
+            return results;
+          } else nodes = this[combinator](nodes);
+          if (tagName == "*") return nodes;
+        }
+        for (var i = 0, node; node = nodes[i]; i++)
+          if (node.tagName.toUpperCase() === uTagName) results.push(node);
+        return results;
+      } else return root.getElementsByTagName(tagName);
+    },
+
+    id: function(nodes, root, id, combinator) {
+      var targetNode = $(id), h = Selector.handlers;
+
+      if (root == document) {
+        if (!targetNode) return [];
+        if (!nodes) return [targetNode];
+      } else {
+        if (!root.sourceIndex || root.sourceIndex < 1) {
+          var nodes = root.getElementsByTagName('*');
+          for (var j = 0, node; node = nodes[j]; j++) {
+            if (node.id === id) return [node];
+          }
+        }
+      }
+
+      if (nodes) {
+        if (combinator) {
+          if (combinator == 'child') {
+            for (var i = 0, node; node = nodes[i]; i++)
+              if (targetNode.parentNode == node) return [targetNode];
+          } else if (combinator == 'descendant') {
+            for (var i = 0, node; node = nodes[i]; i++)
+              if (Element.descendantOf(targetNode, node)) return [targetNode];
+          } else if (combinator == 'adjacent') {
+            for (var i = 0, node; node = nodes[i]; i++)
+              if (Selector.handlers.previousElementSibling(targetNode) == node)
+                return [targetNode];
+          } else nodes = h[combinator](nodes);
+        }
+        for (var i = 0, node; node = nodes[i]; i++)
+          if (node == targetNode) return [targetNode];
+        return [];
+      }
+      return (targetNode && Element.descendantOf(targetNode, root)) ? [targetNode] : [];
+    },
+
+    className: function(nodes, root, className, combinator) {
+      if (nodes && combinator) nodes = this[combinator](nodes);
+      return Selector.handlers.byClassName(nodes, root, className);
+    },
+
+    byClassName: function(nodes, root, className) {
+      if (!nodes) nodes = Selector.handlers.descendant([root]);
+      var needle = ' ' + className + ' ';
+      for (var i = 0, results = [], node, nodeClassName; node = nodes[i]; i++) {
+        nodeClassName = node.className;
+        if (nodeClassName.length == 0) continue;
+        if (nodeClassName == className || (' ' + nodeClassName + ' ').include(needle))
+          results.push(node);
+      }
+      return results;
+    },
+
+    attrPresence: function(nodes, root, attr, combinator) {
+      if (!nodes) nodes = root.getElementsByTagName("*");
+      if (nodes && combinator) nodes = this[combinator](nodes);
+      var results = [];
+      for (var i = 0, node; node = nodes[i]; i++)
+        if (Element.hasAttribute(node, attr)) results.push(node);
+      return results;
+    },
+
+    attr: function(nodes, root, attr, value, operator, combinator) {
+      if (!nodes) nodes = root.getElementsByTagName("*");
+      if (nodes && combinator) nodes = this[combinator](nodes);
+      var handler = Selector.operators[operator], results = [];
+      for (var i = 0, node; node = nodes[i]; i++) {
+        var nodeValue = Element.readAttribute(node, attr);
+        if (nodeValue === null) continue;
+        if (handler(nodeValue, value)) results.push(node);
+      }
+      return results;
+    },
+
+    pseudo: function(nodes, name, value, root, combinator) {
+      if (nodes && combinator) nodes = this[combinator](nodes);
+      if (!nodes) nodes = root.getElementsByTagName("*");
+      return Selector.pseudos[name](nodes, value, root);
+    }
+  },
+
+  pseudos: {
+    'first-child': function(nodes, value, root) {
+      for (var i = 0, results = [], node; node = nodes[i]; i++) {
+        if (Selector.handlers.previousElementSibling(node)) continue;
+          results.push(node);
+      }
+      return results;
+    },
+    'last-child': function(nodes, value, root) {
+      for (var i = 0, results = [], node; node = nodes[i]; i++) {
+        if (Selector.handlers.nextElementSibling(node)) continue;
+          results.push(node);
+      }
+      return results;
+    },
+    'only-child': function(nodes, value, root) {
+      var h = Selector.handlers;
+      for (var i = 0, results = [], node; node = nodes[i]; i++)
+        if (!h.previousElementSibling(node) && !h.nextElementSibling(node))
+          results.push(node);
+      return results;
+    },
+    'nth-child':        function(nodes, formula, root) {
+      return Selector.pseudos.nth(nodes, formula, root);
+    },
+    'nth-last-child':   function(nodes, formula, root) {
+      return Selector.pseudos.nth(nodes, formula, root, true);
+    },
+    'nth-of-type':      function(nodes, formula, root) {
+      return Selector.pseudos.nth(nodes, formula, root, false, true);
+    },
+    'nth-last-of-type': function(nodes, formula, root) {
+      return Selector.pseudos.nth(nodes, formula, root, true, true);
+    },
+    'first-of-type':    function(nodes, formula, root) {
+      return Selector.pseudos.nth(nodes, "1", root, false, true);
+    },
+    'last-of-type':     function(nodes, formula, root) {
+      return Selector.pseudos.nth(nodes, "1", root, true, true);
+    },
+    'only-of-type':     function(nodes, formula, root) {
+      var p = Selector.pseudos;
+      return p['last-of-type'](p['first-of-type'](nodes, formula, root), formula, root);
+    },
+
+    getIndices: function(a, b, total) {
+      if (a == 0) return b > 0 ? [b] : [];
+      return $R(1, total).inject([], function(memo, i) {
+        if (0 == (i - b) % a && (i - b) / a >= 0) memo.push(i);
+        return memo;
+      });
+    },
+
+    nth: function(nodes, formula, root, reverse, ofType) {
+      if (nodes.length == 0) return [];
+      if (formula == 'even') formula = '2n+0';
+      if (formula == 'odd')  formula = '2n+1';
+      var h = Selector.handlers, results = [], indexed = [], m;
+      h.mark(nodes);
+      for (var i = 0, node; node = nodes[i]; i++) {
+        if (!node.parentNode._countedByPrototype) {
+          h.index(node.parentNode, reverse, ofType);
+          indexed.push(node.parentNode);
+        }
+      }
+      if (formula.match(/^\d+$/)) { // just a number
+        formula = Number(formula);
+        for (var i = 0, node; node = nodes[i]; i++)
+          if (node.nodeIndex == formula) results.push(node);
+      } else if (m = formula.match(/^(-?\d*)?n(([+-])(\d+))?/)) { // an+b
+        if (m[1] == "-") m[1] = -1;
+        var a = m[1] ? Number(m[1]) : 1;
+        var b = m[2] ? Number(m[2]) : 0;
+        var indices = Selector.pseudos.getIndices(a, b, nodes.length);
+        for (var i = 0, node, l = indices.length; node = nodes[i]; i++) {
+          for (var j = 0; j < l; j++)
+            if (node.nodeIndex == indices[j]) results.push(node);
+        }
+      }
+      h.unmark(nodes);
+      h.unmark(indexed);
+      return results;
+    },
+
+    'empty': function(nodes, value, root) {
+      for (var i = 0, results = [], node; node = nodes[i]; i++) {
+        if (node.tagName == '!' || node.firstChild) continue;
+        results.push(node);
+      }
+      return results;
+    },
+
+    'not': function(nodes, selector, root) {
+      var h = Selector.handlers, selectorType, m;
+      var exclusions = new Selector(selector).findElements(root);
+      h.mark(exclusions);
+      for (var i = 0, results = [], node; node = nodes[i]; i++)
+        if (!node._countedByPrototype) results.push(node);
+      h.unmark(exclusions);
+      return results;
+    },
+
+    'enabled': function(nodes, value, root) {
+      for (var i = 0, results = [], node; node = nodes[i]; i++)
+        if (!node.disabled && (!node.type || node.type !== 'hidden'))
+          results.push(node);
+      return results;
+    },
+
+    'disabled': function(nodes, value, root) {
+      for (var i = 0, results = [], node; node = nodes[i]; i++)
+        if (node.disabled) results.push(node);
+      return results;
+    },
+
+    'checked': function(nodes, value, root) {
+      for (var i = 0, results = [], node; node = nodes[i]; i++)
+        if (node.checked) results.push(node);
+      return results;
+    }
+  },
+
+  operators: {
+    '=':  function(nv, v) { return nv == v; },
+    '!=': function(nv, v) { return nv != v; },
+    '^=': function(nv, v) { return nv == v || nv && nv.startsWith(v); },
+    '$=': function(nv, v) { return nv == v || nv && nv.endsWith(v); },
+    '*=': function(nv, v) { return nv == v || nv && nv.include(v); },
+    '~=': function(nv, v) { return (' ' + nv + ' ').include(' ' + v + ' '); },
+    '|=': function(nv, v) { return ('-' + (nv || "").toUpperCase() +
+     '-').include('-' + (v || "").toUpperCase() + '-'); }
+  },
+
+  split: function(expression) {
+    var expressions = [];
+    expression.scan(/(([\w#:.~>+()\s-]+|\*|\[.*?\])+)\s*(,|$)/, function(m) {
+      expressions.push(m[1].strip());
+    });
+    return expressions;
+  },
+
+  matchElements: function(elements, expression) {
+    var matches = $$(expression), h = Selector.handlers;
+    h.mark(matches);
+    for (var i = 0, results = [], element; element = elements[i]; i++)
+      if (element._countedByPrototype) results.push(element);
+    h.unmark(matches);
+    return results;
+  },
+
+  findElement: function(elements, expression, index) {
+    if (Object.isNumber(expression)) {
+      index = expression; expression = false;
+    }
+    return Selector.matchElements(elements, expression || '*')[index || 0];
+  },
+
+  findChildElements: function(element, expressions) {
+    expressions = Selector.split(expressions.join(','));
+    var results = [], h = Selector.handlers;
+    for (var i = 0, l = expressions.length, selector; i < l; i++) {
+      selector = new Selector(expressions[i].strip());
+      h.concat(results, selector.findElements(element));
+    }
+    return (l > 1) ? h.unique(results) : results;
+  }
+});
+
+if (Prototype.Browser.IE) {
+  Object.extend(Selector.handlers, {
+    concat: function(a, b) {
+      for (var i = 0, node; node = b[i]; i++)
+        if (node.tagName !== "!") a.push(node);
+      return a;
+    }
+  });
+}
+
+function $$() {
+  return Selector.findChildElements(document, $A(arguments));
+}
+
+var Form = {
+  reset: function(form) {
+    form = $(form);
+    form.reset();
+    return form;
+  },
+
+  serializeElements: function(elements, options) {
+    if (typeof options != 'object') options = { hash: !!options };
+    else if (Object.isUndefined(options.hash)) options.hash = true;
+    var key, value, submitted = false, submit = options.submit;
+
+    var data = elements.inject({ }, function(result, element) {
+      if (!element.disabled && element.name) {
+        key = element.name; value = $(element).getValue();
+        if (value != null && element.type != 'file' && (element.type != 'submit' || (!submitted &&
+            submit !== false && (!submit || key == submit) && (submitted = true)))) {
+          if (key in result) {
+            if (!Object.isArray(result[key])) result[key] = [result[key]];
+            result[key].push(value);
+          }
+          else result[key] = value;
+        }
+      }
+      return result;
+    });
+
+    return options.hash ? data : Object.toQueryString(data);
+  }
+};
+
+Form.Methods = {
+  serialize: function(form, options) {
+    return Form.serializeElements(Form.getElements(form), options);
+  },
+
+  getElements: function(form) {
+    var elements = $(form).getElementsByTagName('*'),
+        element,
+        arr = [ ],
+        serializers = Form.Element.Serializers;
+    for (var i = 0; element = elements[i]; i++) {
+      arr.push(element);
+    }
+    return arr.inject([], function(elements, child) {
+      if (serializers[child.tagName.toLowerCase()])
+        elements.push(Element.extend(child));
+      return elements;
+    })
+  },
+
+  getInputs: function(form, typeName, name) {
+    form = $(form);
+    var inputs = form.getElementsByTagName('input');
+
+    if (!typeName && !name) return $A(inputs).map(Element.extend);
+
+    for (var i = 0, matchingInputs = [], length = inputs.length; i < length; i++) {
+      var input = inputs[i];
+      if ((typeName && input.type != typeName) || (name && input.name != name))
+        continue;
+      matchingInputs.push(Element.extend(input));
+    }
+
+    return matchingInputs;
+  },
+
+  disable: function(form) {
+    form = $(form);
+    Form.getElements(form).invoke('disable');
+    return form;
+  },
+
+  enable: function(form) {
+    form = $(form);
+    Form.getElements(form).invoke('enable');
+    return form;
+  },
+
+  findFirstElement: function(form) {
+    var elements = $(form).getElements().findAll(function(element) {
+      return 'hidden' != element.type && !element.disabled;
+    });
+    var firstByIndex = elements.findAll(function(element) {
+      return element.hasAttribute('tabIndex') && element.tabIndex >= 0;
+    }).sortBy(function(element) { return element.tabIndex }).first();
+
+    return firstByIndex ? firstByIndex : elements.find(function(element) {
+      return /^(?:input|select|textarea)$/i.test(element.tagName);
+    });
+  },
+
+  focusFirstElement: function(form) {
+    form = $(form);
+    form.findFirstElement().activate();
+    return form;
+  },
+
+  request: function(form, options) {
+    form = $(form), options = Object.clone(options || { });
+
+    var params = options.parameters, action = form.readAttribute('action') || '';
+    if (action.blank()) action = window.location.href;
+    options.parameters = form.serialize(true);
+
+    if (params) {
+      if (Object.isString(params)) params = params.toQueryParams();
+      Object.extend(options.parameters, params);
+    }
+
+    if (form.hasAttribute('method') && !options.method)
+      options.method = form.method;
+
+    return new Ajax.Request(action, options);
+  }
+};
+
+/*--------------------------------------------------------------------------*/
+
+
+Form.Element = {
+  focus: function(element) {
+    $(element).focus();
+    return element;
+  },
+
+  select: function(element) {
+    $(element).select();
+    return element;
+  }
+};
+
+Form.Element.Methods = {
+
+  serialize: function(element) {
+    element = $(element);
+    if (!element.disabled && element.name) {
+      var value = element.getValue();
+      if (value != undefined) {
+        var pair = { };
+        pair[element.name] = value;
+        return Object.toQueryString(pair);
+      }
+    }
+    return '';
+  },
+
+  getValue: function(element) {
+    element = $(element);
+    var method = element.tagName.toLowerCase();
+    return Form.Element.Serializers[method](element);
+  },
+
+  setValue: function(element, value) {
+    element = $(element);
+    var method = element.tagName.toLowerCase();
+    Form.Element.Serializers[method](element, value);
+    return element;
+  },
+
+  clear: function(element) {
+    $(element).value = '';
+    return element;
+  },
+
+  present: function(element) {
+    return $(element).value != '';
+  },
+
+  activate: function(element) {
+    element = $(element);
+    try {
+      element.focus();
+      if (element.select && (element.tagName.toLowerCase() != 'input' ||
+          !(/^(?:button|reset|submit)$/i.test(element.type))))
+        element.select();
+    } catch (e) { }
+    return element;
+  },
+
+  disable: function(element) {
+    element = $(element);
+    element.disabled = true;
+    return element;
+  },
+
+  enable: function(element) {
+    element = $(element);
+    element.disabled = false;
+    return element;
+  }
+};
+
+/*--------------------------------------------------------------------------*/
+
+var Field = Form.Element;
+
+var $F = Form.Element.Methods.getValue;
+
+/*--------------------------------------------------------------------------*/
+
+Form.Element.Serializers = {
+  input: function(element, value) {
+    switch (element.type.toLowerCase()) {
+      case 'checkbox':
+      case 'radio':
+        return Form.Element.Serializers.inputSelector(element, value);
+      default:
+        return Form.Element.Serializers.textarea(element, value);
+    }
+  },
+
+  inputSelector: function(element, value) {
+    if (Object.isUndefined(value)) return element.checked ? element.value : null;
+    else element.checked = !!value;
+  },
+
+  textarea: function(element, value) {
+    if (Object.isUndefined(value)) return element.value;
+    else element.value = value;
+  },
+
+  select: function(element, value) {
+    if (Object.isUndefined(value))
+      return this[element.type == 'select-one' ?
+        'selectOne' : 'selectMany'](element);
+    else {
+      var opt, currentValue, single = !Object.isArray(value);
+      for (var i = 0, length = element.length; i < length; i++) {
+        opt = element.options[i];
+        currentValue = this.optionValue(opt);
+        if (single) {
+          if (currentValue == value) {
+            opt.selected = true;
+            return;
+          }
+        }
+        else opt.selected = value.include(currentValue);
+      }
+    }
+  },
+
+  selectOne: function(element) {
+    var index = element.selectedIndex;
+    return index >= 0 ? this.optionValue(element.options[index]) : null;
+  },
+
+  selectMany: function(element) {
+    var values, length = element.length;
+    if (!length) return null;
+
+    for (var i = 0, values = []; i < length; i++) {
+      var opt = element.options[i];
+      if (opt.selected) values.push(this.optionValue(opt));
+    }
+    return values;
+  },
+
+  optionValue: function(opt) {
+    return Element.extend(opt).hasAttribute('value') ? opt.value : opt.text;
+  }
+};
+
+/*--------------------------------------------------------------------------*/
+
+
+Abstract.TimedObserver = Class.create(PeriodicalExecuter, {
+  initialize: function($super, element, frequency, callback) {
+    $super(callback, frequency);
+    this.element   = $(element);
+    this.lastValue = this.getValue();
+  },
+
+  execute: function() {
+    var value = this.getValue();
+    if (Object.isString(this.lastValue) && Object.isString(value) ?
+        this.lastValue != value : String(this.lastValue) != String(value)) {
+      this.callback(this.element, value);
+      this.lastValue = value;
+    }
+  }
+});
+
+Form.Element.Observer = Class.create(Abstract.TimedObserver, {
+  getValue: function() {
+    return Form.Element.getValue(this.element);
+  }
+});
+
+Form.Observer = Class.create(Abstract.TimedObserver, {
+  getValue: function() {
+    return Form.serialize(this.element);
+  }
+});
+
+/*--------------------------------------------------------------------------*/
+
+Abstract.EventObserver = Class.create({
+  initialize: function(element, callback) {
+    this.element  = $(element);
+    this.callback = callback;
+
+    this.lastValue = this.getValue();
+    if (this.element.tagName.toLowerCase() == 'form')
+      this.registerFormCallbacks();
+    else
+      this.registerCallback(this.element);
+  },
+
+  onElementEvent: function() {
+    var value = this.getValue();
+    if (this.lastValue != value) {
+      this.callback(this.element, value);
+      this.lastValue = value;
+    }
+  },
+
+  registerFormCallbacks: function() {
+    Form.getElements(this.element).each(this.registerCallback, this);
+  },
+
+  registerCallback: function(element) {
+    if (element.type) {
+      switch (element.type.toLowerCase()) {
+        case 'checkbox':
+        case 'radio':
+          Event.observe(element, 'click', this.onElementEvent.bind(this));
+          break;
+        default:
+          Event.observe(element, 'change', this.onElementEvent.bind(this));
+          break;
+      }
+    }
+  }
+});
+
+Form.Element.EventObserver = Class.create(Abstract.EventObserver, {
+  getValue: function() {
+    return Form.Element.getValue(this.element);
+  }
+});
+
+Form.EventObserver = Class.create(Abstract.EventObserver, {
+  getValue: function() {
+    return Form.serialize(this.element);
+  }
+});
+(function() {
+
+  var Event = {
+    KEY_BACKSPACE: 8,
+    KEY_TAB:       9,
+    KEY_RETURN:   13,
+    KEY_ESC:      27,
+    KEY_LEFT:     37,
+    KEY_UP:       38,
+    KEY_RIGHT:    39,
+    KEY_DOWN:     40,
+    KEY_DELETE:   46,
+    KEY_HOME:     36,
+    KEY_END:      35,
+    KEY_PAGEUP:   33,
+    KEY_PAGEDOWN: 34,
+    KEY_INSERT:   45,
+
+    cache: {}
+  };
+
+  var docEl = document.documentElement;
+  var MOUSEENTER_MOUSELEAVE_EVENTS_SUPPORTED = 'onmouseenter' in docEl
+    && 'onmouseleave' in docEl;
+
+  var _isButton;
+  if (Prototype.Browser.IE) {
+    var buttonMap = { 0: 1, 1: 4, 2: 2 };
+    _isButton = function(event, code) {
+      return event.button === buttonMap[code];
+    };
+  } else if (Prototype.Browser.WebKit) {
+    _isButton = function(event, code) {
+      switch (code) {
+        case 0: return event.which == 1 && !event.metaKey;
+        case 1: return event.which == 1 && event.metaKey;
+        default: return false;
+      }
+    };
+  } else {
+    _isButton = function(event, code) {
+      return event.which ? (event.which === code + 1) : (event.button === code);
+    };
+  }
+
+  function isLeftClick(event)   { return _isButton(event, 0) }
+
+  function isMiddleClick(event) { return _isButton(event, 1) }
+
+  function isRightClick(event)  { return _isButton(event, 2) }
+
+  function element(event) {
+    event = Event.extend(event);
+
+    var node = event.target, type = event.type,
+     currentTarget = event.currentTarget;
+
+    if (currentTarget && currentTarget.tagName) {
+      if (type === 'load' || type === 'error' ||
+        (type === 'click' && currentTarget.tagName.toLowerCase() === 'input'
+          && currentTarget.type === 'radio'))
+            node = currentTarget;
+    }
+
+    if (node.nodeType == Node.TEXT_NODE)
+      node = node.parentNode;
+
+    return Element.extend(node);
+  }
+
+  function findElement(event, expression) {
+    var element = Event.element(event);
+    if (!expression) return element;
+    var elements = [element].concat(element.ancestors());
+    return Selector.findElement(elements, expression, 0);
+  }
+
+  function pointer(event) {
+    return { x: pointerX(event), y: pointerY(event) };
+  }
+
+  function pointerX(event) {
+    var docElement = document.documentElement,
+     body = document.body || { scrollLeft: 0 };
+
+    return event.pageX || (event.clientX +
+      (docElement.scrollLeft || body.scrollLeft) -
+      (docElement.clientLeft || 0));
+  }
+
+  function pointerY(event) {
+    var docElement = document.documentElement,
+     body = document.body || { scrollTop: 0 };
+
+    return  event.pageY || (event.clientY +
+       (docElement.scrollTop || body.scrollTop) -
+       (docElement.clientTop || 0));
+  }
+
+
+  function stop(event) {
+    Event.extend(event);
+    event.preventDefault();
+    event.stopPropagation();
+
+    event.stopped = true;
+  }
+
+  Event.Methods = {
+    isLeftClick: isLeftClick,
+    isMiddleClick: isMiddleClick,
+    isRightClick: isRightClick,
+
+    element: element,
+    findElement: findElement,
+
+    pointer: pointer,
+    pointerX: pointerX,
+    pointerY: pointerY,
+
+    stop: stop
+  };
+
+
+  var methods = Object.keys(Event.Methods).inject({ }, function(m, name) {
+    m[name] = Event.Methods[name].methodize();
+    return m;
+  });
+
+  if (Prototype.Browser.IE) {
+    function _relatedTarget(event) {
+      var element;
+      switch (event.type) {
+        case 'mouseover': element = event.fromElement; break;
+        case 'mouseout':  element = event.toElement;   break;
+        default: return null;
+      }
+      return Element.extend(element);
+    }
+
+    Object.extend(methods, {
+      stopPropagation: function() { this.cancelBubble = true },
+      preventDefault:  function() { this.returnValue = false },
+      inspect: function() { return '[object Event]' }
+    });
+
+    Event.extend = function(event, element) {
+      if (!event) return false;
+      if (event._extendedByPrototype) return event;
+
+      event._extendedByPrototype = Prototype.emptyFunction;
+      var pointer = Event.pointer(event);
+
+      Object.extend(event, {
+        target: event.srcElement || element,
+        relatedTarget: _relatedTarget(event),
+        pageX:  pointer.x,
+        pageY:  pointer.y
+      });
+
+      return Object.extend(event, methods);
+    };
+  } else {
+    Event.prototype = window.Event.prototype || document.createEvent('HTMLEvents').__proto__;
+    Object.extend(Event.prototype, methods);
+    Event.extend = Prototype.K;
+  }
+
+  function _createResponder(element, eventName, handler) {
+    var registry = Element.retrieve(element, 'prototype_event_registry');
+
+    if (Object.isUndefined(registry)) {
+      CACHE.push(element);
+      registry = Element.retrieve(element, 'prototype_event_registry', $H());
+    }
+
+    var respondersForEvent = registry.get(eventName);
+    if (Object.isUndefined(respondersForEvent)) {
+      respondersForEvent = [];
+      registry.set(eventName, respondersForEvent);
+    }
+
+    if (respondersForEvent.pluck('handler').include(handler)) return false;
+
+    var responder;
+    if (eventName.include(":")) {
+      responder = function(event) {
+        if (Object.isUndefined(event.eventName))
+          return false;
+
+        if (event.eventName !== eventName)
+          return false;
+
+        Event.extend(event, element);
+        handler.call(element, event);
+      };
+    } else {
+      if (!MOUSEENTER_MOUSELEAVE_EVENTS_SUPPORTED &&
+       (eventName === "mouseenter" || eventName === "mouseleave")) {
+        if (eventName === "mouseenter" || eventName === "mouseleave") {
+          responder = function(event) {
+            Event.extend(event, element);
+
+            var parent = event.relatedTarget;
+            while (parent && parent !== element) {
+              try { parent = parent.parentNode; }
+              catch(e) { parent = element; }
+            }
+
+            if (parent === element) return;
+
+            handler.call(element, event);
+          };
+        }
+      } else {
+        responder = function(event) {
+          Event.extend(event, element);
+          handler.call(element, event);
+        };
+      }
+    }
+
+    responder.handler = handler;
+    respondersForEvent.push(responder);
+    return responder;
+  }
+
+  function _destroyCache() {
+    for (var i = 0, length = CACHE.length; i < length; i++) {
+      Event.stopObserving(CACHE[i]);
+      CACHE[i] = null;
+    }
+  }
+
+  var CACHE = [];
+
+  if (Prototype.Browser.IE)
+    window.attachEvent('onunload', _destroyCache);
+
+  if (Prototype.Browser.WebKit)
+    window.addEventListener('unload', Prototype.emptyFunction, false);
+
+
+  var _getDOMEventName = Prototype.K;
+
+  if (!MOUSEENTER_MOUSELEAVE_EVENTS_SUPPORTED) {
+    _getDOMEventName = function(eventName) {
+      var translations = { mouseenter: "mouseover", mouseleave: "mouseout" };
+      return eventName in translations ? translations[eventName] : eventName;
+    };
+  }
+
+  function observe(element, eventName, handler) {
+    element = $(element);
+
+    var responder = _createResponder(element, eventName, handler);
+
+    if (!responder) return element;
+
+    if (eventName.include(':')) {
+      if (element.addEventListener)
+        element.addEventListener("dataavailable", responder, false);
+      else {
+        element.attachEvent("ondataavailable", responder);
+        element.attachEvent("onfilterchange", responder);
+      }
+    } else {
+      var actualEventName = _getDOMEventName(eventName);
+
+      if (element.addEventListener)
+        element.addEventListener(actualEventName, responder, false);
+      else
+        element.attachEvent("on" + actualEventName, responder);
+    }
+
+    return element;
+  }
+
+  function stopObserving(element, eventName, handler) {
+    element = $(element);
+
+    var registry = Element.retrieve(element, 'prototype_event_registry');
+
+    if (Object.isUndefined(registry)) return element;
+
+    if (eventName && !handler) {
+      var responders = registry.get(eventName);
+
+      if (Object.isUndefined(responders)) return element;
+
+      responders.each( function(r) {
+        Element.stopObserving(element, eventName, r.handler);
+      });
+      return element;
+    } else if (!eventName) {
+      registry.each( function(pair) {
+        var eventName = pair.key, responders = pair.value;
+
+        responders.each( function(r) {
+          Element.stopObserving(element, eventName, r.handler);
+        });
+      });
+      return element;
+    }
+
+    var responders = registry.get(eventName);
+
+    if (!responders) return;
+
+    var responder = responders.find( function(r) { return r.handler === handler; });
+    if (!responder) return element;
+
+    var actualEventName = _getDOMEventName(eventName);
+
+    if (eventName.include(':')) {
+      if (element.removeEventListener)
+        element.removeEventListener("dataavailable", responder, false);
+      else {
+        element.detachEvent("ondataavailable", responder);
+        element.detachEvent("onfilterchange",  responder);
+      }
+    } else {
+      if (element.removeEventListener)
+        element.removeEventListener(actualEventName, responder, false);
+      else
+        element.detachEvent('on' + actualEventName, responder);
+    }
+
+    registry.set(eventName, responders.without(responder));
+
+    return element;
+  }
+
+  function fire(element, eventName, memo, bubble) {
+    element = $(element);
+
+    if (Object.isUndefined(bubble))
+      bubble = true;
+
+    if (element == document && document.createEvent && !element.dispatchEvent)
+      element = document.documentElement;
+
+    var event;
+    if (document.createEvent) {
+      event = document.createEvent('HTMLEvents');
+      event.initEvent('dataavailable', true, true);
+    } else {
+      event = document.createEventObject();
+      event.eventType = bubble ? 'ondataavailable' : 'onfilterchange';
+    }
+
+    event.eventName = eventName;
+    event.memo = memo || { };
+
+    if (document.createEvent)
+      element.dispatchEvent(event);
+    else
+      element.fireEvent(event.eventType, event);
+
+    return Event.extend(event);
+  }
+
+
+  Object.extend(Event, Event.Methods);
+
+  Object.extend(Event, {
+    fire:          fire,
+    observe:       observe,
+    stopObserving: stopObserving
+  });
+
+  Element.addMethods({
+    fire:          fire,
+
+    observe:       observe,
+
+    stopObserving: stopObserving
+  });
+
+  Object.extend(document, {
+    fire:          fire.methodize(),
+
+    observe:       observe.methodize(),
+
+    stopObserving: stopObserving.methodize(),
+
+    loaded:        false
+  });
+
+  if (window.Event) Object.extend(window.Event, Event);
+  else window.Event = Event;
+})();
+
+(function() {
+  /* Support for the DOMContentLoaded event is based on work by Dan Webb,
+     Matthias Miller, Dean Edwards, John Resig, and Diego Perini. */
+
+  var timer;
+
+  function fireContentLoadedEvent() {
+    if (document.loaded) return;
+    if (timer) window.clearTimeout(timer);
+    document.loaded = true;
+    document.fire('dom:loaded');
+  }
+
+  function checkReadyState() {
+    if (document.readyState === 'complete') {
+      document.stopObserving('readystatechange', checkReadyState);
+      fireContentLoadedEvent();
+    }
+  }
+
+  function pollDoScroll() {
+    try { document.documentElement.doScroll('left'); }
+    catch(e) {
+      timer = pollDoScroll.defer();
+      return;
+    }
+    fireContentLoadedEvent();
+  }
+
+  if (document.addEventListener) {
+    document.addEventListener('DOMContentLoaded', fireContentLoadedEvent, false);
+  } else {
+    document.observe('readystatechange', checkReadyState);
+    if (window == top)
+      timer = pollDoScroll.defer();
+  }
+
+  Event.observe(window, 'load', fireContentLoadedEvent);
+})();
+
+Element.addMethods();
+
+/*------------------------------- DEPRECATED -------------------------------*/
+
+Hash.toQueryString = Object.toQueryString;
+
+var Toggle = { display: Element.toggle };
+
+Element.Methods.childOf = Element.Methods.descendantOf;
+
+var Insertion = {
+  Before: function(element, content) {
+    return Element.insert(element, {before:content});
+  },
+
+  Top: function(element, content) {
+    return Element.insert(element, {top:content});
+  },
+
+  Bottom: function(element, content) {
+    return Element.insert(element, {bottom:content});
+  },
+
+  After: function(element, content) {
+    return Element.insert(element, {after:content});
+  }
+};
+
+var $continue = new Error('"throw $continue" is deprecated, use "return" instead');
+
+var Position = {
+  includeScrollOffsets: false,
+
+  prepare: function() {
+    this.deltaX =  window.pageXOffset
+                || document.documentElement.scrollLeft
+                || document.body.scrollLeft
+                || 0;
+    this.deltaY =  window.pageYOffset
+                || document.documentElement.scrollTop
+                || document.body.scrollTop
+                || 0;
+  },
+
+  within: function(element, x, y) {
+    if (this.includeScrollOffsets)
+      return this.withinIncludingScrolloffsets(element, x, y);
+    this.xcomp = x;
+    this.ycomp = y;
+    this.offset = Element.cumulativeOffset(element);
+
+    return (y >= this.offset[1] &&
+            y <  this.offset[1] + element.offsetHeight &&
+            x >= this.offset[0] &&
+            x <  this.offset[0] + element.offsetWidth);
+  },
+
+  withinIncludingScrolloffsets: function(element, x, y) {
+    var offsetcache = Element.cumulativeScrollOffset(element);
+
+    this.xcomp = x + offsetcache[0] - this.deltaX;
+    this.ycomp = y + offsetcache[1] - this.deltaY;
+    this.offset = Element.cumulativeOffset(element);
+
+    return (this.ycomp >= this.offset[1] &&
+            this.ycomp <  this.offset[1] + element.offsetHeight &&
+            this.xcomp >= this.offset[0] &&
+            this.xcomp <  this.offset[0] + element.offsetWidth);
+  },
+
+  overlap: function(mode, element) {
+    if (!mode) return 0;
+    if (mode == 'vertical')
+      return ((this.offset[1] + element.offsetHeight) - this.ycomp) /
+        element.offsetHeight;
+    if (mode == 'horizontal')
+      return ((this.offset[0] + element.offsetWidth) - this.xcomp) /
+        element.offsetWidth;
+  },
+
+
+  cumulativeOffset: Element.Methods.cumulativeOffset,
+
+  positionedOffset: Element.Methods.positionedOffset,
+
+  absolutize: function(element) {
+    Position.prepare();
+    return Element.absolutize(element);
+  },
+
+  relativize: function(element) {
+    Position.prepare();
+    return Element.relativize(element);
+  },
+
+  realOffset: Element.Methods.cumulativeScrollOffset,
+
+  offsetParent: Element.Methods.getOffsetParent,
+
+  page: Element.Methods.viewportOffset,
+
+  clone: function(source, target, options) {
+    options = options || { };
+    return Element.clonePosition(target, source, options);
+  }
+};
+
+/*--------------------------------------------------------------------------*/
+
+if (!document.getElementsByClassName) document.getElementsByClassName = function(instanceMethods){
+  function iter(name) {
+    return name.blank() ? null : "[contains(concat(' ', @class, ' '), ' " + name + " ')]";
+  }
+
+  instanceMethods.getElementsByClassName = Prototype.BrowserFeatures.XPath ?
+  function(element, className) {
+    className = className.toString().strip();
+    var cond = /\s/.test(className) ? $w(className).map(iter).join('') : iter(className);
+    return cond ? document._getElementsByXPath('.//*' + cond, element) : [];
+  } : function(element, className) {
+    className = className.toString().strip();
+    var elements = [], classNames = (/\s/.test(className) ? $w(className) : null);
+    if (!classNames && !className) return elements;
+
+    var nodes = $(element).getElementsByTagName('*');
+    className = ' ' + className + ' ';
+
+    for (var i = 0, child, cn; child = nodes[i]; i++) {
+      if (child.className && (cn = ' ' + child.className + ' ') && (cn.include(className) ||
+          (classNames && classNames.all(function(name) {
+            return !name.toString().blank() && cn.include(' ' + name + ' ');
+          }))))
+        elements.push(Element.extend(child));
+    }
+    return elements;
+  };
+
+  return function(className, parentElement) {
+    return $(parentElement || document.body).getElementsByClassName(className);
+  };
+}(Element.Methods);
+
+/*--------------------------------------------------------------------------*/
+
+Element.ClassNames = Class.create();
+Element.ClassNames.prototype = {
+  initialize: function(element) {
+    this.element = $(element);
+  },
+
+  _each: function(iterator) {
+    this.element.className.split(/\s+/).select(function(name) {
+      return name.length > 0;
+    })._each(iterator);
+  },
+
+  set: function(className) {
+    this.element.className = className;
+  },
+
+  add: function(classNameToAdd) {
+    if (this.include(classNameToAdd)) return;
+    this.set($A(this).concat(classNameToAdd).join(' '));
+  },
+
+  remove: function(classNameToRemove) {
+    if (!this.include(classNameToRemove)) return;
+    this.set($A(this).without(classNameToRemove).join(' '));
+  },
+
+  toString: function() {
+    return $A(this).join(' ');
+  }
+};
+
+Object.extend(Element.ClassNames.prototype, Enumerable);
+
+/*--------------------------------------------------------------------------*/
Index: ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web-data/lib/scriptaculous.js
===================================================================
--- ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web-data/lib/scriptaculous.js	(revision 14969)
+++ ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web-data/lib/scriptaculous.js	(revision 14969)
@@ -0,0 +1,1192 @@
+// script.aculo.us scriptaculous.js v1.8.2, Tue Nov 18 18:30:58 +0100 2008
+
+// Copyright (c) 2005-2008 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+// For details, see the script.aculo.us web site: http://script.aculo.us/
+
+var Scriptaculous = {
+  Version: '1.8.2',
+  require: function(libraryName) {
+    // inserting via DOM fails in Safari 2.0, so brute force approach
+    document.write('<script type="text/javascript" src="'+libraryName+'"><\/script>');
+  },
+  REQUIRED_PROTOTYPE: '1.6.0.3',
+  load: function() {
+    function convertVersionString(versionString) {
+      var v = versionString.replace(/_.*|\./g, '');
+      v = parseInt(v + '0'.times(4-v.length));
+      return versionString.indexOf('_') > -1 ? v-1 : v;
+    }
+
+    if((typeof Prototype=='undefined') ||
+       (typeof Element == 'undefined') ||
+       (typeof Element.Methods=='undefined') ||
+       (convertVersionString(Prototype.Version) <
+        convertVersionString(Scriptaculous.REQUIRED_PROTOTYPE)))
+       throw("script.aculo.us requires the Prototype JavaScript framework >= " +
+        Scriptaculous.REQUIRED_PROTOTYPE);
+
+    var js = /scriptaculous\.js(\?.*)?$/;
+    $$('head script[src]').findAll(function(s) {
+      return s.src.match(js);
+    }).each(function(s) {
+      var path = s.src.replace(js, ''),
+      includes = s.src.match(/\?.*load=([a-z,]*)/);
+      (includes ? includes[1] : 'builder,effects,dragdrop,controls,slider,sound').split(',').each(
+       function(include) { Scriptaculous.require(path+include+'.js') });
+    });
+  }
+};
+
+Scriptaculous.load();
+
+//ADDED BY STEPHAN REICHHOLF - effects.js
+//script.aculo.us effects.js v1.8.2, Tue Nov 18 18:30:58 +0100 2008
+
+//Copyright (c) 2005-2008 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
+//Contributors:
+//Justin Palmer (http://encytemedia.com/)
+//Mark Pilgrim (http://diveintomark.org/)
+//Martin Bialasinki
+//
+//script.aculo.us is freely distributable under the terms of an MIT-style license.
+//For details, see the script.aculo.us web site: http://script.aculo.us/
+
+//converts rgb() and #xxx to #xxxxxx format,
+//returns self (or first argument) if not convertable
+String.prototype.parseColor = function() {
+var color = '#';
+if (this.slice(0,4) == 'rgb(') {
+ var cols = this.slice(4,this.length-1).split(',');
+ var i=0; do { color += parseInt(cols[i]).toColorPart() } while (++i<3);
+} else {
+ if (this.slice(0,1) == '#') {
+   if (this.length==4) for(var i=1;i<4;i++) color += (this.charAt(i) + this.charAt(i)).toLowerCase();
+   if (this.length==7) color = this.toLowerCase();
+ }
+}
+return (color.length==7 ? color : (arguments[0] || this));
+};
+
+/*--------------------------------------------------------------------------*/
+
+Element.collectTextNodes = function(element) {
+return $A($(element).childNodes).collect( function(node) {
+ return (node.nodeType==3 ? node.nodeValue :
+   (node.hasChildNodes() ? Element.collectTextNodes(node) : ''));
+}).flatten().join('');
+};
+
+Element.collectTextNodesIgnoreClass = function(element, className) {
+return $A($(element).childNodes).collect( function(node) {
+ return (node.nodeType==3 ? node.nodeValue :
+   ((node.hasChildNodes() && !Element.hasClassName(node,className)) ?
+     Element.collectTextNodesIgnoreClass(node, className) : ''));
+}).flatten().join('');
+};
+
+Element.setContentZoom = function(element, percent) {
+element = $(element);
+element.setStyle({fontSize: (percent/100) + 'em'});
+if (Prototype.Browser.WebKit) window.scrollBy(0,0);
+return element;
+};
+
+Element.getInlineOpacity = function(element){
+return $(element).style.opacity || '';
+};
+
+Element.forceRerendering = function(element) {
+try {
+ element = $(element);
+ var n = document.createTextNode(' ');
+ element.appendChild(n);
+ element.removeChild(n);
+} catch(e) { }
+};
+
+/*--------------------------------------------------------------------------*/
+
+var Effect = {
+_elementDoesNotExistError: {
+ name: 'ElementDoesNotExistError',
+ message: 'The specified DOM element does not exist, but is required for this effect to operate'
+},
+Transitions: {
+ linear: Prototype.K,
+ sinoidal: function(pos) {
+   return (-Math.cos(pos*Math.PI)/2) + .5;
+ },
+ reverse: function(pos) {
+   return 1-pos;
+ },
+ flicker: function(pos) {
+   var pos = ((-Math.cos(pos*Math.PI)/4) + .75) + Math.random()/4;
+   return pos > 1 ? 1 : pos;
+ },
+ wobble: function(pos) {
+   return (-Math.cos(pos*Math.PI*(9*pos))/2) + .5;
+ },
+ pulse: function(pos, pulses) {
+   return (-Math.cos((pos*((pulses||5)-.5)*2)*Math.PI)/2) + .5;
+ },
+ spring: function(pos) {
+   return 1 - (Math.cos(pos * 4.5 * Math.PI) * Math.exp(-pos * 6));
+ },
+ none: function(pos) {
+   return 0;
+ },
+ full: function(pos) {
+   return 1;
+ }
+},
+DefaultOptions: {
+ duration:   1.0,   // seconds
+ fps:        100,   // 100= assume 66fps max.
+ sync:       false, // true for combining
+ from:       0.0,
+ to:         1.0,
+ delay:      0.0,
+ queue:      'parallel'
+},
+tagifyText: function(element) {
+ var tagifyStyle = 'position:relative';
+ if (Prototype.Browser.IE) tagifyStyle += ';zoom:1';
+
+ element = $(element);
+ $A(element.childNodes).each( function(child) {
+   if (child.nodeType==3) {
+     child.nodeValue.toArray().each( function(character) {
+       element.insertBefore(
+         new Element('span', {style: tagifyStyle}).update(
+           character == ' ' ? String.fromCharCode(160) : character),
+           child);
+     });
+     Element.remove(child);
+   }
+ });
+},
+multiple: function(element, effect) {
+ var elements;
+ if (((typeof element == 'object') ||
+     Object.isFunction(element)) &&
+    (element.length))
+   elements = element;
+ else
+   elements = $(element).childNodes;
+
+ var options = Object.extend({
+   speed: 0.1,
+   delay: 0.0
+ }, arguments[2] || { });
+ var masterDelay = options.delay;
+
+ $A(elements).each( function(element, index) {
+   new effect(element, Object.extend(options, { delay: index * options.speed + masterDelay }));
+ });
+},
+PAIRS: {
+ 'slide':  ['SlideDown','SlideUp'],
+ 'blind':  ['BlindDown','BlindUp'],
+ 'appear': ['Appear','Fade']
+},
+toggle: function(element, effect) {
+ element = $(element);
+ effect = (effect || 'appear').toLowerCase();
+ var options = Object.extend({
+   queue: { position:'end', scope:(element.id || 'global'), limit: 1 }
+ }, arguments[2] || { });
+ Effect[element.visible() ?
+   Effect.PAIRS[effect][1] : Effect.PAIRS[effect][0]](element, options);
+}
+};
+
+Effect.DefaultOptions.transition = Effect.Transitions.sinoidal;
+
+/* ------------- core effects ------------- */
+
+Effect.ScopedQueue = Class.create(Enumerable, {
+initialize: function() {
+ this.effects  = [];
+ this.interval = null;
+},
+_each: function(iterator) {
+ this.effects._each(iterator);
+},
+add: function(effect) {
+ var timestamp = new Date().getTime();
+
+ var position = Object.isString(effect.options.queue) ?
+   effect.options.queue : effect.options.queue.position;
+
+ switch(position) {
+   case 'front':
+     // move unstarted effects after this effect
+     this.effects.findAll(function(e){ return e.state=='idle' }).each( function(e) {
+         e.startOn  += effect.finishOn;
+         e.finishOn += effect.finishOn;
+       });
+     break;
+   case 'with-last':
+     timestamp = this.effects.pluck('startOn').max() || timestamp;
+     break;
+   case 'end':
+     // start effect after last queued effect has finished
+     timestamp = this.effects.pluck('finishOn').max() || timestamp;
+     break;
+ }
+
+ effect.startOn  += timestamp;
+ effect.finishOn += timestamp;
+
+ if (!effect.options.queue.limit || (this.effects.length < effect.options.queue.limit))
+   this.effects.push(effect);
+
+ if (!this.interval)
+   this.interval = setInterval(this.loop.bind(this), 15);
+},
+remove: function(effect) {
+ this.effects = this.effects.reject(function(e) { return e==effect });
+ if (this.effects.length == 0) {
+   clearInterval(this.interval);
+   this.interval = null;
+ }
+},
+loop: function() {
+ var timePos = new Date().getTime();
+ for(var i=0, len=this.effects.length;i<len;i++)
+   this.effects[i] && this.effects[i].loop(timePos);
+}
+});
+
+Effect.Queues = {
+instances: $H(),
+get: function(queueName) {
+ if (!Object.isString(queueName)) return queueName;
+
+ return this.instances.get(queueName) ||
+   this.instances.set(queueName, new Effect.ScopedQueue());
+}
+};
+Effect.Queue = Effect.Queues.get('global');
+
+Effect.Base = Class.create({
+position: null,
+start: function(options) {
+ function codeForEvent(options,eventName){
+   return (
+     (options[eventName+'Internal'] ? 'this.options.'+eventName+'Internal(this);' : '') +
+     (options[eventName] ? 'this.options.'+eventName+'(this);' : '')
+   );
+ }
+ if (options && options.transition === false) options.transition = Effect.Transitions.linear;
+ this.options      = Object.extend(Object.extend({ },Effect.DefaultOptions), options || { });
+ this.currentFrame = 0;
+ this.state        = 'idle';
+ this.startOn      = this.options.delay*1000;
+ this.finishOn     = this.startOn+(this.options.duration*1000);
+ this.fromToDelta  = this.options.to-this.options.from;
+ this.totalTime    = this.finishOn-this.startOn;
+ this.totalFrames  = this.options.fps*this.options.duration;
+
+ this.render = (function() {
+   function dispatch(effect, eventName) {
+     if (effect.options[eventName + 'Internal'])
+       effect.options[eventName + 'Internal'](effect);
+     if (effect.options[eventName])
+       effect.options[eventName](effect);
+   }
+
+   return function(pos) {
+     if (this.state === "idle") {
+       this.state = "running";
+       dispatch(this, 'beforeSetup');
+       if (this.setup) this.setup();
+       dispatch(this, 'afterSetup');
+     }
+     if (this.state === "running") {
+       pos = (this.options.transition(pos) * this.fromToDelta) + this.options.from;
+       this.position = pos;
+       dispatch(this, 'beforeUpdate');
+       if (this.update) this.update(pos);
+       dispatch(this, 'afterUpdate');
+     }
+   };
+ })();
+
+ this.event('beforeStart');
+ if (!this.options.sync)
+   Effect.Queues.get(Object.isString(this.options.queue) ?
+     'global' : this.options.queue.scope).add(this);
+},
+loop: function(timePos) {
+ if (timePos >= this.startOn) {
+   if (timePos >= this.finishOn) {
+     this.render(1.0);
+     this.cancel();
+     this.event('beforeFinish');
+     if (this.finish) this.finish();
+     this.event('afterFinish');
+     return;
+   }
+   var pos   = (timePos - this.startOn) / this.totalTime,
+       frame = (pos * this.totalFrames).round();
+   if (frame > this.currentFrame) {
+     this.render(pos);
+     this.currentFrame = frame;
+   }
+ }
+},
+cancel: function() {
+ if (!this.options.sync)
+   Effect.Queues.get(Object.isString(this.options.queue) ?
+     'global' : this.options.queue.scope).remove(this);
+ this.state = 'finished';
+},
+event: function(eventName) {
+ if (this.options[eventName + 'Internal']) this.options[eventName + 'Internal'](this);
+ if (this.options[eventName]) this.options[eventName](this);
+},
+inspect: function() {
+ var data = $H();
+ for(property in this)
+   if (!Object.isFunction(this[property])) data.set(property, this[property]);
+ return '#<Effect:' + data.inspect() + ',options:' + $H(this.options).inspect() + '>';
+}
+});
+
+Effect.Parallel = Class.create(Effect.Base, {
+initialize: function(effects) {
+ this.effects = effects || [];
+ this.start(arguments[1]);
+},
+update: function(position) {
+ this.effects.invoke('render', position);
+},
+finish: function(position) {
+ this.effects.each( function(effect) {
+   effect.render(1.0);
+   effect.cancel();
+   effect.event('beforeFinish');
+   if (effect.finish) effect.finish(position);
+   effect.event('afterFinish');
+ });
+}
+});
+
+Effect.Tween = Class.create(Effect.Base, {
+initialize: function(object, from, to) {
+ object = Object.isString(object) ? $(object) : object;
+ var args = $A(arguments), method = args.last(),
+   options = args.length == 5 ? args[3] : null;
+ this.method = Object.isFunction(method) ? method.bind(object) :
+   Object.isFunction(object[method]) ? object[method].bind(object) :
+   function(value) { object[method] = value };
+ this.start(Object.extend({ from: from, to: to }, options || { }));
+},
+update: function(position) {
+ this.method(position);
+}
+});
+
+Effect.Event = Class.create(Effect.Base, {
+initialize: function() {
+ this.start(Object.extend({ duration: 0 }, arguments[0] || { }));
+},
+update: Prototype.emptyFunction
+});
+
+Effect.Opacity = Class.create(Effect.Base, {
+initialize: function(element) {
+ this.element = $(element);
+ if (!this.element) throw(Effect._elementDoesNotExistError);
+ // make this work on IE on elements without 'layout'
+ if (Prototype.Browser.IE && (!this.element.currentStyle.hasLayout))
+   this.element.setStyle({zoom: 1});
+ var options = Object.extend({
+   from: this.element.getOpacity() || 0.0,
+   to:   1.0
+ }, arguments[1] || { });
+ this.start(options);
+},
+update: function(position) {
+ this.element.setOpacity(position);
+}
+});
+
+Effect.Move = Class.create(Effect.Base, {
+initialize: function(element) {
+ this.element = $(element);
+ if (!this.element) throw(Effect._elementDoesNotExistError);
+ var options = Object.extend({
+   x:    0,
+   y:    0,
+   mode: 'relative'
+ }, arguments[1] || { });
+ this.start(options);
+},
+setup: function() {
+ this.element.makePositioned();
+ this.originalLeft = parseFloat(this.element.getStyle('left') || '0');
+ this.originalTop  = parseFloat(this.element.getStyle('top')  || '0');
+ if (this.options.mode == 'absolute') {
+   this.options.x = this.options.x - this.originalLeft;
+   this.options.y = this.options.y - this.originalTop;
+ }
+},
+update: function(position) {
+ this.element.setStyle({
+   left: (this.options.x  * position + this.originalLeft).round() + 'px',
+   top:  (this.options.y  * position + this.originalTop).round()  + 'px'
+ });
+}
+});
+
+//for backwards compatibility
+Effect.MoveBy = function(element, toTop, toLeft) {
+return new Effect.Move(element,
+ Object.extend({ x: toLeft, y: toTop }, arguments[3] || { }));
+};
+
+Effect.Scale = Class.create(Effect.Base, {
+initialize: function(element, percent) {
+ this.element = $(element);
+ if (!this.element) throw(Effect._elementDoesNotExistError);
+ var options = Object.extend({
+   scaleX: true,
+   scaleY: true,
+   scaleContent: true,
+   scaleFromCenter: false,
+   scaleMode: 'box',        // 'box' or 'contents' or { } with provided values
+   scaleFrom: 100.0,
+   scaleTo:   percent
+ }, arguments[2] || { });
+ this.start(options);
+},
+setup: function() {
+ this.restoreAfterFinish = this.options.restoreAfterFinish || false;
+ this.elementPositioning = this.element.getStyle('position');
+
+ this.originalStyle = { };
+ ['top','left','width','height','fontSize'].each( function(k) {
+   this.originalStyle[k] = this.element.style[k];
+ }.bind(this));
+
+ this.originalTop  = this.element.offsetTop;
+ this.originalLeft = this.element.offsetLeft;
+
+ var fontSize = this.element.getStyle('font-size') || '100%';
+ ['em','px','%','pt'].each( function(fontSizeType) {
+   if (fontSize.indexOf(fontSizeType)>0) {
+     this.fontSize     = parseFloat(fontSize);
+     this.fontSizeType = fontSizeType;
+   }
+ }.bind(this));
+
+ this.factor = (this.options.scaleTo - this.options.scaleFrom)/100;
+
+ this.dims = null;
+ if (this.options.scaleMode=='box')
+   this.dims = [this.element.offsetHeight, this.element.offsetWidth];
+ if (/^content/.test(this.options.scaleMode))
+   this.dims = [this.element.scrollHeight, this.element.scrollWidth];
+ if (!this.dims)
+   this.dims = [this.options.scaleMode.originalHeight,
+                this.options.scaleMode.originalWidth];
+},
+update: function(position) {
+ var currentScale = (this.options.scaleFrom/100.0) + (this.factor * position);
+ if (this.options.scaleContent && this.fontSize)
+   this.element.setStyle({fontSize: this.fontSize * currentScale + this.fontSizeType });
+ this.setDimensions(this.dims[0] * currentScale, this.dims[1] * currentScale);
+},
+finish: function(position) {
+ if (this.restoreAfterFinish) this.element.setStyle(this.originalStyle);
+},
+setDimensions: function(height, width) {
+ var d = { };
+ if (this.options.scaleX) d.width = width.round() + 'px';
+ if (this.options.scaleY) d.height = height.round() + 'px';
+ if (this.options.scaleFromCenter) {
+   var topd  = (height - this.dims[0])/2;
+   var leftd = (width  - this.dims[1])/2;
+   if (this.elementPositioning == 'absolute') {
+     if (this.options.scaleY) d.top = this.originalTop-topd + 'px';
+     if (this.options.scaleX) d.left = this.originalLeft-leftd + 'px';
+   } else {
+     if (this.options.scaleY) d.top = -topd + 'px';
+     if (this.options.scaleX) d.left = -leftd + 'px';
+   }
+ }
+ this.element.setStyle(d);
+}
+});
+
+Effect.Highlight = Class.create(Effect.Base, {
+initialize: function(element) {
+ this.element = $(element);
+ if (!this.element) throw(Effect._elementDoesNotExistError);
+ var options = Object.extend({ startcolor: '#ffff99' }, arguments[1] || { });
+ this.start(options);
+},
+setup: function() {
+ // Prevent executing on elements not in the layout flow
+ if (this.element.getStyle('display')=='none') { this.cancel(); return; }
+ // Disable background image during the effect
+ this.oldStyle = { };
+ if (!this.options.keepBackgroundImage) {
+   this.oldStyle.backgroundImage = this.element.getStyle('background-image');
+   this.element.setStyle({backgroundImage: 'none'});
+ }
+ if (!this.options.endcolor)
+   this.options.endcolor = this.element.getStyle('background-color').parseColor('#ffffff');
+ if (!this.options.restorecolor)
+   this.options.restorecolor = this.element.getStyle('background-color');
+ // init color calculations
+ this._base  = $R(0,2).map(function(i){ return parseInt(this.options.startcolor.slice(i*2+1,i*2+3),16) }.bind(this));
+ this._delta = $R(0,2).map(function(i){ return parseInt(this.options.endcolor.slice(i*2+1,i*2+3),16)-this._base[i] }.bind(this));
+},
+update: function(position) {
+ this.element.setStyle({backgroundColor: $R(0,2).inject('#',function(m,v,i){
+   return m+((this._base[i]+(this._delta[i]*position)).round().toColorPart()); }.bind(this)) });
+},
+finish: function() {
+ this.element.setStyle(Object.extend(this.oldStyle, {
+   backgroundColor: this.options.restorecolor
+ }));
+}
+});
+
+Effect.ScrollTo = function(element) {
+var options = arguments[1] || { },
+scrollOffsets = document.viewport.getScrollOffsets(),
+elementOffsets = $(element).cumulativeOffset();
+
+if (options.offset) elementOffsets[1] += options.offset;
+
+return new Effect.Tween(null,
+ scrollOffsets.top,
+ elementOffsets[1],
+ options,
+ function(p){ scrollTo(scrollOffsets.left, p.round()); }
+);
+};
+
+/* ------------- combination effects ------------- */
+
+Effect.Fade = function(element) {
+element = $(element);
+var oldOpacity = element.getInlineOpacity();
+var options = Object.extend({
+ from: element.getOpacity() || 1.0,
+ to:   0.0,
+ afterFinishInternal: function(effect) {
+   if (effect.options.to!=0) return;
+   effect.element.hide().setStyle({opacity: oldOpacity});
+ }
+}, arguments[1] || { });
+return new Effect.Opacity(element,options);
+};
+
+Effect.Appear = function(element) {
+element = $(element);
+var options = Object.extend({
+from: (element.getStyle('display') == 'none' ? 0.0 : element.getOpacity() || 0.0),
+to:   1.0,
+// force Safari to render floated elements properly
+afterFinishInternal: function(effect) {
+ effect.element.forceRerendering();
+},
+beforeSetup: function(effect) {
+ effect.element.setOpacity(effect.options.from).show();
+}}, arguments[1] || { });
+return new Effect.Opacity(element,options);
+};
+
+Effect.Puff = function(element) {
+element = $(element);
+var oldStyle = {
+ opacity: element.getInlineOpacity(),
+ position: element.getStyle('position'),
+ top:  element.style.top,
+ left: element.style.left,
+ width: element.style.width,
+ height: element.style.height
+};
+return new Effect.Parallel(
+[ new Effect.Scale(element, 200,
+   { sync: true, scaleFromCenter: true, scaleContent: true, restoreAfterFinish: true }),
+  new Effect.Opacity(element, { sync: true, to: 0.0 } ) ],
+  Object.extend({ duration: 1.0,
+   beforeSetupInternal: function(effect) {
+     Position.absolutize(effect.effects[0].element);
+   },
+   afterFinishInternal: function(effect) {
+      effect.effects[0].element.hide().setStyle(oldStyle); }
+  }, arguments[1] || { })
+);
+};
+
+Effect.BlindUp = function(element) {
+element = $(element);
+element.makeClipping();
+return new Effect.Scale(element, 0,
+ Object.extend({ scaleContent: false,
+   scaleX: false,
+   restoreAfterFinish: true,
+   afterFinishInternal: function(effect) {
+     effect.element.hide().undoClipping();
+   }
+ }, arguments[1] || { })
+);
+};
+
+Effect.BlindDown = function(element) {
+element = $(element);
+var elementDimensions = element.getDimensions();
+return new Effect.Scale(element, 100, Object.extend({
+ scaleContent: false,
+ scaleX: false,
+ scaleFrom: 0,
+ scaleMode: {originalHeight: elementDimensions.height, originalWidth: elementDimensions.width},
+ restoreAfterFinish: true,
+ afterSetup: function(effect) {
+   effect.element.makeClipping().setStyle({height: '0px'}).show();
+ },
+ afterFinishInternal: function(effect) {
+   effect.element.undoClipping();
+ }
+}, arguments[1] || { }));
+};
+
+Effect.SwitchOff = function(element) {
+element = $(element);
+var oldOpacity = element.getInlineOpacity();
+return new Effect.Appear(element, Object.extend({
+ duration: 0.4,
+ from: 0,
+ transition: Effect.Transitions.flicker,
+ afterFinishInternal: function(effect) {
+   new Effect.Scale(effect.element, 1, {
+     duration: 0.3, scaleFromCenter: true,
+     scaleX: false, scaleContent: false, restoreAfterFinish: true,
+     beforeSetup: function(effect) {
+       effect.element.makePositioned().makeClipping();
+     },
+     afterFinishInternal: function(effect) {
+       effect.element.hide().undoClipping().undoPositioned().setStyle({opacity: oldOpacity});
+     }
+   });
+ }
+}, arguments[1] || { }));
+};
+
+Effect.DropOut = function(element) {
+element = $(element);
+var oldStyle = {
+ top: element.getStyle('top'),
+ left: element.getStyle('left'),
+ opacity: element.getInlineOpacity() };
+return new Effect.Parallel(
+ [ new Effect.Move(element, {x: 0, y: 100, sync: true }),
+   new Effect.Opacity(element, { sync: true, to: 0.0 }) ],
+ Object.extend(
+   { duration: 0.5,
+     beforeSetup: function(effect) {
+       effect.effects[0].element.makePositioned();
+     },
+     afterFinishInternal: function(effect) {
+       effect.effects[0].element.hide().undoPositioned().setStyle(oldStyle);
+     }
+   }, arguments[1] || { }));
+};
+
+Effect.Shake = function(element) {
+element = $(element);
+var options = Object.extend({
+ distance: 20,
+ duration: 0.5
+}, arguments[1] || {});
+var distance = parseFloat(options.distance);
+var split = parseFloat(options.duration) / 10.0;
+var oldStyle = {
+ top: element.getStyle('top'),
+ left: element.getStyle('left') };
+ return new Effect.Move(element,
+   { x:  distance, y: 0, duration: split, afterFinishInternal: function(effect) {
+ new Effect.Move(effect.element,
+   { x: -distance*2, y: 0, duration: split*2,  afterFinishInternal: function(effect) {
+ new Effect.Move(effect.element,
+   { x:  distance*2, y: 0, duration: split*2,  afterFinishInternal: function(effect) {
+ new Effect.Move(effect.element,
+   { x: -distance*2, y: 0, duration: split*2,  afterFinishInternal: function(effect) {
+ new Effect.Move(effect.element,
+   { x:  distance*2, y: 0, duration: split*2,  afterFinishInternal: function(effect) {
+ new Effect.Move(effect.element,
+   { x: -distance, y: 0, duration: split, afterFinishInternal: function(effect) {
+     effect.element.undoPositioned().setStyle(oldStyle);
+}}); }}); }}); }}); }}); }});
+};
+
+Effect.SlideDown = function(element) {
+element = $(element).cleanWhitespace();
+// SlideDown need to have the content of the element wrapped in a container element with fixed height!
+var oldInnerBottom = element.down().getStyle('bottom');
+var elementDimensions = element.getDimensions();
+return new Effect.Scale(element, 100, Object.extend({
+ scaleContent: false,
+ scaleX: false,
+ scaleFrom: window.opera ? 0 : 1,
+ scaleMode: {originalHeight: elementDimensions.height, originalWidth: elementDimensions.width},
+ restoreAfterFinish: true,
+ afterSetup: function(effect) {
+   effect.element.makePositioned();
+   effect.element.down().makePositioned();
+   if (window.opera) effect.element.setStyle({top: ''});
+   effect.element.makeClipping().setStyle({height: '0px'}).show();
+ },
+ afterUpdateInternal: function(effect) {
+   effect.element.down().setStyle({bottom:
+     (effect.dims[0] - effect.element.clientHeight) + 'px' });
+ },
+ afterFinishInternal: function(effect) {
+   effect.element.undoClipping().undoPositioned();
+   effect.element.down().undoPositioned().setStyle({bottom: oldInnerBottom}); }
+ }, arguments[1] || { })
+);
+};
+
+Effect.SlideUp = function(element) {
+element = $(element).cleanWhitespace();
+var oldInnerBottom = element.down().getStyle('bottom');
+var elementDimensions = element.getDimensions();
+return new Effect.Scale(element, window.opera ? 0 : 1,
+Object.extend({ scaleContent: false,
+ scaleX: false,
+ scaleMode: 'box',
+ scaleFrom: 100,
+ scaleMode: {originalHeight: elementDimensions.height, originalWidth: elementDimensions.width},
+ restoreAfterFinish: true,
+ afterSetup: function(effect) {
+   effect.element.makePositioned();
+   effect.element.down().makePositioned();
+   if (window.opera) effect.element.setStyle({top: ''});
+   effect.element.makeClipping().show();
+ },
+ afterUpdateInternal: function(effect) {
+   effect.element.down().setStyle({bottom:
+     (effect.dims[0] - effect.element.clientHeight) + 'px' });
+ },
+ afterFinishInternal: function(effect) {
+   effect.element.hide().undoClipping().undoPositioned();
+   effect.element.down().undoPositioned().setStyle({bottom: oldInnerBottom});
+ }
+}, arguments[1] || { })
+);
+};
+
+//Bug in opera makes the TD containing this element expand for a instance after finish
+Effect.Squish = function(element) {
+return new Effect.Scale(element, window.opera ? 1 : 0, {
+ restoreAfterFinish: true,
+ beforeSetup: function(effect) {
+   effect.element.makeClipping();
+ },
+ afterFinishInternal: function(effect) {
+   effect.element.hide().undoClipping();
+ }
+});
+};
+
+Effect.Grow = function(element) {
+element = $(element);
+var options = Object.extend({
+ direction: 'center',
+ moveTransition: Effect.Transitions.sinoidal,
+ scaleTransition: Effect.Transitions.sinoidal,
+ opacityTransition: Effect.Transitions.full
+}, arguments[1] || { });
+var oldStyle = {
+ top: element.style.top,
+ left: element.style.left,
+ height: element.style.height,
+ width: element.style.width,
+ opacity: element.getInlineOpacity() };
+
+var dims = element.getDimensions();
+var initialMoveX, initialMoveY;
+var moveX, moveY;
+
+switch (options.direction) {
+ case 'top-left':
+   initialMoveX = initialMoveY = moveX = moveY = 0;
+   break;
+ case 'top-right':
+   initialMoveX = dims.width;
+   initialMoveY = moveY = 0;
+   moveX = -dims.width;
+   break;
+ case 'bottom-left':
+   initialMoveX = moveX = 0;
+   initialMoveY = dims.height;
+   moveY = -dims.height;
+   break;
+ case 'bottom-right':
+   initialMoveX = dims.width;
+   initialMoveY = dims.height;
+   moveX = -dims.width;
+   moveY = -dims.height;
+   break;
+ case 'center':
+   initialMoveX = dims.width / 2;
+   initialMoveY = dims.height / 2;
+   moveX = -dims.width / 2;
+   moveY = -dims.height / 2;
+   break;
+}
+
+return new Effect.Move(element, {
+ x: initialMoveX,
+ y: initialMoveY,
+ duration: 0.01,
+ beforeSetup: function(effect) {
+   effect.element.hide().makeClipping().makePositioned();
+ },
+ afterFinishInternal: function(effect) {
+   new Effect.Parallel(
+     [ new Effect.Opacity(effect.element, { sync: true, to: 1.0, from: 0.0, transition: options.opacityTransition }),
+       new Effect.Move(effect.element, { x: moveX, y: moveY, sync: true, transition: options.moveTransition }),
+       new Effect.Scale(effect.element, 100, {
+         scaleMode: { originalHeight: dims.height, originalWidth: dims.width },
+         sync: true, scaleFrom: window.opera ? 1 : 0, transition: options.scaleTransition, restoreAfterFinish: true})
+     ], Object.extend({
+          beforeSetup: function(effect) {
+            effect.effects[0].element.setStyle({height: '0px'}).show();
+          },
+          afterFinishInternal: function(effect) {
+            effect.effects[0].element.undoClipping().undoPositioned().setStyle(oldStyle);
+          }
+        }, options)
+   );
+ }
+});
+};
+
+Effect.Shrink = function(element) {
+element = $(element);
+var options = Object.extend({
+ direction: 'center',
+ moveTransition: Effect.Transitions.sinoidal,
+ scaleTransition: Effect.Transitions.sinoidal,
+ opacityTransition: Effect.Transitions.none
+}, arguments[1] || { });
+var oldStyle = {
+ top: element.style.top,
+ left: element.style.left,
+ height: element.style.height,
+ width: element.style.width,
+ opacity: element.getInlineOpacity() };
+
+var dims = element.getDimensions();
+var moveX, moveY;
+
+switch (options.direction) {
+ case 'top-left':
+   moveX = moveY = 0;
+   break;
+ case 'top-right':
+   moveX = dims.width;
+   moveY = 0;
+   break;
+ case 'bottom-left':
+   moveX = 0;
+   moveY = dims.height;
+   break;
+ case 'bottom-right':
+   moveX = dims.width;
+   moveY = dims.height;
+   break;
+ case 'center':
+   moveX = dims.width / 2;
+   moveY = dims.height / 2;
+   break;
+}
+
+return new Effect.Parallel(
+ [ new Effect.Opacity(element, { sync: true, to: 0.0, from: 1.0, transition: options.opacityTransition }),
+   new Effect.Scale(element, window.opera ? 1 : 0, { sync: true, transition: options.scaleTransition, restoreAfterFinish: true}),
+   new Effect.Move(element, { x: moveX, y: moveY, sync: true, transition: options.moveTransition })
+ ], Object.extend({
+      beforeStartInternal: function(effect) {
+        effect.effects[0].element.makePositioned().makeClipping();
+      },
+      afterFinishInternal: function(effect) {
+        effect.effects[0].element.hide().undoClipping().undoPositioned().setStyle(oldStyle); }
+    }, options)
+);
+};
+
+Effect.Pulsate = function(element) {
+element = $(element);
+var options    = arguments[1] || { },
+ oldOpacity = element.getInlineOpacity(),
+ transition = options.transition || Effect.Transitions.linear,
+ reverser   = function(pos){
+   return 1 - transition((-Math.cos((pos*(options.pulses||5)*2)*Math.PI)/2) + .5);
+ };
+
+return new Effect.Opacity(element,
+ Object.extend(Object.extend({  duration: 2.0, from: 0,
+   afterFinishInternal: function(effect) { effect.element.setStyle({opacity: oldOpacity}); }
+ }, options), {transition: reverser}));
+};
+
+Effect.Fold = function(element) {
+element = $(element);
+var oldStyle = {
+ top: element.style.top,
+ left: element.style.left,
+ width: element.style.width,
+ height: element.style.height };
+element.makeClipping();
+return new Effect.Scale(element, 5, Object.extend({
+ scaleContent: false,
+ scaleX: false,
+ afterFinishInternal: function(effect) {
+ new Effect.Scale(element, 1, {
+   scaleContent: false,
+   scaleY: false,
+   afterFinishInternal: function(effect) {
+     effect.element.hide().undoClipping().setStyle(oldStyle);
+   } });
+}}, arguments[1] || { }));
+};
+
+Effect.Morph = Class.create(Effect.Base, {
+initialize: function(element) {
+ this.element = $(element);
+ if (!this.element) throw(Effect._elementDoesNotExistError);
+ var options = Object.extend({
+   style: { }
+ }, arguments[1] || { });
+
+ if (!Object.isString(options.style)) this.style = $H(options.style);
+ else {
+   if (options.style.include(':'))
+     this.style = options.style.parseStyle();
+   else {
+     this.element.addClassName(options.style);
+     this.style = $H(this.element.getStyles());
+     this.element.removeClassName(options.style);
+     var css = this.element.getStyles();
+     this.style = this.style.reject(function(style) {
+       return style.value == css[style.key];
+     });
+     options.afterFinishInternal = function(effect) {
+       effect.element.addClassName(effect.options.style);
+       effect.transforms.each(function(transform) {
+         effect.element.style[transform.style] = '';
+       });
+     };
+   }
+ }
+ this.start(options);
+},
+
+setup: function(){
+ function parseColor(color){
+   if (!color || ['rgba(0, 0, 0, 0)','transparent'].include(color)) color = '#ffffff';
+   color = color.parseColor();
+   return $R(0,2).map(function(i){
+     return parseInt( color.slice(i*2+1,i*2+3), 16 );
+   });
+ }
+ this.transforms = this.style.map(function(pair){
+   var property = pair[0], value = pair[1], unit = null;
+
+   if (value.parseColor('#zzzzzz') != '#zzzzzz') {
+     value = value.parseColor();
+     unit  = 'color';
+   } else if (property == 'opacity') {
+     value = parseFloat(value);
+     if (Prototype.Browser.IE && (!this.element.currentStyle.hasLayout))
+       this.element.setStyle({zoom: 1});
+   } else if (Element.CSS_LENGTH.test(value)) {
+       var components = value.match(/^([\+\-]?[0-9\.]+)(.*)$/);
+       value = parseFloat(components[1]);
+       unit = (components.length == 3) ? components[2] : null;
+   }
+
+   var originalValue = this.element.getStyle(property);
+   return {
+     style: property.camelize(),
+     originalValue: unit=='color' ? parseColor(originalValue) : parseFloat(originalValue || 0),
+     targetValue: unit=='color' ? parseColor(value) : value,
+     unit: unit
+   };
+ }.bind(this)).reject(function(transform){
+   return (
+     (transform.originalValue == transform.targetValue) ||
+     (
+       transform.unit != 'color' &&
+       (isNaN(transform.originalValue) || isNaN(transform.targetValue))
+     )
+   );
+ });
+},
+update: function(position) {
+ var style = { }, transform, i = this.transforms.length;
+ while(i--)
+   style[(transform = this.transforms[i]).style] =
+     transform.unit=='color' ? '#'+
+       (Math.round(transform.originalValue[0]+
+         (transform.targetValue[0]-transform.originalValue[0])*position)).toColorPart() +
+       (Math.round(transform.originalValue[1]+
+         (transform.targetValue[1]-transform.originalValue[1])*position)).toColorPart() +
+       (Math.round(transform.originalValue[2]+
+         (transform.targetValue[2]-transform.originalValue[2])*position)).toColorPart() :
+     (transform.originalValue +
+       (transform.targetValue - transform.originalValue) * position).toFixed(3) +
+         (transform.unit === null ? '' : transform.unit);
+ this.element.setStyle(style, true);
+}
+});
+
+Effect.Transform = Class.create({
+initialize: function(tracks){
+ this.tracks  = [];
+ this.options = arguments[1] || { };
+ this.addTracks(tracks);
+},
+addTracks: function(tracks){
+ tracks.each(function(track){
+   track = $H(track);
+   var data = track.values().first();
+   this.tracks.push($H({
+     ids:     track.keys().first(),
+     effect:  Effect.Morph,
+     options: { style: data }
+   }));
+ }.bind(this));
+ return this;
+},
+play: function(){
+ return new Effect.Parallel(
+   this.tracks.map(function(track){
+     var ids = track.get('ids'), effect = track.get('effect'), options = track.get('options');
+     var elements = [$(ids) || $$(ids)].flatten();
+     return elements.map(function(e){ return new effect(e, Object.extend({ sync:true }, options)) });
+   }).flatten(),
+   this.options
+ );
+}
+});
+
+Element.CSS_PROPERTIES = $w(
+'backgroundColor backgroundPosition borderBottomColor borderBottomStyle ' +
+'borderBottomWidth borderLeftColor borderLeftStyle borderLeftWidth ' +
+'borderRightColor borderRightStyle borderRightWidth borderSpacing ' +
+'borderTopColor borderTopStyle borderTopWidth bottom clip color ' +
+'fontSize fontWeight height left letterSpacing lineHeight ' +
+'marginBottom marginLeft marginRight marginTop markerOffset maxHeight '+
+'maxWidth minHeight minWidth opacity outlineColor outlineOffset ' +
+'outlineWidth paddingBottom paddingLeft paddingRight paddingTop ' +
+'right textIndent top width wordSpacing zIndex');
+
+Element.CSS_LENGTH = /^(([\+\-]?[0-9\.]+)(em|ex|px|in|cm|mm|pt|pc|\%))|0$/;
+
+String.__parseStyleElement = document.createElement('div');
+String.prototype.parseStyle = function(){
+var style, styleRules = $H();
+if (Prototype.Browser.WebKit)
+ style = new Element('div',{style:this}).style;
+else {
+ String.__parseStyleElement.innerHTML = '<div style="' + this + '"></div>';
+ style = String.__parseStyleElement.childNodes[0].style;
+}
+
+Element.CSS_PROPERTIES.each(function(property){
+ if (style[property]) styleRules.set(property, style[property]);
+});
+
+if (Prototype.Browser.IE && this.include('opacity'))
+ styleRules.set('opacity', this.match(/opacity:\s*((?:0|1)?(?:\.\d*)?)/)[1]);
+
+return styleRules;
+};
+
+if (document.defaultView && document.defaultView.getComputedStyle) {
+Element.getStyles = function(element) {
+ var css = document.defaultView.getComputedStyle($(element), null);
+ return Element.CSS_PROPERTIES.inject({ }, function(styles, property) {
+   styles[property] = css[property];
+   return styles;
+ });
+};
+} else {
+Element.getStyles = function(element) {
+ element = $(element);
+ var css = element.currentStyle, styles;
+ styles = Element.CSS_PROPERTIES.inject({ }, function(results, property) {
+   results[property] = css[property];
+   return results;
+ });
+ if (!styles.opacity) styles.opacity = element.getOpacity();
+ return styles;
+};
+}
+
+Effect.Methods = {
+morph: function(element, style) {
+ element = $(element);
+ new Effect.Morph(element, Object.extend({ style: style }, arguments[2] || { }));
+ return element;
+},
+visualEffect: function(element, effect, options) {
+ element = $(element);
+ var s = effect.dasherize().camelize(), klass = s.charAt(0).toUpperCase() + s.substring(1);
+ new Effect[klass](element, options);
+ return element;
+},
+highlight: function(element, options) {
+ element = $(element);
+ new Effect.Highlight(element, options);
+ return element;
+}
+};
+
+$w('fade appear grow shrink fold blindUp blindDown slideUp slideDown '+
+'pulsate shake puff squish switchOff dropOut').each(
+function(effect) {
+ Effect.Methods[effect] = function(element, options){
+   element = $(element);
+   Effect[effect.charAt(0).toUpperCase() + effect.substring(1)](element, options);
+   return element;
+ };
+}
+);
+
+$w('getInlineOpacity forceRerendering setContentZoom collectTextNodes collectTextNodesIgnoreClass getStyles').each(
+function(f) { Effect.Methods[f] = Element[f]; }
+);
+
+Element.addMethods(Effect.Methods);
Index: ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web-data/lib/trimpath-template-1.0.38.js
===================================================================
--- ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web-data/lib/trimpath-template-1.0.38.js	(revision 14969)
+++ ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web-data/lib/trimpath-template-1.0.38.js	(revision 14969)
@@ -0,0 +1,397 @@
+/**
+ * TrimPath Template. Release 1.0.38.
+ * Copyright (C) 2004, 2005 Metaha.
+ * 
+ * TrimPath Template is licensed under the GNU General Public License
+ * and the Apache License, Version 2.0, as follows:
+ *
+ * This program is free software; you can redistribute it and/or 
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * 
+ * This program is distributed WITHOUT ANY WARRANTY; without even the 
+ * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
+ * See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var TrimPath;
+
+// TODO: Debugging mode vs stop-on-error mode - runtime flag.
+// TODO: Handle || (or) characters and backslashes.
+// TODO: Add more modifiers.
+
+(function() {               // Using a closure to keep global namespace clean.
+    if (TrimPath == null)
+        TrimPath = new Object();
+    if (TrimPath.evalEx == null)
+        TrimPath.evalEx = function(src) { return eval(src); };
+
+    var UNDEFINED;
+    if (Array.prototype.pop == null)  // IE 5.x fix from Igor Poteryaev.
+        Array.prototype.pop = function() {
+            if (this.length === 0) {return UNDEFINED;}
+            return this[--this.length];
+        };
+    if (Array.prototype.push == null) // IE 5.x fix from Igor Poteryaev.
+        Array.prototype.push = function() {
+            for (var i = 0; i < arguments.length; ++i) {this[this.length] = arguments[i];}
+            return this.length;
+        };
+
+    TrimPath.parseTemplate = function(tmplContent, optTmplName, optEtc) {
+        if (optEtc == null)
+            optEtc = TrimPath.parseTemplate_etc;
+        var funcSrc = parse(tmplContent, optTmplName, optEtc);
+        var func = TrimPath.evalEx(funcSrc, optTmplName, 1);
+        if (func != null)
+            return new optEtc.Template(optTmplName, tmplContent, funcSrc, func, optEtc);
+        return null;
+    }
+    
+    try {
+        String.prototype.process = function(context, optFlags) {
+            var template = TrimPath.parseTemplate(this, null);
+            if (template != null)
+                return template.process(context, optFlags);
+            return this;
+        }
+    } catch (e) { // Swallow exception, such as when String.prototype is sealed.
+    }
+    
+    TrimPath.parseTemplate_etc = {};            // Exposed for extensibility.
+    TrimPath.parseTemplate_etc.statementTag = "forelse|for|if|elseif|else|var|macro";
+    TrimPath.parseTemplate_etc.statementDef = { // Lookup table for statement tags.
+        "if"     : { delta:  1, prefix: "if (", suffix: ") {", paramMin: 1 },
+        "else"   : { delta:  0, prefix: "} else {" },
+        "elseif" : { delta:  0, prefix: "} else if (", suffix: ") {", paramDefault: "true" },
+        "/if"    : { delta: -1, prefix: "}" },
+        "for"    : { delta:  1, paramMin: 3, 
+                     prefixFunc : function(stmtParts, state, tmplName, etc) {
+                        if (stmtParts[2] != "in")
+                            throw new etc.ParseError(tmplName, state.line, "bad for loop statement: " + stmtParts.join(' '));
+                        var iterVar = stmtParts[1];
+                        var listVar = "__LIST__" + iterVar;
+                        return [ "var ", listVar, " = ", stmtParts[3], ";",
+                             // Fix from Ross Shaull for hash looping, make sure that we have an array of loop lengths to treat like a stack.
+                             "var __LENGTH_STACK__;",
+                             "if (typeof(__LENGTH_STACK__) == 'undefined' || !__LENGTH_STACK__.length) __LENGTH_STACK__ = new Array();", 
+                             "__LENGTH_STACK__[__LENGTH_STACK__.length] = 0;", // Push a new for-loop onto the stack of loop lengths.
+                             "if ((", listVar, ") != null) { ",
+                             "var ", iterVar, "_ct = 0;",       // iterVar_ct variable, added by B. Bittman     
+                             "for (var ", iterVar, "_index in ", listVar, ") { ",
+                             iterVar, "_ct++;",
+                             "if (typeof(", listVar, "[", iterVar, "_index]) == 'function') {continue;}", // IE 5.x fix from Igor Poteryaev.
+                             "__LENGTH_STACK__[__LENGTH_STACK__.length - 1]++;",
+                             "var ", iterVar, " = ", listVar, "[", iterVar, "_index];" ].join("");
+                     } },
+        "forelse" : { delta:  0, prefix: "} } if (__LENGTH_STACK__[__LENGTH_STACK__.length - 1] == 0) { if (", suffix: ") {", paramDefault: "true" },
+        "/for"    : { delta: -1, prefix: "} }; delete __LENGTH_STACK__[__LENGTH_STACK__.length - 1];" }, // Remove the just-finished for-loop from the stack of loop lengths.
+        "var"     : { delta:  0, prefix: "var ", suffix: ";" },
+        "macro"   : { delta:  1, 
+                      prefixFunc : function(stmtParts, state, tmplName, etc) {
+                          var macroName = stmtParts[1].split('(')[0];
+                          return [ "var ", macroName, " = function", 
+                                   stmtParts.slice(1).join(' ').substring(macroName.length),
+                                   "{ var _OUT_arr = []; var _OUT = { write: function(m) { if (m) _OUT_arr.push(m); } }; " ].join('');
+                     } }, 
+        "/macro"  : { delta: -1, prefix: " return _OUT_arr.join(''); };" }
+    }
+    TrimPath.parseTemplate_etc.modifierDef = {
+        "eat"        : function(v)    { return ""; },
+        "escape"     : function(s)    { return String(s).replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;"); },
+        "capitalize" : function(s)    { return String(s).toUpperCase(); },
+        "default"    : function(s, d) { return s != null ? s : d; }
+    }
+    TrimPath.parseTemplate_etc.modifierDef.h = TrimPath.parseTemplate_etc.modifierDef.escape;
+
+    TrimPath.parseTemplate_etc.Template = function(tmplName, tmplContent, funcSrc, func, etc) {
+        this.process = function(context, flags) {
+            if (context == null)
+                context = {};
+            if (context._MODIFIERS == null)
+                context._MODIFIERS = {};
+            if (context.defined == null)
+                context.defined = function(str) { return (context[str] != undefined); };
+            for (var k in etc.modifierDef) {
+                if (context._MODIFIERS[k] == null)
+                    context._MODIFIERS[k] = etc.modifierDef[k];
+            }
+            if (flags == null)
+                flags = {};
+            var resultArr = [];
+            var resultOut = { write: function(m) { resultArr.push(m); } };
+            try {
+                func(resultOut, context, flags);
+            } catch (e) {
+                if (flags.throwExceptions == true)
+                    throw e;
+                var result = new String(resultArr.join("") + "[ERROR: " + e.toString() + (e.message ? '; ' + e.message : '') + "]");
+                result["exception"] = e;
+                return result;
+            }
+            return resultArr.join("");
+        }
+        this.name       = tmplName;
+        this.source     = tmplContent; 
+        this.sourceFunc = funcSrc;
+        this.toString   = function() { return "TrimPath.Template [" + tmplName + "]"; }
+    }
+    TrimPath.parseTemplate_etc.ParseError = function(name, line, message) {
+        this.name    = name;
+        this.line    = line;
+        this.message = message;
+    }
+    TrimPath.parseTemplate_etc.ParseError.prototype.toString = function() { 
+        return ("TrimPath template ParseError in " + this.name + ": line " + this.line + ", " + this.message);
+    }
+    
+    var parse = function(body, tmplName, etc) {
+        body = cleanWhiteSpace(body);
+        var funcText = [ "var TrimPath_Template_TEMP = function(_OUT, _CONTEXT, _FLAGS) { with (_CONTEXT) {" ];
+        var state    = { stack: [], line: 1 };                              // TODO: Fix line number counting.
+        var endStmtPrev = -1;
+        while (endStmtPrev + 1 < body.length) {
+            var begStmt = endStmtPrev;
+            // Scan until we find some statement markup.
+            begStmt = body.indexOf("{", begStmt + 1);
+            while (begStmt >= 0) {
+                var endStmt = body.indexOf('}', begStmt + 1);
+                var stmt = body.substring(begStmt, endStmt);
+                var blockrx = stmt.match(/^\{(cdata|minify|eval)/); // From B. Bittman, minify/eval/cdata implementation.
+                if (blockrx) {
+                    var blockType = blockrx[1]; 
+                    var blockMarkerBeg = begStmt + blockType.length + 1;
+                    var blockMarkerEnd = body.indexOf('}', blockMarkerBeg);
+                    if (blockMarkerEnd >= 0) {
+                        var blockMarker;
+                        if( blockMarkerEnd - blockMarkerBeg <= 0 ) {
+                            blockMarker = "{/" + blockType + "}";
+                        } else {
+                            blockMarker = body.substring(blockMarkerBeg + 1, blockMarkerEnd);
+                        }                        
+                        
+                        var blockEnd = body.indexOf(blockMarker, blockMarkerEnd + 1);
+                        if (blockEnd >= 0) {                            
+                            emitSectionText(body.substring(endStmtPrev + 1, begStmt), funcText);
+                            
+                            var blockText = body.substring(blockMarkerEnd + 1, blockEnd);
+                            if (blockType == 'cdata') {
+                                emitText(blockText, funcText);
+                            } else if (blockType == 'minify') {
+                                emitText(scrubWhiteSpace(blockText), funcText);
+                            } else if (blockType == 'eval') {
+                                if (blockText != null && blockText.length > 0) // From B. Bittman, eval should not execute until process().
+                                    funcText.push('_OUT.write( (function() { ' + blockText + ' })() );');
+                            }
+                            begStmt = endStmtPrev = blockEnd + blockMarker.length - 1;
+                        }
+                    }                        
+                } else if (body.charAt(begStmt - 1) != '$' &&               // Not an expression or backslashed,
+                           body.charAt(begStmt - 1) != '\\') {              // so check if it is a statement tag.
+                    var offset = (body.charAt(begStmt + 1) == '/' ? 2 : 1); // Close tags offset of 2 skips '/'.
+                                                                            // 10 is larger than maximum statement tag length.
+                    if (body.substring(begStmt + offset, begStmt + 10 + offset).search(TrimPath.parseTemplate_etc.statementTag) == 0) 
+                        break;                                              // Found a match.
+                }
+                begStmt = body.indexOf("{", begStmt + 1);
+            }
+            if (begStmt < 0)                              // In "a{for}c", begStmt will be 1.
+                break;
+            var endStmt = body.indexOf("}", begStmt + 1); // In "a{for}c", endStmt will be 5.
+            if (endStmt < 0)
+                break;
+            emitSectionText(body.substring(endStmtPrev + 1, begStmt), funcText);
+            emitStatement(body.substring(begStmt, endStmt + 1), state, funcText, tmplName, etc);
+            endStmtPrev = endStmt;
+        }
+        emitSectionText(body.substring(endStmtPrev + 1), funcText);
+        if (state.stack.length != 0)
+            throw new etc.ParseError(tmplName, state.line, "unclosed, unmatched statement(s): " + state.stack.join(","));
+        funcText.push("}}; TrimPath_Template_TEMP");
+        return funcText.join("");
+    }
+    
+    var emitStatement = function(stmtStr, state, funcText, tmplName, etc) {
+        var parts = stmtStr.slice(1, -1).split(' ');
+        var stmt = etc.statementDef[parts[0]]; // Here, parts[0] == for/if/else/...
+        if (stmt == null) {                    // Not a real statement.
+            emitSectionText(stmtStr, funcText);
+            return;
+        }
+        if (stmt.delta < 0) {
+            if (state.stack.length <= 0)
+                throw new etc.ParseError(tmplName, state.line, "close tag does not match any previous statement: " + stmtStr);
+            state.stack.pop();
+        } 
+        if (stmt.delta > 0)
+            state.stack.push(stmtStr);
+
+        if (stmt.paramMin != null &&
+            stmt.paramMin >= parts.length)
+            throw new etc.ParseError(tmplName, state.line, "statement needs more parameters: " + stmtStr);
+        if (stmt.prefixFunc != null)
+            funcText.push(stmt.prefixFunc(parts, state, tmplName, etc));
+        else 
+            funcText.push(stmt.prefix);
+        if (stmt.suffix != null) {
+            if (parts.length <= 1) {
+                if (stmt.paramDefault != null)
+                    funcText.push(stmt.paramDefault);
+            } else {
+                for (var i = 1; i < parts.length; i++) {
+                    if (i > 1)
+                        funcText.push(' ');
+                    funcText.push(parts[i]);
+                }
+            }
+            funcText.push(stmt.suffix);
+        }
+    }
+
+    var emitSectionText = function(text, funcText) {
+        if (text.length <= 0)
+            return;
+        var nlPrefix = 0;               // Index to first non-newline in prefix.
+        var nlSuffix = text.length - 1; // Index to first non-space/tab in suffix.
+        while (nlPrefix < text.length && (text.charAt(nlPrefix) == '\n'))
+            nlPrefix++;
+        while (nlSuffix >= 0 && (text.charAt(nlSuffix) == ' ' || text.charAt(nlSuffix) == '\t'))
+            nlSuffix--;
+        if (nlSuffix < nlPrefix)
+            nlSuffix = nlPrefix;
+        if (nlPrefix > 0) {
+            funcText.push('if (_FLAGS.keepWhitespace == true) _OUT.write("');
+            var s = text.substring(0, nlPrefix).replace('\n', '\\n'); // A macro IE fix from BJessen.
+            if (s.charAt(s.length - 1) == '\n')
+            	s = s.substring(0, s.length - 1);
+            funcText.push(s);
+            funcText.push('");');
+        }
+        var lines = text.substring(nlPrefix, nlSuffix + 1).split('\n');
+        for (var i = 0; i < lines.length; i++) {
+            emitSectionTextLine(lines[i], funcText);
+            if (i < lines.length - 1)
+                funcText.push('_OUT.write("\\n");\n');
+        }
+        if (nlSuffix + 1 < text.length) {
+            funcText.push('if (_FLAGS.keepWhitespace == true) _OUT.write("');
+            var s = text.substring(nlSuffix + 1).replace('\n', '\\n');
+            if (s.charAt(s.length - 1) == '\n')
+            	s = s.substring(0, s.length - 1);
+            funcText.push(s);
+            funcText.push('");');
+        }
+    }
+    
+    var emitSectionTextLine = function(line, funcText) {
+        var endMarkPrev = '}';
+        var endExprPrev = -1;
+        while (endExprPrev + endMarkPrev.length < line.length) {
+            var begMark = "${", endMark = "}";
+            var begExpr = line.indexOf(begMark, endExprPrev + endMarkPrev.length); // In "a${b}c", begExpr == 1
+            if (begExpr < 0)
+                break;
+            if (line.charAt(begExpr + 2) == '%') {
+                begMark = "${%";
+                endMark = "%}";
+            }
+            var endExpr = line.indexOf(endMark, begExpr + begMark.length);         // In "a${b}c", endExpr == 4;
+            if (endExpr < 0)
+                break;
+            emitText(line.substring(endExprPrev + endMarkPrev.length, begExpr), funcText);                
+            // Example: exprs == 'firstName|default:"John Doe"|capitalize'.split('|')
+            var exprArr = line.substring(begExpr + begMark.length, endExpr).replace(/\|\|/g, "#@@#").split('|');
+            for (var k in exprArr) {
+                if (exprArr[k].replace) // IE 5.x fix from Igor Poteryaev.
+                    exprArr[k] = exprArr[k].replace(/#@@#/g, '||');
+            }
+            funcText.push('_OUT.write(');
+            emitExpression(exprArr, exprArr.length - 1, funcText); 
+            funcText.push(');');
+            endExprPrev = endExpr;
+            endMarkPrev = endMark;
+        }
+        emitText(line.substring(endExprPrev + endMarkPrev.length), funcText); 
+    }
+    
+    var emitText = function(text, funcText) {
+        if (text == null ||
+            text.length <= 0)
+            return;
+        text = text.replace(/\\/g, '\\\\');
+        text = text.replace(/\n/g, '\\n');
+        text = text.replace(/"/g,  '\\"');
+        funcText.push('_OUT.write("');
+        funcText.push(text);
+        funcText.push('");');
+    }
+    
+    var emitExpression = function(exprArr, index, funcText) {
+        // Ex: foo|a:x|b:y1,y2|c:z1,z2 is emitted as c(b(a(foo,x),y1,y2),z1,z2)
+        var expr = exprArr[index]; // Ex: exprArr == [firstName,capitalize,default:"John Doe"]
+        if (index <= 0) {          // Ex: expr    == 'default:"John Doe"'
+            funcText.push(expr);
+            return;
+        }
+        var parts = expr.split(':');
+        funcText.push('_MODIFIERS["');
+        funcText.push(parts[0]); // The parts[0] is a modifier function name, like capitalize.
+        funcText.push('"](');
+        emitExpression(exprArr, index - 1, funcText);
+        if (parts.length > 1) {
+            funcText.push(',');
+            funcText.push(parts[1]);
+        }
+        funcText.push(')');
+    }
+
+    var cleanWhiteSpace = function(result) {
+        result = result.replace(/\t/g,   "    ");
+        result = result.replace(/\r\n/g, "\n");
+        result = result.replace(/\r/g,   "\n");
+        result = result.replace(/^(\s*\S*(\s+\S+)*)\s*$/, '$1'); // Right trim by Igor Poteryaev.
+        return result;
+    }
+
+    var scrubWhiteSpace = function(result) {
+        result = result.replace(/^\s+/g,   "");
+        result = result.replace(/\s+$/g,   "");
+        result = result.replace(/\s+/g,   " ");
+        result = result.replace(/^(\s*\S*(\s+\S+)*)\s*$/, '$1'); // Right trim by Igor Poteryaev.
+        return result;
+    }
+
+    // The DOM helper functions depend on DOM/DHTML, so they only work in a browser.
+    // However, these are not considered core to the engine.
+    //
+    TrimPath.parseDOMTemplate = function(elementId, optDocument, optEtc) {
+        if (optDocument == null)
+            optDocument = document;
+        var element = optDocument.getElementById(elementId);
+        var content = element.value;     // Like textarea.value.
+        if (content == null)
+            content = element.innerHTML; // Like textarea.innerHTML.
+        content = content.replace(/&lt;/g, "<").replace(/&gt;/g, ">");
+        return TrimPath.parseTemplate(content, elementId, optEtc);
+    }
+
+    TrimPath.processDOMTemplate = function(elementId, context, optFlags, optDocument, optEtc) {
+        return TrimPath.parseDOMTemplate(elementId, optDocument, optEtc).process(context, optFlags);
+    }
+}) ();
Index: ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web-data/objects.js
===================================================================
--- ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web-data/objects.js	(revision 14969)
+++ ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web-data/objects.js	(revision 14969)
@@ -0,0 +1,857 @@
+// $Header$
+// store all objects here
+
+//START class EPGList 
+
+function getNodeContent(xml, nodename, defaultString){
+	try{
+		var node = xml.getElementsByTagName(nodename);
+		var retVal = node.item(0).firstChild.data;
+
+		if(retVal === "" || retVal === null){
+			return 'N/A';		
+		} else if (retVal === "None"){
+			return "";
+		}
+		
+		return retVal;
+	} catch(e){
+		if(typeof(defaultString) !== 'undefined') {
+			return defaultString;
+		}		
+	}
+	
+	return 'N/A';
+}
+
+function getNamedChildren(xml, parentname, childname){
+	try {
+		var ret = xml.getElementsByTagName(parentname).item(0).getElementsByTagName(childname);
+		return ret;
+	} catch (e) {
+		return {};
+	}
+}
+
+//START class EPGEvent
+function EPGEvent(xml, number){	
+	this.eventID = getNodeContent(xml, 'e2eventid', '');
+	this.startTime = parseNr(getNodeContent(xml, 'e2eventstart', ''));	
+	this.duration = parseNr(getNodeContent(xml, 'e2eventduration', ''));
+	this.currentTime = parseNr(getNodeContent(xml, 'e2eventcurrenttime')),
+	this.title = getNodeContent(xml, 'e2eventtitle', '');
+	this.serviceRef = getNodeContent(xml, 'e2eventservicereference', '');
+	this.serviceName = getNodeContent(xml, 'e2eventservicename', '');
+	this.fileName = getNodeContent(xml, 'e2filename', '');	
+	this.description = getNodeContent(xml, 'e2eventdescription');
+	this.descriptionE = getNodeContent(xml, 'e2eventdescriptionextended');
+	
+	if(typeof(number) != "undefined"){
+		this.number = number;
+	} else {
+		this.number = 0;
+	}
+	
+	this.getFilename = function() {
+		return this.fileName;
+	};
+	this.getEventId = function() {
+		return this.eventID;
+	};
+	this.getTimeStart = function() {
+		var date = new Date(this.startTime *1000);
+		return date;
+	};
+	this.getTimeStartString = function() {
+		var h = this.getTimeStart().getHours();
+		var m = this.getTimeStart().getMinutes();
+		if (m < 10){
+			m="0"+m;
+		}
+		return h+":"+m;
+	};
+	this.getTimeDay = function() {
+		var weekday = ["So", "Mo", "Tu", "We", "Th", "Fr", "Sa"];
+		var wday = weekday[this.getTimeStart().getDay()];
+		var day = this.getTimeStart().getDate();
+		var month = this.getTimeStart().getMonth()+1;
+		var year = this.getTimeStart().getFullYear();
+		
+		return wday+".&nbsp;"+day+"."+month+"."+year;
+	};
+	this.getTimeBegin = function(){
+		return this.getTimeStart().getTime()/1000;
+	};
+	this.getTimeEnd = function() {
+		var date = new Date(( this.startTime + this.duration ) * 1000);
+		return parseInt( date.getTime()/1000 );
+	};
+	this.getTimeEndString = function() {
+		var date = new Date(( this.startTime + this.duration ) * 1000);
+		var h = date.getHours();
+		var m = date.getMinutes();
+		if (m < 10){
+			m="0"+m;
+		}
+		return h+":"+m;
+	};
+	this.getDuration = function() {		
+		var date = new Date( this.duration * 1000);
+		return date;
+	};
+	this.getTimeRemainingString = function() {
+		
+		if( this.currentTime <= this.startTime ){
+			return Math.ceil(this.getDuration() / 60000);
+		} else {
+			if( this.getTimeEnd() > 0){
+				var remaining = Math.ceil( ( this.getTimeEnd() - this.currentTime ) / 60);
+				return remaining;
+			} else {
+				return this.getTimeEnd();
+			}
+		}
+	};
+	
+	this.getTitle = function() {
+		return this.title;
+	};
+	this.getDescription = function() {
+		return this.description;
+	};
+	this.getDescriptionExtended = function() {
+		return this.descriptionE;
+	};
+	this.getServiceReference = function() {
+		return encodeURIComponent(this.serviceRef);
+	};
+	this.getServiceName = function() {
+		return this.serviceName;
+	};
+	
+	this.json = {
+			'date': this.getTimeDay(),
+			'eventid': this.getEventId(),
+			'servicereference': this.getServiceReference(),
+			'servicename': quotes2html(this.getServiceName()),
+			'title': quotes2html(this.getTitle()),
+			'shorttitle': quotes2html(this.getTitle().substring(0, 40) ) + '...',
+			'titleESC': escape(this.getTitle()),
+			'starttime': this.getTimeStartString(), 
+			'duration': Math.ceil(this.getDuration()/60000), 
+			'description': quotes2html(this.getDescription()),
+			'endtime': this.getTimeEndString(), 
+			'remaining': this.getTimeRemainingString(),
+			'extdescription': quotes2html(this.getDescriptionExtended()),
+			'number': String(this.number),
+			'start': this.getTimeBegin(),
+			'end': this.getTimeEnd()
+			};
+	
+	this.toJSON = function() {
+		return this.json;
+	};
+	
+}
+//END class EPGEvent
+
+
+function EPGList(xml){
+	// parsing values from xml-element
+	try{
+		this.xmlitems = xml.getElementsByTagName("e2eventlist").item(0).getElementsByTagName("e2event");
+	} catch (e) {
+		notify("Error Parsing EPG: " + e, false);
+	}
+	
+	this.getArray = function(sortbytime){
+		debug("[EPGList] Sort by time "+sortbytime);
+		var list = [];
+		
+		if (sortbytime === true){
+			var sortList = [];
+			for(var i=0;i<this.xmlitems.length;i++){
+				var event = new EPGEvent(this.xmlitems.item(i), i).toJSON();
+				sortList.push( [event.starttime, event] );
+			}
+			sortList.sort(this.sortFunction);
+			
+			list = [];
+			for(i=0;i<sortList.length;i++){
+				list.push(sortList[i][1]);
+			}
+			
+			return list;
+			
+		}else{
+			list = [];
+			for (i=0;i<this.xmlitems.length;i++){
+				xv = new EPGEvent(this.xmlitems.item(i)).toJSON();
+				list.push(xv);			
+			}
+			return list;
+		}
+	};
+	
+	this.sortFunction = function(a, b){
+	  return a[0] - b[0];
+	};
+}
+//END class EPGList
+
+// START class Service
+function Service(xml, cssclass){	
+	this.servicereference = getNodeContent(xml, 'e2servicereference', '');
+	this.servicename = getNodeContent(xml, 'e2servicename');
+	this.videowidth = getNodeContent(xml, 'e2videowidth');
+	this.videoheight = getNodeContent(xml, 'e2videoheight');
+	this.videosize = getNodeContent(xml, 'e2servicevideosize');
+	this.widescreen = getNodeContent(xml, 'e2iswidescreen');
+	this.apid = dec2hex( getNodeContent(xml, 'e2apid'),4 );
+	this.vpid = dec2hex( getNodeContent(xml, 'e2vpid'),4 );
+	this.pcrpid = dec2hex( getNodeContent(xml, 'e2pcrpid'),4 );
+	this.pmtpid = dec2hex( getNodeContent(xml, 'e2pmtpid'),4 );
+	this.txtpid = dec2hex( getNodeContent(xml, 'e2txtpid'),4 );
+	this.tsid = dec2hex( getNodeContent(xml, 'e2tsid'),4 );
+	this.onid = dec2hex( getNodeContent(xml, 'e2onid'),4 );
+	this.sid = dec2hex( getNodeContent(xml, 'e2sid'),4 );
+	
+	this.getServiceReference = function(){
+		return encodeURIComponent(this.servicereference);
+	};
+	
+	this.getClearServiceReference = function(){
+		return this.servicereference;
+	};
+		
+	this.getServiceName = function(){
+		return this.servicename.replace('&quot;', '"');
+	};
+	
+	this.setServiceReference = function(sref){
+		this.servicereference = sref;
+	};
+		
+	this.setServiceName = function(sname){
+		this.servicename = sname.replace('&quot;', '"');
+	};
+	
+	if( typeof( cssclass ) == undefined ){
+		cssclass = 'odd';
+	}
+	
+	this.json = { 	
+			'servicereference' : this.getServiceReference(),
+			'servicename' : this.getServiceName(),
+			'videowidth' : this.videowidth,
+			'videoheight' : this.videoheight,
+			'videosize' : this.videosize,
+			'widescreen' : this.widescreen,
+			'apid' : this.apid,
+			'vpid' : this.vpid,
+			'pcrpid' : this.pcrpid,
+			'pmtpid' : this.pmtpid,
+			'txtpid' : this.txtpid,
+			'tsid' : this.tsid,
+			'onid' : this.onid,
+			'sid' : this.sid,
+			'cssclass' : cssclass
+	};
+	
+	this.toJSON = function(){
+		return this.json;
+	};
+}	
+//END class Service
+
+// START class ServiceList
+function ServiceList(xml){
+	this.xmlitems = getNamedChildren(xml, "e2servicelist", "e2service");
+	this.servicelist = [];
+	this.getArray = function(){
+		if(this.servicelist.length === 0){
+			var cssclass = 'even';
+			
+			for (var i=0;i<this.xmlitems.length;i++){
+				cssclass = cssclass == 'even' ? 'odd' : 'even';
+				var service = new Service(this.xmlitems.item(i), cssclass).toJSON();
+				this.servicelist.push(service);
+			}
+		}
+		
+		return this.servicelist;
+	};
+}
+//END class ServiceList
+
+
+// START class Movie
+function Movie(xml, cssclass){	
+	this.servicereference = getNodeContent(xml, 'e2servicereference');
+	this.servicename = getNodeContent(xml, 'e2servicename');
+	this.title = getNodeContent(xml, 'e2title');
+	this.descriptionextended = getNodeContent(xml, 'e2descriptionextended');
+	this.description = getNodeContent(xml, 'e2description');
+	this.tags = getNodeContent(xml, 'e2tags', '&nbsp;');
+	this.filename = getNodeContent(xml, 'e2filename');
+	this.filesize = getNodeContent(xml, 'e2filesize', 0);
+	this.startTime = getNodeContent(xml, 'e2time', 0);
+	this.length = getNodeContent(xml, 'e2length', 0);
+
+	this.getLength = function() {
+		return this.length;
+	};
+	
+	this.getTimeStart = function() {
+		var date = new Date(parseInt(this.startTime, 10)*1000);
+		return date;
+	};
+	
+	this.getTimeStartString = function() {
+		var h = this.getTimeStart().getHours();
+		var m = this.getTimeStart().getMinutes();
+		if (m < 10){
+			m="0"+m;
+		}
+		return h+":"+m;
+	};
+	
+	this.getTimeDay = function() {
+		var Wochentag = ["So", "Mo", "Di", "Mi", "Do", "Fr", "Sa"];
+		var wday = Wochentag[this.getTimeStart().getDay()];
+		var day = this.getTimeStart().getDate();
+		var month = this.getTimeStart().getMonth()+1;
+		var year = this.getTimeStart().getFullYear();
+		
+		return wday+".&nbsp;"+day+"."+month+"."+year;
+	};
+
+	this.getServiceReference = function(){
+		return encodeURIComponent(this.servicereference);
+	};
+	this.getServiceName = function(){
+		return this.servicename.replace('&quot;', '"');
+	};
+	
+	this.getTitle = function(){
+		return this.title;
+	};
+	
+	this.getDescription = function(){
+		return this.description;
+	};
+	
+	this.getDescriptionExtended = function(){
+		return this.descriptionextended;
+	};
+	
+	this.getTags = function(){		
+		return this.tags.split(" ");
+	};
+	
+	this.getFilename = function(){		
+		return encodeURIComponent(this.filename);		
+	};
+	
+	this.getFilesizeMB = function(){		
+		return Math.round((parseInt(this.filesize, 10)/1024)/1024)+"MB";
+	};
+	
+	if( typeof( cssclass) == 'undefined'){
+		cssclass = 'odd';
+	}
+	
+	this.json = {
+			'servicereference': escape(this.getServiceReference()),
+			'servicename': this.getServiceName(),
+			'title': this.getTitle(),
+			'escapedTitle': escape(this.getTitle()),
+			'description': this.getDescription(), 
+			'descriptionextended': this.getDescriptionExtended(),
+			'filename': String(this.getFilename()),
+			'filesize': this.getFilesizeMB(),
+			'tags': this.getTags().join(', ') ,
+			'length': this.getLength() ,
+			'time': this.getTimeDay()+"&nbsp;"+ this.getTimeStartString(),
+			'cssclass' : cssclass
+	};
+	
+	this.toJSON = function(){
+		return this.json;
+	};
+}	
+//END class Movie
+
+
+// START class MovieList
+function MovieList(xml){
+	this.xmlitems = getNamedChildren(xml, "e2movielist", "e2movie");
+	this.movielist = [];
+	
+	this.getArray = function(){
+		if(this.movielist.length === 0){
+			var cssclass = "even";
+			
+			for(var i=0;i<this.xmlitems.length;i++){
+				cssclass = cssclass == 'even' ? 'odd' : 'even';
+				
+				var movie = new Movie(this.xmlitems.item(i), cssclass).toJSON();
+				this.movielist.push(movie);			
+			}
+		}
+		
+		return this.movielist;
+	};
+}
+//END class MovieList
+
+
+
+// START class Timer
+function Timer(xml, cssclass){	
+	this.servicereference = getNodeContent(xml, 'e2servicereference');
+	this.servicename = getNodeContent(xml, 'e2servicename');
+	this.eventid = getNodeContent(xml, 'e2eit');
+	this.name = getNodeContent(xml, 'e2name');
+	this.description = getNodeContent(xml, 'e2description', '');
+	this.descriptionextended = getNodeContent(xml, 'e2descriptionextended', '');
+	this.disabled = getNodeContent(xml, 'e2disabled', '0');
+	this.timebegin = getNodeContent(xml, 'e2timebegin');
+	this.timeend = getNodeContent(xml, 'e2timeend');
+	this.duration = getNodeContent(xml, 'e2duration', '0');
+	this.startprepare = getNodeContent(xml, 'e2startprepare');
+	this.justplay = getNodeContent(xml, 'e2justplay', '');
+	this.afterevent = getNodeContent(xml, 'e2afterevent', '0');
+	this.dirname = getNodeContent(xml, 'e2dirname', '/hdd/movie/');
+	this.tags = getNodeContent(xml, 'e2tags', '');
+	this.logentries = getNodeContent(xml, 'e2logentries');
+	this.tfilename = getNodeContent(xml, 'e2filename');
+	this.backoff = getNodeContent(xml, 'e2backoff');
+	this.nextactivation = getNodeContent(xml, 'e2nextactivation');
+	this.firsttryprepare = getNodeContent(xml, 'e2firsttryprepare');
+	this.state = getNodeContent(xml, 'e2state');
+	this.repeated = getNodeContent(xml, 'e2repeated', '0');
+	this.dontsave = getNodeContent(xml, 'e2dontsave');
+	this.cancled = getNodeContent(xml, 'e2cancled');
+	this.color = getNodeContent(xml, 'e2color');
+	this.toggledisabled = getNodeContent(xml, 'e2toggledisabled');
+	this.toggledisabledimg = getNodeContent(xml, 'e2toggledisabledimg');
+
+	this.getColor = function(){
+		return this.color;
+	};
+	
+	this.getToggleDisabled = function(){
+		return this.toggledisabled;
+	};
+	
+	this.getToggleDisabledIMG = function(){
+		return this.toggledisabledimg;
+	};
+	
+	this.getToggleDisabledText = function(){
+		var retVal = this.toggledisabled == "0" ? "Enable timer" : "Disable timer";
+		return retVal;
+	};
+	
+	this.getServiceReference = function(){
+		return encodeURIComponent(this.servicereference);
+	};
+	
+	this.getServiceName = function(){
+		return this.servicename.replace('&quot;', '"');
+	};
+	
+	this.getEventID = function(){
+		return this.eventid;
+	};
+	
+	this.getName = function(){
+		return this.name;
+	};
+	
+	this.getDescription = function(){
+		return this.description;
+	};
+	
+	this.getDescriptionExtended = function(){
+		return this.descriptionextended;
+	};
+	
+	this.getDisabled = function(){
+		return this.disabled;
+	};
+	
+	this.getTimeBegin = function(){
+		return this.timebegin;
+	};
+	
+	this.getTimeEnd = function(){
+		return this.timeend;
+	};
+	
+	this.getDuration = function(){
+		return parseInt(this.duration, 10);
+	};
+	
+	this.getStartPrepare = function(){
+		return this.startprepare;
+	};
+	
+	this.getJustplay = function(){
+		return this.justplay;
+	};
+	
+	this.getAfterevent = function(){
+		return this.afterevent;
+	};
+	
+	this.getDirname = function(){
+		return this.dirname;
+	};
+
+	this.getTags = function(){
+		return this.tags;
+	};
+
+	this.getLogentries = function(){
+		return this.logentries;
+	};
+	
+	this.getFilename = function(){
+		return this.tfilename;
+	};
+	
+	this.getBackoff = function(){
+		return this.backoff;
+	};
+	
+	this.getNextActivation = function(){
+		return this.nextactivation;
+	};
+	
+	this.getFirsttryprepare = function(){
+		return this.firsttryprepare;
+	};
+	
+	this.getState = function(){
+		return this.state;
+	};
+	
+	this.getRepeated = function(){
+		return this.repeated;
+	};
+	
+	this.getDontSave = function(){
+		return this.dontsave;
+	};
+	
+	this.isCancled = function(){
+		return this.cancled;
+	};
+	
+	if( typeof( cssclass ) == undefined ){
+		cssclass = 'odd';
+	}
+	
+	this.beginDate = new Date(Number(this.getTimeBegin()) * 1000);
+	this.endDate = new Date(Number(this.getTimeEnd()) * 1000);
+	
+	this.aftereventReadable = [ 'Nothing', 'Standby',
+	                            'Deepstandby/Shutdown', 'Auto' ];
+	
+	this.justplayReadable = [ 'record', 'zap' ];
+	
+	this.json = {
+			'servicereference' : this.getServiceReference(),
+			'servicename' : quotes2html(this.getServiceName()),
+			'title' : quotes2html(this.getName()),
+			'description' : quotes2html(this.getDescription()),
+			'descriptionextended' : quotes2html(this
+					.getDescriptionExtended()),
+			'begin' : this.getTimeBegin(),
+			'beginDate' : dateToString(this.beginDate),
+			'end' : this.getTimeEnd(),
+			'endDate' : dateToString(this.endDate),
+			'state' : this.getState(),
+			'duration' : Math.ceil((this.getDuration() / 60)),
+			'repeated' : this.getRepeated(),
+			'repeatedReadable' : repeatedReadable(this.getRepeated()),
+			'justplay' : this.getJustplay(),
+			'justplayReadable' : this.justplayReadable[Number(this
+					.getJustplay())],
+			'afterevent' : this.getAfterevent(),
+			'aftereventReadable' : this.aftereventReadable[Number(this
+					.getAfterevent())],
+			'dirname' : this.getDirname(),
+			'tags' : this.getTags(),
+			'disabled' : this.getDisabled(),
+			'onOff' : this.getToggleDisabledIMG(),
+			'enDis' : this.getToggleDisabledText(),
+			'cssclass' : cssclass
+	};
+	
+	this.toJSON = function(){
+		return this.json;
+	};
+}
+
+
+// START class TimerList
+function TimerList(xml){
+	this.xmlitems = getNamedChildren(xml, "e2timerlist", "e2timer");
+	this.timerlist = [];
+	
+	this.getArray = function(){
+		if(this.timerlist.length === 0){
+			var cssclass = 'even';
+			
+			for(var i=0;i<this.xmlitems.length;i++){
+				cssclass = cssclass == 'even' ? 'odd' : 'even';
+				var timer = new Timer(this.xmlitems.item(i), cssclass).toJSON();
+				this.timerlist.push(timer);			
+			}
+		}
+		
+		return this.timerlist;
+	};
+}
+//END class TimerList
+function DeviceInfo(xml){
+	xml = xml.getElementsByTagName("e2deviceinfo").item(0);
+	
+	this.info = {};
+	
+	this.nims = [];
+	this.hdds = [];
+	this.nics = [];
+	
+	this.fpversion = "V"+xml.getElementsByTagName('e2fpversion').item(0).firstChild.data;
+	
+	var nimnodes = xml.getElementsByTagName('e2frontends').item(0).getElementsByTagName('e2frontend');			
+	for(var i = 0; i < nimnodes.length; i++){					
+		try {
+			var name = nimnodes.item(i).getElementsByTagName('e2name').item(0).firstChild.data;
+			var model = nimnodes.item(i).getElementsByTagName('e2model').item(0).firstChild.data;
+			this.nims[i] = { 
+					'name' : name, 
+					'model' : model
+			};					
+		} catch (e) {
+			notify("Error parsing frontend data: " + e);
+		}
+	}
+	
+	
+	var hddnodes = xml.getElementsByTagName('e2hdd');			
+	for( var i = 0; i < hddnodes.length; i++){
+		try{			
+			var hdd = hddnodes.item(i);
+	
+			var model 	= hdd.getElementsByTagName('e2model').item(0).firstChild.data;
+			var capacity = hdd.getElementsByTagName('e2capacity').item(0).firstChild.data;
+			var free		= hdd.getElementsByTagName('e2free').item(0).firstChild.data;
+	
+			this.hdds[i] = {	
+					'model'		: model,
+					'capacity' 	: capacity,
+					'free'		: free
+			};
+		} catch(e){
+			notify("Error parsing HDD data: " + e, false);			
+		}
+	}
+	
+	
+	var nicnodes = xml.getElementsByTagName('e2interface');
+	for( var i = 0; i < nicnodes.length; i++){
+		try {
+			var nic = nicnodes.item(i);
+			var name = nic.getElementsByTagName('e2name').item(0).firstChild.data;
+			var mac = nic.getElementsByTagName('e2mac').item(0).firstChild.data;
+			var dhcp = nic.getElementsByTagName('e2dhcp').item(0).firstChild.data;
+			var ip = nic.getElementsByTagName('e2ip').item(0).firstChild.data;
+			var gateway = nic.getElementsByTagName('e2gateway').item(0).firstChild.data;
+			var netmask = nic.getElementsByTagName('e2netmask').item(0).firstChild.data;
+	
+			this.nics[i] = {
+					'name' : name,
+					'mac' : mac,
+					'dhcp' : dhcp,
+					'ip' : ip,
+					'gateway' : gateway,
+					'netmask' : netmask
+			};
+		} catch (e) {
+			notify("Error parsing NIC data: " + e, false);			
+		}
+	}
+	
+	try{
+		this.info = {
+				'devicename' : xml.getElementsByTagName('e2devicename').item(0).firstChild.data,	
+				'enigmaVersion': xml.getElementsByTagName('e2enigmaversion').item(0).firstChild.data,
+				'imageVersion': xml.getElementsByTagName('e2imageversion').item(0).firstChild.data,
+				'fpVersion': this.fpversion,
+				'webifversion': xml.getElementsByTagName('e2webifversion').item(0).firstChild.data,
+				'recPath': xml.getElementsByTagName('e2recPath').item(0).firstChild.data,
+				'recCapacity': xml.getElementsByTagName('e2recCapacity').item(0).firstChild.data,
+				'recFree': xml.getElementsByTagName('e2recFree').item(0).firstChild.data
+		};
+	} catch (e) {
+		notify("Error parsing deviceinfo data: " + e, false);		
+	}
+	
+	this.json = {
+			info : this.info,
+			hdds : this.hdds,		
+			nics : this.nics,
+			nims : this.nims
+	};
+	
+	this.toJSON = function(){
+		return this.json;
+	};
+	
+}
+
+function SimpleXMLResult(xml){		
+	try{
+		this.xmlitems = xml.getElementsByTagName("e2simplexmlresult").item(0);
+	} catch (e) {
+		notify("Error parsing e2simplexmlresult: " + e, false);
+	}
+
+	this.state = getNodeContent(this.xmlitems, 'e2state', 'False');
+	this.statetext = getNodeContent(this.xmlitems, 'e2statetext', 'Error Parsing XML');
+
+	this.getState = function(){
+		if(this.state == 'True'){
+			return true;
+		}else{
+			return false;
+		}
+	};
+	
+	this.getStateText = function(){
+			return this.statetext;
+	};
+}
+// END SimpleXMLResult
+
+// START SimpleXMLList
+function SimpleXMLList(xml, tagname){
+	// parsing values from xml-element
+	try{
+		this.xmlitems = xml.getElementsByTagName(tagname);
+	} catch (e) {
+		notify("Error parsing SimpleXMLList: " + e, false);	
+	}
+	
+	this.xmllist = [];
+	
+	this.getList = function(){
+		if(this.xmllist.length === 0){
+			for(var i=0;i<this.xmlitems.length;i++){
+				this.xmllist.push(this.xmlitems.item(i).firstChild.data);			
+			}
+		}
+		
+		return this.xmllist;
+	};
+}
+// END SimpleXMLList
+
+
+// START class Setting
+function Setting(xml){	
+	this.settingvalue = getNodeContent(xml, 'e2settingvalue');
+	this.settingname = getNodeContent(xml, 'e2settingname');
+	
+	this.getSettingValue = function(){
+		return this.settingvalue;
+	};
+		
+	this.getSettingName = function(){
+		return this.settingname;
+	};
+	
+}
+
+
+// START class Settings
+function Settings(xml){
+	// parsing values from xml-element
+	try{
+		this.xmlitems = xml.getElementsByTagName("e2settings").item(0).getElementsByTagName("e2setting");
+		debug("[Settings] Number of items: " + this.xmlitems);
+	} catch (e) {
+		notify("Error parsing Settings: " + e, false);	
+	}	
+	
+	this.settings = [];
+	
+	this.getArray = function(){
+		if(this.settings.length === 0){
+			for (var i=0;i<this.xmlitems.length;i++){
+				var setting = new Setting(this.xmlitems.item(i));
+				this.settings.push(setting);			
+			}
+		}
+		
+		return this.settings;		
+	};
+}
+//END class Settings
+
+//START class FileList
+function FileList(xml){
+	// parsing values from xml-element
+	try{
+		this.xmlitems = xml.getElementsByTagName("e2filelist").item(0).getElementsByTagName("e2file");
+	} catch (e) {
+		notify("Error parsing FileList: " + e, false);
+	}
+	this.filelist = [];
+
+	this.getArray = function(){
+		if(this.filelist.length === 0){
+			for(var i=0;i<this.xmlitems.length;i++){
+				var file = new File(this.xmlitems.item(i));
+				this.filelist.push(file);			
+			}
+		}
+
+		return this.filelist;
+	};
+}
+//END class FileList
+
+//START class File
+function File(xml){	
+	// parsing values from xml-element
+	this.servicereference = getNodeContent(xml, 'e2servicereference', 'Filesystems');
+	this.isdirectory = getNodeContent(xml, 'e2isdirectory');
+	this.root = getNodeContent(xml, 'e2root', 'Filesystems');
+
+	this.getServiceReference = function(){
+		return this.servicereference;
+	};
+	
+	this.getNameOnly = function(){
+		if(this.root == '/') {
+			return this.servicereference;
+		} else {
+			return this.servicereference.replace(new RegExp('.*'+this.root, "i"), '');
+		}
+	};
+	
+	this.getIsDirectory = function(){
+		return this.isdirectory;
+	};
+	
+	this.getRoot = function(){
+		return this.root;
+	};
+}	
+//END class File
Index: ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web-data/statics.js
===================================================================
--- ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web-data/statics.js	(revision 14969)
+++ ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web-data/statics.js	(revision 14969)
@@ -0,0 +1,71 @@
+// $Header$
+
+function url() {
+	this.tpl = '/web-data/tpl/default/';
+	
+	this.getcurrent = '/web/getcurrent';
+	
+	this.getvolume = '/web/vol'; 
+	this.setvolume = '/web/vol?set=set'; // plus new value eg: set=set15
+	this.volumeup = '/web/vol?set=up';
+	this.volumedown = '/web/vol?set=down';
+	this.volumemute = '/web/vol?set=mute';
+	
+	this.epgservice = "/web/epgservice?sRef="; // plus serviceRef
+	this.epgsearch = "/web/epgsearch?search="; // plus serviceRef
+	this.epgservicenow = "/web/epgservicenow?sRef="; // plus serviceRef
+	this.epgservicenext = "/web/epgservicenext?sRef="; // plus serviceRef
+	this.epgnow = "/web/epgnow?bRef="; // plus bouquetRev
+	this.epgnext = "/web/epgnext?bRef="; // plus bouquetRev
+	
+	this.getservices = "/web/getservices?sRef="; // plus serviceref
+	this.subservices = "/web/subservices"; // subservices for current service
+	this.streamsubservices = "/web/streamsubservices?sRef="; // subservices for streaming service
+	
+	this.movielist= "/web/movielist"; // plus dirname,tag
+	this.moviedelete= "/web/moviedelete"; // plus serviceref
+	
+	this.about= "/web/about";	
+	this.settings= "/web/settings";	
+	this.parentcontrol= "/web/parentcontrollist";
+	this.signal = "/web/signal";
+	this.deviceinfo = "/web/deviceinfo";
+	
+	this.mediaplayerlist= "/web/mediaplayerlist?types=audio&path="; // plus full qualified path
+	this.mediaplayerplay= "/web/mediaplayerplay?file="; // plus file-serviceref
+	this.mediaplayerremove= "/web/mediaplayerremove?file="; // plus file-serviceref
+	this.mediaplayercmd= "/web/mediaplayercmd?command="; // plus command
+	this.mediaplayerwrite= "/web/mediaplayerwrite?filename="; // plus filename
+	
+	this.filelist = "/web/mediaplayerlist?path="; // plus full qualified path
+	
+	this.timerlist= "/web/timerlist";
+	this.recordnow= "/web/recordnow";
+	this.timeradd= "/web/timeradd"; // plus serviceref,begin,end,name,description,dirname,tags,eit,disabled,justplay,afterevent
+	this.timerchange= "/web/timerchange"; // plus serviceref,begin,end,name,description,dirname,tags,eit,disabled,justplay,afterevent
+	this.timeraddbyeventid= "/web/timeraddbyeventid"; // plus serviceref,eventid
+	this.timerdelete= "/web/timerdelete"; // plus serviceref,begin,end
+	this.timerlistwrite="/web/timerlistwrite?write=saveWriteNow";
+	this.timercleanup="/web/timercleanup?cleanup=true";
+	
+	this.getcurrlocation="/web/getcurrlocation";
+	this.getlocations="/web/getlocations";
+	this.gettags="/web/gettags";
+	
+	this.message = "/web/message"; // plus text,type,timeout
+	this.messageanswer = "/web/messageanswer?getanswer=now"; 
+	
+	this.powerstate = "/web/powerstate"; // plus new powerstate
+	this.remotecontrol = "/web/remotecontrol"; // plus command
+};
+
+var URL = new url();
+
+var bouquetsTv = '1:7:1:0:0:0:0:0:0:0:(type == 1) || (type == 17) || (type == 195) || (type == 25) FROM BOUQUET "bouquets.tv" ORDER BY bouquet';
+var bouquetsRadio = '1:7:2:0:0:0:0:0:0:0:(type == 2)FROM BOUQUET "bouquets.radio" ORDER BY bouquet';
+var providerTv = '1:7:1:0:0:0:0:0:0:0:(type == 1) || (type == 17) || (type == 195) || (type == 25) FROM PROVIDERS ORDER BY name';
+var providerRadio ='1:7:2:0:0:0:0:0:0:0:(type == 2) FROM PROVIDERS ORDER BY name';
+var satellitesTv = '1:7:1:0:0:0:0:0:0:0:(type == 1) || (type == 17) || (type == 195) || (type == 25) FROM SATELLITES ORDER BY name';
+var satellitesRadio ='1:7:2:0:0:0:0:0:0:0:(type == 2) FROM SATELLITES ORDER BY name';
+var allTv = '1:7:1:0:0:0:0:0:0:0:(type == 1) || (type == 17) || (type == 195) || (type == 25) ORDER BY name';
+var allRadio = '1:7:2:0:0:0:0:0:0:0:(type == 2) ORDER BY name';
Index: ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web-data/streaminterface.html
===================================================================
--- ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web-data/streaminterface.html	(revision 14969)
+++ ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web-data/streaminterface.html	(revision 14969)
@@ -0,0 +1,167 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+	<meta content="text/html; charset=UTF-8" http-equiv="content-type">
+	<title>AAF WebTV</title>
+	<!-- External libs
+	<script type="text/javascript" src="/web-data/lib/prototype-1.6.1_rc3.js"></script>
+	<script type="text/javascript" src="/web-data/lib/scriptaculous.js?load=effects"></script>
+	<script type="text/javascript" src="/web-data/lib/shadedborder.js"></script>
+	<script type="text/javascript" src="/web-data/lib/trimpath-template-1.0.38.js"></script>
+	 -->
+	<script type="text/javascript" src="/web-data/lib/libs_minified.js"></script>
+	<!-- userprefs Object -->
+	<script type="text/javascript" src="/web-data/userprefs.js"></script>	
+	<!-- our stuff //-->
+	<script type="text/javascript" src="/web-data/objects.js" ></script>
+	<script type="text/javascript" src="/web-data/statics.js" ></script>
+	<script type="text/javascript" src="/web-data/tools.js" ></script>
+	<script type="text/javascript" src="/web-data/timer.js" ></script>	
+	<script type="text/javascript" src="/web-data/vlcplayer.js" ></script>
+	<link href="/web-data/tpl/default/streaminterface/style.css" type="text/css" rel="stylesheet">
+	<link rel="shortcut icon" type="/web-data/image/x-icon" href="/web-data/img/favicon.ico">
+	<!-- Live RSS Feeds //-->
+	<link rel="alternate" type="application/rss+xml" title="Movie List" href="/web/movielist.rss?tag" >
+	<script language="javascript" type="text/javascript">
+		
+		if (!window.$) {
+			window.$ = function(id) { return document.getElementById(id); }
+		}
+		
+		function getWinSize(win) 
+		{ 
+			if(!win) win = window; 
+			var s = {}; 
+			if(typeof win.innerWidth != 'undefined') 
+			{ 
+				s.width = win.innerWidth; 
+				s.height = win.innerHeight; 
+			} 
+			else 
+			{ 
+				 var obj = getBody(win); 
+				 s.width = parseInt(obj.clientWidth); 
+				 s.height = parseInt(obj.clientHeight); 
+			} 
+			return s; 
+		} 
+
+		function getBody(w) 
+		{ 
+			return (w.document.compatMode && w.document.compatMode == "CSS1Compat") ? w.document.documentElement : w.document.body || null; 
+		} 
+		
+		function setMaxHeight(element){
+			/*
+			try{			
+				var slc = $(element);
+				size = getWinSize();
+				slc.style.maxHeight = size.height - 200+"px";
+			} catch (e) {}
+			*/
+			//onresize="setMaxHeight('contentMain')" 
+		}
+
+	</script>
+</head>
+<body onload="document.getElementById('notification').style.display='none'">
+	<div id="container">
+		<div id="banner">
+			<span id="notification"><div></div></span>
+			<div id="bannerLeft">
+				<div id="bannerText" style="font-size: 24px;">
+					<img src="/web-data/tpl/default/streaminterface/img/aafwebtv.png" alt="AAF WebTV">
+				</div>
+				<div id="current">
+				</div>
+			</div>			
+			<div id="bannerRight">
+				<table id="volumeTable">
+					<tr>
+						<td>Volume: </td>
+						<td id="vlcVolume"></td>
+					</tr>
+				</table>				
+			</div>
+		</div>
+		<div id="content">
+			<div id="contentMain">
+				<center>
+					<div id="vlcPlayer">
+						<embed 
+							type="application/x-vlc-plugin" 
+							pluginspage="http://www.videolan.org" 
+							version="VideoLAN.VLCPlugin.2"
+						    width="768"
+						    height="576"
+						    id="vlc">
+						</embed>
+					</div>
+					<div id="vlcButtons">
+						<button onClick="vlcPrev()" title="Previous Service">
+							<img src="/web-data/tpl/default/streaminterface/img/control_start_blue.png" alt="&lt;&lt;" />
+						</button>
+						<button onClick="vlcPlay()" title="Play">
+							<img src="/web-data/tpl/default/streaminterface/img/control_play_blue.png" alt="&gt;" />
+						</button>
+						<button onClick="vlcNext()" title="Next Service">
+							<img src="/web-data/tpl/default/streaminterface/img/control_end_blue.png" alt="&lt;&lt;" />
+						</button>
+						<button onClick="vlcStop()" title="Stop">
+							<img src="/web-data/tpl/default/streaminterface/img/control_stop_blue.png" alt="Stop" />
+						</button>
+						<button onClick="vlcFullscreen()" title="Fullscren">
+							<img src="/web-data/tpl/default/streaminterface/img/monitor.png" alt="Fullscreen" />
+						</button>
+						<button onClick="vlcVolumeDown()" title="Volume Down">
+							<img src="/web-data/tpl/default/streaminterface/img/sound_delete.png" alt="Vol-" />
+						</button>
+						<button onClick="vlcToogleMute()"  title="Mute Audio">
+							<img src="/web-data/tpl/default/streaminterface/img/sound_mute.png" alt="Mute" />							
+						</button>
+						<button onClick="vlcVolumeUp()"  title="Volume Up">
+							<img src="/web-data/tpl/default/streaminterface/img/sound_add.png" alt="Vol+" />
+						</button>
+						<input type="checkbox" id="vlcZap" title="Also zap on TV (for Subservices)">Zap</input>
+						<br>
+						<span id="bouquetList"></span>
+						<span id="channelList"></span>
+					</div>
+				</center>
+			</div>				
+		</div>	
+	</div>
+	<script language="JavaScript" type="Text/Javascript">
+	<!--
+	function addtoFavorites(){ 
+		var url = location.href.replace("#", ""); 
+		var title = "Dreambox WebTV"; 
+		
+		if (window.sidebar){
+			// firefox
+			window.sidebar.addPanel(title, url, "");
+	
+		} else if(window.opera && window.print){
+			// opera
+			var elem = document.createElement('a');
+			elem.setAttribute('href', url);
+			elem.setAttribute('title', title);
+			elem.setAttribute('rel', 'sidebar');
+			elem.click();
+
+		} else if(document.all){
+			// ie
+			window.external.AddFavorite(url,title);
+		}
+	}
+	-->
+	</script>
+	<div>
+		<a style="color: #FFF;font-size: 12px; font-weight: normal;" href="#" onClick="addtoFavorites()">Add to Favorites</a>
+	</div>
+	<script language="javascript" type="text/javascript">			
+		initWebTv();
+	</script>
+</body>
+</html>
Index: ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web-data/timer.js
===================================================================
--- ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web-data/timer.js	(revision 14969)
+++ ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web-data/timer.js	(revision 14969)
@@ -0,0 +1,731 @@
+// $Header$
+
+// TimerEdit variables:
+var addTimerEditFormArray = [];
+addTimerEditFormArray.TVList = [];
+addTimerEditFormArray.TVListFilled = 0;
+addTimerEditFormArray.RadioListFilled = 0;
+addTimerEditFormArray.deleteOldOnSave = 0;
+addTimerEditFormArray.eventID = 0;
+addTimerEditFormArray.locationsList = [];
+addTimerEditFormArray.tagsList = [];
+
+var days = [ 'mo', 'tu', 'we', 'th', 'fr', 'sa', 'su' ];
+
+var servicereftoloadepgnow = '';
+// Channel menu consists of:
+// 1. The currently selected channel, unless it is contained in 2.
+// 2. The currently selected bouquet
+// 3. The TV bouquets and the Radio bouquets
+function addTimerFormPrepareChannelMenu() {
+	var result = {};
+	var tvblist = addTimerEditFormArray.TVList;
+	var radioblist = addTimerEditFormArray.RadioList;
+	var currbouquet = addTimerEditFormArray.currBouquetName;
+	var currblist = addTimerEditFormArray.currBouquetList;
+
+	var found = false;
+	for (var i = 0; i < currblist.length; i++) {
+		var service = currblist[i];
+		if (addTimerEditFormArray.channel == service.servicename) {
+			found = true;
+			break;
+		}		
+	}
+	if (!found) {
+		result[addTimerEditFormArray.channel] = addTimerEditFormArray.channelName;
+	}
+	
+	if (currbouquet) {
+		result["<Currbouquet>"] = "-- " + currbouquet + " --";
+		for (var i = 0; i < currblist.length; i++) {
+			var service = currblist[i];
+			result[service.servicereference] = service.servicename;
+		}
+	}
+	result["<Bouquets>"] = "-- Bouquets --";
+	for (var i = 0; i < tvblist.length; i++) {
+		service = tvblist[i];
+		result[service.servicereference] = service.servicename;		
+	}
+	for (var i = 0; i < radioblist.length; i++) {
+		service = radioblist[i];
+		result[service.servicereference] = service.servicename;	
+	}
+	return result;
+}
+
+function addTimerFormChangeChannel(newchannel) {
+	var tvblist = addTimerEditFormArray.TVList;
+	var radioblist = addTimerEditFormArray.RadioList;
+	if (newchannel == "<Currbouquet>" || newchannel == "<Bouquets>") {
+		// reset selection to last valid channel
+		for ( var i = 0; i < $('channel').options.length; i++) {
+			if ($('channel').options[i].value == addTimerEditFormArray.channel) {
+				$('channel').options[i].selected = true;
+				break;
+			}
+		}
+		return;
+	}
+	var found = false;
+	for (var i = 0; i < tvblist.length; i++) {
+		var service = tvblist[i];
+		if (service.servicereference == newchannel) {
+			found = true;
+			addTimerEditFormArray.currBouquetName = service.servicename;
+			addTimerEditFormArray.currBouquetList = [];
+			break;
+		}
+	}
+	if (!found) {
+		for (var i = 0; i < radioblist.length; i++) {
+			var service = radioblist[i];
+			if (service.servicereference == newchannel) {
+				found = true;
+				addTimerEditFormArray.currBouquetName = service.servicename;
+				addTimerEditFormArray.currBouquetList = [];
+				break;
+			}
+		}
+	}
+	if (found) {
+		// bouquet selected, update menu
+		servicereftoloadepgnow = service.servicereference;
+		if (typeof (loadedChannellist[servicereftoloadepgnow]) == "undefined") {
+			doRequest(URL.getservices + servicereftoloadepgnow,
+					incomingAddTimerFormChangeChannel, true);
+		} else {
+			incomingAddTimerFormChangeChannel();
+		}
+	} else {
+		// real channel selected, update channel and channelName
+		addTimerEditFormArray.channel = newchannel;
+		for (i = 0; i < $('channel').options.length; i++) {
+			if ($('channel').options[i].value == newchannel) {
+				addTimerEditFormArray.channelName = $('channel').options[i].text;
+				break;
+			}
+		}
+	}
+}
+
+function incomingAddTimerFormChangeChannel(request) {
+	var services = null;
+	if (typeof (loadedChannellist[servicereftoloadepgnow]) != "undefined") {
+		services = loadedChannellist[servicereftoloadepgnow];
+	} else if (request.readyState == 4) {
+		services = new ServiceList(getXML(request)).getArray();
+		loadedChannellist[servicereftoloadepgnow] = services;
+	}
+	if (services !== null) {
+		debug("[incomingAddTimerFormChangeChannel] Got " + services.length + " Services");
+		for ( var i = 0; i < services.length; i++) {
+			var service = services[i];
+			addTimerEditFormArray.currBouquetList[i] = service;
+		}
+	}
+
+	var lst = addTimerFormPrepareChannelMenu();
+
+	for (i = $('channel').options.length; i !== 0; i--) {
+		$('channel').options[i - 1] = null;
+	}
+	for (var element in lst) {
+		$('channel').options[i] = new Option(lst[element]);
+		$('channel').options[i].value = element;
+		if (element == addTimerEditFormArray.channel) {
+			$('channel').options[i].selected = true;
+		}
+		i++;
+	}
+}
+
+function addTimerFormPrepareTagsMenu(currtags) {
+	var result = {};
+	var resultsuff = {};
+	var taglist = addTimerEditFormArray.tagsList;
+
+	if (currtags === "") {
+		i = 0;
+		result[""] = "<None>";
+		for ( var i = 0; i < taglist.length; i++) {
+			result[taglist[i]] = taglist[i];
+		}
+	} else {
+		result[currtags] = currtags;
+		var tags = currtags.split(" ");
+		for ( var i = 0; i < taglist.length; i++) {
+			var res = "";
+			var found = false;
+			for ( var j = 0; j < tags.length; j++) {
+				if (tags[j] != taglist[i]) {
+					res += " " + tags[j];
+				} else {
+					found = true;
+				}
+			}
+			if (!found) {
+				res += " " + taglist[i];
+			}
+			if (res.length > 0) {
+				res = res.substring(1, res.length);
+			}
+			if (found) {
+				resultsuff[res] = "- " + taglist[i];
+			} else {
+				result[res] = "+ " + taglist[i];
+			}
+		}
+		if (tags.length > 1) {
+			for (var ele in resultsuff) {
+				result[ele] = resultsuff[ele];
+			}
+		}
+		result[""] = "<None>";
+	}
+	return result;
+}
+
+function addTimerFormChangeTags(newtags) {
+	var lst = addTimerFormPrepareTagsMenu(newtags);
+
+	for ( var i = $('tags').options.length; i !== 0; i--) {
+		$('tags').options[i - 1] = null;
+	}
+
+	for (var element in lst) {
+		$('tags').options[i] = new Option(lst[element]);
+		$('tags').options[i].value = element;
+		i++;
+	}
+}
+
+// Timer
+function addTimerByID(sRef, eventID, justplay) {
+	if (parentPin(sRef)) {
+		debug("[addTimerByID] eventID: " + eventID);
+		doRequest(URL.timeraddbyeventid + "?sRef=" + sRef + "&eventid="	+ 
+				eventID + "&justplay=" + justplay, incomingTimerAddResult, false);
+	}
+}
+
+function incomingTimerAddResult(request) {
+	debug("[incomingTimerAddResult] called");
+	if (request.readyState == 4) {
+		var result = new SimpleXMLResult(getXML(request));
+		if (result.getState()) {
+			//timer has been added
+			loadTimerList();
+		}
+		simpleResultHandler(result);
+	}
+}
+
+function loadTimerList() {
+	doRequest(URL.timerlist, incomingTimerList, false);
+}
+
+function incomingTimerList(request) {
+	if (request.readyState == 4) {
+		var timerList = new TimerList(getXML(request)).getArray();
+		debug("[incomingTimerList] Got " + timerList.length + " timers");
+
+		var data = {
+			timer : timerList
+		};
+		processTpl('tplTimerList', data, 'contentMain');
+	}
+}
+
+function repeatedReadable(num) {
+	num = Number(num);
+	if (num === 0) {
+		return "One Time";
+	}
+
+	var retVal = "";
+	var Repeated = {};
+	Repeated["Mo-Su"] = 127;
+	Repeated["Mo-Fr"] = 31;
+	Repeated["Su"] = 64;
+	Repeated["Sa"] = 32;
+	Repeated["Fr"] = 16;
+	Repeated["Th"] = 8;
+	Repeated["We"] = 4;
+	Repeated["Tu"] = 2;
+	Repeated["Mo"] = 1;
+
+	for (var rep in Repeated) {
+		if (rep.toString() != 'extend') {
+			var check = Number(Repeated[rep]);
+			if (!(~num & check)) {
+				num -= check;
+				if (retVal === '') {
+					retVal += rep.toString();
+				} else {
+					retVal = rep.toString() + ',' + retVal;
+				}
+			}
+		}
+	}
+	return retVal;
+}
+
+function delTimer(sRef, begin, end, servicename, title, description,
+		readyFunction) {
+	debug("[delTimer] sRef(" + sRef + "),begin(" + begin + "),end(" + 
+			end	+ "),servicename(" + servicename + "),title(" + 
+			title + "),description(" + description + ")");
+	var result = confirm("Selected timer:\n" + "Channel: " + servicename + "\n"	+ 
+			"Title: " + title + "\n" + "Description: " + description + "\n"	+ 
+			"Are you sure that you want to delete the Timer?");
+	if (result) {
+		debug("[delTimer] ok confirm panel");
+		doRequest(URL.timerdelete + "?sRef=" + sRef + "&begin=" + begin + 
+				"&end=" + end, readyFunction, false);
+		return true;
+
+	} else {
+		debug("[delTimer] cancel confirm panel");
+	}
+	return false;
+}
+
+function incomingTimerDelResult(request) {
+	debug("[incomingTimerDelResult] called");
+	if (request.readyState == 4) {
+		var result = new SimpleXMLResult(getXML(request));
+		simpleResultHandler(result);
+		debug("[incomingTimerDelResult] Loading List");
+		loadTimerList();
+	}
+}
+
+function loadTimerFormNow() {
+	var now = new Date();
+	addTimerEditFormArray.year = now.getFullYear();
+	addTimerEditFormArray.month = now.getMonth() + 1;
+	addTimerEditFormArray.day = now.getDate();
+	addTimerEditFormArray.shour = now.getHours();
+	addTimerEditFormArray.smin = now.getMinutes();
+
+	var plusTwoHours = new Date(now.getTime() + ((120 * 60) * 1000));
+	addTimerEditFormArray.ehour = plusTwoHours.getHours();
+	addTimerEditFormArray.emin = plusTwoHours.getMinutes();
+
+	addTimerEditFormArray.justplay = "0";
+	addTimerEditFormArray.channel = "";
+	addTimerEditFormArray.channelName = "";
+	addTimerEditFormArray.name = "";
+	addTimerEditFormArray.description = "";
+	addTimerEditFormArray.dirname = "";
+	addTimerEditFormArray.tags = "";
+	addTimerEditFormArray.repeated = 0;
+	addTimerEditFormArray.afterEvent = "3";
+	addTimerEditFormArray.deleteOldOnSave = 0;
+
+	addTimerEditFormArray.beginOld = 0;
+	addTimerEditFormArray.endOld = 0;
+	addTimerEditFormArray.eventID = 0;
+
+	debug("[loadTimerFormNow] done");
+	loadTimerFormTags();
+}
+
+function loadTimerEditForm(justplay, begin, end, repeated, channel,
+		channelName, name, description, dirname, tags, afterEvent,
+		deleteOldOnSave, eit) {
+	debug('[loadTimerEditForm] justplay: ' + justplay + ',begin: ' + begin + 
+			',end: ' + end + ',repeated: ' + repeated + ',channel: ' + 
+			channel + ',name: ' + name + ',description: ' + description + 
+			',dirname: ' + dirname + ',tags: ' + tags + ',afterEvent: '	+ 
+			afterEvent + ',deleteOldOnSave: ' + deleteOldOnSave);
+	var start = new Date(Number(begin) * 1000);
+	addTimerEditFormArray.year = start.getFullYear();
+	addTimerEditFormArray.month = start.getMonth() + 1;
+	addTimerEditFormArray.day = start.getDate();
+	addTimerEditFormArray.shour = start.getHours();
+	addTimerEditFormArray.smin = start.getMinutes();
+
+	var stopp = new Date(Number(end) * 1000);
+	addTimerEditFormArray.ehour = stopp.getHours();
+	addTimerEditFormArray.emin = stopp.getMinutes();
+
+	addTimerEditFormArray.justplay = String(justplay);
+	addTimerEditFormArray.channel = String(channel);
+	addTimerEditFormArray.channelName = String(channelName);
+	addTimerEditFormArray.name = String(name);
+	addTimerEditFormArray.description = String(description);
+	addTimerEditFormArray.dirname = String(dirname);
+	addTimerEditFormArray.tags = String(tags);
+	addTimerEditFormArray.repeated = Number(repeated);
+	addTimerEditFormArray.afterEvent = afterEvent;
+
+	debug("[loadTimerEditForm]" + justplay + "|" + begin + "|" + end + "|" + 
+			repeated + "|" + channel + "|" + name + "|" + description + "|"	+ 
+			dirname + "|" + tags + "|" + afterEvent);
+
+	addTimerEditFormArray.deleteOldOnSave = Number(deleteOldOnSave);
+	addTimerEditFormArray.beginOld = Number(begin);
+	addTimerEditFormArray.endOld = Number(end);
+
+	addTimerEditFormArray.eventID = Number(eit);
+
+	loadTimerFormTags();
+}
+
+function loadTimerFormTags() {
+	doRequest(URL.gettags, incomingTimerFormTags, false);
+}
+
+function incomingTimerFormTags(request) {
+	debug("[incomingTimerFormTags] called");
+	if (request.readyState == 4) {
+		var result = new SimpleXMLList(getXML(request), "e2tag");
+		addTimerEditFormArray.tagsList = result.getList();
+		loadTimerFormLocations();
+	}
+}
+
+function loadTimerFormLocations() {
+	doRequest(URL.getlocations, incomingTimerFormLocations, false);
+}
+
+function incomingTimerFormLocations(request) {
+	debug("[incomingTimerFormLocations] called");
+	if (request.readyState == 4) {
+		var result = new SimpleXMLList(getXML(request), "e2location");
+		addTimerEditFormArray.locationsList = result.getList();
+		if (addTimerEditFormArray.locationsList.length === 0) {
+			addTimerEditFormArray.locationsList = [ "/hdd/movie" ];
+		}
+		loadTimerFormChannels();
+	}
+}
+
+// starting to load for TV
+function loadTimerFormChannels() {
+	if (addTimerEditFormArray.TVListFilled === 1 && 
+			addTimerEditFormArray.RadioListFilled === 1) {
+		loadTimerForm();
+	} else if (addTimerEditFormArray.TVListFilled === 1	&& 
+			addTimerEditFormArray.RadioListFilled === 0) {
+		addTimerListFormatTV();
+	} else {
+		doRequest(URL.getservices + encodeURIComponent(bouquetsTv),
+				addTimerListFormatTV, false);
+	}
+}
+
+function addTimerListFormatTV(request) {
+	if (addTimerEditFormArray.RadioListFilled === 0) {
+		if (request.readyState == 4) {
+			var serviceList = new ServiceList(getXML(request)).getArray();
+			var tv = [];
+			
+			for ( var i = 0; i < serviceList.length; i++) {
+				var service = serviceList[i];
+				tv[i] = service;
+			}
+			
+			addTimerEditFormArray.TVListFilled = 1;
+			addTimerEditFormArray.TVList = tv;
+		}
+	}
+	if (addTimerEditFormArray.RadioListFilled == 1) {
+		loadTimerForm();
+	} else {
+		doRequest(URL.getservices + encodeURIComponent(bouquetsRadio),
+				addTimerListFormatRadio, false);
+	}
+}
+
+function addTimerListFormatRadio(request) {
+	if (request.readyState == 4) {
+		var serviceList = new ServiceList(getXML(request)).getArray();
+		var radio = [];
+		
+		for ( var i = 0; i < serviceList.length; i++) {
+			var service = serviceList[i];
+			radio[i] = service;
+		}
+		
+		addTimerEditFormArray.RadioListFilled = 1;
+		addTimerEditFormArray.RadioList = radio;
+	}
+	addTimerEditFormArray.currBouquetName = "";
+	addTimerEditFormArray.currBouquetList = {};
+	loadTimerForm();
+}
+
+function loadTimerForm() {
+
+	var Action = {};
+	Action["0"] = "Record";
+	Action["1"] = "Zap";
+
+	var Repeated = {};
+	Repeated["1"] = "mo";
+	Repeated["2"] = "tu";
+	Repeated["4"] = "we";
+	Repeated["8"] = "th";
+	Repeated["16"] = "fr";
+	Repeated["32"] = "sa";
+	Repeated["64"] = "su";
+	Repeated["31"] = "mf";
+	Repeated["127"] = "ms";
+
+	var AfterEvent = {};
+	AfterEvent["0"] = "Nothing";
+	AfterEvent["1"] = "Standby";
+	AfterEvent["2"] = "Deepstandby/Shutdown";
+	AfterEvent["3"] = "Auto";
+
+	addTimerEditFormArray.name = (typeof (addTimerEditFormArray.name) != 'undefined') ? addTimerEditFormArray.name
+			: '';
+	addTimerEditFormArray.name = (addTimerEditFormArray.name === '') ? ' '
+			: addTimerEditFormArray.name;
+
+	addTimerEditFormArray.description = (typeof (addTimerEditFormArray.description) != 'undefined') ? addTimerEditFormArray.description
+			: '';
+	addTimerEditFormArray.description = (addTimerEditFormArray.description === '') ? ' '
+			: addTimerEditFormArray.description;
+
+	var channelObject = addTimerFormPrepareChannelMenu(
+			addTimerEditFormArray.TVList, addTimerEditFormArray.RadioList);
+
+	var locationsObject = {};
+	for ( var i = 0; i < addTimerEditFormArray.locationsList.length; i++) {
+		str = addTimerEditFormArray.locationsList[i];
+		locationsObject[str] = str;
+	}
+
+	var tagsObject = addTimerFormPrepareTagsMenu(addTimerEditFormArray.tags);
+
+	var namespace = {
+		'year' : createOptions(2009, 2015, addTimerEditFormArray.year),
+		'month' : createOptions(1, 12, addTimerEditFormArray.month),
+		'day' : createOptions(1, 31, addTimerEditFormArray.day),
+		'shour' : createOptions(0, 23, addTimerEditFormArray.shour),
+		'smin' : createOptions(0, 59, addTimerEditFormArray.smin),
+		'ehour' : createOptions(0, 23, addTimerEditFormArray.ehour),
+		'emin' : createOptions(0, 59, addTimerEditFormArray.emin),
+		'action' : createOptionList(Action, addTimerEditFormArray.justplay),
+		'channel' : createOptionList(channelObject,
+				addTimerEditFormArray.channel),
+		'afterEvent' : createOptionList(AfterEvent,
+				addTimerEditFormArray.afterEvent),
+		'repeated' : createOptionListRepeated(Repeated,
+				addTimerEditFormArray.repeated),
+		'dirname' : createOptionList(locationsObject,
+				addTimerEditFormArray.dirname),
+		'tags' : createOptionList(tagsObject, addTimerEditFormArray.tags),
+
+		'timer' : {
+			'name' : addTimerEditFormArray.name,
+			'description' : addTimerEditFormArray.description,
+			'deleteOldOnSave' : addTimerEditFormArray.deleteOldOnSave,
+			'channelOld' : addTimerEditFormArray.channel,
+			'beginOld' : addTimerEditFormArray.beginOld,
+			'endOld' : addTimerEditFormArray.endOld,
+			'eventID' : addTimerEditFormArray.eventID
+		}
+	};
+	var data = namespace;
+	processTpl('tplTimerEdit', data, 'contentMain');
+}
+
+function createOptions(start, end, number) {
+	var namespace = [];
+
+	for ( var i = start; i <= end; i++) {
+		var txt = (String(i).length == 1) ? "0" + String(i) : String(i);
+		var selected = (i == Number(number)) ? "selected" : " ";
+		namespace[i] = {
+			'value' : i,
+			'txt' : txt,
+			'selected' : selected
+		};
+	}
+	return namespace;
+}
+
+function createOptionList(object, selected) {
+	var namespace = Array();
+	var i = 0;
+	for ( var element in object) {
+		var txt = String(object[element]);
+		var sel = " ";
+
+		if (element == selected) {
+			sel = "selected";
+		}
+
+		if (element != "extend") {
+			namespace[i] = {
+				'value' : element,
+				'txt' : txt,
+				'selected' : sel
+			};
+			i++;
+		}
+	}
+
+	return namespace;
+}
+
+function createOptionListRepeated(Repeated, repeated) {
+	var num = Number(repeated);
+
+	var list = [ 1, 2, 4, 8, 16, 32, 64, 31, 127 ];
+	var namespace = [];
+	var checked = [];
+
+	for ( var i = 0; i < list.length; i++) {
+		checked[i] = " ";
+		if (!(~num & list[list.length - 1 - i])) {
+			num -= list[list.length - 1 - i];
+			checked[i] = "checked";
+		}
+	}
+	for ( var i = 0; i < list.length; i++) {
+		var txt = String(Repeated[String(list[i])]);
+		if (String(Repeated[String(list[i])]) == "mf") {
+			txt = "Mo-Fr";
+		} else if (String(Repeated[String(list[i])]) == "ms") {
+			txt = "Mo-Su";
+		} else {
+			txt = txt.substr(0, 1).toUpperCase() + txt.substr(1, 1);
+		}
+		namespace[i] = {
+			'id' : Repeated[String(list[i])],
+			'name' : Repeated[String(list[i])],
+			'value' : list[i],
+			'txt' : txt,
+			'checked' : checked[list.length - 1 - i]
+		};
+	}
+	return namespace;
+}
+
+function sendAddTimer() {
+	debug("[sendAddTimer]" + "parentChannel:" + $('channel').value);
+
+	if (parentPin($('channel').value)) {
+		var beginD = new Date(parseNr($('year').value),
+				(parseNr($('month').value) - 1), parseNr($('day').value),
+				parseNr($('shour').value), parseNr($('smin').value));
+		var begin = beginD.getTime() / 1000;
+
+		var endD = new Date(parseNr($('year').value),
+				(parseNr($('month').value) - 1), parseNr($('day').value),
+				parseNr($('ehour').value), parseNr($('emin').value));
+		var end = endD.getTime() / 1000;
+		if (end < begin) {
+			end += 86400;
+		}
+
+		var descriptionClean = ($('descr').value == " " || $('descr').value == "N/A") ? ""
+				: $('descr').value;
+		var nameClean = ($('name').value == " " || $('name').value == "N/A") ? ""
+				: $('name').value;
+
+		descriptionClean = encodeURIComponent(descriptionClean);
+		nameClean = encodeURIComponent(nameClean);
+
+		var dirname = encodeURIComponent($F($('timerDir').dirname));
+		var tags = encodeURIComponent($F($('timerTags').tags));
+
+		var repeated = 0;
+		if ($('ms').checked) {
+			repeated = parseNr($('ms').value);
+		} else if ($('mf').checked) {
+			repeated = parseNr($('mf').value);
+			if ($('su').checked) {
+				repeated += parseNr($('su').value);
+			}
+			if ($('sa').checked) {
+				repeated += parseNr($('sa').value);
+			}
+		} else {
+			for ( var i = 0; i < days.length; i++) {
+				if ($(days[i]).checked) {
+					repeated += parseNr($(days[i]).value);
+				}
+			}
+		}
+		//addTimerByID(\'%(servicereference)\',\'%(eventid)\',\'False\');
+		doRequest(URL.timerchange + "?" + "sRef=" + 
+				($('channel').value).replace("&quot;", '"') + "&begin="	+ 
+				begin + "&end=" + end + "&name=" + nameClean + 
+				"&description=" + descriptionClean + "&dirname=" + dirname+ 
+				"&tags=" + tags + "&afterevent=" + $('after_event').value + 
+				"&eit=0&disabled=0" + "&justplay=" + parseNr($('justplay').value) + 
+				"&repeated=" + repeated	+ "&channelOld=" + $('channelOld').value + 
+				"&beginOld=" + $('beginOld').value + "&endOld=" + $('endOld').value	+ 
+				"&eventID" + $('eventID').value + "&deleteOldOnSave=" + 
+				parseNr($('deleteOldOnSave').value), incomingTimerAddResult, false
+			);
+	}
+}
+
+function cleanTimerListNow() {
+	debug("[cleanTimerListNow] called");
+	var result = confirm("Do you really want to cleanup the List of Timers?");
+	if (result) {
+		doRequest(URL.timercleanup, incomingCleanTimerListNow, false);
+	}
+}
+
+function incomingCleanTimerListNow(request) {
+	if (request.readyState == 4) {
+		var result = new SimpleXMLResult(getXML(request));
+		simpleResultHandler(result);
+		loadTimerList();
+	}
+}
+
+function incomingJustDoNothing(request) {
+	debug("[incomingJustDoNothing] called");
+}
+
+function sendToggleTimerDisable(justplay, begin, end, repeated, channel, name,
+		description, dirname, tags, afterEvent, disabled) {
+	disabled = (parseNr(disabled) === 0) ? 1 : 0;
+
+	var descriptionClean = (description == " " || description == "N/A") ? ""
+			: description;
+	var nameClean = (name == " " || name == "N/A") ? "" : name;
+
+	nameClean = encodeURIComponent(nameClean);
+	descriptionClean = encodeURIComponent(descriptionClean);
+	tags = encodeURIComponent(tags);
+
+	doRequest(URL.timerchange + "?" + "sRef=" + channel.replace("&quot;", '"') + 
+			"&begin=" + begin + "&end=" + end + "&name=" + nameClean+ 
+			"&description=" + descriptionClean + "&dirname=" + dirname + 
+			"&tags=" + tags + "&afterevent=" + afterEvent + "&eit=0&disabled=" + 
+			disabled + "&justplay=" + justplay + "&repeated=" + repeated +
+			"&channelOld=" + channel + "&beginOld="	+ begin + "&endOld=" + end + 
+			"&deleteOldOnSave=1", incomingTimerAddResult, false
+		);
+}
+
+function recordNowDecision(recordNowCurrent) {
+	var recordNow = "infinite";
+	if (recordNowCurrent === true) {
+		recordNow = "current";
+	}
+	doRequest(URL.recordnow + "?recordnow=" + recordNow,
+			incomingTimerAddResult, false);
+}
+
+function incomingWriteTimerListNow(request) {
+	var result = new SimpleXMLResult(getXML(request));
+	simpleResultHandler(result);
+}
+
+function writeTimerListNow() {
+	doRequest(URL.timerlistwrite, incomingWriteTimerListNow);
+}
Index: ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web-data/tools.js
===================================================================
--- ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web-data/tools.js	(revision 14969)
+++ ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web-data/tools.js	(revision 14969)
@@ -0,0 +1,1438 @@
+//$Header: /cvsroot/enigma2-plugins/enigma2-plugins/webinterface/src/web-data/tools.js,v 1.219 2010-07-26 10:28:43 sreichholf Exp $
+var templates = {};
+var loadedChannellist = {};
+
+var epgListData = {};
+var signalPanelData = {};
+
+var mediaPlayerStarted = false; 
+var popUpBlockerHinted = false;
+
+var settings = null;
+var parentControlList = null;
+
+var requestcounter = 0;
+
+var debugWin = '';
+var signalWin = '';
+var webRemoteWin = '';
+var EPGListWin = '';
+
+var currentBouquet = bouquetsTv;
+
+var updateBouquetItemsPoller = '';
+var updateCurrentPoller = '';
+var signalPanelUpdatePoller = '';
+
+var hideNotifierTimeout = '';
+
+var isActive = {};
+isActive.getCurrent = false;
+
+var currentLocation = "/hdd/movie";
+var locationsList = [];
+var tagsList = [];
+
+var boxtype = "";
+
+function startUpdateCurrentPoller(){
+	clearInterval(updateCurrentPoller);
+	updateCurrentPoller = setInterval(updateItems, userprefs.data.updateCurrentInterval);
+}
+function stopUpdateCurrentPoller(){
+	clearInterval(updateCurrentPoller);
+}
+function getXML(request){
+	var xmlDoc = "";
+
+	if(window.ActiveXObject){ // we're on IE
+		xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
+		xmlDoc.async="false";
+		xmlDoc.loadXML(request.responseText);
+	} else { //we're not on IE
+		if (!window.google || !google.gears){
+			xmlDoc = request.responseXML;
+		} else { //no responseXML on gears
+			xmlDoc = (new DOMParser()).parseFromString(request.responseText, "text/xml");
+		}
+	}
+
+	return xmlDoc;
+}
+/*
+* Set boxtype Variable for being able of determining model specific stuff correctly (like WebRemote)
+*/
+function incomingDeviceInfoBoxtype(request){
+	debug("[incomingAboutBoxtype] returned");
+	boxtype = getXML(request).getElementsByTagName("e2devicename").item(0).firstChild.data;
+
+	debug("[incomingAboutBoxtype] Boxtype: " + boxtype);
+}
+function getBoxtype(){
+	doRequest(URL.deviceinfo, incomingDeviceInfoBoxtype, false);	
+}
+function toggleStandby(){
+	sendPowerState(0);
+}
+function incomingPowerState(request){
+	var standby = getXML(request).getElementsByTagName("e2instandby").item(0).firstChild.data;
+	
+	var signal = $('openSignalPanel');
+	var signalImg = $('openSignalPanelImg');
+	
+	if(standby.strip() == "false"){
+		signal.stopObserving('click', openSignalPanel);
+		signal.observe('click', openSignalPanel);
+		
+		signalImg.src = "/web-data/img/signal.png";
+		signalImg.title = "Show Signal Panel";
+		
+	} else {
+		signal.stopObserving('click', openSignalPanel);		
+		
+		signalImg.src = "/web-data/img/signal_off.png";
+		signalImg.title = "Please disable standby first";
+	}
+}
+function getPowerState(){
+	doRequest(URL.powerstate, incomingPowerState);	
+}
+function set(element, value){
+	element = parent.$(element);
+	if (element){
+		element.update(value);
+	}
+}
+function hideNotifier(){
+	$('notification').fade({duration : 0.5 });
+}
+function notify(text, state){
+	notif = $('notification');
+
+	if(notif !== null){
+		//clear possibly existing hideNotifier timeout of a previous notfication
+		clearTimeout(hideNotifierTimeout);
+		if(state === false){
+			notif.style.background = "#C00";
+		} else {
+			notif.style.background = "#85C247";
+		}				
+
+		set('notification', "<div>"+text+"</div>");
+		notif.appear({duration : 0.5, to: 0.9 });
+		hideNotifierTimeout = setTimeout(hideNotifier, 10000);
+	}
+}
+function simpleResultHandler(simpleResult){
+	notify(simpleResult.getStateText(), simpleResult.getState());
+}
+function startUpdateBouquetItemsPoller(){
+	debug("[startUpdateBouquetItemsPoller] called");
+	clearInterval(updateBouquetItemsPoller);
+	updateBouquetItemsPoller = setInterval(updateItemsLazy, userprefs.data.updateBouquetInterval);
+}
+function stopUpdateBouquetItemsPoller(){
+	debug("[stopUpdateBouquetItemsPoller] called");
+	clearInterval(updateBouquetItemsPoller);
+}
+//General Helpers
+function parseNr(num) {
+	if(isNaN(num)){
+		return 0;
+	} else {
+		return parseInt(num);
+	}
+}
+function dec2hex(nr, len){
+
+	var hex = parseInt(nr, 10).toString(16).toUpperCase();
+	if(len > 0){
+		try{
+			while(hex.length < len){
+				hex = "0"+hex;
+			}
+		} 
+		catch(e){
+			//something went wrong, return -1
+			hex = -1;
+		}
+	}
+	
+	hex = '0x' + hex;
+	
+	return hex;
+}
+function quotes2html(txt) {
+	if(typeof(txt) != "undefined"){
+		return txt.escapeHTML().replace('\n', '<br>');
+	} else {
+		return "";
+	}
+}
+function addLeadingZero(nr){
+	if(nr < 10){
+		return '0' + nr;
+	}
+	return nr;
+}
+function dateToString(date){
+
+	var dateString = "";
+
+	dateString += date.getFullYear();
+	dateString += "-" + addLeadingZero(date.getMonth()+1);
+	dateString += "-" + addLeadingZero(date.getDate());
+	dateString += " " + addLeadingZero(date.getHours());
+	dateString += ":" + addLeadingZero(date.getMinutes());
+
+	return dateString;
+}
+function showhide(id){
+	var s = $(id).style;
+	s.display = (s.display!="none")? "none":"";
+}
+function show(id){
+	try{
+		$(id).style.display = "";
+	} catch(e) {
+		debug("[show] Could not show element with id: " + id);
+	}
+}
+function hide(id){
+	try{
+		$(id).style.display = "none";
+	} catch(e) {
+		debug("[hide] Could not hide element with id: " + id);
+	}
+}
+/*
+* Sets the Loading Notification to the given HTML Element
+* @param targetElement - The element the Ajax-Loader should be set in
+*/
+function setAjaxLoad(targetElement){
+	$(targetElement).update( getAjaxLoad() );
+}
+//Ajax Request Helpers
+//requestindikator
+function requestIndicatorUpdate(){
+	/*debug(requestcounter+" open requests");
+	if(requestcounter>=1){
+		$('RequestIndicator').style.display = "inline";
+	}else{
+		$('RequestIndicator').style.display = "none";
+	}*/
+}
+function requestStarted(){
+	requestcounter +=1;
+	requestIndicatorUpdate();
+}
+function requestFinished(){
+	requestcounter -= 1;
+	requestIndicatorUpdate();
+}
+//Popup And Messagebox Helpers
+function messageBox(m){
+	alert(m);
+}
+function popUpBlockerHint(){
+	if(!popUpBlockerHinted){
+		popUpBlockerHinted = true;
+		messageBox("Please disable your Popup-Blocker for enigma2 WebControl to work flawlessly!");
+
+	}
+}
+function setWindowContent(window, html){
+	window.document.write(html);
+	window.document.close();
+}
+function openPopup(title, html, width, height, x, y){
+	try {
+		var popup = window.open('about:blank',title,'scrollbars=yes, width='+width+',height='+height);		
+		setWindowContent(popup, html);
+		return popup;
+	} catch(e){
+		popUpBlockerHint();
+		return "";
+	}
+}
+function openPopupPage(title, uri, width, height, x, y){
+	try {
+		var popup = window.open(uri,title,'scrollbars=yes, width='+width+',height='+height);
+		return popup;
+	} catch(e){
+		popUpBlockerHint();
+		return "";
+	}
+}
+function debug(text){
+	var DBG = userprefs.data.debug || false;
+	
+	if(DBG){
+		try{
+			if(!debugWin.closed && debugWin.location){
+				var inner = debugWin.document.getElementById('debugContent').innerHTML;
+				debugWin.document.getElementById('debugContent').innerHTML = new Date().toLocaleString() + ": "+text+"<br>" + inner;
+			} else { 			
+				openDebug();
+				
+				setTimeout(	function(){
+									var inner = debugWin.document.getElementById('debugContent').innerHTML;
+									debugWin.document.getElementById('debugContent').innerHTML = new Date().toLocaleString() + ": "+text+"<br>" + inner;
+								}, 
+								1000
+						  	);
+			}
+		} catch (Exception) {}
+	}
+}
+function saveSettings(){
+	userprefs.load();
+	
+	var debug = $('enableDebug').checked;
+	var changed = false;
+	if(typeof(debug) != "undefined"){
+		if( userprefs.data.debug != debug ){
+			userprefs.data.debug = debug;
+			changed = true;
+	
+			if(debug){
+				openDebug();
+			}
+		}		
+	}
+	
+	var updateCurrentInterval = parseNr( $F('updateCurrentInterval') ) * 1000;
+	if( updateCurrentInterval < 10000){
+		updateCurrentInterval = 120000;
+	}
+	
+	if( userprefs.data.updateCurrentInterval != updateCurrentInterval){
+		userprefs.data.updateCurrentInterval = updateCurrentInterval;
+		
+		changed = true;
+		startUpdateCurrentPoller();
+	}
+	
+	var updateBouquetInterval = parseNr( $F('updateBouquetInterval') )  * 1000;
+	if( updateBouquetInterval < 60000){
+		updateBouquetInterval = 300000;
+	}
+	
+	if( userprefs.data.updateBouquetInterval != updateBouquetInterval){
+		userprefs.data.updateBouquetInterval = updateBouquetInterval;
+		
+		changed = true;
+		startUpdateBouquetItemsPoller();
+	}
+	
+	if(changed){
+		userprefs.save();
+	}
+}
+//Template Helpers
+function saveTpl(request, tplName){
+	debug("[saveTpl] saving template: " + tplName);
+	templates[tplName] = request.responseText;
+}
+function renderTpl(tpl, data, domElement) {	
+	var result = tpl.process(data);
+
+	try{
+		$(domElement).update( result );
+	}catch(ex){
+		//		debug("[renderTpl] exception: " + ex);
+	}
+}
+function fetchTpl(tplName, callback){
+	if(typeof(templates[tplName]) == "undefined") {
+		var url = URL.tpl+tplName+".htm";
+		
+		doRequest(
+				url, 
+				function(transport){
+					saveTpl(transport, tplName);
+					if(typeof(callback) == 'function'){
+						callback();
+					}
+				}
+		);
+	} else {
+		if(typeof(callback) == 'function'){
+			callback();
+		}
+	}
+}
+function incomingProcessTpl(request, data, domElement, callback){
+	if(request.readyState == 4){
+		renderTpl(request.responseText, data, domElement);
+		if(typeof(callback) == 'function') {
+			callback();
+		}
+	}
+}
+function processTpl(tplName, data, domElement, callback){
+	var url = URL.tpl+tplName+".htm";
+	
+	doRequest(url, 
+			function(transport){
+		incomingProcessTpl(transport, data, domElement, callback);
+	}
+	);
+}
+//Debugging Window
+function openDebug(){
+	var uri = URL.tpl+'tplDebug.htm';
+	debugWin = openPopupPage("Debug", uri, 500, 300);
+}
+function requestFailed(transport){
+	var notifText = "Request failed for:  " + transport.request.url + "<br>Status: " + transport.status + " " + transport.statusText;
+	notify(notifText, false);
+}
+function doRequest(url, readyFunction){
+	requestStarted();
+	var request = '';
+	// gears or not that's the question here
+	if (!window.google || !google.gears){ //no gears, how sad
+//		debug("NO GEARS!!");		
+		try{
+			request = new Ajax.Request(url,
+					{
+						asynchronous: true,
+						method: 'GET',
+						requestHeaders: ['Cache-Control', 'no-cache,no-store', 'Expires', '-1'],
+						onException: function(o,e){ throw(e); },				
+						onSuccess: function (transport, json) {						
+							if(typeof(readyFunction) != "undefined"){
+								readyFunction(transport);
+							}
+						},
+						onFailure: function(transport){
+							requestFailed(transport);
+						},
+						onComplete: requestFinished 
+					});
+		} catch(e) {}
+	} else { //we're on gears!
+		try{
+			request = google.gears.factory.create('beta.httprequest');
+			request.open('GET', url);
+
+
+			request.onreadystatechange = function(){				
+				if(request.readyState == 4){
+					if(request.status == 200){
+						if( typeof(readyFunction) != "undefined" ){
+							readyFunction(request);
+						}
+					} else {
+						requestFailed(transport);
+					}
+				}
+			};
+			request.send();
+		} catch(e) {}
+	}
+}
+//Parental Control
+function incomingParentControl(request) {
+	if(request.readyState == 4){
+		parentControlList = new ServiceList(getXML(request)).getArray();
+		debug("[incomingParentControl] Got "+parentControlList.length + " services");
+	}
+}
+function getParentControl() {
+	doRequest(URL.parentcontrol, incomingParentControl, false);
+}
+function getParentControlByRef(txt) {
+	debug("[getParentControlByRef] ("+txt+")");
+	for(var i = 0; i < parentControlList.length; i++) {
+		debug( "[getParentControlByRef] "+parentControlList[i].getClearServiceReference() );
+		if(String(parentControlList[i].getClearServiceReference()) == String(txt)) {
+			return parentControlList[i].getClearServiceReference();
+		} 
+	}
+	return "";
+}
+//Settings
+function getSettingByName(txt) {
+	debug("[getSettingByName] (" + txt + ")");
+	for(var i = 0; i < settings.length; i++) {
+		debug("("+settings[i].getSettingName()+") (" +settings[i].getSettingValue()+")");
+		if(String(settings[i].getSettingName()) == String(txt)) {
+			return settings[i].getSettingValue().toLowerCase();
+		} 
+	}
+	return "";
+}
+function parentPin(servicereference) {
+	debug("[parentPin] parentControlList");
+	servicereference = decodeURIComponent(servicereference);
+	if(parentControlList === null || String(getSettingByName("config.ParentalControl.configured")) != "true") {
+		return true;
+	}
+	//debug("parentPin " + parentControlList.length);
+	if(getParentControlByRef(servicereference) == servicereference) {
+		if(String(getSettingByName("config.ParentalControl.type.value")) == "whitelist") {
+			debug("[parentPin] Channel in whitelist");
+			return true;
+		}
+	} else {
+		debug("[parentPin] sRef differs ");
+		return true;
+	}
+	debug("[parentPin] Asking for PIN");
+
+	var userInput = prompt('Parental Control is enabled!<br> Please enter the Parental Control PIN','PIN');
+	if (userInput !== '' && userInput !== null) {
+		if(String(userInput) == String(getSettingByName("config.ParentalControl.servicepin.0")) ) {
+			return true;
+		} else {
+			return parentPin(servicereference);
+		}
+	} else {
+		return false;
+	}
+}
+function incomingGetDreamboxSettings(request){
+	if(request.readyState == 4){
+		settings = new Settings(getXML(request)).getArray();
+
+		debug("[incomingGetDreamboxSettings] config.ParentalControl.configured="+ getSettingByName("config.ParentalControl.configured"));
+
+		if(String(getSettingByName("config.ParentalControl.configured")) == "true") {
+			getParentControl();
+		}
+	}
+}
+function getDreamboxSettings(){
+	doRequest(URL.settings, incomingGetDreamboxSettings, false);
+}
+//Subservices
+function incomingSubServiceRequest(request){
+	if(request.readyState == 4){
+		var services = new ServiceList(getXML(request)).getArray();
+		debug("[incomingSubServiceRequest] Got " + services.length + " SubServices");
+
+		if(services.length > 1) {
+
+			var first = services[0];
+
+			// we already have the main service in our servicelist so we'll
+			// start with the second element			
+			services.shift();
+			
+			var data = { subservices : services };
+			
+
+			var id = 'SUB'+first.servicereference;
+			show('tr' + id);
+			processTpl('tplSubServices', data, id);
+		}
+	}
+}
+function getSubServices(bouquet) {
+	doRequest(URL.subservices, incomingSubServiceRequest, false);
+}
+function delayedGetSubservices(){
+	setTimeout(getSubServices, 5000);
+}
+//zap zap
+function zap(servicereference){
+	doRequest("/web/zap?sRef=" + servicereference);	
+	setTimeout(updateItemsLazy, 7000); //reload epg and subservices
+	setTimeout(updateItems, 3000);
+}
+//SignalPanel
+function updateSignalPanel(){	
+	var html = templates.tplSignalPanel.process(signalPanelData);
+
+	if (!signalWin.closed && signalWin.location) {
+		setWindowContent(signalWin, html);
+	} else {
+		clearInterval(signalPanelUpdatePoller);
+		signalPanelUpdatePoller = '';
+	}
+}
+function incomingSignalPanel(request){
+	var namespace = {};
+
+	if (request.readyState == 4){
+		var xml = getXML(request).getElementsByTagName("e2frontendstatus").item(0);
+		namespace = {
+				snrdb : xml.getElementsByTagName('e2snrdb').item(0).firstChild.data,
+				snr : xml.getElementsByTagName('e2snr').item(0).firstChild.data,
+				ber : xml.getElementsByTagName('e2ber').item(0).firstChild.data,
+				acg : xml.getElementsByTagName('e2acg').item(0).firstChild.data
+		};
+	}
+
+	signalPanelData = { signal : namespace };
+	fetchTpl('tplSignalPanel', updateSignalPanel); 	
+}
+function reloadSignalPanel(){
+	doRequest(URL.signal, incomingSignalPanel, false);
+}
+function openSignalPanel(){
+	if (!(!signalWin.closed && signalWin.location)){
+		signalWin = openPopup('SignalPanel', '', 220, 120);
+		if(signalPanelUpdatePoller === ''){
+			signalPanelUpdatePoller = setInterval(reloadSignalPanel, 5000);
+		}
+	}
+	reloadSignalPanel();
+}
+//EPG functions
+function showEpgList(){
+	var html = templates.tplEpgList.process(epgListData);
+
+	if (!EPGListWin.closed && EPGListWin.location) {
+		setWindowContent(EPGListWin, html);
+	} else {
+		EPGListWin = openPopup("EPG", html, 900, 500);
+	}
+}
+function incomingEPGrequest(request){
+	debug("[incomingEPGrequest] readyState" +request.readyState);		
+	if (request.readyState == 4){
+		var EPGItems = new EPGList(getXML(request)).getArray(true);
+		debug("[incomingEPGrequest] got "+EPGItems.length+" e2events");
+
+		if( EPGItems.length > 0){
+			epgListData = {epg : EPGItems};
+			fetchTpl('tplEpgList', showEpgList);
+		} else {
+			messageBox('No Items found!', 'Sorry but I could not find any EPG Content containing your search value');
+		}
+	}
+}
+function loadEPGBySearchString(string){
+	doRequest(URL.epgsearch+escape(string),incomingEPGrequest, false);
+}
+function loadEPGByServiceReference(servicereference){
+	doRequest(URL.epgservice+servicereference,incomingEPGrequest, false);
+}
+function buildServiceListEPGItem(epgevent, type){
+	var data = { epg : epgevent,
+				 nownext: type
+				};
+
+	var id = type + epgevent.servicereference;
+
+	show('tr' + id);
+
+	if(typeof(templates.tplServiceListEPGItem) != "undefined"){
+		renderTpl(templates.tplServiceListEPGItem, data, id, true);
+	} else {
+		debug("[buildServiceListEPGItem] tplServiceListEPGItem N/A");
+	}
+}
+function incomingServiceEPGNowNext(request, type){
+	if(request.readyState == 4){
+		var epgevents = getXML(request).getElementsByTagName("e2eventlist").item(0).getElementsByTagName("e2event");
+		for (var c = 0; c < epgevents.length; c++){
+			try{
+				var epgEvt = new EPGEvent(epgevents.item(c), c).toJSON();
+			} catch (e){
+				debug("[incomingServiceEPGNowNext]" + e);
+			}
+
+			if (epgEvt.eventid != ''){
+				buildServiceListEPGItem(epgEvt, type);
+			}
+		}
+	}
+}
+function incomingServiceEPGNow(request){
+	incomingServiceEPGNowNext(request, 'NOW');
+}
+function incomingServiceEPGNext(request){
+	incomingServiceEPGNowNext(request, 'NEXT');
+}
+function loadServiceEPGNowNext(servicereference, next){
+	var url = URL.epgnow+servicereference;
+
+	if(typeof(next) == 'undefined'){
+		doRequest(url, incomingServiceEPGNow, false);
+	} else {
+		url = URL.epgnext+servicereference;
+		doRequest(url, incomingServiceEPGNext, false);
+	}
+}
+function getBouquetEpg(){
+	loadServiceEPGNowNext(currentBouquet);
+	loadServiceEPGNowNext(currentBouquet, true);
+}
+function recordNowPopup(){
+	var result = confirm(	
+			"OK: Record current event\n" +
+			"Cancel: Start infinite recording"
+	);
+
+	if( result === true || result === false){
+		recordNowDecision(result);
+	}
+}
+//+++++++++++++++++++++++++++++++++++++++++++++++++++++
+//+++++++++++++++++++++++++++++++++++++++++++++++++++++
+//++++ volume functions ++++
+//+++++++++++++++++++++++++++++++++++++++++++++++++++++
+//+++++++++++++++++++++++++++++++++++++++++++++++++++++
+function handleVolumeRequest(request){
+	if (request.readyState == 4) {
+		var b = getXML(request).getElementsByTagName("e2volume");
+		var newvalue = b.item(0).getElementsByTagName('e2current').item(0).firstChild.data;
+		var mute = b.item(0).getElementsByTagName('e2ismuted').item(0).firstChild.data;
+		debug("[handleVolumeRequest] Volume " + newvalue + " | Mute: " + mute);
+
+		for (var i = 1; i <= 10; i++)		{
+			if ( (newvalue/10)>=i){
+				$("volume"+i).src = "/web-data/img/led_on.png";
+			}else{
+				$("volume"+i).src = "/web-data/img/led_off.png";
+			}
+		}
+		if (mute == "False"){
+			$("speaker").src = "/web-data/img/speak_on.png";
+		}else{
+			$("speaker").src = "/web-data/img/speak_off.png";
+		}
+	}    	
+}
+function getVolume(){
+	doRequest(URL.getvolume, handleVolumeRequest, false);
+}
+function volumeSet(val){
+	doRequest(URL.setvolume+val, handleVolumeRequest, false);
+}
+function volumeUp(){
+	doRequest(URL.volumeup, handleVolumeRequest, false);
+}
+function volumeDown(){
+	doRequest(URL.volumedown, handleVolumeRequest, false);
+}
+function volumeMute(){
+	doRequest(URL.volumemute, handleVolumeRequest, false);
+}
+function initVolumePanel(){
+	getVolume(); 
+}
+//Channels and Bouquets
+function incomingChannellist(request){
+	var serviceList = null;
+	if(typeof(loadedChannellist[currentBouquet]) != "undefined"){
+		serviceList = loadedChannellist[currentBouquet];
+	} else if(request.readyState == 4) {
+		serviceList = new ServiceList(getXML(request)).getArray();
+		debug("[incomingChannellist] got "+serviceList.length+" Services");
+	}
+	if(serviceList !== null) {		
+		var data = { services : serviceList };
+
+		processTpl('tplServiceList', data, 'contentServices', getBouquetEpg);
+		delayedGetSubservices();
+	} else {
+		debug("[incomingChannellist] services is null");
+	}
+}
+function loadBouquet(servicereference, name){ 
+	debug("[loadBouquet] called");
+	setAjaxLoad('contentServices');
+	
+	currentBouquet = servicereference;
+
+	setContentHd(name);
+	
+	var input = new Element('input');
+	input.id = 'serviceSearch';
+	input.value = 'Search for service';
+	
+	$('contentHdExt').update(input);
+	
+	input.observe('focus', onServiceSearchFocus);
+	input.observe('keyup', serviceSearch);	
+
+	startUpdateBouquetItemsPoller();
+	doRequest(URL.getservices+servicereference, incomingChannellist, true);
+}
+function incomingBouquetListInitial(request){
+	if (request.readyState == 4) {
+		var bouquetList = new ServiceList(getXML(request)).getArray();
+		debug("[incomingBouquetListInitial] Got " + bouquetList.length + " TV Bouquets!");	
+	
+		// loading first entry of TV Favorites as default for ServiceList
+		incomingBouquetList(
+				request, 
+				function(){
+					loadBouquet(bouquetList[0].servicereference, bouquetList[0].servicename);;
+				}
+			);
+	}
+}
+function incomingBouquetList(request, callback){
+	if (request.readyState == 4) {
+		var bouquetList = new ServiceList(getXML(request)).getArray();
+		debug("[incomingBouquetList] got " + bouquetList.length + " TV Bouquets!");	
+		var data = { bouquets : bouquetList };
+		
+		if( $('contentBouquets') != "undefined" && $('contentBouquets') != null ){
+			processTpl('tplBouquetList', data, 'contentBouquets');
+			if(typeof(callback) == 'function')
+				callback();
+		} else {
+			processTpl(					
+					'tplBouquetsAndServices', 
+					null, 
+					'contentMain',
+					function(){
+						processTpl('tplBouquetList', data, 'contentBouquets');
+						if(typeof(callback) == 'function')
+							callback();
+					}
+			);
+		}
+	}
+}
+function initChannelList(){
+	var url = URL.getservices+encodeURIComponent(bouquetsTv);
+	currentBouquet = bouquetsTv;
+
+	doRequest(url, incomingBouquetListInitial, true);
+}
+//Movies
+function initMovieList(){
+	// get videodirs, last_videodir, and all tags
+	doRequest(URL.getcurrlocation, incomingMovieListCurrentLocation, false);
+}
+function incomingMovieListCurrentLocation(request){
+	if(request.readyState == 4){
+		result  = new SimpleXMLList(getXML(request), "e2location");
+		currentLocation = result.getList()[0];
+		debug("[incomingMovieListCurrentLocation].currentLocation" + currentLocation);
+		doRequest(URL.getlocations, incomingMovieListLocations, false);
+	}
+}
+function incomingMovieListLocations(request){
+	if(request.readyState == 4){
+		result  = new SimpleXMLList(getXML(request), "e2location");
+		locationsList = result.getList();
+
+		if (locationsList.length === 0) {
+			locationsList = ["/hdd/movie"];
+		}
+		doRequest(URL.gettags, incomingMovieListTags, false);
+	}
+}
+function incomingMovieListTags(request){
+	if(request.readyState == 4){
+		result  = new SimpleXMLList(getXML(request), "e2tag");
+		tagsList = result.getList();
+	}
+}
+function createOptionListSimple(lst, selected) {
+	var namespace = Array();
+	var i = 0;
+	var found = false;
+
+	for (i = 0; i < lst.length; i++) {
+		if (lst[i] == selected) {
+			found = true;
+		}
+	}
+
+	if (!found) {
+		lst = [ selected ].concat(lst);
+	}
+
+	for (i = 0; i < lst.length; i++) {
+		namespace[i] = {
+				'value': lst[i],
+				'txt': lst[i],
+				'selected': (lst[i] == selected ? "selected" : " ")};
+	}
+
+	return namespace;
+}
+function loadMovieNav(){
+	// fill in menus
+	var data = {
+			dirname: createOptionListSimple(locationsList, currentLocation),
+			tags: createOptionListSimple(tagsList, "")
+	};
+
+	processTpl('tplNavMovies', data, 'navContent');
+}
+function incomingMovieList(request){
+	if(request.readyState == 4){
+
+		var movieList = new MovieList(getXML(request)).getArray();
+		debug("[incomingMovieList] Got "+movieList.length+" movies");
+
+		var data = { movies : movieList };
+		processTpl('tplMovieList', data, 'contentMain');
+	}		
+}
+function loadMovieList(loc, tag){
+	if(typeof(loc) == 'undefined'){
+		loc = currentLocation;
+	}
+	if(typeof(tag) == 'undefined'){
+		tag = '';
+	}
+	debug("[loadMovieList] Loading movies in location '"+loc+"' with tag '"+tag+"'");
+	doRequest(URL.movielist+"?dirname="+loc+"&tag="+tag, incomingMovieList, false);
+}
+function incomingDelMovieResult(request) {
+	debug("[incomingDelMovieResult] called");
+	if(request.readyState == 4){
+		var result = new SimpleXMLResult(getXML(request));
+		if(result.getState()){			
+			loadMovieList();
+		}
+		simpleResultHandler(result);
+	}		
+}
+function delMovie(sref ,servicename, title, description) {
+	debug("[delMovie] File(" + unescape(sref) + "), servicename(" + servicename + ")," +
+			"title(" + unescape(title) + "), description(" + description + ")");
+
+	result = confirm( "Are you sure want to delete the Movie?\n" +
+			"Servicename: " + servicename + "\n" +
+			"Title: " + unescape(title) + "\n" + 
+			"Description: " + description + "\n");
+
+	if(result){
+		debug("[delMovie] ok confirm panel"); 
+		doRequest(URL.moviedelete+"?sRef="+unescape(sref), incomingDelMovieResult, false); 
+		return true;
+	}
+	else{
+		debug("[delMovie] cancel confirm panel");
+		return false;
+	}
+}
+//Send Messages and Receive the Answer
+function incomingMessageResult(request){
+	if(request.readyState== 4){
+		var result = new SimpleXMLResult(getXML(request));
+		simpleResultHandler(result);
+	}
+}
+function getMessageAnswer() {
+	doRequest(URL.messageanswer, incomingMessageResult, false);
+}
+function sendMessage(messagetext, messagetype, messagetimeout){
+	if(!messagetext){
+		messagetext = $('MessageSendFormText').value;
+	}	
+	if(!messagetimeout){
+		messagetimeout = $('MessageSendFormTimeout').value;
+	}	
+	if(!messagetype){
+		var index = $('MessageSendFormType').selectedIndex;
+		messagetype = $('MessageSendFormType').options[index].value;
+	}	
+	if(parseNr(messagetype) === 0){
+		doRequest(URL.message+'?text='+messagetext+'&type='+messagetype+'&timeout='+messagetimeout);
+		setTimeout(getMessageAnswer, parseNr(messagetimeout)*1000);
+	} else {
+		doRequest(URL.message+'?text='+messagetext+'&type='+messagetype+'&timeout='+messagetimeout, incomingMessageResult, false);
+	}
+}
+//Screenshots
+function getScreenShot(what) {
+	debug("[getScreenShot] called");
+
+	var buffer = new Image();
+	var downloadStart;
+	var data = {};
+
+	buffer.onload = function () { 
+		debug("[getScreenShot] image assigned");
+
+		data = { img : { src : buffer.src } };	
+		processTpl('tplGrab', data, 'contentMain');
+
+		return true;
+	};
+
+	buffer.onerror = function (meldung) { 
+		debug("[getScreenShot] Loading image failed"); 
+		return true;
+	};
+
+	switch(what){
+	case "o":
+		what = "&o=&n=";
+		break;
+	case "v":
+		what = "&v=";
+		break;
+	default:
+		what = "";
+	break;
+	}
+
+	downloadStart = new Date().getTime();
+	buffer.src = '/grab?format=jpg&r=720&' + what + '&filename=/tmp/' + downloadStart;
+}
+function getVideoShot() {
+	getScreenShot("v");
+}
+function getOsdShot(){
+	getScreenShot("o");
+}
+//RemoteControl Code
+function incomingRemoteControlResult(request){
+//	if(request.readyState == 4){
+//		var b = getXML(request).getElementsByTagName("e2remotecontrol");
+//		var result = b.item(0).getElementsByTagName('e2result').item(0).firstChild.data;
+//		var resulttext = b.item(0).getElementsByTagName('e2resulttext').item(0).firstChild.data;
+//	}
+}
+function openWebRemote(){
+	var template = templates.tplWebRemote;
+	template = templates.tplWebRemote;
+
+	if (!webRemoteWin.closed && webRemoteWin.location) {
+		setWindowContent(webRemoteWin, template);
+	} else {
+		webRemoteWin = openPopup('WebRemote', template, 250, 620);
+	}
+
+}
+function loadAndOpenWebRemote(){
+	fetchTpl('tplWebRemote', openWebRemote);
+}
+function sendRemoteControlRequest(command){
+	var long = webRemoteWin.document.getElementById('long')
+	if(long.checked){
+		doRequest(URL.remotecontrol+'?command='+command+'&type=long', incomingRemoteControlResult, false);
+		long.checked = undefined;
+	} else {
+		doRequest(URL.remotecontrol+'?command='+command, incomingRemoteControlResult, false);
+	}
+	
+	if(webRemoteWin.document.getElementById('getScreen').checked) {
+		if(webRemoteWin.document.getElementById('getVideo').checked){
+			getScreenShot();
+		} else {
+			getScreenShot("o");
+		}
+	}
+}
+// Array.insert( index, value ) - Insert value at index, without overwriting existing keys
+Array.prototype.insert = function( j, v ) {
+	if( j>=0 ) {
+		var a = this.slice(), b = a.splice( j );
+		a[j] = v;
+		return a.concat( b );
+	}
+};
+
+//Array.splice() - Remove or replace several elements and return any deleted
+//elements
+if( typeof Array.prototype.splice==='undefined' ) {
+	Array.prototype.splice = function( a, c ) {
+		var e = arguments, d = this.copy(), f = a, l = this.length;
+
+		if( !c ) { 
+			c = l - a; 
+		}
+
+		for( var i = 0; i < e.length - 2; i++ ) { 
+			this[a + i] = e[i + 2]; 
+		}
+
+
+		for( var j = a; j < l - c; j++ ) { 
+			this[j + e.length - 2] = d[j - c]; 
+		}
+		this.length -= c - e.length + 2;
+
+		return d.slice( f, f + c );
+	};
+}
+function ifChecked(rObj) {
+	if(rObj.checked) {
+		return rObj.value;
+	} else {
+		return "";
+	}
+}
+//Device Info
+/*
+ * Handles an incoming request for /web/deviceinfo Parses the Data, and calls
+ * everything needed to render the Template using the parsed data and set the
+ * result into contentMain @param request - the XHR
+ */
+function incomingDeviceInfo(request) {
+	if(request.readyState == 4){
+		debug("[incomingDeviceInfo] called");
+		var deviceInfo = new DeviceInfo(getXML(request));
+
+		processTpl('tplDeviceInfo', deviceInfo, 'contentMain');
+	}
+}
+/*
+ * Show Device Info Information in contentMain
+ */
+function showDeviceInfo() {
+	doRequest(URL.deviceinfo, incomingDeviceInfo, false);
+}
+function showSettings(){
+	var debug = userprefs.data.debug;
+	var debugChecked = "";
+	if(debug){
+		debugChecked = 'checked';
+	}
+	
+	var updateCurrentInterval = userprefs.data.updateCurrentInterval / 1000;
+	var updateBouquetInterval = userprefs.data.updateBouquetInterval / 1000;
+	
+
+	data = {'debug' : debugChecked,
+			'updateCurrentInterval' : updateCurrentInterval,
+			'updateBouquetInterval' : updateBouquetInterval
+	};
+	processTpl('tplSettings', data, 'contentMain');
+}
+// Spezial functions, mostly for testing purpose
+function openHiddenFunctions(){
+	openPopup("Extra Hidden Functions",tplExtraHiddenFunctions,300,100,920,0);
+}
+function startDebugWindow() {
+	DBG = true;
+	debugWin = openPopup("DEBUG", "", 300, 300,920,140, "debugWindow");
+}
+function restartTwisted() {
+	doRequest( "/web/restarttwisted" );
+}
+//Powerstate
+/*
+ * Sets the Powerstate @param newState - the new Powerstate Possible Values
+ * (also see WebComponents/Sources/PowerState.py) #-1: get current state # 0:
+ * toggle standby # 1: poweroff/deepstandby # 2: rebootdreambox # 3:
+ * rebootenigma
+ */
+function sendPowerState(newState){
+	doRequest( URL.powerstate+'?newstate='+newState, incomingPowerState);
+}
+//Currently Running Service
+function incomingCurrent(request){
+	//	debug("[incomingCurrent called]");
+	if(request.readyState == 4){
+		try{
+			var xml = getXML(request);
+			var epg = new EPGList(xml).getArray();
+			epg = epg[0];
+			
+			var service = new Service(xml).toJSON(); 
+			
+			var data = { 
+						'current' : epg,
+						'service' : service
+					};
+
+			if(typeof(templates.tplCurrent) != "undefined"){
+				var display = 'none';
+				try{
+					var display = $('trExtCurrent').style.display;
+				} catch(e){}
+				
+				renderTpl(templates.tplCurrent, data, "currentContent");
+				$('trExtCurrent').style.display = display;
+			} else {
+				debug("[incomingCurrent] tplCurrent N/A");
+			}
+
+		} catch (e){}
+		
+		isActive.getCurrent = false;
+	}
+}
+function getCurrent(){
+	if(!isActive.getCurrent){
+		isActive.getCurrent = true;
+		doRequest(URL.getcurrent, incomingCurrent, false);
+	}
+}
+//Navigation and Content Helper Functions
+
+/*
+ * Loads all Bouquets for the given enigma2 servicereference and sets the
+ * according contentHeader @param sRef - the Servicereference for the bouquet to
+ * load
+ */
+function getBouquets(sRef){	
+	var url = URL.getservices+encodeURIComponent(sRef);
+	
+	doRequest(url, incomingBouquetList, true);		
+}
+/*
+ * Loads another navigation template and sets the navigation header
+ * @param template - The name of the template
+ * @param title - The title to set for the navigation
+ */
+function reloadNav(template, title){
+	setAjaxLoad('navContent');
+	processTpl(template, null, 'navContent');
+	setNavHd(title);
+}
+function reloadNavDynamic(fnc, title){
+	setAjaxLoad('navContent');
+	setNavHd(title);
+	fnc();
+}
+function getBouquetsTv(){
+	getBouquets(bouquetsTv);
+}
+function getProviderTv(){
+	getBouquets(providerTv);
+}
+function getSatellitesTv(){
+	getBouquets(satellitesTv);
+}
+function getAllTv(){
+	loadBouquet(allTv, "All (TV)");
+}
+function getBouquetsRadio(){
+	getBouquets(bouquetsRadio);
+}
+function getProviderRadio(){
+	getBouquets(providerRadio);
+}
+function getSatellitesRadio(){
+	getBouquets(satellitesRadio);
+}
+function getAllRadio(){
+	loadBouquet(allRadio, "All (Radio)");
+}
+/*
+ * Loads dynamic content to $(contentMain) by calling a execution function
+ * @param fnc - The function used to load the content
+ * @param title - The Title to set on the contentpanel
+ */
+function loadContentDynamic(fnc, title, domid){
+	if(typeof(domid) != "undefined" && $(domid) != null){
+		setAjaxLoad(domid);
+	} else {
+		setAjaxLoad('contentMain');
+	}
+	setContentHd(title);
+	stopUpdateBouquetItemsPoller();
+
+	fnc();
+}
+/*
+ * like loadContentDynamic but without the AjaxLoaderAnimation being shown
+ */
+function reloadContentDynamic(fnc, title){
+	setContentHd(title);
+	fnc();
+}
+/*
+ * Loads a static template to $(contentMain)
+ * @param template - Name of the Template
+ * @param title - The Title to set on the Content-Panel
+ */
+function loadContentStatic(template, title){
+	setAjaxLoad('contentMain');
+	setContentHd(title);
+	stopUpdateBouquetItemsPoller();
+	processTpl(template, null, 'contentMain');
+}
+/*
+ * Opens the given Control
+ * @param control - Control Page as String
+ * Possible Values: power, extras, message, screenshot, videoshot, osdshot
+ */
+function loadControl(control){
+	switch(control){
+	case "power":
+		loadContentStatic('tplPower', 'PowerControl');
+		break;
+	
+	case "softcam":
+		loadContentStatic('tplSoftcam', 'SoftcamPanel');
+		break;
+	
+	case "videomode":
+		loadContentStatic('tplVideomode', 'A/V Einstellungen');
+		break;
+	
+	case "pluginsipk":
+		loadContentStatic('tplIPK', 'PluginPanel');
+		break;
+	
+	case "flashen":
+		loadContentStatic('tplFlashen', 'UpdatePanel');
+		break;
+			
+	case "backuprestore":
+		loadContentStatic('tplBackupRestore', 'Backup&Restore');
+		break;
+
+	case "overclock":
+		loadContentStatic('tplOverclock', 'OverClock');
+		break;
+		
+	case "message":
+		loadContentStatic('tplSendMessage', 'Send a Message');
+		break;
+
+	case "remote":
+		loadAndOpenWebRemote();
+		break;
+
+	case "screenshot":
+		loadContentDynamic(getScreenShot, 'Screenshot');
+		break;
+
+	case "videoshot":
+		loadContentDynamic(getVideoShot, 'Videoshot');
+		break;
+
+	case "osdshot":
+		loadContentDynamic(getOsdShot, 'OSDshot');
+		break;
+
+	default:
+		break;
+	}
+}
+function loadDeviceInfo(){
+	loadContentDynamic(showDeviceInfo, 'Device Information');
+}
+function loadTools(){
+	loadContentStatic('tplTools', 'Tools');
+}
+function loadAbout(){
+	loadContentStatic('tplAbout', 'About');
+}
+function loadSettings(){
+	loadContentDynamic(showSettings, 'Settings');
+}
+
+var cachedServiceElements = null;
+
+function onServiceSearchFocus(event){
+	event.element().value = '';
+	cachedServiceElements = null;
+	serviceSearch(event);
+}
+function serviceSearch(event){
+	var needle = event.element().value.toLowerCase();
+	
+	if(cachedServiceElements == null){
+		cachedServiceElements = $$('.sListRow');
+	}
+	
+	for(var i = 0; i < cachedServiceElements.length; i++){
+		var row = cachedServiceElements[i];
+		var serviceName = row.readAttribute('data-servicename').toLowerCase();
+		
+		if(serviceName.match(needle) != needle && serviceName != ""){
+			row.hide();
+		} else {		
+			row.show();
+		}
+	}
+	
+	debug('serviceNames');
+}
+/*
+ * Switches Navigation Modes
+ * @param mode - The Navigation Mode you want to switch to
+ * Possible Values: TV, Radio, Movies, Timer, Extras
+ */
+function switchMode(mode){
+	switch(mode){
+	case "TV":
+		reloadNav('tplNavTv', 'TeleVision');
+		break;
+
+	case "Radio":
+		reloadNav('tplNavRadio', 'Radio');
+		break;
+
+	case "Movies":
+		//The Navigation
+		reloadNavDynamic(loadMovieNav, 'Movies');
+
+		// The Movie list
+		loadContentDynamic(loadMovieList, 'Movies');
+		break;
+
+	case "Timer":
+		//The Navigation
+		reloadNav('tplNavTimer', 'Timer');
+
+		// The Timerlist
+		loadContentDynamic(loadTimerList, 'Timer');
+		break;
+
+	case "BoxControl":
+		reloadNav('tplNavBoxControl', 'BoxControl');
+		break;
+
+	case "AAF-Panel":
+		reloadNav('tplNavExtras', 'AAF-Panel');
+		break;
+		
+	default:
+		break;
+	}
+}
+function openWebTV(){
+	window.open('/web-data/streaminterface.html', 'WebTV', 'scrollbars=no, width=800, height=740');
+}
+function clearSearch(){
+	$('epgSearch').value = "";
+	$('epgSearch').focus();
+}
+function updateItems(){
+	getCurrent();
+	getPowerState();
+}
+function updateItemsLazy(bouquet){
+	getSubServices();
+	getBouquetEpg();
+}
+/*
+ * Does the everything required on initial pageload
+ */
+function init(){
+	var DBG = userprefs.data.debug || false;
+	
+	if(DBG){
+		openDebug();
+	}
+	if( parseNr(userprefs.data.updateCurrentInterval) < 10000){
+		userprefs.data.updateCurrentInterval = 120000;
+		userprefs.save();
+	}
+	if( parseNr(userprefs.data.updateBouquetInterval) < 60000 ){
+		userprefs.data.updateBouquetInterval = 300000;
+		userprefs.save();
+	}
+	if (typeof document.body.style.maxHeight == "undefined") {
+		alert("Due to the tremendous amount of work needed to get everthing to " +
+		"work properly, there is (for now) no support for Internet Explorer Versions below 7");
+	}
+	getBoxtype();
+
+	setAjaxLoad('navContent');
+	setAjaxLoad('contentMain');
+
+	fetchTpl('tplServiceListEPGItem');
+	fetchTpl('tplBouquetsAndServices');
+	fetchTpl('tplCurrent');	
+	reloadNav('tplNavTv', 'TeleVision');
+
+	initChannelList();
+	initVolumePanel();
+	initMovieList();
+
+	updateItems();
+	startUpdateCurrentPoller();
+}
Index: ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web-data/tpl/default/index.html
===================================================================
--- ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web-data/tpl/default/index.html	(revision 14969)
+++ ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web-data/tpl/default/index.html	(revision 14969)
@@ -0,0 +1,202 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+	<meta content="text/html; charset=UTF-8" http-equiv="content-type">
+	<META HTTP-EQUIV="CACHE-CONTROL" CONTENT="NO-CACHE">
+	<title>AAF WebControl</title>
+	<link href="/web-data/tpl/default/style.css" type="text/css" rel="stylesheet">
+	<link rel="shortcut icon" type="/web-data/image/x-icon" href="/web-data/img/favicon.ico">
+	<!-- External libs
+	<script type="text/javascript" src="/web-data/lib/prototype-1.6.1.js"></script>
+	<script type="text/javascript" src="/web-data/lib/scriptaculous.js?load=effects"></script>
+	<script type="text/javascript" src="/web-data/lib/curvycorners.js"></script>
+	<script type="text/javascript" src="/web-data/lib/trimpath-template-1.0.38.js"></script>
+	 -->
+	<script type="text/javascript" src="/web-data/lib/libs_minified.js"></script>
+	<!-- userprefs Object -->
+	<script type="text/javascript" src="/web-data/userprefs.js"></script>
+	<!-- our stuff //-->
+	<script type="text/javascript" src="/web-data/objects.js" ></script>
+	<script type="text/javascript" src="/web-data/statics.js" ></script>
+	<script type="text/javascript" src="/web-data/tools.js" ></script>
+	<script type="text/javascript" src="/web-data/timer.js" ></script>
+	<!-- Live RSS Feeds //-->
+	<link rel="alternate" type="application/rss+xml" title="Movie List" href="/web/movielist.rss?tag" >
+	<script language="javascript" type="text/javascript">
+		
+		if (!window.$) {
+			window.$ = function(id) { return document.getElementById(id); }
+		}
+		
+		function getWinSize(win) 
+		{ 
+			if(!win) win = window; 
+			var s = {}; 
+			if(typeof win.innerWidth != 'undefined') 
+			{ 
+				s.width = win.innerWidth; 
+				s.height = win.innerHeight; 
+			} 
+			else 
+			{ 
+				 var obj = getBody(win); 
+				 s.width = parseInt(obj.clientWidth); 
+				 s.height = parseInt(obj.clientHeight); 
+			} 
+			return s; 
+		} 
+
+		function getBody(w) 
+		{ 
+			return (w.document.compatMode && w.document.compatMode == "CSS1Compat") ? w.document.documentElement : w.document.body || null; 
+		} 
+		
+		function setMaxHeight(element){
+			try{			
+				var slc = $(element);
+				size = getWinSize();
+				slc.style.maxHeight = size.height - 200+"px";
+			} catch (e) {}
+		}
+
+	</script>
+</head>
+<body onresize="setMaxHeight('contentMain')" onload="document.getElementById('notification').style.display='none'">
+	<div id="container">
+		<div id="banner">
+			<span id="notification"><div></div></span>
+			<div id="bannerLeft">
+				<div id="bannerText" style="font-size: 24px;">
+					<img src="/web-data/img/aafweb.png" alt="AAF Web">
+				</div>
+				<ul id="mainMenu">
+					<li><a href="#" onClick="switchMode('TV')">TV</a></li>
+					<li><a href="#" onClick="switchMode('Radio')">Radio</a></li>
+					<li><a href="#" onClick="switchMode('Movies')">Movies</a></li>
+					<li><a href="#" onClick="switchMode('Timer')">Timer</a></li>
+					<li><a href="#" onClick="switchMode('BoxControl')">BoxControl</a></li>
+					<li><a href="#" onClick="switchMode('AAF-Panel')">AAF-Panel</a></li>
+					<li>
+						<a href="#" onClick="openWebTV();">
+							WebTV
+						</a></li>
+				</ul>
+			</div>
+			<div id="bannerRight">
+				<div>					
+					<a id="openSignalPanel" href="#" >
+						<img id="openSignalPanelImg" border="0" src="/web-data/img/signal.png" alt="Signal" title="Show Signal Panel">
+					</a><br>
+					<a id="doInstantRecord" href="#" onClick="recordNowPopup()">
+						<img  id="doInstantRecordImg" border="0" src="/web-data/img/record.png" alt="R" title="Instant Record">
+					</a>
+				</div>			
+			</div>
+		</div>
+		<div id="current">
+			<div id="currentContent">
+				<table id="currentTable">
+					<tr>
+						<td id="currentName">N/A</td>
+					</tr>	
+				</table>
+			</div>
+		</div>
+		<div id="main">
+			<div id="navContainer">
+				<div id="nav">
+					<div id="navHd" class="header"><div>SubNav</div></div>
+					<div id="navContent">loading...</div>
+				</div>
+				<div id="navVolume">
+					<div id="volHd" class="header"><div>Volume</div></div>
+					<span class="boxContent center" style="width: 94%; display:block;">
+						<!-- Volume "Slider" -->
+						<a href="#" onClick="volumeSet(10)">
+							<img id='volume1' src='/web-data/img/led_off.png' title="Volume to 10%" alt="10%">
+						</a>
+						<a href="#" onClick="volumeSet(20)">
+							<img id='volume2' src='/web-data/img/led_off.png' title="Volume to 20%" alt="20%">
+						</a>
+						<a href="#" onClick="volumeSet(30)">
+							<img id='volume3' src='/web-data/img/led_off.png' title="Volume to 30%" alt="30%">
+						</a>
+						<a href="#" onClick="volumeSet(40)">
+							<img id='volume4' src='/web-data/img/led_off.png' title="Volume to 40%" alt="40%">
+						</a>
+						<a href="#" onClick="volumeSet(50)">
+							<img id='volume5' src='/web-data/img/led_off.png' title="Volume to 50%" alt="50%">
+						</a>
+						<a href="#" onClick="volumeSet(60)">
+							<img id='volume6' src='/web-data/img/led_off.png' title="Volume to 60%" alt="60%">
+						</a>
+						<a href="#" onClick="volumeSet(70)">
+							<img id='volume7' src='/web-data/img/led_off.png' title="Volume to 70%" alt="70%">
+						</a>
+						<a href="#" onClick="volumeSet(80)">
+							<img id='volume8' src='/web-data/img/led_off.png' title="Volume to 80%" alt="80%">
+						</a>
+						<a href="#" onClick="volumeSet(90)">
+							<img id='volume9' src='/web-data/img/led_off.png' title="Volume to 90%" alt="90%">
+						</a>
+						<a href="#" onClick="volumeSet(100)">
+							<img id='volume10' src='/web-data/img/led_off.png' title="Volume to 100%" alt="100%">
+						</a>
+						<br>
+						<!-- Volume Control -->
+						<a href="#" onClick="volumeDown()">
+							<img src='/web-data/img/arrow_down.png'  title="Volume Down" alt="Down">
+						</a>
+						<a href="#" onClick="volumeUp()">
+							<img src='/web-data/img/arrow_up.png'  title="Volume Up" alt="Up">
+						</a>
+						<a href="#" onClick="volumeMute()">
+							<img id='speaker' src='/web-data/img/speak_on.png'  title="Mute" alt="Mute">
+						</a>						
+					</span>
+				</div>
+				<div id="navSearch">
+					<div id="searchHd" class="header"><div>EPG-Search</div></div>
+					<div class="boxContent">
+						<form action="" onSubmit="loadEPGBySearchString($('epgSearch').value); return false;">
+							<input type="text" id="epgSearch" onfocus="this.value=''" value="Search EPG" />
+							<img style="vertical-align:middle" src="/web-data/img/cross.png" alt="clear..." title="Clear Search" onClick="clearSearch()" />
+						</form>						
+					</div>
+				</div>
+			</div>
+			<div id="content">
+				<table style="margin:0px; padding:0px; background:#000;width:100%" cellpadding="0" cellspacing="0">
+					<tr>
+						<td><div id="contentHd" class="header"><div>Content</div></div></td>
+						<td style="text-align: right"><div id="contentHdExt"></div></td>
+					</tr>
+				</table>
+				<div id="contentMain">loading...</div>
+			</div>	
+		</div>
+	</div>
+	<script language="javascript" type="text/javascript">	
+		function setNavHd(content){
+			set("navHd", '<div style="background-color: #000">'+content+'</div>');
+		}
+		
+		function setContentHd(content){
+			var div = new Element('div');
+			div.setStyle({background: 'black'});
+			div.update(content);
+			$('contentHd').update(div);
+			$('contentHdExt').update('');
+		}
+		
+		function getAjaxLoad(){
+			return ('<center><img style="padding-top: 50px;" src="/web-data/gfx/ajaxload.gif" alt="loading..."></center>');
+		}
+		
+		setMaxHeight('contentMain');		
+		
+		init();
+	</script>
+</body>
+</html>
Index: ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web-data/tpl/default/streaminterface/style.css
===================================================================
--- ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web-data/tpl/default/streaminterface/style.css	(revision 14969)
+++ ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web-data/tpl/default/streaminterface/style.css	(revision 14969)
@@ -0,0 +1,158 @@
+	body{
+		font-family: Tahoma, Sans-Serif;
+		font-size: 14px;
+		font-weight: bold;
+		color: #fff;
+		text-align: center;
+		background-color: #555
+	}	
+	a, a:visited, a:active{
+		color: #485052;
+		text-decoration: none;
+	}
+	img{
+		border: 0px;
+	}
+	#notification{		
+		color: #000;
+		width: 500px;
+		height: 50px;
+		position: absolute;
+		top: 0px;
+		left: 134px;
+		text-align: center;
+		vertical-align: bottom;
+		z-index: 2;		
+	}
+/***********************
+ GENERAL
+ ***********************/
+	.odd{
+		background-color: #FFF;
+	}
+	.even{
+		background-color: #DDD;
+	}
+	.fullwidth {
+		width: 100%;
+	}
+	.center {
+		text-align: center;
+	}
+	#container {
+		margin: 0 auto;   /* align for good browsers */
+		text-align: left; /* counter the body center */
+		width: 768px;
+		border: 2px solid #DDD;
+	}
+/***********************
+ BANNER with MainMenu
+ ***********************/
+	#banner{
+		width: 762px;
+		height: 70px;
+		background-color: #000;
+		padding-left: 5px;
+		margin-bottom: 0px;
+		border-bottom: 1px solid #FFF;
+		position: relative;
+	}
+	#banner a, #banner a:visited, #banner a:active{
+		color: #FFF;
+		text-decoration: none;
+	}
+	#bannerText{
+		margin-bottom: 10px;
+		padding-left: 2px;
+		padding-top: 6px;
+	}
+	#bannerLeft{
+		width: 600px;
+		float: left;
+	}
+	#bannerRight{
+		width: 162px;
+		text-align: right;
+		height: 60px;
+		float: left;
+	}
+	#bannerRight img{
+		padding-top: 5px;
+	}	
+	#mainMenu{
+		background-color: #485052;
+		text-align: center;
+		overflow:hidden; 
+		background: #000; 
+		margin: 0; 
+		padding: 0; 
+		width: 600px;
+	}
+	#mainMenu li{
+		list-style: none;
+		float: left;
+		width: 130px;
+		height: 21px;
+		margin-left: 2px;
+	}
+	#mainMenu li { background-color: #485052; }
+	#mainMenu a{ display:block; padding: 1px; }
+	#mainMenu li:hover, { background: #AAA; }
+	#mainMenu li.hover, { background: #AAA; }
+/**************
+ vlcPlayer
+ **************/
+	#vlcPlayer {
+		margin: 0px;
+		padding: 0px;
+	}
+	#vlcButtons{
+		background-color: #000;
+		border-top: 1px solid #FFF;
+	}
+	#volumeTable{
+		width: 100%;
+		text-align: right;
+	}
+	#vlcVolume{
+		width: 30px;
+	}
+/**************
+ Content
+ **************/
+	#content{
+		width: 768px;
+		min-height: 308px;
+		margin: 0px;
+		padding: 0px;
+	}
+/**************
+ Current
+ **************/	
+	#currentTable{
+		padding-left: 2px;
+		padding-top: 3px;
+		width: 100%;
+	}
+	#currentDuration{
+		text-align: right;
+	}			
+/***************
+* IE6 Hackstuff
+***************/
+	* html #banner{
+		width: 772px;
+		height: 78px;
+	}
+	* html #bannerRight{
+		width: 120px;
+		height: 60px;		
+	}
+	* html #nav{
+		width: 99%;
+		height: 250px;		
+		padding-left: 5px;
+	}
+	* html .navTable{
+		width: 95%;
+	}
Index: ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web-data/tpl/default/streaminterface/tplBouquetList.htm
===================================================================
--- ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web-data/tpl/default/streaminterface/tplBouquetList.htm	(revision 14969)
+++ ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web-data/tpl/default/streaminterface/tplBouquetList.htm	(revision 14969)
@@ -0,0 +1,7 @@
+<!-- tplBouquetList -->
+<select id="bouquetSelect" onChange="onBouquetSelected()" width="100px">
+	{for b in bouquets}
+		<option id="${b.servicereference}" >${b.servicename}</option>
+	{/for}
+</select>
+<!-- tplBouquetList -->
Index: ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web-data/tpl/default/streaminterface/tplCurrent.htm
===================================================================
--- ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web-data/tpl/default/streaminterface/tplCurrent.htm	(revision 14969)
+++ ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web-data/tpl/default/streaminterface/tplCurrent.htm	(revision 14969)
@@ -0,0 +1,7 @@
+<!-- tplCurrent -->
+<table id="currentTable">
+	<tr>
+		<td id="currentName">${current.servicename} - ${current.title} (+${current.remaining} of ${current.duration} min)</td>
+	</tr>
+</table>
+<!-- /tplCurrent -->
Index: ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web-data/tpl/default/streaminterface/tplServiceList.htm
===================================================================
--- ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web-data/tpl/default/streaminterface/tplServiceList.htm	(revision 14969)
+++ ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web-data/tpl/default/streaminterface/tplServiceList.htm	(revision 14969)
@@ -0,0 +1,13 @@
+<!-- tplServiceList -->
+<select id="channelSelect" onChange="onServiceSelected()" width="100px">
+	<option id="vlcemptyservice"></option>
+	{for e in events}
+	<option id="${e.servicereference}" >
+	${e.servicename}	
+	{if e.duration != 0} 
+		(${e.shorttitle}) +${e.remaining} of ${e.duration} min.
+	{/if}
+	</option>
+	{/for}
+</select>
+<!-- /tplServiceList -->
Index: ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web-data/tpl/default/style.css
===================================================================
--- ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web-data/tpl/default/style.css	(revision 14969)
+++ ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web-data/tpl/default/style.css	(revision 14969)
@@ -0,0 +1,549 @@
+	html, body{
+		font-family: Tahoma, Sans-Serif;
+		font-size: 14px;
+		font-weight: bold;
+		color: #fff;
+		text-align: center;
+		background: #555
+	}
+	a, a:visited, a:active{
+		color: #485052;
+		text-decoration: none;
+	}
+	img{
+		border: 0px;
+	}
+	form{
+		margin: 2px;		
+	}
+	#notification{		
+		color: #000;
+		width: 50%;
+		height: 32px;
+		position: absolute;
+		top: 0px;
+		left: 25%;		
+		text-align: center;
+		vertical-align: bottom;
+		z-index: 2;		
+	}
+/***********************
+ WAP
+ ***********************/
+	.wap a, .wap a:visited, .wap a:active{
+		color: #fff;		
+	}
+/***********************
+ GENERAL
+ ***********************/
+	.black{
+		background: #000;
+	}
+	.odd{
+		background-color: #FFF;
+	}
+	.even{
+		background-color: #DDD;
+	}
+	.fullwidth {
+		width: 100%;
+	}
+	.center {
+		text-align: center;
+	}
+/***********************
+ BANNER with MainMenu
+ ***********************/
+	#banner{
+		width: 1000px;
+		height: 67px;
+		background: #000;
+		padding-left: 5px;
+		margin-bottom: 8px;
+
+    	border-radius: 5px;
+    	-webkit-border-radius: 5px;
+    	-moz-border-radius: 5px;	
+	}
+	#banner a, #banner a:visited, #banner a:active{
+		color: #FFF;
+		text-decoration: none;
+	}
+	#bannerText{
+		margin-bottom: 5px;
+		padding-left: 2px;
+		padding-top: 6px;
+	}
+	#bannerLeft{
+		width: 940px;
+		float: left;
+	}
+	#powerState{
+		border: 0px;
+		margin-left: 93px;
+		text-algin: right;
+	}
+	#bannerRight{
+		width: 50px;
+		text-align: right;
+		height: 60px;
+		float: left;
+	}
+	#bannerRight img{
+		padding-top: 5px;
+	}
+	#current a{
+		color: #FFF;
+	}
+	#current{
+		width: 999px;
+		background: #000;
+		padding-left: 3px;
+		padding-right: 3px;
+		padding-bottom: 1px;
+		margin-bottom: 8px;
+				
+    	border-radius: 5px;
+    	-webkit-border-radius: 5px;
+    	-moz-border-radius: 5px;    	
+    	
+	}
+	.techInfo{
+		font-size: 10px;
+	}
+	#currentTable{
+		margin-bottom: 10px;
+		padding-left: 2px;
+		padding-top: 3px;
+		width: 100%;
+	}
+	#currentDuration{
+		text-align: right;
+	}
+	#mainMenu{
+		background-color: #485052;
+		text-align: center;
+		overflow:hidden;
+		background: #000; 
+		margin: 0;
+		padding: 0;
+		width: 940px;
+	}
+	#mainMenu li{
+		list-style: none;
+		float: left;
+		width: 100px;
+		height: 21px;
+		margin-left: 2px;
+		background:#485052; 
+		margin-top: 6px;
+		margin-bottom: 0px;
+		padding: 0px;
+		
+		border-radius: 5px;
+    	-webkit-border-radius: 5px;
+    	-moz-border-radius: 5px;		
+	}
+	#mainMenu a:hover, #mainMenu a:hover{ background: #AAA; }
+	#mainMenu li.hover, #mainMenu li.hover{ background: #AAA; }
+	#mainMenu a{
+		display:block;
+		padding-top: 1px;
+		padding-bottom: 3px;
+				
+		border-radius: 5px;
+    	-webkit-border-radius: 5px;
+    	-moz-border-radius: 5px;
+	}
+/***************
+ Upper Left Nav
+ ***************/
+	#navContainer{
+		float:left;
+		width: 160px;
+	}
+	#nav{
+		width: 100%;
+		height: 250px;
+		background: #000;
+		padding-left: 5px;
+				
+		border: 2px solid #000;
+		border-radius: 5px;
+    	-webkit-border-radius: 5px;
+    	-moz-border-radius: 5px;
+	}
+	#nav a{
+		display: block;
+	}
+	#nav{ 
+		background:#FFF; 
+		padding-left: 0px;
+		padding-right: 0px;		
+		
+	}
+	#navHd{
+		background: #000;
+		text-align: center;		
+		width: 153px;
+	}
+	#navContent{
+		color: #485052;
+		padding-left: 5px;
+	}
+	#navSearch{
+		width: 100%;
+		height: 61px;
+		background: #FFF;
+		margin-top: 8px;
+		
+		border: 2px solid #000;
+		border-radius: 5px;
+    	-webkit-border-radius: 5px;
+    	-moz-border-radius: 5px;
+	}
+	#searchHd{
+		background: #000;
+		text-align: center;
+		width: 153px;
+	}
+	#navVolume{
+		width: 100%;
+		height: 75px;
+		background: #FFF;
+		margin-top: 8px;
+		
+		border: 2px solid #000;
+		border-radius: 5px;
+    	-webkit-border-radius: 5px;
+    	-moz-border-radius: 5px;
+	}
+	#volHd{
+		background: #000;
+		text-align: center;
+		width: 153px;
+	}
+/**************
+ Content
+ **************/
+	#content{
+		float: left;
+		background: #FFF;
+		width: 833px;
+		min-height: 308px;
+		margin-left: 8px;
+		
+		border: 2px solid #000;		
+		border-radius: 5px;
+    	-webkit-border-radius: 5px;
+    	-moz-border-radius: 5px;
+	}
+	#contentHd{
+		background: #000;
+		width: 527px;
+	}
+	#contentHdExt{
+		background: #000;		
+		dipslay:block;
+	}
+	#contentHdExt input{
+		padding: 1px;
+		margin-right: 2px;
+		margin-bottom: 2px;
+		border: 0px;
+		color: #485052;
+	}
+	#epgSearch{ width: 120px; }
+	.boxContent{
+		color: #485052;
+		padding: 3px;	
+	}
+/*****************
+* Subnavigation
+******************/	
+	.navTable{
+		width: 100%;
+	}
+	.navTable a:hover{
+		background-color:#CCC;
+		color: #485052;
+		display: block;
+	}
+/*****************
+* ServiceList
+******************/		
+	.sListSName a{
+		display: block;
+		margin-right: 5px;
+		color: #485052;
+	}
+	.sListSName a:hover{
+		background-color:#CCC;
+		color: #485052;
+		display: block;
+	}
+	.sListEPGItem{
+		font-size:12px;
+		margin: 0px;
+		padding: 0px;
+	}
+	.header{
+		padding-top: 2px;
+		padding-left: 4px;
+		padding-right: 4px;
+		display:block;
+		height: 22px;
+	}
+	#container {
+		margin: 0 auto;   /* align for good browsers */
+		text-align: left; /* counter the body center */
+		width: 1005px;
+	}
+	#contentTable{
+		scrollbar: auto;
+		width: 785px;
+	}
+	#contentServices{
+		vertical-align: top;		
+		width: 585px;
+	}
+	#contentServices table{
+		scrollbar: auto;
+		width: 585px;
+	}
+	#contentBouquets{
+		border-right: 1px solid #ccc;
+		vertical-align: top;		
+		width: 220px;
+	}
+	#contentMain{
+		padding: 8px;
+		margin-bottom: 5px;
+	}
+	#contentMain {
+		clear: both;
+		overflow-y: auto;
+		width: 815px;
+		color: #485052;
+	}
+	#contentMain div table {
+		float: left;
+		width: 599px;
+	}
+	.sListItem{
+		/*border-bottom: 2px solid #CCC;*/
+		width: 580px;
+		color: #485052;
+	}
+	.mListItem{
+		/*border-bottom: 2px solid #CCC;*/
+		width: 780px;
+		color: #485052;
+	}
+/*****************
+* ServiceList EPG
+******************/		
+	.epgStart{
+		width: 50px;
+		color: #485052;		
+	}
+	.epgTitle{
+		width: 430px;
+		color: #485052;
+	}
+	.epgLength{
+		width: 100px;
+		text-align: right;
+		color: #485052;
+	}
+/*****************
+* MovieList EPG
+******************/	
+	.mListDetail{
+		font-size: 12px;
+		color: #485052;
+	}
+	.mStart{
+		width: 160px;	
+		color: #485052;	
+	}
+	.mTitle{
+		width: 650px;
+		color: #485052;
+	}
+	.mLength{
+		width: 90px;
+		text-align: right;
+		color: #485052;
+	}
+/*****************
+* Tools
+******************/	
+	#tools{
+		font-size: 12px;
+		text-align: center;
+	}
+	#tools h1{
+		font-size: 14px;
+	}
+	.tools a, .tools a:hover, .tools a:visited {
+		text-decoration: underline;
+	}
+	.toolsHeader {
+		color:#FFF;
+		font-weight:bold;
+		background-color:#000;
+	}
+	.tools {
+		border: 1px solid #CCC;
+		width: 100%;
+		margin: 0px;
+		padding: 0px;		
+	}
+	.tools td{
+		font-size:12px;
+		padding: 5px;
+		vertical-align:top;	
+		
+	}
+	.toolsElementLeft{
+		font-weight: bold;
+		width: 15%;
+		text-align: left;
+	}
+	.toolsElementCenter{
+		text-align: left;
+	}
+	.toolsElementRight{
+		width: 10%;
+		text-align: left;
+	}
+/*****************
+* About
+******************/	
+	#about{
+		font-size: 12px;
+		text-align: center;
+	}
+	#about h1{
+		font-size: 14px;
+	}
+	#about a, #about a:hover, #about a:visited{
+		text-decoration: underline;
+	}
+	.aboutHeader {
+		width:100%;
+		color:#FFF;
+		font-weight:bold;
+		background-color:#000;
+	}
+	.about {
+		border: 1px solid #CCC;
+		width: 100%;
+		margin: 0px;
+		padding: 0px;		
+	}
+	.about td{
+		font-size:12px;
+	}
+	.aboutElementLeft{
+		font-weight:bold;
+		width: 50%;
+		text-align: left;
+	}
+	.aboutElementRight{
+		width: 50%;
+	}
+	.w200h50{
+		width: 200px;
+		height: 50px;
+	}
+/*****************
+* Timer
+******************/		
+	.tListItemTable{
+		width: 100%;
+	}
+	.tListHead{
+		/*background-color: #DDD; */
+	}
+	.tListSName{
+		text-align: left;
+	}
+	.tListItem{
+/*		background-color: #EEE; */
+		font-weight: bold;
+		font-size: 12px;
+	}
+	.tListTitle{
+		width: 150px;
+		text-align: left;
+	}
+	.tListDescr{
+		width: 150px;
+		text-align: left;
+	}
+	.tListRepeat{
+		width: 70px;
+		text-align: left;
+	}
+	.tListDuration{
+		width: 70px;
+		text-align: left;
+	}
+	.tListBegin{
+		width: 100px;
+		text-align: left;
+	}
+	.tListEnd{
+		width: 100px;
+		text-align: left;
+	}
+	.tListAfter{
+		width: 85px;
+		text-align: left;
+	}
+	.tListOption{
+		width: 80px;
+		text-align: center;
+	}
+	.timerState0 {
+		color: #485052;
+	}
+	.timerState1 {
+		color: #990000;
+	}
+	.timerState2 {
+		color: #009900;
+	}
+	.timerState3 {
+		color: #000099;		
+	}
+/*****************
+* EPG List
+******************/			
+	.epgListItem{
+		font-size:12px;
+		font-weight: bold;
+	
+	}
+/***************
+* IE6 Hackstuff
+***************/
+	* html #banner{
+		width: 1005px;
+		height: 78px;
+	}
+	* html #bannerRight{
+		width: 120px;
+		height: 60px;		
+	}
+	* html #nav{
+		width: 99%;
+		height: 250px;
+		background: #000;
+		padding-left: 5px;
+	}
+	* html .navTable{
+		width: 95%;
+	}
Index: ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web-data/tpl/default/tplBackupRestore.htm
===================================================================
--- ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web-data/tpl/default/tplBackupRestore.htm	(revision 14969)
+++ ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web-data/tpl/default/tplBackupRestore.htm	(revision 14969)
@@ -0,0 +1,5 @@
+<!-- tplbackup -->
+<table  id="navExtras" height="350" width="100%">
+	<center><iframe src="../settingbackuprestore" width="70%" height="300" vspace="0" hspace="0" marginwidth="0" marginheight="0" frameborder="0" scrolling="no"></iframe></center>
+</table>
+<!-- /tplbackup -->
Index: ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web-data/tpl/default/tplBouquetList.htm
===================================================================
--- ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web-data/tpl/default/tplBouquetList.htm	(revision 14969)
+++ ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web-data/tpl/default/tplBouquetList.htm	(revision 14969)
@@ -0,0 +1,28 @@
+<!-- tplBouquetList -->	
+<table id="bouquetTable">
+	{for bouquet in bouquets}
+		<tr><td>
+			<table>
+				<tr>
+					<td>
+						<a target="_blank" onclick="return parentPin( '${bouquet.servicereference}' );" href="/web/services.m3u?bRef=${bouquet.servicereference}">
+							<img src="/web-data/img/screen.png" title="Open ${bouquet.servicename} as Playlist" border="0">
+						</a>
+					</td>									
+					<td>										
+						<div class="sListSName">
+							<a href="#" id="${bouquet.servicereference}" onclick="{ loadBouquet(this.id, this.innerHTML); }" class="sListSLink" title="Load Bouquet ${bouquet.servicename}">
+								${bouquet.servicename}
+							</a>
+						</div>
+					</td>
+				</tr>
+			</table>
+		</td></tr>
+			{forelse}
+		<tr><td>
+			<table><tr><td>No Bouquets to Display</td></tr></table>
+		</td></tr>
+			{/for}		
+</table>
+<!-- /tplBouquetList -->
Index: ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web-data/tpl/default/tplBouquetsAndServices.htm
===================================================================
--- ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web-data/tpl/default/tplBouquetsAndServices.htm	(revision 14969)
+++ ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web-data/tpl/default/tplBouquetsAndServices.htm	(revision 14969)
@@ -0,0 +1,10 @@
+<!-- tplBouquetsAndServices -->	
+<table>
+	<tr>
+		<td id="contentBouquets">
+		</td>
+		<td id="contentServices">
+		</td>
+	</tr>
+</table>
+<!-- /tplBouquetsAndServices -->
Index: ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web-data/tpl/default/tplCurrent.htm
===================================================================
--- ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web-data/tpl/default/tplCurrent.htm	(revision 14969)
+++ ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web-data/tpl/default/tplCurrent.htm	(revision 14969)
@@ -0,0 +1,77 @@
+<!-- tplCurrent -->
+{if current.title != ""}		
+	<table id="currentTable">
+		<tr>
+			<td id="currentName">
+				<a href="#" onclick="showhide('trExtCurrent')" title="Click to show/hide extended Description">
+					${current.servicename} - ${current.title}
+				</a>
+			</td>
+			<td id="currentDuration">																	
+				<a href="#" onclick="if ( parentPin( '${current.servicereference}' ) ) { loadEPGByServiceReference( '${current.servicereference}' ); }">
+					<img src="/web-data/img/epg.png" border="0" title="Show EPG for ${current.servicename}"/>
+				</a>
+				<a target="_blank" onclick="return parentPin( '${current.servicereference}' );" href="/web/stream.m3u?ref=${current.servicereference}">
+					<img src="/web-data/img/screen.png" title="Stream ${current.servicename}" border="0">
+				</a>	
+					+${current.remaining} of ${current.duration} min
+			</td>
+		</tr>
+		<tr id="trExtCurrent">
+			<td colspan=2>
+				<table>
+					<tr>
+						<td class="epgLong">${current.extdescription}</td>
+					</tr>
+					<tr>
+						<td class="techInfo">
+							<table style="width: 350px; border: 1px solid #AAA">
+					<tr>
+						<th colspan="4" style="text-align: center">Technical Information</th>
+					</tr>
+					<tr>
+						<td>Videosize:</td>
+						<td>${service.videosize}</td>
+						<td>Widescreen:</td> 
+						<td>${service.widescreen}</td>
+					</tr>
+					<tr>
+						<td>APID:</td>
+						<td>${service.apid}</td> 
+						<td>VPID:</td>
+						<td>${service.vpid}</td>
+					</tr>
+					<tr>									
+						<td>PCRPID:</td> 
+						<td>${service.pcrpid}</td>
+						<td>PMTPID:</td> 
+						<td>${service.pmtpid}</td>
+					</tr>
+					<tr>										
+						<td>TXTPID:</td> 
+						<td>${service.txtpid}</td>									
+						<td>TSID:</td> 
+						<td>${service.tsid}</td>
+					</tr>
+					<tr>										
+						<td>ONID:</td> 
+						<td>${service.onid}</td>						
+						<td>SID:</td> 
+						<td>${service.sid}</td>
+					</tr>
+				</table>
+			</td>
+		</tr>
+							
+	</table>	
+</td>
+</tr>
+</table>
+{elseif}
+	<table id="currentTable">
+		<tr>
+			<td id="currentName">Nothing running</td>					
+		</tr>	
+	</table>
+{/if}
+<!-- /tplCurrent -->
Index: ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web-data/tpl/default/tplDeviceInfo.htm
===================================================================
--- ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web-data/tpl/default/tplDeviceInfo.htm	(revision 14969)
+++ ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web-data/tpl/default/tplDeviceInfo.htm	(revision 14969)
@@ -0,0 +1,119 @@
+<!-- tplDeviceInfo -->
+<table class="fullwidth">
+	<tr>
+		<td class="fullwidth">
+			<table cellspacing="0" class="about">
+				<tr>
+					<th colspan="2" class="aboutHeader">Device &amp; Versions</th>
+				</tr>
+				<tr>
+					<td class="aboutElementLeft">Devicename:</td>
+					<td class="aboutElementRight">${info.devicename}</td>
+				</tr>
+				<tr>
+					<td class="aboutElementLeft">Enigma Version:</td>
+					<td class="aboutElementRight">${info.enigmaVersion}</td>
+				</tr>
+				<tr>
+					<td class="aboutElementLeft">Image Version:</td>
+					<td class="aboutElementRight">${info.imageVersion}</td>
+				</tr>			
+				<tr>
+					<td class="aboutElementLeft">Frontprozessor Version:</td>
+					<td class="aboutElementRight">${info.fpVersion}</td>
+				</tr>
+				<tr>
+					<td class="aboutElementLeft">Webinterface Version:</td>
+					<td class="aboutElementRight">${info.webifversion}</td>
+				</tr>
+			</table>
+		</td>
+	</tr>
+	<tr>
+		<td class="fullwidth">
+			<table cellspacing="0" class="about">
+				<tr>
+					<th colspan="2" class="aboutHeader">Tuners</th>
+				</tr>
+					{for nim in nims}
+				<tr>
+					<td class="aboutElementLeft">${nim.name}:</td>
+					<td class="aboutElementRight">${nim.model}</td>
+				</tr>
+					{/for}
+			</table>
+		</td>
+	</tr>
+		{for hdd in hdds}
+	<tr>
+		<td class="fullwidth">
+			<table cellspacing="0" class="about">																
+				<tr>
+					<th colspan="2" class="aboutHeader">Harddisk (${hdd.model})</th>
+				</tr>
+				<tr>
+					<td class="aboutElementLeft">Capacity:</td>
+					<td class="aboutElementRight">${hdd.capacity}</td>
+				</tr>
+				<tr>
+					<td class="aboutElementLeft">Free:</td>
+					<td class="aboutElementRight">${hdd.free}</td>
+				</tr>
+			</table>
+		</td>
+	</tr>
+{/for}
+	<tr>
+		<td class="fullwidth">
+			<table cellspacing="0" class="about">
+				<tr>
+					<th colspan="2" class="aboutHeader">Recording Path</th>
+				</tr>
+				<tr>
+					<td class="aboutElementLeft">Path:</td>
+					<td class="aboutElementRight">${info.recPath}</td>
+				</tr>
+				<tr>
+					<td class="aboutElementLeft">Capacity:</td>
+					<td class="aboutElementRight">${info.recCapacity}</td>
+				</tr>
+				<tr>
+					<td class="aboutElementLeft">Free:</td>
+					<td class="aboutElementRight">${info.recFree}</td>
+				</tr>
+			</table>
+		</td>
+	</tr>
+{for nic in nics}
+	<tr>
+		<td class="fullwidth">
+			<table cellspacing="0" class="about">
+				<tr>
+					<th colspan="2" class="aboutHeader">Network Interface (${nic.name})</th>
+				</tr>
+				<tr>
+					<td class="aboutElementLeft">Mac Address:</td>
+					<td class="aboutElementRight">${nic.mac}</td>
+				</tr>
+				<tr>
+					<td class="aboutElementLeft">DHCP enabled:</td>
+					<td class="aboutElementRight">${nic.dhcp}</td>
+				</tr>
+				<tr>
+					<td class="aboutElementLeft">IP:</td>
+					<td class="aboutElementRight">${nic.ip}</td>
+				</tr>
+				<tr>
+					<td class="aboutElementLeft">Netmask:</td>
+					<td class="aboutElementRight">${nic.netmask}</td>
+				</tr>
+				<tr>
+					<td class="aboutElementLeft">Gateway:</td>
+					<td class="aboutElementRight">${nic.gateway}</td>
+				</tr>
+			</table>
+		</td>
+	</tr>
+{/for}
+</table>
+<!-- /tplDeviceInfo -->
Index: ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web-data/tpl/default/tplEpgList.htm
===================================================================
--- ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web-data/tpl/default/tplEpgList.htm	(revision 14969)
+++ ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web-data/tpl/default/tplEpgList.htm	(revision 14969)
@@ -0,0 +1,52 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional" "http://www.w3.org/TR/html4/loose.dtd">  
+<html>
+<!-- tplEpgList -->     
+	<head>
+		<meta content="text/html; charset=UTF-8" http-equiv="content-type">
+		<title>Enigma2 WebControl - EPG</title>
+		
+		<link href="/web-data/tpl/default/style.css" type="text/css" rel="stylesheet">
+	</head>
+	<body style="scrollbar: auto; color: #485052;">
+		<table style="width: 100%">
+			<tr>
+				<td>
+					{for e in epg}
+					<table class="epgListItem" width="100%" border="0" cellspacing="1" cellpadding="0">
+						<tr style="background-color: #DDDDDD;">
+							<td width="10%">${e.date}</td>
+							<td width="30%">${e.servicename}</td>
+							<td>${e.title}</td>
+						</tr>
+
+						<tr style="background-color: #DDDDDD;">
+							<td>${e.starttime}</td>
+							<td>${e.duration} min.</td>
+							<td>${e.description}</td>
+						</tr>
+
+						<tr style="background-color: #DDDDDD;">
+							<td valign="top">${e.endtime}</td>
+							<td colspan="2"rowspan="2" id="extdescription${e.number}">${e.extdescription}</td>
+						</tr>
+
+						<tr style="background-color: #DDDDDD;">
+							<td>
+								<a href="#" onclick="return false;"><img src="/web-data/img/timer.png" title="Add Timer" border="0" onclick=" if( opener.parentPin( '${e.servicereference}' ) ) { opener.addTimerByID('${e.servicereference}','${e.eventid}','0');}"></a>&nbsp;&nbsp;
+								<a href="#" onclick="return false;"><img src="/web-data/img/zap.png" title="Add zap Timer" border="0" onclick="if ( opener.parentPin( '${e.servicereference}' ) ) { opener.addTimerByID('${e.servicereference}','${e.eventid}','1');}"></a>&nbsp;&nbsp;
+								<a href="#" onclick="return false;"><img src="/web-data/img/edit.png" title="Edit and add timer" border="0" onclick="opener.loadTimerEditForm(0,'${e.start}','${e.end}',0,'${e.servicereference}','${e.servicename}','${e.title}','${e.description}',0,'','3',0,'${e.eventid}');"></a><br/>
+								<a target="_blank" href="/web/epgsearch.rss?search=${e.title}" ><img src="/web-data/img/feed.png" title="RSS-Feed for this Title" border="0"></a><br/>
+								<a target="_blank" href="http://www.imdb.com/find?s=all&amp;q=${e.titleESC}" ><img src="/web-data/img/world.png" title="Search IMDb" border="0"></a><br/>
+							</td>
+						</tr>
+						<tr>
+							<td colspan="3">&nbsp;</td>
+						</tr>
+					</table>
+					{/for}
+				</td>
+			</tr>
+		</table>
+	</body>
+<!-- /tplEpgList -->
+</html>
Index: ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web-data/tpl/default/tplFlashen.htm
===================================================================
--- ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web-data/tpl/default/tplFlashen.htm	(revision 14969)
+++ ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web-data/tpl/default/tplFlashen.htm	(revision 14969)
@@ -0,0 +1,5 @@
+<!-- tplflash -->
+<table  id="navExtras" height="350" width="100%">
+	<center><iframe src="../UpdatePanel" width="70%" height="400" vspace="0" hspace="0" marginwidth="0" marginheight="0" frameborder="0" scrolling="no"></iframe></center>
+</table>
+<!-- /tplflash -->
Index: ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web-data/tpl/default/tplGrab.htm
===================================================================
--- ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web-data/tpl/default/tplGrab.htm	(revision 14969)
+++ ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web-data/tpl/default/tplGrab.htm	(revision 14969)
@@ -0,0 +1,9 @@
+<!-- tplGrab -->
+<table id="contentTable">
+	<tr>
+		<td>
+			<img id="grabPageImg" src="${img.src}" alt="loading image">
+		</td>
+	</tr>
+</table>
+<!-- /tplGrab -->
Index: ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web-data/tpl/default/tplIPK.htm
===================================================================
--- ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web-data/tpl/default/tplIPK.htm	(revision 14969)
+++ ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web-data/tpl/default/tplIPK.htm	(revision 14969)
@@ -0,0 +1,5 @@
+<!-- tplipk -->
+<table  id="navExtras" height="510" width="100%">
+	<center><iframe src="../IPK" width="70%" height="500" vspace="0" hspace="0" marginwidth="0" marginheight="0" frameborder="0" scrolling="no"></iframe></center>
+</table>
+<!-- /tplipk -->
Index: ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web-data/tpl/default/tplMovieList.htm
===================================================================
--- ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web-data/tpl/default/tplMovieList.htm	(revision 14969)
+++ ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web-data/tpl/default/tplMovieList.htm	(revision 14969)
@@ -0,0 +1,61 @@
+
+<!-- tplMovieList -->
+						<table id="contentTable">
+							{for movie in movies}
+							<tr>
+								<td class="${movie.cssclass}" >
+									<table class="mListItem">
+										<tr>
+											<td style="width: 640px;">										
+												<div class="sListSName">
+													<a href="#" id="${movie.servicereference}" onclick="{ zap(this.id); }" class="sListSLink" title="Play ${movie.title}">
+														${movie.title} - ${movie.description} (${movie.servicename})
+													</a>
+												</div>
+											</td>
+											<td style="width: 100px;font-size: 12px;text-align: right;padding-right: 15px;">
+												${movie.tags}
+											</td>
+											<td>
+												<a target="_blank" href="/web/ts.m3u?file=${movie.filename}">
+													<img src="/web-data/img/screen.png" title="Stream ${movie.title}" border="0">
+												</a>
+											</td>
+											<td>
+												<a target="_blank" href="/file?file=${movie.filename}">
+													<img src="/web-data/img/save.png" title="Download ${movie.title}" border="0">
+												</a>
+											</td>
+											<td>
+												<a href="#" onclick="delMovie('${movie.servicereference}','${movie.servicename}','${movie.escapedTitle}','${movie.description}');">
+													<img src="/web-data/img/delete.png" title="Delete ${movie.title}" border="0">
+												</a>
+											</td>
+										</tr>
+										<tr class="mListDetail">
+											<td colspan="4" class="mListDetailItem">
+												<table cellspacing="0">
+													<tr>
+														<td class="mStart">${movie.time}</td>
+														<td class="mTitle">${movie.descriptionextended}</td>
+														<td class="mLength">${movie.length}</td>
+													</tr>
+												</table>
+											</td>
+										</tr>
+									</table>
+								</td>
+							</tr>
+							{forelse}
+							<tr>
+								<td>
+									<table>
+										<tr>
+											<td>No Movies to Display</td>
+										</tr>
+									</table>
+								</td>
+							</tr>
+							{/for}		
+						</table>
+<!-- /tplMovieList -->
Index: ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web-data/tpl/default/tplNavBoxControl.htm
===================================================================
--- ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web-data/tpl/default/tplNavBoxControl.htm	(revision 14969)
+++ ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web-data/tpl/default/tplNavBoxControl.htm	(revision 14969)
@@ -0,0 +1,23 @@
+
+<!-- tplNavBoxControl -->
+<table id="navExtras" class="navTable">
+	<tr>
+		<td><a href="#" onclick="loadControl('power');">PowerControl</a><td>
+	</tr>
+	<tr>
+		<td><a href="#" onclick="loadControl('message');">Send a Message</a><td>
+	</tr>
+	<tr>
+		<td><a href="#" onclick="loadControl('remote')">WebRemote</a><td>
+	</tr>
+	<tr>
+		<td><a href="#" onclick="loadControl('screenshot')">Screenshot (All)</a><td>
+	</tr>	
+	<tr>
+		<td><a href="#" onclick="loadControl('videoshot')">Screenshot (Video)</a><td>
+	</tr>
+	<tr>
+		<td><a href="#" onclick="loadControl('osdshot')">Screenshot (OSD)</a><td>
+	</tr>	
+</table>
+<!-- /tplNavBoxControl -->
Index: ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web-data/tpl/default/tplNavExtras.htm
===================================================================
--- ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web-data/tpl/default/tplNavExtras.htm	(revision 14969)
+++ ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web-data/tpl/default/tplNavExtras.htm	(revision 14969)
@@ -0,0 +1,34 @@
+<!-- tplNavExtras -->
+<table id="navTimer" class="navTable">
+	<tr>
+		<td><a href="#" onclick="loadControl('videomode');">A/V Einstellungen</a><td>
+	</tr>
+	<tr>
+		<td><a href="#" onclick="loadControl('backuprestore');">Backup&Restore</a><td>
+	</tr>
+	<tr>
+		<td><a href="#" onclick="loadControl('softcam');">SoftcamPanel</a><td>
+	</tr>
+	<tr>
+		<td><a href="#" onclick="loadControl('pluginsipk');">PluginPanel</a><td>
+	</tr>
+	<tr>
+		<td><a href="#" onclick="loadControl('flashen');">UpdatePanel</a><td>
+	</tr>
+	<tr>
+		<td><a href="../bouqueteditor" target="_blank">WebBouquetEditor</a><td>
+	</tr>
+	<tr>
+		<td><a href="#" onclick="loadControl('overclock');">OverClock</a><td>
+	</tr>
+	<tr>
+		<td><a href="#" onclick="loadDeviceInfo();">Device Info</a><td>
+	</tr>
+	<tr>
+		<td><a href="#" onclick="loadSettings();">Settings</a><td>
+	</tr>	
+	<tr>
+		<td><a href="#" onclick="loadTools();">Tools</a><td>
+	</tr>
+</table>
+<!-- /tplNavExtras -->
Index: ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web-data/tpl/default/tplNavMovies.htm
===================================================================
--- ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web-data/tpl/default/tplNavMovies.htm	(revision 14969)
+++ ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web-data/tpl/default/tplNavMovies.htm	(revision 14969)
@@ -0,0 +1,29 @@
+
+<!-- tplNavMovies -->
+<table id="navTimer" class="navTable">
+	<tr>
+		<td>Movie Location:</td>
+	</tr>
+	<tr>
+		<td>
+			<select id="dirname" name="dirname" size="1" onchange="javascript:loadMovieList($('dirname').options[$('dirname').selectedIndex].value,$('tags').options[$('tags').selectedIndex].value)">
+				{for d in dirname}
+				<option value="${d.value}" ${d.selected}>${d.txt}</option>
+				{/for}
+			</select>
+		</td>
+	</tr>
+	<tr>
+		<td>Tag Filter:</td>
+	</tr>
+	<tr>
+		<td>
+			<select id="tags" name="tags" size="1" onchange="javascript:loadMovieList($('dirname').options[$('dirname').selectedIndex].value,$('tags').options[$('tags').selectedIndex].value)">
+				{for t in tags}
+				<option value="${t.value}" ${t.selected}>${t.txt}</option>
+				{/for}
+			</select>
+		</td>
+	</tr>
+</table>
+<!-- /tplNavMovies -->
Index: ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web-data/tpl/default/tplNavRadio.htm
===================================================================
--- ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web-data/tpl/default/tplNavRadio.htm	(revision 14969)
+++ ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web-data/tpl/default/tplNavRadio.htm	(revision 14969)
@@ -0,0 +1,19 @@
+
+<!-- tplNavRadio -->
+<table id="navRadio" class="navTable">
+	<tr>
+		<td><a href="#" onclick="loadContentDynamic(getBouquetsRadio, 'Bouquets (Radio)', 'contentBouquets');">Bouquets</a><td>
+	</tr>
+	<tr>
+		<td><a href="#" onclick="loadContentDynamic(getProviderRadio, 'Provider (Radio)', 'contentBouquets');">Provider</a><td>
+	</tr>
+	 <!--
+	<tr>
+		<td><a href="#" onclick="loadContentDynamic(getSatellitesRadio, 'Satellites (Radio)');">Satellites</a><td>
+	</tr>
+	-->	
+	<tr>
+		<td><a href="#" onclick="loadContentDynamic(getAllRadio, 'All (Radio)', 'contentServices');">All</a><td>
+	</tr>
+</table>
+<!-- /tplNavRadio -->
Index: ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web-data/tpl/default/tplNavTimer.htm
===================================================================
--- ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web-data/tpl/default/tplNavTimer.htm	(revision 14969)
+++ ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web-data/tpl/default/tplNavTimer.htm	(revision 14969)
@@ -0,0 +1,11 @@
+
+<!-- tplNavTimer -->
+<table id="navTimer" class="navTable">
+	<tr>
+		<td><a href="#" onclick="loadTimerList();">Show/Edit Timers</a><td>
+	</tr>
+	<tr>
+		<td><a href="#" onclick="loadTimerFormNow();">Add new Timer</a><td>
+	</tr>
+</table>
+<!-- /tplNavTimer -->
Index: ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web-data/tpl/default/tplNavTv.htm
===================================================================
--- ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web-data/tpl/default/tplNavTv.htm	(revision 14969)
+++ ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web-data/tpl/default/tplNavTv.htm	(revision 14969)
@@ -0,0 +1,13 @@
+<!-- tplNavTv -->
+<table id="navTv" class="navTable">
+	<tr>
+		<td><a href="#" onclick="loadContentDynamic(getBouquetsTv, 'Bouquets (TV)', 'contentBouquets');">Bouquets</a><td>
+	</tr>
+	<tr>
+		<td><a href="#" onclick="loadContentDynamic(getProviderTv, 'Provider (TV)', 'contentBouquets');">Provider</a><td>
+	</tr>
+	<tr>
+		<td><a href="#" onclick="loadContentDynamic(getAllTv, 'All (Tv)', 'contentServices');">All</a><td>
+	</tr>
+</table>
+<!-- /tplNavTv -->
Index: ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web-data/tpl/default/tplOverclock.htm
===================================================================
--- ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web-data/tpl/default/tplOverclock.htm	(revision 14969)
+++ ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web-data/tpl/default/tplOverclock.htm	(revision 14969)
@@ -0,0 +1,5 @@
+<!-- tploverclock -->
+<table  id="navExtras" height="240" width="100%">
+	<center><iframe src="../overclock" width="85%" height="240" vspace="0" hspace="0" marginwidth="0" marginheight="0" frameborder="0" scrolling="no"></iframe></center>
+</table>
+<!-- /tploverclock -->
Index: ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web-data/tpl/default/tplPower.htm
===================================================================
--- ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web-data/tpl/default/tplPower.htm	(revision 14969)
+++ ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web-data/tpl/default/tplPower.htm	(revision 14969)
@@ -0,0 +1,22 @@
+<!-- tplPower -->
+<table id="contentTable">
+	<tr>
+		<td>
+			<table style="width: 100%; text-align: center">
+				<tr>
+					<td><button class="w200h50" onclick="sendPowerState(0)">Toggle Standby</button></td>
+				</tr>
+				<tr>
+					<td><button class="w200h50" onclick="sendPowerState(1)">Deepstandby</button></td>
+				</tr>
+				<tr>
+					<td><button class="w200h50" onclick="sendPowerState(2)">Reboot</button></td>
+				</tr>
+				<tr>
+					<td><button class="w200h50" onclick="sendPowerState(3)">Restart Enigma2</button></td>
+				</tr>
+			</table>
+		</tr>
+	</td>
+</table>
+<!-- /tplPower -->
Index: ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web-data/tpl/default/tplSendMessage.htm
===================================================================
--- ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web-data/tpl/default/tplSendMessage.htm	(revision 14969)
+++ ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web-data/tpl/default/tplSendMessage.htm	(revision 14969)
@@ -0,0 +1,32 @@
+<!-- tplSendMessage -->
+<table id="contentTable">
+	<tr>
+		<td>
+			<table style="width: 100%;">
+				<tr>
+					<td>Text</td>
+					<td><textarea id="MessageSendFormText" cols="40" rows="5"></textarea></td>
+				</tr>
+				<tr>
+					<td>Timeout</td>
+					<td><input type="text" id="MessageSendFormTimeout" value="30"></td>
+				</tr>
+				<tr>
+					<td>Typ</td>
+					<td>
+						<select id="MessageSendFormType">';
+							<option value="2">Info</option>';
+							<option value="1">Warning</option>';
+							<option value="0">YesNo</option>';													
+							<option value="3">Error</option>';
+						</select>
+					</td>
+				</tr>
+				<tr>
+					<td colspan="2"><button onclick="sendMessage()">Send Message</button></td>
+				</tr>
+			</table>
+		</td>
+	</tr>
+</table>
+<!-- /tplSendMessage -->
Index: ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web-data/tpl/default/tplServiceList.htm
===================================================================
--- ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web-data/tpl/default/tplServiceList.htm	(revision 14969)
+++ ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web-data/tpl/default/tplServiceList.htm	(revision 14969)
@@ -0,0 +1,47 @@
+
+<!-- tplServiceList -->
+									<table>
+										{for service in services}
+										<tr class="sListRow" data-servicename="${service.servicename}">
+											<td class="${service.cssclass}">
+												<table class="sListItem">
+													<tr>
+														<td style="width: 640px;">										
+															<div class="sListSName">
+																<a href="#" id="${service.servicereference}" onclick="{ zap(this.id); }" class="sListSLink" title="Zap to ${service.servicename}">
+																	${service.servicename}
+																</a>
+															</div>
+														</td>
+														<td>
+															<a href="#" onclick="if ( parentPin( '${service.servicereference}' ) ) { loadEPGByServiceReference( '${service.servicereference}' ); }">
+																<img src="/web-data/img/epg.png" border="0" title="Show EPG for ${service.servicename}"/>
+															</a>
+														</td>
+														<td>
+															<a target="_blank" onclick="return parentPin( '${service.servicereference}' );" href="/web/stream.m3u?ref=${service.servicereference}">
+																<img src="/web-data/img/screen.png" title="Stream ${service.servicename}" border="0">
+															</a>
+														</td>											
+													</tr>
+													<tr id="trNOW${service.servicereference}" class="sListEPGNow" style="display:none;">
+														<td id="NOW${service.servicereference}" class="sListEPGItem" colspan="3"></td>
+													</tr>
+													<tr id="trNEXT${service.servicereference}" class="sListEPGNext" style="display:none;">
+														<td id="NEXT${service.servicereference}" class="sListEPGItem" colspan="3"></td>
+													</tr>
+													<tr id="trSUB${service.servicereference}" class="sListSubService" style="display:none;">
+														<td id="SUB${service.servicereference}" colspan="3"></td>
+													</tr>
+												</table>
+											</td>
+										</tr>
+										{forelse}
+										<tr>
+											<td>
+												<table><tr><td>No Services to Display</td></tr></table>
+											</td>
+										</tr>
+										{/for}		
+									</table>						
+<!-- /tplServiceList -->
Index: ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web-data/tpl/default/tplServiceListEPGItem.htm
===================================================================
--- ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web-data/tpl/default/tplServiceListEPGItem.htm	(revision 14969)
+++ ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web-data/tpl/default/tplServiceListEPGItem.htm	(revision 14969)
@@ -0,0 +1,21 @@
+
+<!-- tplServiceListEPGItem -->	
+	{if epg.title != 'None'}
+	<a href="#" onclick="showhide('trExt${nownext}${epg.servicereference}')" title="Click to show/hide extended Description">
+		<table cellspacing="0">
+			<tr>
+				<td class="epgStart">${epg.starttime}</td>
+				<td class="epgTitle">${epg.title}</td>
+				{if epg.duration != epg.remaining}
+				<td class="epgLength">+${epg.remaining} of ${epg.duration}</td>
+				{else}
+				<td class="epgLength">${epg.duration}</td>
+				{/if}
+			</tr>
+			<tr id="trExt${nownext}${epg.servicereference}" style="display:none">
+				<td colspan="4" class="epgLong">${epg.extdescription}</td>
+			</tr>
+		</table>
+	</a>
+	{/if}
+<!-- /tplServiceListEPGItem -->
Index: ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web-data/tpl/default/tplSettings.htm
===================================================================
--- ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web-data/tpl/default/tplSettings.htm	(revision 14969)
+++ ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web-data/tpl/default/tplSettings.htm	(revision 14969)
@@ -0,0 +1,30 @@
+<!-- tplSettings -->
+<table id="contentTable">
+	<tr>
+		<td>									
+			<table style="width: 100%;">
+				<tr>
+					<td colspan="2">WARNING: This functionality requires Cookies to store it's settings!</td>
+				</tr>
+				<tr>
+					<td>
+						Update-Interval for current service (min. 10 sec)
+					</td>
+					<td>
+						<form><input type="text" id="updateCurrentInterval" value="${updateCurrentInterval}">sec</form>
+					</td>										
+				</tr>
+				<tr>
+					<td>
+						Update-Interval for current bouquets EPG (min. 60 sec)
+					</td>
+					<td colspan="2">
+						<form><input type="text" id="updateBouquetInterval" value="${updateBouquetInterval}" />sec</form>
+					</td>										
+				</tr>																				
+				<tr><td><button onClick="saveSettings()">Save</button></td></tr>
+					</table>						
+					</td>
+				</tr>
+</table>
+<!-- /tplSettings -->
Index: ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web-data/tpl/default/tplSignalPanel.htm
===================================================================
--- ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web-data/tpl/default/tplSignalPanel.htm	(revision 14969)
+++ ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web-data/tpl/default/tplSignalPanel.htm	(revision 14969)
@@ -0,0 +1,36 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional"
+       "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<!-- tplSignalPanel -->
+	<head>
+		<meta content="text/html; charset=UTF-8" http-equiv="content-type">
+		<title>Enigma2 WebControl - EPG</title>
+		
+		<link href="/web-data/tpl/default/style.css" type="text/css" rel="stylesheet">
+	</head>
+	<body style="color:#000; scrollbar: auto;">
+		<table width="100%" id="SignalPanelTable">
+			<tr>
+				<td style="background-color: #DDDDDD;">dB</td><td style="background-color: #DDDDDD;">
+					<div id="SNRdB">${signal.snrdb}</div>
+				</td>
+			</tr>
+			<tr>
+				<td style="background-color: #DDDDDD;">SNR</td><td style="background-color: #DDDDDD;">
+					<div id="SNR">${signal.snr}</div>
+				</td>
+			</tr>
+			<tr>
+				<td style="background-color: #DDDDDD;">AGC</td><td style="background-color: #DDDDDD;">
+					<div id="AGC">${signal.acg}</div>
+				</td>
+			</tr>
+			<tr>
+				<td style="background-color: #DDDDDD;">BER</td><td style="background-color: #DDDDDD;">
+					<div id="BER">${signal.ber}</div>
+				</td>
+			</tr>
+		</table>
+	</body>
+<!-- /tplSignalPanel -->
+</html>
Index: ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web-data/tpl/default/tplSoftcam.htm
===================================================================
--- ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web-data/tpl/default/tplSoftcam.htm	(revision 14969)
+++ ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web-data/tpl/default/tplSoftcam.htm	(revision 14969)
@@ -0,0 +1,5 @@
+<!-- tplsoftcam -->
+<table  id="navExtras" height="510" width="100%">
+	<center><iframe src="../SoftCamPanel" width="70%" height="500" vspace="0" hspace="0" marginwidth="0" marginheight="0" frameborder="0" scrolling="no"></iframe></center>
+</table>
+<!-- /tplsoftcam -->
Index: ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web-data/tpl/default/tplSubServices.htm
===================================================================
--- ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web-data/tpl/default/tplSubServices.htm	(revision 14969)
+++ ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web-data/tpl/default/tplSubServices.htm	(revision 14969)
@@ -0,0 +1,20 @@
+<!-- tplSubServices -->								
+{for s in subservices}				
+	<table style="width: 586px;">
+		<tr>
+			<td style="width: 576px;">										
+				<div class="sListSName">
+					<a href="#" id="${s.servicereference}" onclick="{ zap(this.id); }" class="sListSLink" title="Zap to ${s.servicename}">
+						${s.servicename}
+					</a>
+				</div>
+			</td>
+			<td>
+				<a target="_blank" onclick="return parentPin( '${s.servicereference}' );" href="/web/stream.m3u?ref=${s.servicereference}">
+					<img src="/web-data/img/screen.png" title="Stream ${s.servicename}" border="0">
+				</a>
+			</td>											
+		</tr>
+	</table>
+{/for}
+<!-- /tplSubServices -->
Index: ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web-data/tpl/default/tplTimerEdit.htm
===================================================================
--- ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web-data/tpl/default/tplTimerEdit.htm	(revision 14969)
+++ ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web-data/tpl/default/tplTimerEdit.htm	(revision 14969)
@@ -0,0 +1,158 @@
+
+<!-- tplTimerEdit -->
+						<table id="contentTable">
+							<tr>
+								<td>
+									<table>
+										<tr>
+											<td colspan="3">Action:</td>
+											<td colspan="3">
+												<select name="justplay" id="justplay" size="1">
+													{for a in action}
+													<option value="${a.value}" ${a.selected}>${a.txt}</option>
+													{/for}
+												</select>
+											</td>
+										</tr>
+										<tr>
+											<td colspan="3">&nbsp;</td>
+											<td colspan="3" style="font-size: 12px;">Note: For recurring events date is not required.</td>
+										</tr>
+										<tr>
+											<td colspan="3">Date:</td>
+											<td colspan="3">
+												<select name="year" size="1" id="year">
+													{for y in year}
+													<option value="${y.value}" ${y.selected}>${y.txt}</option>
+													{/for}
+												</select>
+												. 
+												<select name="month" id="month" size="1">
+													{for m in month}
+													<option value="${m.value}" ${m.selected}>${m.txt}</option>
+													{/for}
+												</select>
+												.
+												<select name="day" id="day" size="1">
+													{for d in day}
+													<option value="${d.value}" ${d.selected}>${d.txt}</option>
+													{/for}
+												</select>
+											</td>
+										</tr>
+										<tr>
+											<td colspan="3">Start:</td>
+											<td colspan="3">
+												<select name="shour" id="shour" size="1">
+													{for hour in shour}
+													<option value="${hour.value}" ${hour.selected}>${hour.txt}</option>
+													{/for}
+												</select>
+												:
+												<select name="smin" id="smin" size="1">
+													{for min in smin}
+													<option value="${min.value}" ${min.selected}>${min.txt}</option>
+													{/for}
+												</select>
+											</td>
+										</tr>
+										<tr>
+											<td colspan="3">End:</td>
+											<td colspan="3">
+												<select name="ehour" id="ehour" size="1">
+													{for hour in ehour}
+													<option value="${hour.value}" ${hour.selected}>${hour.txt}</option>
+													{/for}
+												</select>
+												:
+												<select name="emin" id="emin" size="1">
+													{for min in emin}
+													<option value="${min.value}" ${min.selected}>${min.txt}</option>
+													{/for}
+												</select>
+											</td>
+										</tr>
+										<tr>
+											<td colspan="3">&nbsp;</td>
+											<td colspan="3" style="font-size: 12px;">Note: For one-time events the "days" field doesn't have to be specified.</td>
+										</tr>
+										<tr>
+											<td colspan="3">Days:</td>
+											<td colspan="3">
+												{for r in repeated}
+												<input type="checkbox" id="${r.id}" name="${r.name}" value="${r.value}" ${r.checked}>&nbsp;${r.txt}&nbsp;&nbsp;
+												{/for}
+											</td>
+										</tr>
+										<tr>
+											<td colspan="3">Channel:</td>
+											<td colspan="3">
+												<select name="channel" id="channel" size="1" onchange="javascript:addTimerFormChangeChannel($('channel').options[$('channel').selectedIndex].value)">
+													{for c in channel}
+													<option value="${c.value}" ${c.selected}>${c.txt}</option>
+													{/for}	
+												</select>
+											</td>
+										</tr>
+										<tr>
+											<td colspan="3">Name:</td>
+											<td colspan="3">
+												<input name="name" id="name" type="text" size="80" maxlength="80" style="color: #000000;" value="${timer.name}">
+											</td>
+										</tr>
+										<tr>
+											<td colspan="3">Description:</td>
+											<td colspan="3">
+												<input name="descr" id="descr" type="text" size="80" maxlength="80" style="color: #000000;" value="${timer.description}">
+											</td>
+										</tr>
+										<tr>
+											<td colspan="3">Location:</td>
+											<td colspan="3">
+											<form id="timerDir">
+												<select id="dirname" name="dirname" size="1">
+													{for d in dirname}
+													<option value="${d.value}" ${d.selected}>${d.txt}</option>
+													{/for}
+												</select>
+											</form>
+											</td>
+										</tr>
+										<tr>
+											<td colspan="3">Tags:</td>
+											<td colspan="3">
+											<form id="timerTags">
+												<select id="tags" name="tags" size="1" onchange="javascript:addTimerFormChangeTags($('tags').options[$('tags').selectedIndex].value)">
+													{for t in tags}
+													<option value="${t.value}" ${t.selected}>${t.txt}</option>
+													{/for}
+												</select>
+											</form>
+											</td>
+										</tr>
+										<tr>
+											<td colspan="3">After event do:</td>
+											<td colspan="3">
+												<select id="after_event" name="after_event" size="1">
+													{for event in afterEvent}
+													<option value="${event.value}" ${event.selected}>${event.txt}</option>
+													{/for}
+												</select>
+											</td>
+										</tr>
+										<tr><td>&nbsp;&nbsp;</td></tr>
+										<tr>
+											<td colspan="3">&nbsp;</td><td colspan="3">
+												<input name="deleteOldOnSave" id="deleteOldOnSave" type="hidden" value="${timer.deleteOldOnSave}">
+												<input name="channelOld" id="channelOld" type="hidden" value="${timer.channelOld}">
+												<input name="beginOld" id="beginOld" type="hidden" value="${timer.beginOld}">
+												<input name="endOld" id="endOld" type="hidden" value="${timer.endOld}">
+												<input name="eventID" id="eventID" type="hidden" value="${timer.eventID}">
+												<button onclick="sendAddTimer();">Add/Save</button>
+											</td>
+										</tr>
+									</table>
+								</td>
+							</tr>
+						</table>
+<!-- /tplTimerEdit -->
Index: ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web-data/tpl/default/tplTimerList.htm
===================================================================
--- ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web-data/tpl/default/tplTimerList.htm	(revision 14969)
+++ ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web-data/tpl/default/tplTimerList.htm	(revision 14969)
@@ -0,0 +1,50 @@
+
+<!-- tplTimerList -->
+						<table id="contentTable" style="width: 100%;">
+							{for t in timer}
+							<tr style="width:100%;">
+								<td style="width:100%;">									
+									<table class="timerState${t.state} tListItemTable ${t.cssclass}" border="0" cellpadding="0" cellspacing="0">				
+										<tr class="tListHead">
+											<td colspan="4" rowspan="1" class="tListSName" title="${t.description.escapeHTML()}, ${t.descriptionextended.escapeHTML()}">
+											${t.title} - {if t.description == ''} N/A {else} ${t.description} {/if} (${t.servicename})
+											</td>											
+										</tr>
+										<tr class="tListItem">
+											<td colspan="1" rowspan="1" class="tListRepeat">${t.repeatedReadable}</td>
+											<td colspan="1" rowspan="1" class="tListBegin">${t.beginDate}</td>												
+											<td colspan="1" rowspan="1" class="tListType">${t.justplayReadable}</td>						
+											<td colspan="1" rowspan="2" class="tListOption">
+												<a href="#">
+													<img src="/web-data/img/delete.png" title="Delete timer ${t.title}" border="0" onclick="delTimer('${t.servicereference}','${t.begin}','${t.end}','${t.servicename}','${t.title}','${t.description}',incomingTimerDelResult);">
+												</a>
+												<a href="#">
+													<img src="/web-data/img/${t.onOff}.png" title="${t.enDis} ${t.title}" border="0" onclick="sendToggleTimerDisable('${t.justplay}','${t.begin}','${t.end}','${t.repeated}','${t.servicereference}','${t.title}','${t.description}','${t.dirname}','${t.tags}','${t.afterevent}','${t.disabled}' );">
+												</a>
+												<a href="#">
+													<img src="/web-data/img/edit.png" title="Edit timer ${t.title}" border="0" onclick="loadTimerEditForm('${t.justplay}','${t.begin}','${t.end}','${t.repeated}','${t.servicereference}','${t.servicename}','${t.title}','${t.description}','${t.dirname}','${t.tags}','${t.afterevent}',1);">
+												</a>
+											</td>	
+										</tr>
+										<tr class="tListItem">						
+											<td class="tListDuration">${t.duration}&nbsp;Min</td>
+											<td class="tListEnd">${t.endDate}</td>												
+											<td class="tListAfter">${t.aftereventReadable}</td>
+										</tr>
+									</table>
+								</td>
+							</tr>
+							{forelse}
+							<tr style="width:100%;">
+								<td>No Timers Available!</td>
+							</tr>
+							{/for}
+										
+							<tr style="width:100%;">
+								<td colspan="7"><button onclick="writeTimerListNow()">Write To Memory</button></td>
+							</tr>
+							<tr style="width:100%;">
+								<td colspan="7"><button onclick="cleanTimerListNow()">Cleanup</button></td>
+							</tr>
+						</table>
+<!-- /tplTimerList -->
Index: ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web-data/tpl/default/tplTools.htm
===================================================================
--- ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web-data/tpl/default/tplTools.htm	(revision 14969)
+++ ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web-data/tpl/default/tplTools.htm	(revision 14969)
@@ -0,0 +1,59 @@
+<!-- tplTools -->
+			<div id="tools">
+				<h1>NOTICE</h1>
+				<pre>
+All Tools are listed here are third party Applications.
+Only the Authors of the individual Applications are responsible for it.
+				</pre>
+			</div>
+			<!-- 
+				Please keep the table alphabetically sorted by the name of the application, thanks. 
+				If you would like to be listed here, please contact one of the listed developers.
+			-->		
+			<table cellspacing="0" class="tools">
+				<tr>
+					<th colspan="1" class="toolsHeader">Name</th>
+					<th colspan="1" class="toolsHeader">OS</th>
+					<th colspan="1" class="toolsHeader">Description</th>
+					<th colspan="1" class="toolsHeader">Link</th>
+				</tr>
+				<tr>
+					<td class="toolsElementLeft">DreamRemote</td>
+					<td class="toolsElementCenter">Maemo/Meego</td>
+					<td class="toolsElementCenter">DreamRemote is an Open-Source enigma2 client for maemo/meego based devices. It allows you to control your aaf-box from your maemo/meego Device.</td>
+					<td class="toolsElementRight">
+						<a href="http://talk.maemo.org/showthread.php?p=657098" target="_blank" >More infos and Download</a>
+					</td>
+				</tr>
+				<tr>
+					<td class="toolsElementLeft">dreaMote</td>
+					<td class="toolsElementCenter">Iphone</td>
+					<td class="toolsElementCenter">dreaMote is an Open-Source enigma2 client for iphones. It allows you to control your aaf-box from your Iphone.</td>
+					<td class="toolsElementRight">
+						<a href="http://www.dream-multimedia-tv.de/board/index.php?page=Thread&threadID=8229" target="_blank" >More infos and Download</a>
+					</td>
+				</tr>
+				<tr>
+					<td class="toolsElementLeft">dreamDroid</td>
+					<td class="toolsElementCenter">Android</td>
+					<td class="toolsElementCenter">DreamDroid is an Open-Source enigma2 client for android based devices. It allows you to control your aaf-box from your Android Device.</td>
+					<td class="toolsElementRight">
+						<a href="http://github.com/sreichholf/dreamDroid/" target="_blank" >GitHub Site</a>
+						<br>
+						<a href="market://search?q=pname:net.reichholf.dreamdroid">Android&nbsp;Market Link</a>
+					</td>
+				</tr>
+				<tr>
+					<td class="toolsElementLeft">Enigmanoid</td>
+					<td class="toolsElementCenter">Android</td>
+					<td class="toolsElementCenter">a Tool to manage and control your aaf-box while you are not at Home. Browse your Servicelists, the EPG and your recorded Movies right from your Android powered Mobilephone. You can add and change Timers, take and save Screenshots and play Music from your SD-Card. It also includes a Satfinder, which helps you while you are on your roof to setup your Dish.</td>
+					<td class="toolsElementRight">
+						<a href="http://wiki.blue-panel.com/index.php/Enigmanoid" target="_blank" >more Informations</a>
+						<br>
+						<a href="market://search?q=pname:de.dreizeh.enigmanoid">Android&nbsp;Market</a>
+						<br>
+						<a href="market://search?q=pname:de.dreizeh.enigmanoid.free">Android&nbsp;Market&nbsp;Freeversion</a>
+					</td>
+				</tr>
+			</table>
+<!-- /tplTools -->
Index: ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web-data/tpl/default/tplVideomode.htm
===================================================================
--- ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web-data/tpl/default/tplVideomode.htm	(revision 14969)
+++ ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web-data/tpl/default/tplVideomode.htm	(revision 14969)
@@ -0,0 +1,5 @@
+<!-- tplvideomode -->
+<table  id="navExtras" height="240" width="100%">
+	<center><iframe src="../VideoMode" width="85%" height="240" vspace="0" hspace="0" marginwidth="0" marginheight="0" frameborder="0" scrolling="no"></iframe></center>
+</table>
+<!-- /tplvideomode -->
Index: ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web-data/tpl/default/tplWebRemote.htm
===================================================================
--- ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web-data/tpl/default/tplWebRemote.htm	(revision 14969)
+++ ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web-data/tpl/default/tplWebRemote.htm	(revision 14969)
@@ -0,0 +1,59 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<!-- tplWebRemote -->
+	<head>
+		<meta content="text/html; charset=UTF-8" http-equiv="content-type">
+		<title>Enigma2 Webremote</title>
+	</head>
+	<body>
+		<center>
+			Send "long" Keypress&nbsp;<input type="checkbox" id="long" name="long" /><br>
+			<!--Get a Screenshoot&nbsp;<input type="checkbox" id="getScreen" name="getScreen" checked><br>
+			Grab Picture & OSD&nbsp;<input type="checkbox" id="getVideo" name="getVideo"><br>-->
+		</center>
+		<br>
+		<!--<center><input type="checkbox" id="getScreen" name="getScreen" checked>&nbsp;Show Screenshot</center><br>-->
+<map id="rcnew" name="rcnew">
+<area shape="rect" nohref coords="5,37,41,57" onClick="opener.sendRemoteControlRequest(2)" alt="1" title="1">
+<area shape="rect" nohref coords="50,37,86,57" onClick="opener.sendRemoteControlRequest(3)" alt="2" title="2">
+<area shape="rect" nohref coords="95,37,131,57" onClick="opener.sendRemoteControlRequest(4)" alt="3" title="3">
+<area shape="rect" nohref coords="5,67,41,87" onClick="opener.sendRemoteControlRequest(5)" alt="4" title="4">
+<area shape="rect" nohref coords="50,67,86,87" onClick="opener.sendRemoteControlRequest(6)" alt="5" title="5">
+<area shape="rect" nohref coords="95,67,131,87" onClick="opener.sendRemoteControlRequest(7)" alt="6" title="6">
+<area shape="rect" nohref coords="5,97,41,117" onClick="opener.sendRemoteControlRequest(8)" alt="7" title="7">
+<area shape="rect" nohref coords="50,97,86,117" onClick="opener.sendRemoteControlRequest(9)" alt="8" title="8">
+<area shape="rect" nohref coords="95,97,131,117" onClick="opener.sendRemoteControlRequest(10)" alt="9" title="9">
+<area shape="rect" nohref coords="50,127,86,147" onClick="opener.sendRemoteControlRequest(11)" alt="0" title="0">
+<area shape="rect" nohref coords="5,127,41,147" onClick="opener.sendRemoteControlRequest(139)" alt="Menu" title="Menu">
+<area shape="rect" nohref coords="95,127,131,147" onClick="opener.sendRemoteControlRequest(388)" alt="text" title="text">
+<area shape="rect" nohref coords="2,316,38,336" onClick="opener.sendRemoteControlRequest(168)" alt="Rewind" title="Rewind">
+<area shape="rect" nohref coords="96,316,132,336" onClick="opener.sendRemoteControlRequest(208)" alt="Fast Forward" title="Fast Forward">
+<area shape="rect" nohref coords="96,342,132,362" onClick="opener.sendRemoteControlRequest(128)" alt="Stop" title="Stop">
+<area shape="rect" nohref coords="2,341,38,361" onClick="opener.sendRemoteControlRequest(119)" alt="Pause" title="Pause">
+<area shape="rect" nohref coords="50,316,86,336" onClick="opener.sendRemoteControlRequest(207)" alt="Play" title="Play">
+<area shape="rect" nohref coords="50,342,86,362" onClick="opener.sendRemoteControlRequest(167)" alt="Record" title="Record">
+<area shape="rect" nohref coords="50,253,86,275" onClick="opener.sendRemoteControlRequest(352)" alt="OK" title="OK">
+<area shape="rect" nohref coords="5,253,41,275" onClick="opener.sendRemoteControlRequest(105)" alt="Left" title="Left">
+<area shape="rect" nohref coords="95,253,131,275" onClick="opener.sendRemoteControlRequest(106)" alt="Right" title="Right">
+<area shape="rect" nohref coords="50,221,86,244" onClick="opener.sendRemoteControlRequest(103)" alt="Up" title="Up">
+<area shape="rect" nohref coords="50,284,86,307" onClick="opener.sendRemoteControlRequest(108)" alt="Down" title="Down">
+<area shape="rect" nohref coords="2,152,26,175" onClick="opener.sendRemoteControlRequest(398)" alt="Red" title="Red">
+<area shape="rect" nohref coords="37,152,61,175" onClick="opener.sendRemoteControlRequest(399)" alt="Green" title="Green">
+<area shape="rect" nohref coords="73,152,97,175" onClick="opener.sendRemoteControlRequest(400)" alt="Yellow" title="Yellow">
+<area shape="rect" nohref coords="108,152,132,175" onClick="opener.sendRemoteControlRequest(401)" alt="Blue" title="Blue">
+<area shape="rect" nohref coords="4,4,30,30" onClick="opener.sendRemoteControlRequest(113)" alt="Mute" title="Mute">
+<area shape="rect" nohref coords="105,4,131,30" onClick="opener.sendRemoteControlRequest(116)" alt="Power" title="Power">
+<area shape="rect" nohref coords="5,181,31,207" onClick="opener.sendRemoteControlRequest(115)" alt="Volume Up" title="Volume Up">
+<area shape="rect" nohref coords="5,219,31,245" onClick="opener.sendRemoteControlRequest(114)" alt="Volume Down" title="Volume Down">
+<area shape="rect" nohref coords="104,180,130,206" onClick="opener.sendRemoteControlRequest(106)" alt="Channel Up" title="Channel Up">
+<area shape="rect" nohref coords="105,218,131,244" onClick="opener.sendRemoteControlRequest(106)" alt="Down" title="Channel Down">
+<area shape="rect" nohref coords="55,180,81,206" onClick="opener.sendRemoteControlRequest(138)" alt="Info" title="Info">
+<area shape="rect" nohref coords="4,282,30,308" onClick="opener.sendRemoteControlRequest(102)" alt="Exit" title="Exit">
+<area shape="rect" nohref coords="105,282,131,308" onClick="opener.sendRemoteControlRequest(365)" alt="EPG" title="EPG">
+</map> 
+		<center>
+			<img src="/web-data/img/rc.png" border="0" alt="Remote Control" usemap="#rcnew">
+		</center>
+	</body>
+<!-- /tplWebRemote -->
+</html>
Index: ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web-data/tpl/default/tplWebRemoteOld.htm
===================================================================
--- ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web-data/tpl/default/tplWebRemoteOld.htm	(revision 14969)
+++ ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web-data/tpl/default/tplWebRemoteOld.htm	(revision 14969)
@@ -0,0 +1,59 @@
+﻿<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional"
+       "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+	<head>
+		<meta content="text/html; charset=UTF-8" http-equiv="content-type">
+		<title>Enigma2 Webremote</title>
+	</head>
+	
+	<body>
+		<center>
+			<!--Get a Screenshoot&nbsp;<input type="checkbox" id="getScreen" name="getScreen"><br>
+			Grab Picture & OSD&nbsp;<input type="checkbox" id="getVideo" name="getVideo"><br>-->
+		</center>
+		<br>
+		<!--<center><input type="checkbox" id="getScreen" name="getScreen" checked>&nbsp;Show Screenshot</center><br>-->
+		<!-- Old Remote -->
+		<map name="rcold">
+			<area shape="circle" coords="43, 252, 14" nohref onclick="opener.sendRemoteControlRequest(113)" alt="mute">
+			<area shape="circle" coords="107, 32, 14" nohref onclick="opener.sendRemoteControlRequest(116)" alt="Power">
+			<area shape="circle" coords="44, 66, 14" nohref onclick="opener.sendRemoteControlRequest(2)" alt="1">
+			<area shape="circle" coords="88, 66, 15" nohref onclick="opener.sendRemoteControlRequest(3)" alt="2">
+			<area shape="circle" coords="129, 66, 15" nohref onclick="opener.sendRemoteControlRequest(4)" alt="3">
+			<area shape="circle" coords="44, 100, 15" nohref onclick="opener.sendRemoteControlRequest(5)" alt="4">
+			<area shape="circle" coords="88, 100, 15" nohref onclick="opener.sendRemoteControlRequest(6)" alt="5">
+			<area shape="circle" coords="129, 100, 15" nohref onclick="opener.sendRemoteControlRequest(7)" alt="6">
+			<area shape="circle" coords="44, 134, 15" nohref onclick="opener.sendRemoteControlRequest(8)" alt="7">
+			<area shape="circle" coords="88, 134, 15" nohref onclick="opener.sendRemoteControlRequest(9)" alt="8">
+			<area shape="circle" coords="129, 134, 15" nohref onclick="opener.sendRemoteControlRequest(10)" alt="9">
+			<area shape="circle" coords="44, 172, 15" nohref onclick="opener.sendRemoteControlRequest(139)" alt="menu">
+			<area shape="circle" coords="88, 172, 15" nohref onclick="opener.sendRemoteControlRequest(11)" alt="0">
+			<area shape="circle" coords="129, 172, 15" nohref onclick="opener.sendRemoteControlRequest(388)" alt="text">
+			<area shape="circle" coords="38, 290, 15" nohref onclick="opener.sendRemoteControlRequest(398)" alt="red">
+			<area shape="circle" coords="72, 290, 15" nohref onclick="opener.sendRemoteControlRequest(399)" alt="green">
+			<area shape="circle" coords="104, 290, 15" nohref onclick="opener.sendRemoteControlRequest(400)" alt="yellow">
+			<area shape="circle" coords="136, 290, 15" nohref onclick="opener.sendRemoteControlRequest(401)" alt="blue">
+			<area shape="circle" coords="128, 211, 15" nohref onclick="opener.sendRemoteControlRequest(115)" alt="volume up">
+			<area shape="circle" coords="130, 252, 15" nohref onclick="opener.sendRemoteControlRequest(138)" alt="info">
+			<area shape="circle" coords="87, 211, 15" nohref onclick="opener.sendRemoteControlRequest(106)" alt="program up">
+			<area shape="circle" coords="46, 211, 15" nohref onclick="opener.sendRemoteControlRequest(114)" alt="volume down">
+			<area shape="circle" coords="87, 329, 15" nohref onclick="opener.sendRemoteControlRequest(103)" alt="up">
+			<area shape="circle" coords="87, 248, 15" nohref onclick="opener.sendRemoteControlRequest(105)" alt="program down">
+			<area shape="circle" coords="44, 367, 15" nohref onclick="opener.sendRemoteControlRequest(105)" alt="left">
+			<area shape="circle" coords="88, 367, 15" nohref onclick="opener.sendRemoteControlRequest(352)" alt="OK">
+			<area shape="circle" coords="132, 367, 15" nohref onclick="opener.sendRemoteControlRequest(106)" alt="right">
+			<area shape="circle" coords="44, 409, 15" nohref onclick="opener.sendRemoteControlRequest(102)" alt="exit">
+			<area shape="circle" coords="88, 409, 15" nohref onclick="opener.sendRemoteControlRequest(108)" alt="down">
+			<area shape="circle" coords="443, 329, 15" nohref onclick="opener.sendRemoteControlRequest(174)" alt="epg">
+			<area shape="circle" coords="44, 445, 15" nohref onclick="opener.sendRemoteControlRequest(102)" alt="2xleft">
+			<area shape="circle" coords="88, 445, 15" nohref onclick="opener.sendRemoteControlRequest(102)" alt="play">
+			<area shape="circle" coords="132, 445, 15" nohref onclick="opener.sendRemoteControlRequest(102)" alt="2xright">
+			<area shape="circle" coords="44, 477, 15" nohref onclick="opener.sendRemoteControlRequest(102)" alt="pause">
+			<area shape="circle" coords="88, 477, 15" nohref onclick="opener.sendRemoteControlRequest(102)" alt="rec">
+			<area shape="circle" coords="132, 477, 15" nohref onclick="opener.openGrabPicture()" alt="TV Screenshot">		</map>
+		<center>
+			<img src="/web-data/img/rcold.png" height="607" width="178" border="0" alt="Remote Control" usemap="#rcold">
+		</center>
+
+	</body>
+</html>
Index: ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web-data/userprefs.js
===================================================================
--- ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web-data/userprefs.js	(revision 14969)
+++ ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web-data/userprefs.js	(revision 14969)
@@ -0,0 +1,26 @@
+/*
+ * This code is inspired by http://www.phpied.com/json-javascript-cookies/
+ * and modified for use with prototype
+ * It's a pretty straight forward way to store and load settings in a nice to use JSON-Object
+ */ 
+
+var userprefs = {
+	data : {},
+
+	load : function() {
+		var the_cookie = document.cookie.split(';');
+		if (the_cookie[0]) {
+			this.data = unescape(the_cookie[0]).evalJSON();
+		}
+		return this.data;
+	},
+
+	save : function(expires, path) {
+		var d = expires || new Date(2222, 01, 01);
+		var p = path || '/';
+		document.cookie = escape( Object.toJSON(this.data) ) + ';path=' + p
+				+ ';expires=' + d.toUTCString();
+	}
+};
+
+userprefs.load();
Index: ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web-data/vlcplayer.js
===================================================================
--- ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web-data/vlcplayer.js	(revision 14969)
+++ ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web-data/vlcplayer.js	(revision 14969)
@@ -0,0 +1,271 @@
+var vlc = '';
+var currentServiceRef = '';
+var bouquetUpdatePoller = '';
+var currentBouquetRef = '';
+/*
+ * incoming request-data for Current Service Epg
+ */
+function incomingVLCServiceEPG(request) {
+	if (request.readyState == 4) {
+		var events = getXML(request).getElementsByTagName("e2eventlist")
+				.item(0).getElementsByTagName("e2event");
+
+		var event = new EPGEvent(events.item(0)).toJSON();
+
+		var data = {
+			'current' : event
+		};
+		processTpl('streaminterface/tplCurrent', data, 'current');
+	}
+}
+
+/*
+ * Load Now information for Service
+ */
+function loadVLCEPGServiceNow(servicereference) {
+	doRequest(URL.epgservicenow + servicereference, incomingVLCServiceEPG);
+}
+
+function onServiceSelected() {
+	currentServiceRef = $('channelSelect').options[$('channelSelect').selectedIndex].id;
+	
+	if(currentServiceRef !== "vlcemptyservice"){
+		loadVLCEPGServiceNow(currentServiceRef);
+		setStreamTarget(currentServiceRef);
+		
+		if($('vlcZap').checked){			
+			doRequest("/web/zap?sRef=" + currentServiceRef);			
+		}
+		delayedLoadVlcSubservices();
+	} else {
+		vlcStop();
+	}
+}
+
+function incomingVLCBouquetList(request) {
+	if (request.readyState == 4) {
+		var services = new ServiceList(getXML(request)).getArray();
+
+		data = {
+			bouquets : services
+		};
+
+		processTpl('streaminterface/tplBouquetList', data, 'bouquetList');
+		loadVLCBouquet(services[0].servicereference);
+	}
+}
+function reloadVLCBouquet(){
+	loadVLCBouquet(currentBouquetRef);
+}
+
+
+function loadVLCBouquet(servicereference) {
+//	clearInterval(bouquetUpdatePoller);	
+	currentBouquetRef = servicereference;
+	
+	loadVLCChannelList(servicereference);
+	
+//	bouquetUpdatePoller = setInterval(reloadVLCBouquet, 30000);
+}
+
+function incomingVLCSubservices(request){
+	if (request.readyState == 4) {
+		var services = new ServiceList(getXML(request)).getArray();
+		debug("[incomincVLCSubservices] Got " + services.length + " SubServices");
+		
+		if(services.length > 1) {			
+			var masterref = $(services[0].servicereference);
+			var lastoption = masterref;
+
+			
+			if(lastoption !== null){
+				// we already have the main service in our servicelist so we'll
+				// start with the second element
+				// to avoid crazy things happening, just check it's not the master-service we've gotten
+				
+				for ( var i = 1; i < services.length ; i++){
+					var service = services[i];
+					
+					//TODO: FIX THIS UGLY CODE
+					if(service.servicereference != masterref){
+						var option = $(service.servicereference);
+						if(option !== null){
+							option.remove();
+						}
+						option = new Option(' |- ' + service.servicename);
+						option.id =  service.servicereference;
+						
+						lastoption.insert( { after : option } );
+						
+						lastoption = option;
+					}
+				}
+			}
+		}
+	}
+}
+
+function loadVlcSubservices(){
+	var url = URL.streamsubservices + currentServiceRef;
+	doRequest(url, incomingVLCSubservices);
+}
+
+function delayedLoadVlcSubservices(){
+	setTimeout(loadVlcSubservices, 7500);
+}
+
+/*
+ * Incoming request-data for EPG Now information
+ * Builds the Channellist
+ */
+function incomingVLCChannelList(request) {
+	if (request.readyState == 4) {
+		var events = new EPGList(getXML(request)).getArray();
+
+		var data = {
+			'events' : events
+		};
+		processTpl('streaminterface/tplServiceList', data, 'channelList');
+	}
+}
+
+/*
+ * Load List of all Channels with epg now where available
+ */
+function loadVLCChannelList(bouquetreference) {
+	doRequest(URL.epgnow + bouquetreference, incomingVLCChannelList);
+}
+
+function vlcPlay() {
+	try {
+		onServiceSelected();
+	} catch (e) {
+		notify("Nothing to play", false);
+	}
+}
+
+function vlcPrev() {
+	if ($('channelSelect').selectedIndex > 0) {
+		$('channelSelect').selectedIndex -= 1;
+		onServiceSelected();
+	}
+}
+
+function vlcNext() {
+	if ($('channelSelect').selectedIndex < $('channelSelect').length - 1) {
+		$('channelSelect').selectedIndex += 1;
+		onServiceSelected();
+	}
+}
+
+function vlcPause() {
+	vlc.playlist.togglePause();
+}
+
+function vlcStop() {
+	try {
+		vlc.playlist.stop();
+	} catch (e) {
+		notify("Nothing to stop", false);
+	}
+}
+
+function vlcVolumeUp() {
+	if (vlc.audio.volume < 200) {
+		if (vlc.audio.volume + 10 > 200) {
+			vlc.audio.volume = 200;
+		} else {
+			vlc.audio.volume += 10;
+		}
+	}
+
+	set('vlcVolume', vlc.audio.volume);
+}
+
+function vlcVolumeDown() {
+	if (vlc.audio.volume > 0) {
+		if (vlc.audio.volume < 10) {
+			vlc.audio.volume = 0;
+		} else {
+			vlc.audio.volume -= 10;
+		}
+	}
+
+	set('vlcVolume', vlc.audio.volume);
+}
+
+function vlcToogleMute() {
+	vlc.audio.mute = !vlc.audio.mute;
+	if (vlc.audio.mute) {
+		set('vlcVolume', 'Muted');
+	} else {
+		set('vlcVolume', vlc.audio.volume);
+	}
+}
+
+function vlcFullscreen() {
+	if (vlc.playlist.isPlaying) {
+		if (vlc.input.hasVout) {
+			vlc.video.fullscreen = true;
+			return;
+		}
+	}
+
+	notify("Cannot enable fullscreen mode when no Video is being played!",
+			false);
+}
+
+function vlcTeletext() {
+	try {
+		vlc.video.teletext = 100;
+	} catch (e) {
+		debug("Error - Could not set teletext");
+	}
+	debug("Current Teletext Page:" + vlc.video.teletext);
+}
+
+function playUrl(url) {
+	current = vlc.playlist.add(url);
+	vlc.playlist.playItem(current);
+	set('vlcVolume', vlc.audio.volume);
+}
+
+function setStreamTarget(servicereference) {
+	host = top.location.host;
+	url = 'http://' + host + ':8001/' + decodeURIComponent(servicereference);
+
+	debug("setStreamTarget " + url);
+	vlc.playlist.clear();
+	playUrl(url);
+}
+
+function loadVLCBouquets() {
+	url = URL.getservices + bouquetsTv;
+	doRequest(url, incomingVLCBouquetList);
+	
+}
+
+/*
+ * Event when the user selected a Bouquet in the bouquets <select>
+ */
+function onBouquetSelected() {
+	var servicereference = $('bouquetSelect').options[$('bouquetSelect').selectedIndex].id;
+	loadVLCBouquet(servicereference);
+}
+
+function initWebTv() {
+	var DBG = userprefs.data.debug || false;
+	if (DBG) {
+		openDebug();
+	}
+
+	vlc = $('vlc');
+
+	try {
+		set('vlcVolume', vlc.audio.volume);
+	} catch (e) {
+		debug('[initWebTv] Error on initializing WebTv');
+	}
+
+	loadVLCBouquets();
+}
Index: ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/about.xml
===================================================================
--- ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/about.xml	(revision 14969)
+++ ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/about.xml	(revision 14969)
@@ -0,0 +1,49 @@
+<e2:screen name="AboutWebScreen">&lt;?xml version="1.0" encoding="UTF-8"?>
+<e2abouts>
+	<e2about>
+		<e2enigmaversion><e2:element source="EnigmaVersion"><e2:convert type="web:TextToHTML" /></e2:element></e2enigmaversion>
+		<e2imageversion><e2:element source="ImageVersion"><e2:convert type="web:TextToHTML" /></e2:element></e2imageversion>
+		<e2webifversion><e2:element source="WebIfVersion"><e2:convert type="web:TextToHTML" /></e2:element></e2webifversion>
+		<e2fpversion><e2:element source="FpVersion"><e2:convert type="web:TextToHTML" /></e2:element></e2fpversion>
+		<e2model><e2:element source="DeviceName"><e2:convert type="web:TextToHTML" /></e2:element></e2model>
+		
+		<e2:element source="About" ><e2:convert type="web:ListFiller" >	
+		&lt;e2lanmac><e2:item name="lanMac" filter="xml"/>&lt;/e2lanmac>
+		&lt;e2landhcp><e2:item name="lanDHCP" filter="xml"/>&lt;/e2landhcp>
+		&lt;e2lanip><e2:item name="lanIP" filter="xml"/>&lt;/e2lanip>
+		&lt;e2lanmask><e2:item name="lanMask" filter="xml"/>&lt;/e2lanmask>
+		&lt;e2langw><e2:item name="lanGW" filter="xml"/>&lt;/e2langw>					
+		</e2:convert><e2:convert type="web:TextToHTML" />
+		</e2:element>
+		
+		<e2:element source="Hdd"><e2:convert type="web:ListFiller">
+		&lt;e2hddinfo>
+			&lt;model><e2:item name="Model" filter="xml"/>&lt;/model>
+			&lt;capacity><e2:item name="Capacity" filter="xml"/>&lt;/capacity>
+			&lt;free><e2:item name="Free" filter="xml"/>&lt;/free>
+		&lt;/e2hddinfo>
+		</e2:convert><e2:convert type="web:TextToHTML" /></e2:element>		
+		<e2tunerinfo><e2:element source="Frontends"><e2:convert type="web:ListFiller" >
+			&lt;e2nim>
+				&lt;name><e2:item name="Name" filter="xml"/>&lt;/name>
+				&lt;type><e2:item name="Type" filter="xml"/>&lt;/type>
+			&lt;/e2nim></e2:convert><e2:convert type="web:TextToHTML" /></e2:element>
+		</e2tunerinfo>		
+		<e2servicename><e2:element source="session.CurrentService"><e2:convert type="ServiceName">Name</e2:convert><e2:convert type="web:TextToXML" /></e2:element></e2servicename>
+		<e2servicenamespace />
+		<e2serviceaspect />
+		<e2serviceprovider><e2:element source="session.CurrentService"><e2:convert type="ServiceName">Provider</e2:convert><e2:convert type="web:TextToXML" /></e2:element></e2serviceprovider>
+		<e2videowidth><e2:element source="session.CurrentService"><e2:convert type="ServiceInfo">VideoWidth</e2:convert><e2:convert type="web:TextToXML" /></e2:element></e2videowidth>
+		<e2videoheight><e2:element source="session.CurrentService"><e2:convert type="ServiceInfo">VideoHeight</e2:convert><e2:convert type="web:TextToXML" /></e2:element></e2videoheight>
+		<e2servicevideosize><e2:element source="session.CurrentService"><e2:convert type="ServiceInfo">VideoWidth</e2:convert><e2:convert type="web:TextToXML" /></e2:element>x<e2:element source="session.CurrentService"><e2:convert type="ServiceInfo">VideoHeight</e2:convert><e2:convert type="web:TextToXML" /></e2:element></e2servicevideosize>
+		<e2apid><e2:element source="session.CurrentService"><e2:convert type="ServiceInfo">AudioPid</e2:convert><e2:convert type="web:TextToXML" /></e2:element></e2apid>
+		<e2vpid><e2:element source="session.CurrentService"><e2:convert type="ServiceInfo">VideoPid</e2:convert><e2:convert type="web:TextToXML" /></e2:element></e2vpid>
+		<e2pcrpid><e2:element source="session.CurrentService"><e2:convert type="ServiceInfo">PcrPid</e2:convert><e2:convert type="web:TextToXML" /></e2:element></e2pcrpid>
+		<e2pmtpid><e2:element source="session.CurrentService"><e2:convert type="ServiceInfo">PmtPid</e2:convert><e2:convert type="web:TextToXML" /></e2:element></e2pmtpid>
+		<e2txtpid><e2:element source="session.CurrentService"><e2:convert type="ServiceInfo">TxtPid</e2:convert><e2:convert type="web:TextToXML" /></e2:element></e2txtpid>
+		<e2tsid><e2:element source="session.CurrentService"><e2:convert type="ServiceInfo">TsId</e2:convert><e2:convert type="web:TextToXML" /></e2:element></e2tsid>
+		<e2onid><e2:element source="session.CurrentService"><e2:convert type="ServiceInfo">OnId</e2:convert><e2:convert type="web:TextToXML" /></e2:element></e2onid>
+		<e2sid><e2:element source="session.CurrentService"><e2:convert type="ServiceInfo">Sid</e2:convert><e2:convert type="web:TextToXML" /></e2:element></e2sid>
+	</e2about>
+</e2abouts>
+</e2:screen>
Index: ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/addlocation.xml
===================================================================
--- ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/addlocation.xml	(revision 14969)
+++ ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/addlocation.xml	(revision 14969)
@@ -0,0 +1,9 @@
+<e2:screen name="LocationsAndTagsWebScreen">&lt;?xml version="1.0" encoding="UTF-8"?>
+<e2:element source="AddLocation" id="dirname,createFolder">
+	<e2:convert type="web:Null" />
+</e2:element>
+<e2simplexmlresult>
+	<e2state><e2:element source="AddLocation"><e2:convert type="SimpleResult">Result</e2:convert><e2:convert type="web:TextToXML" /></e2:element></e2state>
+	<e2statetext><e2:element source="AddLocation"><e2:convert type="SimpleResult">ResultText</e2:convert><e2:convert type="web:TextToXML" /></e2:element></e2statetext>	
+</e2simplexmlresult>		
+</e2:screen>
Index: ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/autotimerlist.xml
===================================================================
--- ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/autotimerlist.xml	(revision 14969)
+++ ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/autotimerlist.xml	(revision 14969)
@@ -0,0 +1,35 @@
+<e2:screen name="AutoTimerWebScreen">&lt;?xml version="1.0" encoding="UTF-8"?>
+<e2autotmerlist><e2:element source="AutoTimerList" id="gl"><e2:convert type="web:ListFiller" >
+	&lt;e2autotimer>
+		&lt;e2name><e2:item name="Name"  filter="xml"/>&lt;/e2name>
+		&lt;e2match><e2:item name="Match"  filter="xml"/>&lt;/e2match>
+  	    &lt;e2enabled><e2:item name="Enabled"  filter="xml"/>&lt;/e2enabled>
+  	    &lt;e2excludetitle><e2:item name="ExcludedTitle"  filter="xml"/>&lt;/e2excludetitle>
+  	    &lt;e2excludeshort><e2:item name="ExcludedShort"  filter="xml"/>&lt;/e2excludeshort>
+  	    &lt;e2excludedescription><e2:item name="ExcludedDescription"  filter="xml"/>&lt;/e2excludedescription>
+  	    &lt;e2excludedays><e2:item name="ExcludedDays"  filter="xml"/>&lt;/e2excludedays>
+  	    &lt;e2includetitle><e2:item name="IncludedTitle"  filter="xml"/>&lt;/e2includetitle>
+  	    &lt;e2includeshort><e2:item name="IncludedShort"  filter="xml"/>&lt;/e2includeshort>
+  	    &lt;e2includedescription><e2:item name="IncludedDescription"  filter="xml"/>&lt;/e2includedescription>
+  	    &lt;e2includedays><e2:item name="IncludedDays"  filter="xml"/>&lt;/e2includedays>
+  	    &lt;e2services><e2:item name="Services"  filter="xml"/>&lt;/e2services>
+  	    &lt;e2bouquets><e2:item name="Bouquets"  filter="xml"/>&lt;/e2bouquets>
+  	    &lt;e2timespanbegin><e2:item name="TimespanBegin"  filter="xml"/>&lt;/e2timespanbegin>
+  	    &lt;e2timespanend><e2:item name="TimespanEnd"  filter="xml"/>&lt;/e2timespanend>
+  	    &lt;e2duration><e2:item name="Duration"  filter="xml"/>&lt;/e2duration>
+  	    &lt;e2counter><e2:item name="Counter"  filter="xml"/>&lt;/e2counter>
+  	    &lt;e2counterleft><e2:item name="CounterLeft"  filter="xml"/>&lt;/e2counterleft>
+  	    &lt;e2counterlimit><e2:item name="CounterLimit"  filter="xml"/>&lt;/e2counterlimit>
+  	    &lt;e2destination><e2:item name="Destination"  filter="xml"/>&lt;/e2destination>
+  	    &lt;e2counterformatstring><e2:item name="CounterFormatString"  filter="xml"/>&lt;/e2counterformatstring>
+  	    &lt;e2lastbegin><e2:item name="LastBegin"  filter="xml"/>&lt;/e2lastbegin>
+  	    &lt;e2justplay><e2:item name="Justplay"  filter="xml"/>&lt;/e2justplay>
+  	    &lt;e2avoidduplicatedescription><e2:item name="AvoidDuplicateDescription"  filter="xml"/>&lt;/e2avoidduplicatedescription>
+  	    &lt;e2tags><e2:item name="Tags"  filter="xml"/>&lt;/e2tags>
+  	    &lt;e2afterevent><e2:item name="AfterEvent"  filter="xml"/>&lt;/e2afterevent>
+  	    &lt;e2toggledisableimg><e2:item name="toggleDisabledIMG"  filter="xml"/>&lt;/e2toggledisableimg>
+	&lt;/e2autotimer>
+	</e2:convert>
+	<e2:convert type="web:TextToHTML" /></e2:element>
+</e2autotmerlist>
+</e2:screen>
Index: ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/currenttime.xml
===================================================================
--- ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/currenttime.xml	(revision 14969)
+++ ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/currenttime.xml	(revision 14969)
@@ -0,0 +1,3 @@
+<e2:screen name="UpdateWebScreen">&lt;?xml version="1.0" encoding="UTF-8"?>
+<e2currenttime><e2:element source="CurrentTime"><e2:convert type="ClockToText">WithSeconds</e2:convert><e2:convert type="web:TextToHTML" /></e2:element></e2currenttime>
+</e2:screen>
Index: ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/deviceinfo.xml
===================================================================
--- ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/deviceinfo.xml	(revision 14969)
+++ ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/deviceinfo.xml	(revision 14969)
@@ -0,0 +1,39 @@
+<e2:screen name="DeviceInfoWebScreen">&lt;?xml version="1.0" encoding="UTF-8"?>
+<e2deviceinfo>
+	<e2enigmaversion><e2:element source="EnigmaVersion"><e2:convert type="web:TextToHTML" /></e2:element></e2enigmaversion>
+	<e2imageversion><e2:element source="ImageVersion"><e2:convert type="web:TextToHTML" /></e2:element></e2imageversion>
+	<e2webifversion><e2:element source="WebIfVersion"><e2:convert type="web:TextToHTML" /></e2:element></e2webifversion>
+	<e2fpversion><e2:element source="FpVersion"><e2:convert type="web:TextToHTML" /></e2:element></e2fpversion>
+	<e2devicename><e2:element source="DeviceName"><e2:convert type="web:TextToHTML" /></e2:element></e2devicename>
+	
+	<e2frontends><e2:element source="Frontends"><e2:convert type="web:ListFiller" >
+		&lt;e2frontend>
+			&lt;e2name><e2:item name="Name" filter="xml"/>&lt;/e2name>
+			&lt;e2model><e2:item name="Type" filter="xml"/>&lt;/e2model>
+		&lt;/e2frontend></e2:convert><e2:convert type="web:TextToHTML" /></e2:element>
+	</e2frontends>
+	
+	<e2network><e2:element source="Network"><e2:convert type="web:ListFiller" >
+		&lt;e2interface>
+			&lt;e2name><e2:item name="Name" filter="xml"/>&lt;/e2name>
+			&lt;e2mac><e2:item name="Mac" filter="xml"/>&lt;/e2mac>
+			&lt;e2dhcp><e2:item name="Dhcp" filter="xml"/>&lt;/e2dhcp>
+			&lt;e2ip><e2:item name="Ip" filter="xml"/>&lt;/e2ip>
+			&lt;e2gateway><e2:item name="Gateway" filter="xml"/>&lt;/e2gateway>
+			&lt;e2netmask><e2:item name="Netmask" filter="xml"/>&lt;/e2netmask>
+		&lt;/e2interface></e2:convert><e2:convert type="web:TextToHTML" /></e2:element>
+	</e2network>
+	
+	<e2hdds><e2:element source="Hdd"><e2:convert type="web:ListFiller">
+		&lt;e2hdd>
+			&lt;e2model><e2:item name="Model" filter="xml"/>&lt;/e2model>
+			&lt;e2capacity><e2:item name="Capacity" filter="xml"/>&lt;/e2capacity>
+			&lt;e2free><e2:item name="Free" filter="xml"/>&lt;/e2free>
+		&lt;/e2hdd></e2:convert><e2:convert type="web:TextToHTML" /></e2:element>
+	</e2hdds>
+
+	<e2recPath><e2:element source="recPath"><e2:convert type="web:TextToHTML" /></e2:element></e2recPath>
+	<e2recCapacity><e2:element source="recCapacity"><e2:convert type="web:TextToHTML" /></e2:element></e2recCapacity>
+	<e2recFree><e2:element source="recFree"><e2:convert type="web:TextToHTML" /></e2:element></e2recFree>
+</e2deviceinfo>
+</e2:screen>
Index: ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/epgbouquet.xml
===================================================================
--- ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/epgbouquet.xml	(revision 14969)
+++ ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/epgbouquet.xml	(revision 14969)
@@ -0,0 +1,15 @@
+<e2:screen name="EpgWebScreen">&lt;?xml version="1.0" encoding="UTF-8"?>
+<e2eventlist><e2:element source="EpgBouquet" id="bRef,time"><e2:convert type="web:ListFiller" >
+	&lt;e2event>
+		&lt;e2eventid><e2:item name="EventID"/>&lt;/e2eventid>
+		&lt;e2eventstart><e2:item name="TimeStart"/>&lt;/e2eventstart>
+		&lt;e2eventduration><e2:item name="Duration"/>&lt;/e2eventduration>
+		&lt;e2eventcurrenttime><e2:item name="CurrentTime"/>&lt;/e2eventcurrenttime>
+		&lt;e2eventtitle><e2:item name="Title" filter="xml"/>&lt;/e2eventtitle>
+		&lt;e2eventdescription><e2:item name="Description" filter="xml"/>&lt;/e2eventdescription>
+		&lt;e2eventdescriptionextended><e2:item name="DescriptionExtended" filter="xml"/>&lt;/e2eventdescriptionextended>
+		&lt;e2eventservicereference><e2:item name="ServiceReference" filter="xml"/>&lt;/e2eventservicereference>
+		&lt;e2eventservicename><e2:item name="ServiceName" filter="xml"/>&lt;/e2eventservicename>
+	&lt;/e2event></e2:convert><e2:convert type="web:TextToHTML" /></e2:element>
+</e2eventlist>
+</e2:screen>
Index: ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/epgnext.xml
===================================================================
--- ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/epgnext.xml	(revision 14969)
+++ ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/epgnext.xml	(revision 14969)
@@ -0,0 +1,17 @@
+<e2:screen name="EpgWebScreen">&lt;?xml version="1.0" encoding="UTF-8"?>
+<e2eventlist>
+	<e2:element source="EpgBouquetNext" id="bRef"><e2:convert type="web:ListFiller" >
+	&lt;e2event>
+		&lt;e2eventid><e2:item name="EventID"/>&lt;/e2eventid>
+		&lt;e2eventstart><e2:item name="TimeStart"/>&lt;/e2eventstart>
+		&lt;e2eventduration><e2:item name="Duration"/>&lt;/e2eventduration>
+		&lt;e2eventcurrenttime><e2:item name="CurrentTime"/>&lt;/e2eventcurrenttime>
+		&lt;e2eventtitle><e2:item name="Title" filter="xml"/>&lt;/e2eventtitle>
+		&lt;e2eventdescription><e2:item name="Description" filter="xml"/>&lt;/e2eventdescription>
+		&lt;e2eventdescriptionextended><e2:item name="DescriptionExtended" filter="xml"/>&lt;/e2eventdescriptionextended>
+		&lt;e2eventservicereference><e2:item name="ServiceReference" filter="xml"/>&lt;/e2eventservicereference>
+		&lt;e2eventservicename><e2:item name="ServiceName" filter="xml"/>&lt;/e2eventservicename>
+	&lt;/e2event>
+	</e2:convert><e2:convert type="web:TextToHTML" /></e2:element>
+</e2eventlist>
+</e2:screen>
Index: ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/epgnow.xml
===================================================================
--- ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/epgnow.xml	(revision 14969)
+++ ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/epgnow.xml	(revision 14969)
@@ -0,0 +1,17 @@
+<e2:screen name="EpgWebScreen">&lt;?xml version="1.0" encoding="UTF-8"?>
+<e2eventlist>
+	<e2:element source="EpgBouquetNow" id="bRef"><e2:convert type="web:ListFiller" >
+	&lt;e2event>
+		&lt;e2eventid><e2:item name="EventID"/>&lt;/e2eventid>
+		&lt;e2eventstart><e2:item name="TimeStart"/>&lt;/e2eventstart>
+		&lt;e2eventduration><e2:item name="Duration"/>&lt;/e2eventduration>
+		&lt;e2eventcurrenttime><e2:item name="CurrentTime"/>&lt;/e2eventcurrenttime>
+		&lt;e2eventtitle><e2:item name="Title" filter="xml"/>&lt;/e2eventtitle>
+		&lt;e2eventdescription><e2:item name="Description" filter="xml"/>&lt;/e2eventdescription>
+		&lt;e2eventdescriptionextended><e2:item name="DescriptionExtended" filter="xml"/>&lt;/e2eventdescriptionextended>
+		&lt;e2eventservicereference><e2:item name="ServiceReference" filter="xml"/>&lt;/e2eventservicereference>
+		&lt;e2eventservicename><e2:item name="ServiceName" filter="xml"/>&lt;/e2eventservicename>
+	&lt;/e2event>
+	</e2:convert><e2:convert type="web:TextToHTML" /></e2:element>
+</e2eventlist>
+</e2:screen>
Index: ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/epgsearch.rss.xml
===================================================================
--- ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/epgsearch.rss.xml	(revision 14969)
+++ ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/epgsearch.rss.xml	(revision 14969)
@@ -0,0 +1,25 @@
+<e2:screen name="EpgWebScreen"><e2:element source="localip" macro="ipadress" />&lt;?xml version="1.0" encoding="UTF-8"?>
+<rss version="2.0">
+	<channel>
+		<title>EPG Search</title>
+		<link>http://<e2:element source="localip" filter="xml" /></link>
+		<description>Automatic search for EPG Content</description>
+		<generator>Enigma2 WebInterface</generator>		
+		<e2:element source="EpgSearch" id="search"><e2:convert type="web:ListFiller" >
+		&lt;item>
+			&lt;title><e2:item name="Title" filter="xml"/>&lt;/title>
+			&lt;description>Service: <e2:item name="ServiceName" filter="xml"/>
+				&lt;br/>Start Time: <e2:item name="TimeStart"/>
+				&lt;br/>Duration: <e2:item name="Duration"/> Seconds
+				&lt;br/><e2:item name="Description" filter="xml"/>
+				&lt;br/><e2:item name="DescriptionExtended" filter="xml"/> 
+				&lt;br/><e2:item name="ServiceReference" filter="xml"/>&lt;/description>
+			&lt;author><e2:item name="ServiceReference" filter="xml"/>&lt;/author>
+			&lt;category><e2:item name="ServiceName" filter="xml"/>&lt;/category>
+		&lt;/item>
+		</e2:convert>
+		<e2:convert type="web:TextToHTML" />
+		</e2:element>
+	</channel>
+</rss>
+</e2:screen>
Index: ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/epgsearch.xml
===================================================================
--- ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/epgsearch.xml	(revision 14969)
+++ ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/epgsearch.xml	(revision 14969)
@@ -0,0 +1,15 @@
+<e2:screen name="EpgWebScreen">&lt;?xml version="1.0" encoding="UTF-8"?>
+<e2eventlist><e2:element source="EpgSearch" id="search"><e2:convert type="web:ListFiller" >
+	&lt;e2event>
+		&lt;e2eventid><e2:item name="EventID"/>&lt;/e2eventid>
+		&lt;e2eventstart><e2:item name="TimeStart"/>&lt;/e2eventstart>
+		&lt;e2eventduration><e2:item name="Duration"/>&lt;/e2eventduration>
+		&lt;e2eventcurrenttime/>
+		&lt;e2eventtitle><e2:item name="Title" filter="xml"/>&lt;/e2eventtitle>
+		&lt;e2eventdescription><e2:item name="Description" filter="xml"/>&lt;/e2eventdescription>
+		&lt;e2eventdescriptionextended><e2:item name="DescriptionExtended" filter="xml"/>&lt;/e2eventdescriptionextended>
+		&lt;e2eventservicereference><e2:item name="ServiceReference" filter="xml"/>&lt;/e2eventservicereference>
+		&lt;e2eventservicename><e2:item name="ServiceName" filter="xml"/>&lt;/e2eventservicename>
+	&lt;/e2event></e2:convert><e2:convert type="web:TextToHTML" /></e2:element>
+</e2eventlist>
+</e2:screen>
Index: ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/epgservice.xml
===================================================================
--- ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/epgservice.xml	(revision 14969)
+++ ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/epgservice.xml	(revision 14969)
@@ -0,0 +1,15 @@
+<e2:screen name="EpgWebScreen">&lt;?xml version="1.0" encoding="UTF-8"?>
+<e2eventlist><e2:element source="EpgService" id="sRef,time,endTime"><e2:convert type="web:ListFiller" >
+	&lt;e2event>
+		&lt;e2eventid><e2:item name="EventID"/>&lt;/e2eventid>
+		&lt;e2eventstart><e2:item name="TimeStart"/>&lt;/e2eventstart>
+		&lt;e2eventduration><e2:item name="Duration"/>&lt;/e2eventduration>
+		&lt;e2eventcurrenttime><e2:item name="CurrentTime"/>&lt;/e2eventcurrenttime>
+		&lt;e2eventtitle><e2:item name="Title" filter="xml"/>&lt;/e2eventtitle>
+		&lt;e2eventdescription><e2:item name="Description" filter="xml"/>&lt;/e2eventdescription>
+		&lt;e2eventdescriptionextended><e2:item name="DescriptionExtended" filter="xml"/>&lt;/e2eventdescriptionextended>
+		&lt;e2eventservicereference><e2:item name="ServiceReference" filter="xml"/>&lt;/e2eventservicereference>
+		&lt;e2eventservicename><e2:item name="ServiceName" filter="xml"/>&lt;/e2eventservicename>
+	&lt;/e2event></e2:convert><e2:convert type="web:TextToHTML" /></e2:element>
+</e2eventlist>
+</e2:screen>
Index: ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/epgservicenext.xml
===================================================================
--- ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/epgservicenext.xml	(revision 14969)
+++ ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/epgservicenext.xml	(revision 14969)
@@ -0,0 +1,18 @@
+<e2:screen name="EpgWebScreen">&lt;?xml version="1.0" encoding="UTF-8"?>
+<e2eventlist><e2:element source="EpgServiceNext" id="sRef">
+	<e2:convert type="web:ListFiller" >
+	&lt;e2event>
+		&lt;e2eventid><e2:item name="EventID"/>&lt;/e2eventid>
+		&lt;e2eventstart><e2:item name="TimeStart"/>&lt;/e2eventstart>
+		&lt;e2eventduration><e2:item name="Duration"/>&lt;/e2eventduration>
+		&lt;e2eventcurrenttime><e2:item name="CurrentTime"/>&lt;/e2eventcurrenttime>
+		&lt;e2eventtitle><e2:item name="Title" filter="xml"/>&lt;/e2eventtitle>
+		&lt;e2eventdescription><e2:item name="Description" filter="xml"/>&lt;/e2eventdescription>
+		&lt;e2eventdescriptionextended><e2:item name="DescriptionExtended" filter="xml"/>&lt;/e2eventdescriptionextended>
+		&lt;e2eventservicereference><e2:item name="ServiceReference" filter="xml"/>&lt;/e2eventservicereference>
+		&lt;e2eventservicename><e2:item name="ServiceName" filter="xml"/>&lt;/e2eventservicename>
+	&lt;/e2event>
+	</e2:convert>
+	<e2:convert type="web:TextToHTML" /></e2:element>
+</e2eventlist>
+</e2:screen>
Index: ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/epgservicenow.xml
===================================================================
--- ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/epgservicenow.xml	(revision 14969)
+++ ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/epgservicenow.xml	(revision 14969)
@@ -0,0 +1,18 @@
+<e2:screen name="EpgWebScreen">&lt;?xml version="1.0" encoding="UTF-8"?>
+<e2eventlist><e2:element source="EpgServiceNow" id="sRef">
+	<e2:convert type="web:ListFiller" >
+	&lt;e2event>
+		&lt;e2eventid><e2:item name="EventID"/>&lt;/e2eventid>
+		&lt;e2eventstart><e2:item name="TimeStart"/>&lt;/e2eventstart>
+		&lt;e2eventduration><e2:item name="Duration"/>&lt;/e2eventduration>
+		&lt;e2eventcurrenttime><e2:item name="CurrentTime"/>&lt;/e2eventcurrenttime>
+		&lt;e2eventtitle><e2:item name="Title" filter="xml"/>&lt;/e2eventtitle>
+		&lt;e2eventdescription><e2:item name="Description" filter="xml"/>&lt;/e2eventdescription>
+		&lt;e2eventdescriptionextended><e2:item name="DescriptionExtended" filter="xml"/>&lt;/e2eventdescriptionextended>
+		&lt;e2eventservicereference><e2:item name="ServiceReference" filter="xml"/>&lt;/e2eventservicereference>
+		&lt;e2eventservicename><e2:item name="ServiceName" filter="xml"/>&lt;/e2eventservicename>
+	&lt;/e2event>
+	</e2:convert>
+	<e2:convert type="web:TextToHTML" /></e2:element>
+</e2eventlist>
+</e2:screen>
Index: ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/epgsimilar.xml
===================================================================
--- ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/epgsimilar.xml	(revision 14969)
+++ ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/epgsimilar.xml	(revision 14969)
@@ -0,0 +1,15 @@
+<e2:screen name="EpgWebScreen">&lt;?xml version="1.0" encoding="UTF-8"?>
+<e2eventlist><e2:element source="EpgSearchSimilar" id="sRef,eventid"><e2:convert type="web:ListFiller" >
+	&lt;e2event>
+		&lt;e2eventid><e2:item name="EventID"/>&lt;/e2eventid>
+		&lt;e2eventstart><e2:item name="TimeStart"/>&lt;/e2eventstart>
+		&lt;e2eventduration><e2:item name="Duration"/>&lt;/e2eventduration>
+		&lt;e2eventcurrenttime><e2:item name="CurrentTime"/>&lt;/e2eventcurrenttime>
+		&lt;e2eventtitle><e2:item name="Title" filter="xml"/>&lt;/e2eventtitle>
+		&lt;e2eventdescription><e2:item name="Description" filter="xml"/>&lt;/e2eventdescription>
+		&lt;e2eventdescriptionextended><e2:item name="DescriptionExtended" filter="xml"/>&lt;/e2eventdescriptionextended>
+		&lt;e2eventservicereference><e2:item name="ServiceReference" filter="xml"/>&lt;/e2eventservicereference>
+		&lt;e2eventservicename><e2:item name="ServiceName" filter="xml"/>&lt;/e2eventservicename>
+	&lt;/e2event></e2:convert><e2:convert type="web:TextToHTML" /></e2:element>
+</e2eventlist>
+</e2:screen>
Index: ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/getallservices.xml
===================================================================
--- ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/getallservices.xml	(revision 14969)
+++ ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/getallservices.xml	(revision 14969)
@@ -0,0 +1,5 @@
+<e2:screen name="ServiceListRecursiveWebScreen">&lt;?xml version="1.0" encoding="UTF-8"?>
+<e2servicelistrecursive>
+<e2:element source="ServiceListRecursive" id="sRef"><e2:convert type="web:TextToHTML" /></e2:element>
+</e2servicelistrecursive>
+</e2:screen>
Index: ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/getaudiotracks.xml
===================================================================
--- ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/getaudiotracks.xml	(revision 14969)
+++ ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/getaudiotracks.xml	(revision 14969)
@@ -0,0 +1,13 @@
+<e2:screen name="AudioWebScreen">&lt;?xml version="1.0" encoding="UTF-8"?>
+<e2audiotracklist><e2:element source="AudioTracks">
+	<e2:convert type="web:ListFiller" >
+		&lt;e2audiotrack>
+			&lt;e2audiotrackdescription><e2:item name="Description" filter="xml"/>&lt;/e2audiotrackdescription>
+			&lt;e2audiotrackid><e2:item name="Id" filter="xml"/>&lt;/e2audiotrackid>
+			&lt;e2audiotrackpid><e2:item name="Pid" filter="xml"/>&lt;/e2audiotrackpid>
+			&lt;e2audiotrackactive><e2:item name="Active" filter="xml"/>&lt;/e2audiotrackactive>
+		&lt;/e2audiotrack>
+	</e2:convert>
+<e2:convert type="web:TextToHTML" /></e2:element>
+</e2audiotracklist>
+</e2:screen>
Index: ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/getcurrent.xml
===================================================================
--- ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/getcurrent.xml	(revision 14969)
+++ ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/getcurrent.xml	(revision 14969)
@@ -0,0 +1,51 @@
+<e2:screen name="UpdateWebScreen">&lt;?xml version="1.0" encoding="UTF-8"?>
+<e2currentserviceinformation>																														
+	<e2service>
+		<e2servicereference><e2:element source="session.CurrentService"><e2:convert type="ServiceName">Reference</e2:convert><e2:convert type="web:TextToXML" /></e2:element></e2servicereference>
+		<e2servicename><e2:element source="session.CurrentService"><e2:convert type="ServiceName">Name</e2:convert><e2:convert type="web:TextToXML" /></e2:element></e2servicename>
+		<e2providername><e2:element source="session.CurrentService"><e2:convert type="ServiceName">Provider</e2:convert><e2:convert type="web:TextToXML" /></e2:element></e2providername>
+		<e2videowidth><e2:element source="session.CurrentService"><e2:convert type="ServiceInfo">VideoWidth</e2:convert><e2:convert type="web:TextToXML" /></e2:element></e2videowidth>
+		<e2videoheight><e2:element source="session.CurrentService"><e2:convert type="ServiceInfo">VideoHeight</e2:convert><e2:convert type="web:TextToXML" /></e2:element></e2videoheight>
+		<e2servicevideosize><e2:element source="session.CurrentService"><e2:convert type="ServiceInfo">VideoWidth</e2:convert><e2:convert type="web:TextToXML" /></e2:element>x<e2:element source="session.CurrentService"><e2:convert type="ServiceInfo">VideoHeight</e2:convert><e2:convert type="web:TextToXML" /></e2:element></e2servicevideosize>
+		<e2iswidescreen><e2:element source="session.CurrentService"><e2:convert type="ServiceInfo">IsWidescreen</e2:convert><e2:convert type="web:TextToXML" /></e2:element></e2iswidescreen>
+		<e2apid><e2:element source="session.CurrentService"><e2:convert type="ServiceInfo">AudioPid</e2:convert><e2:convert type="web:TextToXML" /></e2:element></e2apid>
+		<e2vpid><e2:element source="session.CurrentService"><e2:convert type="ServiceInfo">VideoPid</e2:convert><e2:convert type="web:TextToXML" /></e2:element></e2vpid>
+		<e2pcrpid><e2:element source="session.CurrentService"><e2:convert type="ServiceInfo">PcrPid</e2:convert><e2:convert type="web:TextToXML" /></e2:element></e2pcrpid>
+		<e2pmtpid><e2:element source="session.CurrentService"><e2:convert type="ServiceInfo">PmtPid</e2:convert><e2:convert type="web:TextToXML" /></e2:element></e2pmtpid>
+		<e2txtpid><e2:element source="session.CurrentService"><e2:convert type="ServiceInfo">TxtPid</e2:convert><e2:convert type="web:TextToXML" /></e2:element></e2txtpid>
+		<e2tsid><e2:element source="session.CurrentService"><e2:convert type="ServiceInfo">TsId</e2:convert><e2:convert type="web:TextToXML" /></e2:element></e2tsid>
+		<e2onid><e2:element source="session.CurrentService"><e2:convert type="ServiceInfo">OnId</e2:convert><e2:convert type="web:TextToXML" /></e2:element></e2onid>
+		<e2sid><e2:element source="session.CurrentService"><e2:convert type="ServiceInfo">Sid</e2:convert><e2:convert type="web:TextToXML" /></e2:element></e2sid>		
+	</e2service>
+	<e2eventlist>
+		<e2event>
+			<e2eventservicereference><e2:element source="session.CurrentService"><e2:convert type="ServiceName">Reference</e2:convert><e2:convert type="web:TextToXML" /></e2:element></e2eventservicereference>
+			<e2eventservicename><e2:element source="session.CurrentService"><e2:convert type="ServiceName">Name</e2:convert><e2:convert type="web:TextToXML" /></e2:element></e2eventservicename>
+			<e2eventprovidername><e2:element source="session.CurrentService"><e2:convert type="ServiceName">Provider</e2:convert><e2:convert type="web:TextToXML" /></e2:element></e2eventprovidername>
+			<e2eventid><e2:element source="session.Event_Now"><e2:convert type="EventName">ID</e2:convert><e2:convert type="web:TextToXML" /></e2:element></e2eventid>	
+			<e2eventname><e2:element source="session.Event_Now"><e2:convert type="EventName">Name</e2:convert><e2:convert type="web:TextToXML" /></e2:element></e2eventname>
+			<e2eventtitle><e2:element source="session.Event_Now"><e2:convert type="EventName">Name</e2:convert><e2:convert type="web:TextToXML" /></e2:element></e2eventtitle>
+			<e2eventdescription><e2:element source="session.Event_Now"><e2:convert type="EventName">Description</e2:convert><e2:convert type="web:TextToXML" /></e2:element></e2eventdescription>
+			<e2eventstart><e2:element source="session.Event_Now"><e2:convert type="EventTime">StartTime</e2:convert><e2:convert type="ClockToText">Timestamp</e2:convert><e2:convert type="web:TextToXML" /></e2:element></e2eventstart>
+			<e2eventduration><e2:element source="session.Event_Now"><e2:convert type="EventTime">Duration</e2:convert><e2:convert type="ClockToText">Timestamp</e2:convert><e2:convert type="web:TextToXML" /></e2:element></e2eventduration>
+			<e2eventremaining><e2:element source="session.Event_Now"><e2:convert type="EventTime">Remaining</e2:convert><e2:convert type="RemainingToText">InSeconds</e2:convert><e2:convert type="web:TextToXML" /></e2:element></e2eventremaining>
+			<e2eventcurrenttime><e2:element source="CurrentTime"><e2:convert type="ClockToText">Timestamp</e2:convert><e2:convert type="web:TextToHTML" /></e2:element></e2eventcurrenttime>
+			<e2eventdescriptionextended><e2:element source="session.Event_Now"><e2:convert type="EventName">ExtendedDescription</e2:convert><e2:convert type="web:TextToXML" /></e2:element></e2eventdescriptionextended>			
+		</e2event>
+		<e2event>
+			<e2eventservicereference><e2:element source="session.CurrentService"><e2:convert type="ServiceName">Reference</e2:convert><e2:convert type="web:TextToXML" /></e2:element></e2eventservicereference>
+			<e2eventservicename><e2:element source="session.CurrentService"><e2:convert type="ServiceName">Name</e2:convert><e2:convert type="web:TextToXML" /></e2:element></e2eventservicename>		
+			<e2eventprovidername><e2:element source="session.CurrentService"><e2:convert type="ServiceName">Provider</e2:convert><e2:convert type="web:TextToXML" /></e2:element></e2eventprovidername>
+			<e2eventid><e2:element source="session.Event_Next"><e2:convert type="EventName">ID</e2:convert><e2:convert type="web:TextToXML" /></e2:element></e2eventid>
+			<e2eventname><e2:element source="session.Event_Next"><e2:convert type="EventName">Name</e2:convert><e2:convert type="web:TextToXML" /></e2:element></e2eventname>
+			<e2eventtitle><e2:element source="session.Event_Next"><e2:convert type="EventName">Name</e2:convert><e2:convert type="web:TextToXML" /></e2:element></e2eventtitle>
+			<e2eventdescription><e2:element source="session.Event_Next"><e2:convert type="EventName">Description</e2:convert><e2:convert type="web:TextToXML" /></e2:element></e2eventdescription>
+			<e2eventstart><e2:element source="session.Event_Next"><e2:convert type="EventTime">StartTime</e2:convert><e2:convert type="ClockToText">Timestamp</e2:convert><e2:convert type="web:TextToXML" /></e2:element></e2eventstart>
+			<e2eventduration><e2:element source="session.Event_Next"><e2:convert type="EventTime">Duration</e2:convert><e2:convert type="ClockToText">Timestamp</e2:convert><e2:convert type="web:TextToXML" /></e2:element></e2eventduration>
+			<e2eventremaining><e2:element source="session.Event_Next"><e2:convert type="EventTime">Remaining</e2:convert><e2:convert type="RemainingToText">InSeconds</e2:convert><e2:convert type="web:TextToXML" /></e2:element></e2eventremaining>
+			<e2eventcurrenttime><e2:element source="CurrentTime"><e2:convert type="ClockToText">Timestamp</e2:convert><e2:convert type="web:TextToHTML" /></e2:element></e2eventcurrenttime>
+			<e2eventdescriptionextended><e2:element source="session.Event_Next"><e2:convert type="EventName">ExtendedDescription</e2:convert><e2:convert type="web:TextToXML" /></e2:element></e2eventdescriptionextended>
+		</e2event>
+	</e2eventlist>	
+</e2currentserviceinformation>
+</e2:screen>
Index: ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/getcurrlocation.xml
===================================================================
--- ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/getcurrlocation.xml	(revision 14969)
+++ ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/getcurrlocation.xml	(revision 14969)
@@ -0,0 +1,5 @@
+<e2:screen name="LocationsAndTagsWebScreen">&lt;?xml version="1.0" encoding="UTF-8"?>
+<e2locations>
+	<e2location><e2:element source="CurrentLocation"><e2:convert type="web:TextToHTML" /></e2:element></e2location>
+</e2locations>
+</e2:screen>
Index: ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/getlocations.xml
===================================================================
--- ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/getlocations.xml	(revision 14969)
+++ ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/getlocations.xml	(revision 14969)
@@ -0,0 +1,8 @@
+<e2:screen name="LocationsAndTagsWebScreen">&lt;?xml version="1.0" encoding="UTF-8"?>
+<e2locations>
+<e2:element source="Locations"><e2:convert type="web:SimpleListFiller">
+	&lt;e2location><e2:item name="" filter="xml" />&lt;/e2location>
+	</e2:convert><e2:convert type="web:TextToHTML" />	
+</e2:element>
+</e2locations>
+</e2:screen>
Index: ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/getpid.xml
===================================================================
--- ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/getpid.xml	(revision 14969)
+++ ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/getpid.xml	(revision 14969)
@@ -0,0 +1,3 @@
+<e2:screen name="GetPidWebScreen">
+http://<e2:element source="localip" />:31339/0,<e2:element source="pids"><e2:convert type="web:TextToHTML" /></e2:element>
+</e2:screen>
Index: ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/getservices.xml
===================================================================
--- ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/getservices.xml	(revision 14969)
+++ ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/getservices.xml	(revision 14969)
@@ -0,0 +1,13 @@
+<e2:screen name="ServiceListWebScreen">&lt;?xml version="1.0" encoding="UTF-8"?>
+<e2servicelist>
+<e2:element source="ServiceList" id="sRef">				
+	<e2:convert type="web:ListFiller">
+	&lt;e2service>
+		&lt;e2servicereference><e2:item name="Reference" filter="xml" />&lt;/e2servicereference>
+		&lt;e2servicename><e2:item name="Name" filter="xml" />&lt;/e2servicename>
+	&lt;/e2service>
+	</e2:convert>
+	<e2:convert type="web:TextToHTML" />			
+</e2:element>
+</e2servicelist>	
+</e2:screen>
Index: ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/gettags.xml
===================================================================
--- ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/gettags.xml	(revision 14969)
+++ ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/gettags.xml	(revision 14969)
@@ -0,0 +1,8 @@
+<e2:screen name="LocationsAndTagsWebScreen">&lt;?xml version="1.0" encoding="UTF-8"?>
+<e2tags>
+<e2:element source="Tags"><e2:convert type="web:SimpleListFiller">
+	&lt;e2tag><e2:item name="" filter="xml" />&lt;/e2tag>
+</e2:convert><e2:convert type="web:TextToHTML" />	
+</e2:element>
+</e2tags>
+</e2:screen>
Index: ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/info.txt
===================================================================
--- ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/info.txt	(revision 14969)
+++ ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/info.txt	(revision 14969)
@@ -0,0 +1,2 @@
+Dieses Image (aafteam) ist eine Betaversion und
+wird vom TDT staendig weiter entwickelt!
Index: ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/message.xml
===================================================================
--- ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/message.xml	(revision 14969)
+++ ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/message.xml	(revision 14969)
@@ -0,0 +1,7 @@
+<e2:screen name="MessageWebScreen">&lt;?xml version="1.0" encoding="UTF-8"?>
+<e2:element source="Message" id="text,type,timeout"><e2:convert type="web:Null" /></e2:element>
+<e2simplexmlresult>	
+	<e2state><e2:element source="Message"><e2:convert type="SimpleResult">Result</e2:convert><e2:convert type="web:TextToXML" /></e2:element></e2state>
+	<e2statetext><e2:element source="Message"><e2:convert type="SimpleResult">ResultText</e2:convert><e2:convert type="web:TextToXML" /></e2:element></e2statetext>	
+</e2simplexmlresult>
+</e2:screen>
Index: ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/messageanswer.xml
===================================================================
--- ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/messageanswer.xml	(revision 14969)
+++ ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/messageanswer.xml	(revision 14969)
@@ -0,0 +1,7 @@
+<e2:screen name="MessageWebScreen">&lt;?xml version="1.0" encoding="UTF-8"?>
+<e2:element source="GetAnswer" id="getanswer"><e2:convert type="web:Null" /></e2:element>
+<e2simplexmlresult>
+	<e2state><e2:element source="GetAnswer"><e2:convert type="SimpleResult">Result</e2:convert><e2:convert type="web:TextToXML" /></e2:element></e2state>
+	<e2statetext><e2:element source="GetAnswer"><e2:convert type="SimpleResult">ResultText</e2:convert><e2:convert type="web:TextToXML" /></e2:element></e2statetext>
+</e2simplexmlresult>
+</e2:screen>
Index: ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/moviedelete.xml
===================================================================
--- ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/moviedelete.xml	(revision 14969)
+++ ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/moviedelete.xml	(revision 14969)
@@ -0,0 +1,7 @@
+<e2:screen name="MovieWebScreen">&lt;?xml version="1.0" encoding="UTF-8"?>
+<e2:element source="MovieFileDel" id="sRef"><e2:convert type="web:Null" /></e2:element>
+<e2simplexmlresult>
+	<e2state><e2:element source="MovieFileDel"><e2:convert type="SimpleResult">Result</e2:convert><e2:convert type="web:TextToXML" /></e2:element></e2state>
+	<e2statetext><e2:element source="MovieFileDel"><e2:convert type="SimpleResult">ResultText</e2:convert><e2:convert type="web:TextToXML" /></e2:element></e2statetext>
+</e2simplexmlresult>
+</e2:screen>
Index: ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/movielist.html.xml
===================================================================
--- ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/movielist.html.xml	(revision 14969)
+++ ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/movielist.html.xml	(revision 14969)
@@ -0,0 +1,32 @@
+<e2:screen name="MovieWebScreen">
+<html>
+	<head>
+		<title>Enigma2 Movielist</title>
+		<link href="/webdata/style.css" type="text/css" rel="stylesheet" />	
+	</head>
+<body>
+	<table width="100%">
+		<e2:element source="MovieList" id="dirname,tag"><e2:convert type="web:ListFiller" >
+		&lt;tr>
+			&lt;td class="pageHeader"><e2:item name="Title" filter="xml"/>&lt;/td>
+		&lt;/tr>
+		&lt;tr>
+			&lt;td>
+				&lt;b>Description: &lt;/b><e2:item name="Description" filter="xml"/>
+				&lt;br/>&lt;b>Extended: &lt;/b><e2:item name="DescriptionExtended" filter="xml"/>
+				&lt;br/>&lt;b>Recording Time: &lt;/b><e2:item name="TimeString" filter="xml"/>
+				&lt;br/>&lt;b>Tags: &lt;/b><e2:item name="Tags" filter="xml"/>
+				&lt;br/>&lt;b>Channel: &lt;/b><e2:item name="ServiceName" filter="xml"/>
+				
+			&lt;/td>		
+		&lt;/tr>
+		&lt;tr height='20'>
+			&lt;td> &lt;/td>
+		&lt;/tr>
+				
+		</e2:convert><e2:convert type="web:TextToHTML" /></e2:element>
+	</table>
+
+</body>
+</html>
+</e2:screen>
Index: ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/movielist.m3u.xml
===================================================================
--- ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/movielist.m3u.xml	(revision 14969)
+++ ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/movielist.m3u.xml	(revision 14969)
@@ -0,0 +1,7 @@
+<e2:screen name="MovieWebScreen"><e2:element source="localip" macro="ipadress" />#EXTM3U
+#EXTVLCOPT--http-reconnect=true
+<e2:element source="MovieList" id="dirname,tag">
+<e2:convert type="web:ListFiller" >#EXTINF:-1,<e2:item name="ServiceName"/>: <e2:item name="Title" filter="xml"/>
+http://<e2:item macro="ipadress" filter="xml" /><e2:item name="Filename" filter="urlencode"/>
+</e2:convert><e2:convert type="web:TextToHTML" /></e2:element>
+</e2:screen>
Index: ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/movielist.rss.xml
===================================================================
--- ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/movielist.rss.xml	(revision 14969)
+++ ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/movielist.rss.xml	(revision 14969)
@@ -0,0 +1,26 @@
+<e2:screen name="MovieWebScreen"><e2:element source="localip" macro="ipadress" />&lt;?xml version="1.0" encoding="UTF-8"?>
+<rss version="2.0" >
+	<channel>
+		<title>Enigma2 Movielist</title>
+		<link>http://<e2:element source="localip" filter="xml" /></link>
+		<description>A list of all recordings </description>
+		<generator>Enigma2 WebInterface</generator>
+		<e2:element source="MovieList" id="dirname,tag"><e2:convert type="web:ListFiller" >
+		&lt;item>
+			&lt;title><e2:item name="Title" filter="xml"/>&lt;/title>
+			&lt;description>Service: <e2:item name="ServiceName" filter="xml"/>\n
+				<e2:item name="Description" filter="xml"/>\n
+				<e2:item name="DescriptionExtended" filter="xml"/>\n
+				<e2:item name="Filename"  filter="xml"/>
+				Tags: <e2:item name="Tags" filter="xml"/>
+				ServiceReference: <e2:item name="ServiceReference" filter="xml"/>
+			&lt;/description>
+			&lt;link>http://<e2:item macro="ipadress" filter="xml" /><e2:item name="Filename" filter="urlencode"/>&lt;/link>
+			&lt;enclosure type="video/mpeg" url="http://<e2:item macro="ipadress" filter="xml" /><e2:item name="Filename" filter="urlencode"/>"/>
+			&lt;pubDate><e2:item name="TimeString" filter="xml" />&lt;/pubDate>
+			&lt;category><e2:item name="ServiceName" filter="xml" />&lt;/category>
+			&lt;author>Dreambox Enigma2&lt;/author>
+		&lt;/item></e2:convert><e2:convert type="web:TextToHTML" /></e2:element>
+	</channel>
+</rss>
+</e2:screen>
Index: ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/movielist.xml
===================================================================
--- ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/movielist.xml	(revision 14969)
+++ ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/movielist.xml	(revision 14969)
@@ -0,0 +1,18 @@
+<e2:screen name="MovieWebScreen">&lt;?xml version="1.0" encoding="UTF-8"?>
+<e2movielist><e2:element source="MovieList" id="dirname,tag"><e2:convert type="web:ListFiller" >
+	&lt;e2movie>
+		&lt;e2servicereference><e2:item name="ServiceReference" filter="xml"/>&lt;/e2servicereference>
+		&lt;e2title><e2:item name="Title" filter="xml"/>&lt;/e2title>
+		&lt;e2description><e2:item name="Description" filter="xml"/>&lt;/e2description>
+		&lt;e2descriptionextended><e2:item name="DescriptionExtended" filter="xml"/>&lt;/e2descriptionextended>
+		&lt;e2servicename><e2:item name="ServiceName" filter="xml"/>&lt;/e2servicename>
+		&lt;e2time><e2:item name="Time" filter="xml"/>&lt;/e2time>
+		&lt;e2length><e2:item name="Length" filter="xml"/>&lt;/e2length>
+		&lt;e2tags><e2:item name="Tags" filter="xml"/>&lt;/e2tags>
+		&lt;e2filename><e2:item name="Filename" filter="xml"/>&lt;/e2filename>
+		&lt;e2filesize><e2:item name="Filesize" filter="xml"/>&lt;/e2filesize>
+	&lt;/e2movie>
+	</e2:convert>
+	<e2:convert type="web:TextToHTML" /></e2:element>
+</e2movielist>
+</e2:screen>
Index: ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/movietags.xml
===================================================================
--- ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/movietags.xml	(revision 14969)
+++ ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/movietags.xml	(revision 14969)
@@ -0,0 +1,8 @@
+<e2:screen name="LocationsAndTagsWebScreen">&lt;?xml version="1.0" encoding="UTF-8"?>
+<e2tags>
+<e2:element source="Tags"><e2:convert type="web:SimpleListFiller">
+	&lt;e2tag><e2:item name="" filter="xml" />&lt;/e2tag>
+</e2:convert><e2:convert type="web:TextToHTML" />	
+</e2:element>
+</e2tags>
+</e2:screen>
Index: ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/parentcontrollist.xml
===================================================================
--- ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/parentcontrollist.xml	(revision 14969)
+++ ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/parentcontrollist.xml	(revision 14969)
@@ -0,0 +1,13 @@
+<e2:screen name="ParentControlWebScreen">&lt;?xml version="1.0" encoding="UTF-8"?>
+<e2servicelist>
+<e2:element source="ParentControlList">				
+	<e2:convert type="web:ListFiller">
+	&lt;e2service>
+		&lt;e2servicereference><e2:item name="ServiceReference" filter="xml" />&lt;/e2servicereference>
+		&lt;e2servicename><e2:item name="ServiceName" filter="xml" />&lt;/e2servicename>
+	&lt;/e2service>
+	</e2:convert>
+	<e2:convert type="web:TextToHTML" />			
+</e2:element>
+</e2servicelist>	
+</e2:screen>
Index: ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/pluginlistread.xml
===================================================================
--- ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/pluginlistread.xml	(revision 14969)
+++ ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/pluginlistread.xml	(revision 14969)
@@ -0,0 +1,9 @@
+<e2:screen name="ReadPluginListWebScreen">&lt;?xml version="1.0" encoding="UTF-8"?>
+<e2:element source="ReadPluginList">
+	<e2:convert type="web:Null" />
+</e2:element>
+<e2simplexmlresult>
+	<e2state><e2:element source="ReadPluginList"><e2:convert type="SimpleResult">Result</e2:convert><e2:convert type="web:TextToXML" /></e2:element></e2state>
+	<e2statetext><e2:element source="ReadPluginList"><e2:convert type="SimpleResult">ResultText</e2:convert><e2:convert type="web:TextToXML" /></e2:element></e2statetext>	
+</e2simplexmlresult>		
+</e2:screen>
Index: ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/powerstate.xml
===================================================================
--- ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/powerstate.xml	(revision 14969)
+++ ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/powerstate.xml	(revision 14969)
@@ -0,0 +1,7 @@
+<e2:screen name="PowerWebScreen">&lt;?xml version="1.0" encoding="UTF-8"?>
+<e2powerstate>
+	<e2instandby><e2:element source="PowerState" id="newstate">
+		<e2:convert type="web:TextToXML" /></e2:element>
+	</e2instandby>
+</e2powerstate>
+</e2:screen>
Index: ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/recordnow.xml
===================================================================
--- ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/recordnow.xml	(revision 14969)
+++ ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/recordnow.xml	(revision 14969)
@@ -0,0 +1,5 @@
+<e2:screen name="TimerWebScreen">
+	<e2:element source="RecordNow" id="recordnow">
+		<e2:convert type="web:TextToHTML" />
+	</e2:element>
+</e2:screen>
Index: ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/remotecontrol.xml
===================================================================
--- ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/remotecontrol.xml	(revision 14969)
+++ ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/remotecontrol.xml	(revision 14969)
@@ -0,0 +1,7 @@
+<e2:screen name="RemoteWebScreen">&lt;?xml version="1.0" encoding="UTF-8"?>
+<e2:element source="RemoteControl" id="command,type"><e2:convert type="web:Null" /></e2:element>
+<e2remotecontrol>
+	<e2result><e2:element source="RemoteControl"><e2:convert type="SimpleResult">Result</e2:convert><e2:convert type="web:TextToXML" /></e2:element></e2result>
+	<e2resulttext><e2:element source="RemoteControl"><e2:convert type="SimpleResult">ResultText</e2:convert><e2:convert type="web:TextToXML" /></e2:element></e2resulttext>
+</e2remotecontrol>
+</e2:screen>
Index: ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/removelocation.xml
===================================================================
--- ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/removelocation.xml	(revision 14969)
+++ ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/removelocation.xml	(revision 14969)
@@ -0,0 +1,9 @@
+<e2:screen name="LocationsAndTagsWebScreen">&lt;?xml version="1.0" encoding="UTF-8"?>
+<e2:element source="RemoveLocation" id="dirname">
+	<e2:convert type="web:Null" />
+</e2:element>
+<e2simplexmlresult>
+	<e2state><e2:element source="RemoveLocation"><e2:convert type="SimpleResult">Result</e2:convert><e2:convert type="web:TextToXML" /></e2:element></e2state>
+	<e2statetext><e2:element source="RemoveLocation"><e2:convert type="SimpleResult">ResultText</e2:convert><e2:convert type="web:TextToXML" /></e2:element></e2statetext>	
+</e2simplexmlresult>		
+</e2:screen>
Index: ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/restarttwisted.xml
===================================================================
--- ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/restarttwisted.xml	(revision 14969)
+++ ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/restarttwisted.xml	(revision 14969)
@@ -0,0 +1,5 @@
+<e2:screen name="RestartWebScreen">
+	<e2:element>
+		<e2:convert type="web:ReturnEmptyXML" />
+	</e2:element>
+</e2:screen>
Index: ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/selectaudiotrack.xml
===================================================================
--- ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/selectaudiotrack.xml	(revision 14969)
+++ ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/selectaudiotrack.xml	(revision 14969)
@@ -0,0 +1,3 @@
+<e2:screen name="AudioWebScreen">&lt;?xml version="1.0" encoding="UTF-8"?>
+<e2result><e2:element source="SelectAudioTrack" id="id"><e2:convert type="web:TextToXML" /></e2:element></e2result>
+</e2:screen>
Index: ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/servicelistplayable.xml
===================================================================
--- ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/servicelistplayable.xml	(revision 14969)
+++ ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/servicelistplayable.xml	(revision 14969)
@@ -0,0 +1,13 @@
+<e2:screen name="ServiceListPlayableWebScreen">&lt;?xml version="1.0" encoding="UTF-8"?>
+<e2servicelistplayable>
+<e2:element source="ServiceListPlayable" id="sRef,sRefPlaying">				
+	<e2:convert type="web:ListFiller">
+	&lt;e2serviceplayable>
+		&lt;e2servicereference><e2:item name="ServiceReference" filter="xml" />&lt;/e2servicereference>
+		&lt;e2isplayable><e2:item name="ServicePlayable" filter="xml" />&lt;/e2isplayable>
+	&lt;/e2serviceplayable>
+	</e2:convert>
+	<e2:convert type="web:TextToHTML" />			
+</e2:element>
+</e2servicelistplayable>	
+</e2:screen>
Index: ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/servicelistreload.xml
===================================================================
--- ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/servicelistreload.xml	(revision 14969)
+++ ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/servicelistreload.xml	(revision 14969)
@@ -0,0 +1,7 @@
+<e2:screen name="ServiceListReloadWebScreen">&lt;?xml version="1.0" encoding="UTF-8"?>
+<e2:element source="ServiceListReload" id="mode"><e2:convert type="web:Null" /></e2:element>
+<e2simplexmlresult>
+	<e2state><e2:element source="ServiceListReload"><e2:convert type="SimpleResult">Result</e2:convert><e2:convert type="web:TextToXML" /></e2:element></e2state>
+	<e2statetext><e2:element source="ServiceListReload"><e2:convert type="SimpleResult">ResultText</e2:convert><e2:convert type="web:TextToXML" /></e2:element></e2statetext>	
+</e2simplexmlresult>
+</e2:screen>
Index: ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/serviceplayable.xml
===================================================================
--- ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/serviceplayable.xml	(revision 14969)
+++ ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/serviceplayable.xml	(revision 14969)
@@ -0,0 +1,11 @@
+<e2:screen name="ServicePlayableWebScreen">&lt;?xml version="1.0" encoding="UTF-8"?> 
+<e2:element source="ServicePlayable" id="sRef,sRefPlaying">				
+	<e2:convert type="web:ListFiller">
+&lt;e2serviceplayable>
+	&lt;e2servicereference><e2:item name="ServiceReference" filter="xml" />&lt;/e2servicereference>
+	&lt;e2isplayable><e2:item name="ServicePlayable" filter="xml" />&lt;/e2isplayable>
+&lt;/e2serviceplayable>
+	</e2:convert>
+	<e2:convert type="web:TextToHTML" />			
+</e2:element>
+</e2:screen>
Index: ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/services.m3u.xml
===================================================================
--- ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/services.m3u.xml	(revision 14969)
+++ ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/services.m3u.xml	(revision 14969)
@@ -0,0 +1,7 @@
+<e2:screen name="ServiceListWebScreen"><e2:element source="localip" macro="ipadress" />#EXTM3U
+#EXTVLCOPT--http-reconnect=true
+<e2:element source="ServiceList" id="bRef"><e2:convert type="web:ListFiller">#EXTINF:-1,<e2:item name="Name" filter="xml" />
+http://<e2:item macro="ipadress" filter="xml" />:8001/<e2:item name="Reference" filter="xml" />
+</e2:convert><e2:convert type="web:TextToHTML" />
+</e2:element>
+</e2:screen>
Index: ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/settings.xml
===================================================================
--- ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/settings.xml	(revision 14969)
+++ ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/settings.xml	(revision 14969)
@@ -0,0 +1,13 @@
+<e2:screen name="SettingsWebScreen">&lt;?xml version="1.0" encoding="UTF-8"?>
+<e2settings>
+<e2:element source="Settings">				
+	<e2:convert type="web:ListFiller">
+	&lt;e2setting>
+		&lt;e2settingname><e2:item name="Name" filter="xml" />&lt;/e2settingname>
+		&lt;e2settingvalue><e2:item name="Value" filter="xml" />&lt;/e2settingvalue>		
+	&lt;/e2setting>
+	</e2:convert>
+	<e2:convert type="web:TextToHTML" />			
+</e2:element>
+</e2settings>	
+</e2:screen>
Index: ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/signal.xml
===================================================================
--- ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/signal.xml	(revision 14969)
+++ ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/signal.xml	(revision 14969)
@@ -0,0 +1,28 @@
+<e2:screen name="DummyWebScreen">&lt;?xml version="1.0" encoding="UTF-8"?>
+<e2frontendstatus>	
+	<e2snrdb>
+		<e2:element source="session.FrontendStatus"  id="SNRdB">
+			<e2:convert type="FrontendInfo">SNRdB</e2:convert>
+			<e2:convert type="web:TextToXML" />
+		</e2:element>
+	</e2snrdb>
+	<e2snr>
+		<e2:element source="session.FrontendStatus"  id="SNR">
+			<e2:convert type="FrontendInfo">SNR</e2:convert>
+			<e2:convert type="web:TextToXML" />
+		</e2:element>
+	</e2snr>
+	<e2ber>
+		<e2:element source="session.FrontendStatus"  id="BER">
+			<e2:convert type="FrontendInfo">BER</e2:convert>
+			<e2:convert type="web:TextToXML" />
+		</e2:element>
+	</e2ber>
+	<e2acg>
+		<e2:element source="session.FrontendStatus"  id="AGC">
+			<e2:convert type="FrontendInfo">AGC</e2:convert>
+			<e2:convert type="web:TextToXML" />
+		</e2:element>
+	</e2acg>
+</e2frontendstatus>
+</e2:screen>
Index: ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/stream.m3u.xml
===================================================================
--- ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/stream.m3u.xml	(revision 14969)
+++ ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/stream.m3u.xml	(revision 14969)
@@ -0,0 +1,4 @@
+<e2:screen name="M3uStreamingWebScreen">#EXTM3U
+#EXTVLCOPT--http-reconnect=true
+http://<e2:element source="localip" />:8001/<e2:element source="ref"><e2:convert type="web:TextToHTML" /></e2:element>
+</e2:screen>
Index: ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/stream.xml
===================================================================
--- ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/stream.xml	(revision 14969)
+++ ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/stream.xml	(revision 14969)
@@ -0,0 +1,4 @@
+<e2:screen name="StreamingWebScreen"><e2:element source="StreamService" streaming="yes">
+<e2:convert type="Streaming" />
+<e2:convert type="web:TextToHTML" />
+</e2:element></e2:screen>
Index: ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/streamcurrent.m3u.xml
===================================================================
--- ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/streamcurrent.m3u.xml	(revision 14969)
+++ ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/streamcurrent.m3u.xml	(revision 14969)
@@ -0,0 +1,4 @@
+<e2:screen name="M3uStreamingCurrentServiceWebScreen">#EXTM3U
+#EXTVLCOPT--http-reconnect=true
+http://<e2:element source="localip" />:8001/<e2:element source="CurrentService"><e2:convert type="web:TextToHTML" /></e2:element>
+</e2:screen>
Index: ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/streamsubservices.xml
===================================================================
--- ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/streamsubservices.xml	(revision 14969)
+++ ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/streamsubservices.xml	(revision 14969)
@@ -0,0 +1,10 @@
+<e2:screen name="StreamSubServiceWebScreen">&lt;?xml version="1.0" encoding="UTF-8"?>
+<e2servicelist><e2:element source="StreamSubServices" id="sRef"><e2:convert type="web:ListFiller" >
+	&lt;e2service>
+		&lt;e2servicereference><e2:item name="ServiceReference"  filter="xml"/>&lt;/e2servicereference>
+		&lt;e2servicename><e2:item name="Name"  filter="xml"/>&lt;/e2servicename>
+	&lt;/e2service>
+	</e2:convert>
+	<e2:convert type="web:TextToHTML" /></e2:element>
+</e2servicelist>
+</e2:screen>
Index: ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/subservices.xml
===================================================================
--- ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/subservices.xml	(revision 14969)
+++ ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/subservices.xml	(revision 14969)
@@ -0,0 +1,10 @@
+<e2:screen name="SubServiceWebScreen">&lt;?xml version="1.0" encoding="UTF-8"?>
+<e2servicelist><e2:element source="SubServices" ><e2:convert type="web:ListFiller" >
+	&lt;e2service>
+		&lt;e2servicereference><e2:item name="ServiceReference"  filter="xml"/>&lt;/e2servicereference>
+		&lt;e2servicename><e2:item name="Name"  filter="xml"/>&lt;/e2servicename>
+	&lt;/e2service>
+	</e2:convert>
+	<e2:convert type="web:TextToHTML" /></e2:element>
+</e2servicelist>
+</e2:screen>
Index: ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/timeradd.xml
===================================================================
--- ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/timeradd.xml	(revision 14969)
+++ ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/timeradd.xml	(revision 14969)
@@ -0,0 +1,9 @@
+<e2:screen name="TimerWebScreen">&lt;?xml version="1.0" encoding="UTF-8"?>
+<e2:element source="TimerAdd" id="sRef,repeated,begin,end,name,description,dirname,tags,eit,disabled,justplay,afterevent">	
+	<e2:convert type="web:Null" />
+</e2:element>
+<e2simplexmlresult>
+	<e2state><e2:element source="TimerAdd"><e2:convert type="SimpleResult">Result</e2:convert><e2:convert type="web:TextToXML" /></e2:element></e2state>
+	<e2statetext><e2:element source="TimerAdd"><e2:convert type="SimpleResult">ResultText</e2:convert><e2:convert type="web:TextToXML" /></e2:element></e2statetext>	
+</e2simplexmlresult>
+</e2:screen>
Index: ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/timeraddbyeventid.xml
===================================================================
--- ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/timeraddbyeventid.xml	(revision 14969)
+++ ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/timeraddbyeventid.xml	(revision 14969)
@@ -0,0 +1,9 @@
+<e2:screen name="TimerWebScreen">&lt;?xml version="1.0" encoding="UTF-8"?>
+<e2:element source="TimerAddEventID" id="sRef,eventid,justplay,dirname,tags">
+	<e2:convert type="web:Null" />
+</e2:element>
+<e2simplexmlresult>
+	<e2state><e2:element source="TimerAddEventID"><e2:convert type="SimpleResult">Result</e2:convert><e2:convert type="web:TextToXML" /></e2:element></e2state>
+	<e2statetext><e2:element source="TimerAddEventID"><e2:convert type="SimpleResult">ResultText</e2:convert><e2:convert type="web:TextToXML" /></e2:element></e2statetext>	
+</e2simplexmlresult>
+</e2:screen>
Index: ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/timerchange.xml
===================================================================
--- ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/timerchange.xml	(revision 14969)
+++ ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/timerchange.xml	(revision 14969)
@@ -0,0 +1,9 @@
+<e2:screen name="TimerWebScreen">&lt;?xml version="1.0" encoding="UTF-8"?>
+<e2:element source="TimerChange" id="sRef,begin,end,name,description,dirname,tags,eit,disabled,justplay,afterevent,repeated,channelOld,beginOld,endOld,deleteOldOnSave">
+	<e2:convert type="web:Null" />
+</e2:element>
+<e2simplexmlresult>
+	<e2state><e2:element source="TimerChange"><e2:convert type="SimpleResult">Result</e2:convert><e2:convert type="web:TextToXML" /></e2:element></e2state>
+	<e2statetext><e2:element source="TimerChange"><e2:convert type="SimpleResult">ResultText</e2:convert><e2:convert type="web:TextToXML" /></e2:element></e2statetext>	
+</e2simplexmlresult>	
+</e2:screen>
Index: ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/timercleanup.xml
===================================================================
--- ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/timercleanup.xml	(revision 14969)
+++ ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/timercleanup.xml	(revision 14969)
@@ -0,0 +1,9 @@
+<e2:screen name="TimerWebScreen">&lt;?xml version="1.0" encoding="UTF-8"?>
+<e2:element source="TimerCleanup" id="cleanup">
+	<e2:convert type="web:Null" />
+</e2:element>
+<e2simplexmlresult>
+	<e2state><e2:element source="TimerCleanup"><e2:convert type="SimpleResult">Result</e2:convert><e2:convert type="web:TextToXML" /></e2:element></e2state>
+	<e2statetext><e2:element source="TimerCleanup"><e2:convert type="SimpleResult">ResultText</e2:convert><e2:convert type="web:TextToXML" /></e2:element></e2statetext>	
+</e2simplexmlresult>		
+</e2:screen>
Index: ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/timerdelete.xml
===================================================================
--- ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/timerdelete.xml	(revision 14969)
+++ ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/timerdelete.xml	(revision 14969)
@@ -0,0 +1,9 @@
+<e2:screen name="TimerWebScreen">&lt;?xml version="1.0" encoding="UTF-8"?>
+<e2:element source="TimerDel" id="sRef,begin,end">
+	<e2:convert type="web:Null" />
+</e2:element>
+<e2simplexmlresult>
+	<e2state><e2:element source="TimerDel"><e2:convert type="SimpleResult">Result</e2:convert><e2:convert type="web:TextToXML" /></e2:element></e2state>
+	<e2statetext><e2:element source="TimerDel"><e2:convert type="SimpleResult">ResultText</e2:convert><e2:convert type="web:TextToXML" /></e2:element></e2statetext>	
+</e2simplexmlresult>
+</e2:screen>
Index: ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/timerlist.xml
===================================================================
--- ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/timerlist.xml	(revision 14969)
+++ ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/timerlist.xml	(revision 14969)
@@ -0,0 +1,32 @@
+<e2:screen name="TimerWebScreen">&lt;?xml version="1.0" encoding="UTF-8"?>
+<e2timerlist><e2:element source="TimerList" ><e2:convert type="web:ListFiller" >
+	&lt;e2timer>
+		&lt;e2servicereference><e2:item name="ServiceReference" />&lt;/e2servicereference>
+		&lt;e2servicename><e2:item name="ServiceName" filter="xml"/>&lt;/e2servicename>
+		&lt;e2eit><e2:item name="EIT" />&lt;/e2eit>
+		&lt;e2name><e2:item name="Name" filter="xml"/>&lt;/e2name>
+		&lt;e2description><e2:item name="Description" filter="xml"/>&lt;/e2description>
+		&lt;e2descriptionextended><e2:item name="DescriptionExtended" filter="xml"/>&lt;/e2descriptionextended>
+		&lt;e2disabled><e2:item name="Disabled" />&lt;/e2disabled>
+		&lt;e2timebegin><e2:item name="TimeBegin" />&lt;/e2timebegin>
+		&lt;e2timeend><e2:item name="TimeEnd" />&lt;/e2timeend>
+		&lt;e2duration><e2:item name="Duration" />&lt;/e2duration>
+		&lt;e2startprepare><e2:item name="startPrepare" />&lt;/e2startprepare>
+		&lt;e2justplay><e2:item name="justPlay" />&lt;/e2justplay>
+		&lt;e2afterevent><e2:item name="afterEvent" />&lt;/e2afterevent>
+		&lt;e2location><e2:item name="Location" />&lt;/e2location>
+		&lt;e2tags><e2:item name="Tags" filter="xml"/>&lt;/e2tags>
+		&lt;e2logentries><e2:item name="LogEntries" filter="xml"/>&lt;/e2logentries>
+		&lt;e2filename><e2:item name="Filename" filter="xml"/>&lt;/e2filename>
+		&lt;e2backoff><e2:item name="Backoff" />&lt;/e2backoff>
+		&lt;e2nextactivation><e2:item name="nextActivation" />&lt;/e2nextactivation>
+		&lt;e2firsttryprepare><e2:item name="firstTryPrepare" />&lt;/e2firsttryprepare>
+		&lt;e2state><e2:item name="State" />&lt;/e2state>
+		&lt;e2repeated><e2:item name="Repeated" />&lt;/e2repeated>
+		&lt;e2dontsave><e2:item name="dontSave" />&lt;/e2dontsave>
+		&lt;e2cancled><e2:item name="Cancled" />&lt;/e2cancled>
+		&lt;e2toggledisabled><e2:item name="toggleDisabled" />&lt;/e2toggledisabled>
+		&lt;e2toggledisabledimg><e2:item name="toggleDisabledIMG" />&lt;/e2toggledisabledimg>
+	&lt;/e2timer></e2:convert><e2:convert type="web:TextToHTML" /></e2:element>
+</e2timerlist>
+</e2:screen>
Index: ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/timerlistwrite.xml
===================================================================
--- ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/timerlistwrite.xml	(revision 14969)
+++ ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/timerlistwrite.xml	(revision 14969)
@@ -0,0 +1,9 @@
+<e2:screen name="TimerWebScreen">
+<e2:element source="TimerListWrite" id="write">
+	<e2:convert type="web:Null" />
+</e2:element>
+<e2simplexmlresult>
+	<e2state><e2:element source="TimerListWrite"><e2:convert type="SimpleResult">Result</e2:convert><e2:convert type="web:TextToXML" /></e2:element></e2state>
+	<e2statetext><e2:element source="TimerListWrite"><e2:convert type="SimpleResult">ResultText</e2:convert><e2:convert type="web:TextToXML" /></e2:element></e2statetext>	
+</e2simplexmlresult>	
+</e2:screen>
Index: ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/ts.m3u.xml
===================================================================
--- ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/ts.m3u.xml	(revision 14969)
+++ ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/ts.m3u.xml	(revision 14969)
@@ -0,0 +1,3 @@
+<e2:screen name="TsM3uWebScreen">#EXTM3U
+http://<e2:element source="localip" />:<e2:element source="localport" />/file?file=<e2:element source="file"><e2:convert type="web:TextToURL" /></e2:element>
+</e2:screen>
Index: ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/tvbrowser.xml
===================================================================
--- ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/tvbrowser.xml	(revision 14969)
+++ ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/tvbrowser.xml	(revision 14969)
@@ -0,0 +1,9 @@
+<e2:screen name="TimerWebScreen">&lt;?xml version="1.0" encoding="UTF-8"?>
+	<e2:element source="TVBrowser" id="sRef,name,description,dirname,tags,eit,disabled,justplay,afterevent,command,year,month,day,shour,smin,ehour,emin,repeated,syear,smonth,sday">
+		<e2:convert type="web:Null" />
+	</e2:element>
+<e2simplexmlresult>
+	<e2state><e2:element source="TVBrowser"><e2:convert type="SimpleResult">Result</e2:convert><e2:convert type="web:TextToXML" /></e2:element></e2state>
+	<e2statetext><e2:element source="TVBrowser"><e2:convert type="SimpleResult">ResultText</e2:convert><e2:convert type="web:TextToXML" /></e2:element></e2statetext>	
+</e2simplexmlresult>
+</e2:screen>
Index: ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/updates.html.xml
===================================================================
--- ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/updates.html.xml	(revision 14969)
+++ ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/updates.html.xml	(revision 14969)
@@ -0,0 +1,76 @@
+<e2:screen name="UpdateWebScreen">
+<e2:element source="CurrentTime" streaming="yes">
+	<e2:convert type="ClockToText"></e2:convert>
+	<e2:convert type="web:JavascriptUpdate" />
+</e2:element>
+
+<e2:element source="session.CurrentService" id="CurrentService" streaming="yes">
+<e2:convert type="ServiceName">Name</e2:convert>
+<e2:convert type="web:JavascriptUpdate" />
+</e2:element>
+
+<e2:element source="session.Event_Now" id="Event_Now_Name" streaming="yes">
+	<e2:convert type="EventName">Name</e2:convert>
+	<e2:convert type="web:JavascriptUpdate" />
+</e2:element>
+
+<e2:element source="session.Event_Now" id="Event_Now_Extended_Description" streaming="yes">
+	<e2:convert type="EventName">ExtendedDescription</e2:convert>
+	<e2:convert type="web:JavascriptUpdate" />
+</e2:element>
+
+<e2:element source="session.Event_Now" id="Event_Now_Begin" streaming="yes">
+	<e2:convert type="EventTime">StartTime</e2:convert>
+	<e2:convert type="ClockToText">Default</e2:convert>
+	<e2:convert type="web:JavascriptUpdate" />
+</e2:element>
+
+<e2:element source="session.Event_Now" id="Event_Now_Remaining" streaming="yes">
+	<e2:convert type="EventTime">Remaining</e2:convert>
+	<e2:convert type="RemainingToText">InMinutes</e2:convert>
+	<e2:convert type="web:JavascriptUpdate" />
+</e2:element>
+
+<e2:element source="session.Event_Next" id="Event_Next_Name" streaming="yes">
+	<e2:convert type="EventName">Name</e2:convert>
+	<e2:convert type="web:JavascriptUpdate" />
+</e2:element>
+
+<e2:element source="session.Event_Next" id="Event_Next_Begin" streaming="yes">
+	<e2:convert type="EventTime">StartTime</e2:convert>
+	<e2:convert type="ClockToText">Default</e2:convert>
+	<e2:convert type="web:JavascriptUpdate" />
+</e2:element>
+
+<e2:element source="session.Event_Next" id="Event_Next_Remaining" streaming="yes">
+	<e2:convert type="EventTime">Remaining</e2:convert>
+	<e2:convert type="RemainingToText">InMinutes</e2:convert>
+	<e2:convert type="web:JavascriptUpdate" />
+</e2:element>
+
+<e2:element source="session.Event_Next" id="Event_Next_Extended_Description" streaming="yes">
+	<e2:convert type="EventName">ExtendedDescription</e2:convert>
+	<e2:convert type="web:JavascriptUpdate" />
+</e2:element>
+
+<e2:element source="session.FrontendStatus"  id="SNRdB" streaming="yes">
+	<e2:convert type="FrontendInfo">SNRdB</e2:convert>
+	<e2:convert type="web:JavascriptUpdate" />
+</e2:element>
+
+<e2:element source="session.FrontendStatus"  id="SNR" streaming="yes">
+	<e2:convert type="FrontendInfo">SNR</e2:convert>
+	<e2:convert type="web:JavascriptUpdate" />
+</e2:element>
+
+<e2:element source="session.FrontendStatus"  id="BER" streaming="yes">
+	<e2:convert type="FrontendInfo">BER</e2:convert>
+	<e2:convert type="web:JavascriptUpdate" />
+</e2:element>
+
+<e2:element source="session.FrontendStatus"  id="AGC" streaming="yes">
+	<e2:convert type="FrontendInfo">AGC</e2:convert>
+	<e2:convert type="web:JavascriptUpdate" />
+</e2:element>
+
+</e2:screen>
Index: ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/vol.xml
===================================================================
--- ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/vol.xml	(revision 14969)
+++ ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/vol.xml	(revision 14969)
@@ -0,0 +1,9 @@
+<e2:screen name="VolumeWebScreen">&lt;?xml version="1.0" encoding="UTF-8"?>
+<e2:element source="Volume" id="set"><e2:convert type="web:Null" /></e2:element>
+<e2volume>
+	<e2result><e2:element source="Volume"><e2:convert type="VolumeInfo">Result</e2:convert><e2:convert type="web:TextToXML" /></e2:element></e2result>
+	<e2resulttext><e2:element source="Volume"><e2:convert type="VolumeInfo">ResultText</e2:convert><e2:convert type="web:TextToXML" /></e2:element></e2resulttext>
+	<e2current><e2:element source="Volume"><e2:convert type="VolumeInfo">Volume</e2:convert><e2:convert type="web:TextToXML" /></e2:element></e2current>
+	<e2ismuted><e2:element source="Volume"><e2:convert type="VolumeInfo">IsMuted</e2:convert><e2:convert type="web:TextToXML" /></e2:element></e2ismuted>
+</e2volume>
+</e2:screen>
Index: ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/zap.xml
===================================================================
--- ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/zap.xml	(revision 14969)
+++ ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/web/zap.xml	(revision 14969)
@@ -0,0 +1,11 @@
+<e2:screen name="SwitchServiceWebScreen">&lt;?xml version="1.0" encoding="UTF-8"?>
+<e2:element source="SwitchService" id="sRef,title">
+	<e2:convert type="web:Null" />
+</e2:element>
+
+<e2simplexmlresult>
+	<e2state><e2:element source="SwitchService"><e2:convert type="SimpleResult">Result</e2:convert><e2:convert type="web:TextToXML" /></e2:element></e2state>
+	<e2statetext><e2:element source="SwitchService"><e2:convert type="SimpleResult">ResultText</e2:convert><e2:convert type="web:TextToXML" /></e2:element></e2statetext>	
+</e2simplexmlresult>
+
+</e2:screen>
Index: ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/webif.py
===================================================================
--- ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/webif.py	(revision 14969)
+++ ipk/source.sh4/swapnetwork_webif/var/swap/extensions/WebInterface/webif.py	(revision 14969)
@@ -0,0 +1,566 @@
+# -*- coding: UTF-8 -*-
+Version = '$Header$';
+# things to improve:
+#	- better error handling
+#	- use namespace parser
+
+from Tools.Import import my_import
+
+from Components.Sources.Source import ObsoleteSource
+from Components.Converter.Converter import Converter
+from Components.Element import Element
+
+from xml.sax import make_parser
+from xml.sax.handler import ContentHandler, feature_namespaces
+from xml.sax.saxutils import escape as escape_xml
+from twisted.python import util
+from urllib2 import quote
+
+#DO NOT REMOVE THIS IMPORT
+#It IS used (dynamically)
+from WebScreens import *
+#DO NOT REMOVE THIS IMPORT
+
+
+global screen_cache
+screen_cache = {}
+
+# The classes and Function in File handle all ScreenPage-based requests
+# ScreenPages use enigma2 standard functionality to bring contents to a webfrontend
+#
+# Like Skins a ScreenPage can consist of several Elements and Converters
+
+#===============================================================================
+# OneTimeElement
+#
+# This is the Standard Element for Rendering a "standard" WebElement
+#===============================================================================
+class OneTimeElement(Element):
+	def __init__(self, id):
+		Element.__init__(self)
+		self.source_id = id
+
+	def handleCommand(self, args):
+		if ',' in self.source_id:
+			paramlist = self.source_id.split(",")
+			list = {}
+			for key in paramlist:
+				arg = args.get(key, ())
+				Len = len(arg)
+				if Len == 0:
+					list[key] = None
+				elif Len == 1:
+					list[key] = "".join(arg)
+				elif Len == 2:
+					list[key] = arg[0]
+			self.source.handleCommand(list)
+		else:
+			for c in args.get(self.source_id, ()):
+				self.source.handleCommand(c)
+
+	def render(self, request):
+		t = self.source.getHTML(self.source_id)
+		request.write(t)
+
+	def execBegin(self):
+		self.suspended = False
+
+	def execEnd(self):
+		self.suspended = True
+
+	def onShow(self):
+		pass
+
+	def onHide(self):
+		pass
+
+	def destroy(self):
+		pass
+
+#===============================================================================
+# MacroElement
+#
+# A MacroElement helps using OneTimeElements inside a (Simple)ListFiller Loop
+#===============================================================================
+class MacroElement(OneTimeElement):
+	def __init__(self, id, macro_dict, macro_name):
+		OneTimeElement.__init__(self, id)
+		self.macro_dict = macro_dict
+		self.macro_name = macro_name
+
+	def render(self, request):
+		self.macro_dict[self.macro_name] = self.source.getHTML(self.source_id)
+
+#===============================================================================
+# StreamingElement
+#
+# In difference to an OneTimeElement a StreamingElement sends an ongoing Stream
+# of Data. The end of the Streaming is usually when the client disconnects
+#===============================================================================
+class StreamingElement(OneTimeElement):
+	def __init__(self, id):
+		OneTimeElement.__init__(self, id)
+		self.request = None
+
+	def changed(self, what):
+		if self.request:
+			self.render(self.request)
+
+	def setRequest(self, request):
+		self.request = request
+
+#===============================================================================
+# ListItem
+#
+# a to-be-filled list item
+#===============================================================================
+class ListItem:
+	def __init__(self, name, filternum):
+		self.name = name
+		self.filternum = filternum
+
+#===============================================================================
+# ListMacroItem
+#
+# MacroItem inside a (Simple)ListFiller
+#===============================================================================
+class ListMacroItem:
+	def __init__(self, macrodict, macroname):
+		self.macrodict = macrodict
+		self.macroname = macroname
+
+
+#===============================================================================
+# TextToHTML
+#
+# Returns the String as is
+#===============================================================================
+class TextToHTML(Converter):
+	def __init__(self, arg):
+		Converter.__init__(self, arg)
+
+	def getHTML(self, id):
+		return self.source.text.replace('\xc2\x86', '').replace('\xc2\x87', '').decode("utf-8", "ignore").encode("utf-8") # encode & etc. here!
+
+#===============================================================================
+# TextToXML
+#
+# Escapes the given Text to be XML conform
+#===============================================================================
+class TextToXML(Converter):
+	def __init__(self, arg):
+		Converter.__init__(self, arg)
+
+	def getHTML(self, id):
+		return escape_xml(self.source.text).replace('\xc2\x86', '').replace('\xc2\x87', '').replace("\x19", "").replace("\x1c", "").replace("\x1e", "").decode("utf-8", "ignore").encode("utf-8")
+
+#===============================================================================
+# TextToURL
+#
+# Escapes the given Text so it can be used inside a URL
+#===============================================================================
+class TextToURL(Converter):
+	def __init__(self, arg):
+		Converter.__init__(self, arg)
+
+	def getHTML(self, id):
+		return self.source.text.replace(" ", "%20").replace("+", "%2b").replace("&", "%26").replace('\xc2\x86', '').replace('\xc2\x87', '').decode("utf-8", "ignore").encode("utf-8")
+
+#===============================================================================
+# ReturnEmptyXML
+# 
+# Returns a XML only consisting of <rootElement />
+#===============================================================================
+class ReturnEmptyXML(Converter):
+	def __init__(self, arg):
+		Converter.__init__(self, arg)
+
+	def getHTML(self, id):
+		return "<rootElement />"
+
+#===============================================================================
+# Null
+# Return simply NOTHING
+# Useful if you only want to issue a command.
+#===============================================================================
+class Null(Converter):
+	def __init__(self, arg):
+		Converter.__init__(self, arg)
+
+	def getHTML(self, id):
+		return ""
+
+
+#===============================================================================
+# JavascriptUpdate
+#
+# Transforms a string into a javascript update pattern
+#===============================================================================
+class JavascriptUpdate(Converter):
+	def __init__(self, arg):
+		Converter.__init__(self, arg)
+
+	def getHTML(self, id):
+		# 3c5x9, added parent. , this is because the ie loads this in a iframe. an the set is in index.html.xml
+		#		 all other will replace this in JS
+		return '<script>parent.set("%s", "%s");</script>\n' % (id, self.source.text.replace("\\", "\\\\").replace("\n", "\\n").replace('"', '\\"').replace('\xb0', '&deg;'))
+
+#===============================================================================
+# SimpleListFiller
+#
+# The performant 'one-dimensonial listfiller' engine (podlfe)
+#===============================================================================
+class SimpleListFiller(Converter):
+	def __init__(self, arg):
+		Converter.__init__(self, arg)
+		
+	def getText(self):
+		l = self.source.simplelist
+		conv_args = self.converter_arguments		
+		
+		list = [ ]
+		for element in conv_args:
+			if isinstance(element, basestring):
+				list.append((element, None))
+			elif isinstance(element, ListItem):
+				list.append((element, element.filternum))
+			elif isinstance(element, ListMacroItem):
+				list.append(element.macrodict[element.macroname], None)
+			else:
+				raise Exception("neither string, ListItem nor ListMacroItem")
+			
+		strlist = [ ]
+		append = strlist.append
+		for item in l:
+			if item is None:
+				item = ""
+				
+			for (element, filternum) in list:
+				#filter out "non-displayable" Characters - at the very end, do it the hard way...
+				item = str(item).replace('\xc2\x86', '').replace('\xc2\x87', '').replace("\x19", "").replace("\x1c", "").replace("\x1e", "").decode("utf-8", "ignore").encode("utf-8")
+				
+				if not filternum:
+					append(element)
+				elif filternum == 2:
+					append(item.replace("\\", "\\\\").replace("\n", "\\n").replace('"', '\\"'))
+				elif filternum == 3:					
+					append(escape_xml(item))
+				elif filternum == 4:
+					append(item.replace("%", "%25").replace("+", "%2B").replace('&', '%26').replace('?', '%3f').replace(' ', '+'))
+				elif filternum == 5:
+					append(quote(item))
+				elif filternum == 6:
+					time = parseint(item) or 0
+					t = localtime(time)
+					append("%02d:%02d" % (t.tm_hour, t.tm_min))
+				elif filternum == 7:
+					time = parseint(item) or 0
+					t = localtime(time)
+					append("%d min" % (time / 60))
+				else:
+					append(item)
+		# (this will be done in c++ later!)
+
+		return ''.join(strlist)		
+	
+	text = property(getText)
+			
+#===============================================================================
+# the performant 'listfiller'-engine (plfe)
+#===============================================================================
+class ListFiller(Converter):
+	def __init__(self, arg):
+		Converter.__init__(self, arg)
+#		print "ListFiller-arg: ",arg
+
+	def getText(self):
+		l = self.source.list
+		lut = self.source.lut
+		conv_args = self.converter_arguments
+
+		# now build a ["string", 1, "string", 2]-styled list, with indices into the
+		# list to avoid lookup of item name for each entry
+		lutlist = [ ]
+		for element in conv_args:
+			if isinstance(element, basestring):
+				lutlist.append((element, None))
+			elif isinstance(element, ListItem):
+				lutlist.append((lut[element.name], element.filternum))
+			elif isinstance(element, ListMacroItem):
+				lutlist.append((element.macrodict[element.macroname], None))
+			else:
+				raise Exception("neither string, ListItem nor ListMacroItem")
+
+		# now, for the huge list, do:
+		strlist = [ ]
+		append = strlist.append
+		for item in l:
+			for (element, filternum) in lutlist:			
+				#None becomes ""
+				curitem = ""
+				if filternum:
+					#filter out "non-displayable" Characters - at the very end, do it the hard way...
+					curitem = str(item[element]).replace('\xc2\x86', '').replace('\xc2\x87', '').replace("\x19", "").replace("\x1c", "").replace("\x1e", "").decode("utf-8", "ignore").encode("utf-8")
+					if curitem is None:
+						curitem = ""
+				else:
+					if element is None:
+						element = ""
+						
+				if not filternum:
+					append(element)
+				elif filternum == 2:
+					append(curitem.replace("\\", "\\\\").replace("\n", "\\n").replace('"', '\\"'))
+				elif filternum == 3:
+					append( escape_xml( curitem ))
+				elif filternum == 4:
+					append(curitem.replace("%", "%25").replace("+", "%2B").replace('&', '%26').replace('?', '%3f').replace(' ', '+'))
+				elif filternum == 5:
+					append(quote(curitem))
+				elif filternum == 6:
+					from time import localtime
+					time = int(float(curitem)) or 0
+					t = localtime(time)
+					append("%02d:%02d" % (t.tm_hour, t.tm_min))
+				elif filternum == 7:
+					from time import localtime
+					time = int(float(curitem)) or 0
+					t = localtime(time)
+					append("%d min" % (time / 60))					
+				else:
+					append(curitem)
+		# (this will be done in c++ later!)
+
+		return ''.join(strlist)
+
+	text = property(getText)
+
+#===============================================================================
+# webifHandler
+#
+# Handles the Content of a Web-Request
+# It looks up the source, instantiates the Element and Calls the Converter
+#===============================================================================
+class webifHandler(ContentHandler):
+	def __init__(self, session, request):
+		self.res = [ ]
+		self.mode = 0
+		self.screen = None
+		self.session = session
+		self.screens = [ ]
+		self.request = request
+		self.macros = { }
+
+	def start_element(self, attrs):
+		scr = self.screen
+
+		wsource = attrs["source"]
+
+		path = wsource.split('.')
+		while len(path) > 1:
+			scr = self.screen.getRelatedScreen(path[0])
+			if scr is None:
+				print "[webif.py] Parent Screen not found!"
+				print wsource
+			path = path[1:]
+
+		source = scr.get(path[0])
+
+		if isinstance(source, ObsoleteSource):
+			# however, if we found an "obsolete source", issue warning, and resolve the real source.
+			print "WARNING: WEBIF '%s' USES OBSOLETE SOURCE '%s', USE '%s' INSTEAD!" % (name, wsource, source.new_source)
+			print "OBSOLETE SOURCE WILL BE REMOVED %s, PLEASE UPDATE!" % (source.removal_date)
+			if source.description:
+				print source.description
+
+			wsource = source.new_source
+		else:
+			pass
+			# otherwise, use that source.
+
+		self.source = source
+		self.source_id = str(attrs.get("id", wsource))
+		self.is_streaming = "streaming" in attrs
+		self.macro_name = attrs.get("macro") or None
+
+	def end_element(self):
+		# instatiate either a StreamingElement or a OneTimeElement, depending on what's required.
+		if not self.is_streaming:
+			if self.macro_name is None:
+				c = OneTimeElement(self.source_id)
+			else:
+				c = MacroElement(self.source_id, self.macros, self.macro_name)
+		else:
+			assert self.macro_name is None
+			c = StreamingElement(self.source_id)
+
+		c.connect(self.source)
+		self.res.append(c)
+		self.screen.renderer.append(c)
+		del self.source
+
+	def start_convert(self, attrs):
+		ctype = attrs["type"]
+
+		# TODO: we need something better here
+		if ctype[:4] == "web:": # for now
+			self.converter = eval(ctype[4:])
+		else:
+			try:
+				self.converter = my_import('.'.join(("Components", "Converter", ctype))).__dict__.get(ctype)
+			except ImportError:
+				self.converter = my_import('.'.join(("Plugins", "Extensions", "WebInterface", "WebComponents", "Converter", ctype))).__dict__.get(ctype)
+		self.sub = [ ]
+
+	def end_convert(self):
+		if len(self.sub) == 1:
+			self.sub = self.sub[0]
+		c = self.converter(self.sub)
+		c.connect(self.source)
+		self.source = c
+		del self.sub
+
+	def parse_item(self, attrs):
+		if "name" in attrs:
+			filter = {"": 1, "javascript_escape": 2, "xml": 3, "uri": 4, "urlencode": 5, "time": 6, "minutes": 7}[attrs.get("filter", "")]
+			self.sub.append(ListItem(attrs["name"], filter))
+		else:
+			assert "macro" in attrs, "e2:item must have a name= or macro= attribute!"
+			self.sub.append(ListMacroItem(self.macros, attrs["macro"]))
+
+	def startElement(self, name, attrs):
+		if name == "e2:screen":
+			if "external_module" in attrs:
+				exec "from " + attrs["external_module"] + " import *"
+			self.screen = eval(attrs["name"])(self.session, self.request) # fixme
+			self.screens.append(self.screen)
+			return
+
+		if name[:3] == "e2:":
+			self.mode += 1
+
+		tag = '<' + name + ''.join([' %s="%s"' % x for x in attrs.items()]) + '>'
+		#tag = tag.encode('utf-8')
+
+		if self.mode == 0:
+			self.res.append(tag)
+		elif self.mode == 1: # expect "<e2:element>"
+			assert name == "e2:element", "found %s instead of e2:element" % name
+			self.start_element(attrs)
+		elif self.mode == 2: # expect "<e2:convert>"
+			if name[:3] == "e2:":
+				assert name == "e2:convert"
+				self.start_convert(attrs)
+			else:
+				self.sub.append(tag)
+		elif self.mode == 3:
+			assert name == "e2:item", "found %s instead of e2:item!" % name
+
+			self.parse_item(attrs)
+
+	def endElement(self, name):
+		if name == "e2:screen":
+			self.screen = None
+			return
+
+		tag = "</" + name + ">"
+		if self.mode == 0:
+			self.res.append(tag)
+		elif self.mode == 2 and name[:3] != "e2:":
+			self.sub.append(tag)
+		elif self.mode == 2: # closed 'convert' -> sub
+			self.end_convert()
+		elif self.mode == 1: # closed 'element'
+			self.end_element()
+		if name[:3] == "e2:":
+			self.mode -= 1
+
+	def processingInstruction(self, target, data):
+		self.res.append('<?' + target + ' ' + data + '>')
+
+	def characters(self, ch):
+		ch = ch.encode('utf-8')
+		if self.mode == 0:
+			self.res.append(ch)
+		elif self.mode == 2:
+			self.sub.append(ch)
+
+	def startEntity(self, name):
+		self.res.append('&' + name + ';');
+
+	def execBegin(self):
+		for screen in self.screens:
+			screen.execBegin()
+
+	def cleanup(self):
+		print "screen cleanup!"
+		for screen in self.screens:
+			screen.execEnd()
+			screen.doClose()
+		self.screens = [ ]
+
+#===============================================================================
+# renderPage
+#
+# Creates the Handler for a Request and calls it
+# Also ensures that the Handler is finished after the Request is done
+#===============================================================================
+def renderPage(request, path, session):
+	# read in the template, create required screens
+	# we don't have persistense yet.
+	# if we had, this first part would only be done once.
+	handler = webifHandler(session, request)
+	parser = make_parser()
+	parser.setFeature(feature_namespaces, 0)
+	parser.setContentHandler(handler)
+	parser.parse(open(util.sibpath(__file__, path)))
+
+	# by default, we have non-streaming pages
+	finish = True
+
+	# first, apply "commands" (aka. URL argument)
+	for x in handler.res:
+		if isinstance(x, Element):
+			x.handleCommand(request.args)
+
+	handler.execBegin()
+
+	# now, we have a list with static texts mixed
+	# with non-static Elements.
+	# flatten this list, write into the request.
+	for x in handler.res:
+		if isinstance(x, Element):
+			if isinstance(x, StreamingElement):
+				finish = False
+				x.setRequest(request)
+			x.render(request)
+		else:
+			request.write(str(x))
+
+	# if we met a "StreamingElement", there is at least one
+	# element which wants to output data more than once,
+	# i.e. on host-originated changes.
+	# in this case, don't finish yet, don't cleanup yet,
+	# but instead do that when the client disconnects.
+	if finish:
+		requestFinish(handler, request)
+	
+	else:	
+		def requestFinishDeferred(nothing, handler, request):
+			from twisted.internet import reactor
+			reactor.callLater(0, requestFinish, handler, request)				
+		
+		d = request.notifyFinish()
+
+		d.addBoth( requestFinishDeferred, handler, request )
+							
+#===============================================================================
+# requestFinish
+#
+# This has to be/is called at the end of every ScreenPage-based Request
+#===============================================================================
+def requestFinish(handler, request):
+	handler.cleanup()
+	request.finish()	
+	
+	del handler
