Merge new Webinterface to HEAD
authorStephan Reichholf <sreichholf@users.schwerkraft.elitedvb.net>
Tue, 30 Dec 2008 15:13:32 +0000 (15:13 +0000)
committerStephan Reichholf <sreichholf@users.schwerkraft.elitedvb.net>
Tue, 30 Dec 2008 15:13:32 +0000 (15:13 +0000)
133 files changed:
webinterface/TODO [new file with mode: 0644]
webinterface/src/WebChilds/Screengrab.py
webinterface/src/WebComponents/Sources/About.py
webinterface/src/WebComponents/Sources/MP.py
webinterface/src/WebComponents/Sources/PowerState.py
webinterface/src/WebComponents/Sources/RequestData.py
webinterface/src/WebComponents/Sources/Timer.py
webinterface/src/__init__.py
webinterface/src/web-data/Makefile.am
webinterface/src/web-data/config.js
webinterface/src/web-data/gfx/ajaxload.gif [new file with mode: 0644]
webinterface/src/web-data/gfx/arrow_down.png [deleted file]
webinterface/src/web-data/gfx/arrow_up.png [deleted file]
webinterface/src/web-data/gfx/favicon.ico
webinterface/src/web-data/gfx/led_off.png [deleted file]
webinterface/src/web-data/gfx/led_on.png [deleted file]
webinterface/src/web-data/gfx/progress.gif
webinterface/src/web-data/gfx/signal.png [deleted file]
webinterface/src/web-data/gfx/speak_off.png [deleted file]
webinterface/src/web-data/gfx/speak_on.png [deleted file]
webinterface/src/web-data/img/Makefile.am [new file with mode: 0644]
webinterface/src/web-data/img/arrow_down.png [new file with mode: 0644]
webinterface/src/web-data/img/arrow_up.png [new file with mode: 0644]
webinterface/src/web-data/img/delete.png [new file with mode: 0644]
webinterface/src/web-data/img/dreamboxweb.png [new file with mode: 0644]
webinterface/src/web-data/img/edit.png [new file with mode: 0644]
webinterface/src/web-data/img/led_off.png [new file with mode: 0644]
webinterface/src/web-data/img/led_on.png [new file with mode: 0644]
webinterface/src/web-data/img/nok.png [new file with mode: 0644]
webinterface/src/web-data/img/off.png [new file with mode: 0644]
webinterface/src/web-data/img/ok.png [new file with mode: 0644]
webinterface/src/web-data/img/on.png [new file with mode: 0644]
webinterface/src/web-data/img/signal.png [new file with mode: 0644]
webinterface/src/web-data/img/speak_off.png [new file with mode: 0644]
webinterface/src/web-data/img/speak_on.png [new file with mode: 0644]
webinterface/src/web-data/img/stream.png [new file with mode: 0644]
webinterface/src/web-data/index.html
webinterface/src/web-data/lib/Makefile.am
webinterface/src/web-data/lib/prototype-1.6.0.3.js [new file with mode: 0644]
webinterface/src/web-data/lib/ptwindow/Makefile.am [deleted file]
webinterface/src/web-data/lib/ptwindow/javascripts/Makefile.am [deleted file]
webinterface/src/web-data/lib/ptwindow/javascripts/debug.js [deleted file]
webinterface/src/web-data/lib/ptwindow/javascripts/effects.js [deleted file]
webinterface/src/web-data/lib/ptwindow/javascripts/extended_debug.js [deleted file]
webinterface/src/web-data/lib/ptwindow/javascripts/prototype.js [deleted file]
webinterface/src/web-data/lib/ptwindow/javascripts/tooltip.js [deleted file]
webinterface/src/web-data/lib/ptwindow/javascripts/window.js [deleted file]
webinterface/src/web-data/lib/ptwindow/javascripts/window_effects.js [deleted file]
webinterface/src/web-data/lib/ptwindow/javascripts/window_ext.js [deleted file]
webinterface/src/web-data/lib/ptwindow/themes/Makefile.am [deleted file]
webinterface/src/web-data/lib/ptwindow/themes/alert.css [deleted file]
webinterface/src/web-data/lib/ptwindow/themes/alert/Makefile.am [deleted file]
webinterface/src/web-data/lib/ptwindow/themes/alert/bottom.gif [deleted file]
webinterface/src/web-data/lib/ptwindow/themes/alert/bottom_left.gif [deleted file]
webinterface/src/web-data/lib/ptwindow/themes/alert/bottom_right.gif [deleted file]
webinterface/src/web-data/lib/ptwindow/themes/alert/left.gif [deleted file]
webinterface/src/web-data/lib/ptwindow/themes/alert/overlay.png [deleted file]
webinterface/src/web-data/lib/ptwindow/themes/alert/progress.gif [deleted file]
webinterface/src/web-data/lib/ptwindow/themes/alert/right.gif [deleted file]
webinterface/src/web-data/lib/ptwindow/themes/alert/top.gif [deleted file]
webinterface/src/web-data/lib/ptwindow/themes/alert/top_left.gif [deleted file]
webinterface/src/web-data/lib/ptwindow/themes/alert/top_right.gif [deleted file]
webinterface/src/web-data/lib/ptwindow/themes/alert_lite.css [deleted file]
webinterface/src/web-data/lib/ptwindow/themes/alphacube.css [deleted file]
webinterface/src/web-data/lib/ptwindow/themes/alphacube/Makefile.am [deleted file]
webinterface/src/web-data/lib/ptwindow/themes/alphacube/bottom-left-c.gif [deleted file]
webinterface/src/web-data/lib/ptwindow/themes/alphacube/bottom-middle.gif [deleted file]
webinterface/src/web-data/lib/ptwindow/themes/alphacube/bottom-right-c.gif [deleted file]
webinterface/src/web-data/lib/ptwindow/themes/alphacube/button-close-focus.gif [deleted file]
webinterface/src/web-data/lib/ptwindow/themes/alphacube/button-max-focus.gif [deleted file]
webinterface/src/web-data/lib/ptwindow/themes/alphacube/button-min-focus.gif [deleted file]
webinterface/src/web-data/lib/ptwindow/themes/alphacube/frame-left.gif [deleted file]
webinterface/src/web-data/lib/ptwindow/themes/alphacube/frame-right.gif [deleted file]
webinterface/src/web-data/lib/ptwindow/themes/alphacube/left-top.gif [deleted file]
webinterface/src/web-data/lib/ptwindow/themes/alphacube/right-top.gif [deleted file]
webinterface/src/web-data/lib/ptwindow/themes/alphacube/top-middle.gif [deleted file]
webinterface/src/web-data/lib/ptwindow/themes/behavior.htc [deleted file]
webinterface/src/web-data/lib/ptwindow/themes/debug.css [deleted file]
webinterface/src/web-data/lib/ptwindow/themes/default.css [deleted file]
webinterface/src/web-data/lib/ptwindow/themes/default/Makefile.am [deleted file]
webinterface/src/web-data/lib/ptwindow/themes/default/bottom_left.gif [deleted file]
webinterface/src/web-data/lib/ptwindow/themes/default/bottom_mid.gif [deleted file]
webinterface/src/web-data/lib/ptwindow/themes/default/bottom_right.gif [deleted file]
webinterface/src/web-data/lib/ptwindow/themes/default/bottom_right_resize.gif [deleted file]
webinterface/src/web-data/lib/ptwindow/themes/default/center_left.gif [deleted file]
webinterface/src/web-data/lib/ptwindow/themes/default/center_right.gif [deleted file]
webinterface/src/web-data/lib/ptwindow/themes/default/clear.gif [deleted file]
webinterface/src/web-data/lib/ptwindow/themes/default/close.gif [deleted file]
webinterface/src/web-data/lib/ptwindow/themes/default/inspect.gif [deleted file]
webinterface/src/web-data/lib/ptwindow/themes/default/maximize.gif [deleted file]
webinterface/src/web-data/lib/ptwindow/themes/default/minimize.gif [deleted file]
webinterface/src/web-data/lib/ptwindow/themes/default/overlay.png [deleted file]
webinterface/src/web-data/lib/ptwindow/themes/default/resize.gif [deleted file]
webinterface/src/web-data/lib/ptwindow/themes/default/sizer.gif [deleted file]
webinterface/src/web-data/lib/ptwindow/themes/default/top_left.gif [deleted file]
webinterface/src/web-data/lib/ptwindow/themes/default/top_mid.gif [deleted file]
webinterface/src/web-data/lib/ptwindow/themes/default/top_right.gif [deleted file]
webinterface/src/web-data/lib/ptwindow/themes/iefix/Makefile.am [deleted file]
webinterface/src/web-data/lib/ptwindow/themes/iefix/blank.gif [deleted file]
webinterface/src/web-data/lib/ptwindow/themes/iefix/iepngfix.css [deleted file]
webinterface/src/web-data/lib/ptwindow/themes/iefix/iepngfix.htc [deleted file]
webinterface/src/web-data/lib/rico.js [deleted file]
webinterface/src/web-data/lib/shadedborder.js [new file with mode: 0644]
webinterface/src/web-data/lib/trimpath-template-1.0.38.js [new file with mode: 0644]
webinterface/src/web-data/objects.js
webinterface/src/web-data/style.css
webinterface/src/web-data/templates.js
webinterface/src/web-data/timer.js
webinterface/src/web-data/tools.js
webinterface/src/web-data/tpl/tplAbout.htm [new file with mode: 0644]
webinterface/src/web-data/tpl/tplBouquetList.htm [new file with mode: 0644]
webinterface/src/web-data/tpl/tplDebug.htm [new file with mode: 0644]
webinterface/src/web-data/tpl/tplEpgList.htm [new file with mode: 0644]
webinterface/src/web-data/tpl/tplGrab.htm [new file with mode: 0644]
webinterface/src/web-data/tpl/tplMediaPlayer.htm [new file with mode: 0644]
webinterface/src/web-data/tpl/tplMovieList.htm [new file with mode: 0644]
webinterface/src/web-data/tpl/tplNavExtras.htm [new file with mode: 0644]
webinterface/src/web-data/tpl/tplNavRadio.htm [new file with mode: 0644]
webinterface/src/web-data/tpl/tplNavTimer.htm [new file with mode: 0644]
webinterface/src/web-data/tpl/tplNavTv.htm [new file with mode: 0644]
webinterface/src/web-data/tpl/tplPower.htm [new file with mode: 0644]
webinterface/src/web-data/tpl/tplSendMessage.htm [new file with mode: 0644]
webinterface/src/web-data/tpl/tplServiceList.htm [new file with mode: 0644]
webinterface/src/web-data/tpl/tplServiceListEPGItem.htm [new file with mode: 0644]
webinterface/src/web-data/tpl/tplSignalPanel.htm [new file with mode: 0644]
webinterface/src/web-data/tpl/tplSubServices.htm [new file with mode: 0644]
webinterface/src/web-data/tpl/tplTimerEdit.htm [new file with mode: 0644]
webinterface/src/web-data/tpl/tplTimerList.htm [new file with mode: 0644]
webinterface/src/web-data/tpl/tplWebRemote.htm [new file with mode: 0644]
webinterface/src/web/about.xml
webinterface/src/web/powerstate.xml
webinterface/src/web/signal.xml [new file with mode: 0644]
webinterface/src/webif.py

diff --git a/webinterface/TODO b/webinterface/TODO
new file mode 100644 (file)
index 0000000..6377b4b
--- /dev/null
@@ -0,0 +1,6 @@
+* Finish "Current Service" Stuff
+* Decide whether the MediaPlayer Menu should stay and if how.
+* Add Support for Multiple NICs in About
+* add box dependent remote control picture (for dm8000)
+* rename "extra" to "boxcontrol"
+* add new button "info" and move "about" from "extra" to "info"
\ No newline at end of file
index 3523489..a0ebe2d 100755 (executable)
@@ -90,7 +90,7 @@ class GrabStream(stream.ProducerStream):
         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,cmd,target=None,save=False):
+    def __init__(self, cmd, target=None, save=False):
         self.cmd = cmd
         self.target = target
         self.save = save
@@ -103,7 +103,7 @@ class GrabStream(stream.ProducerStream):
         print "AiO grab starting aio grab with cmdline:",self.cmd
         self.container.execute(cmd)
 
-    def cmdFinished(self,data):
+    def cmdFinished(self, data):
         if int(data) is 0 and self.target is not None:
             try:
                 fp = open(self.target)
@@ -121,5 +121,5 @@ class GrabStream(stream.ProducerStream):
             self.write("internal error")
         self.finish()
 
-    def dataAvail(self,data):
+    def dataAvail(self, data):
         print "AiO grab:",data
index d32bed9..6b76e97 100644 (file)
@@ -35,6 +35,7 @@ class About( Source):
             return retstr
 
         iface = "eth0"
+        list.append(iNetwork.getAdapterAttribute(iface, "mac"))
         list.append(iNetwork.getAdapterAttribute(iface, "dhcp"))
         list.append(ConvertIP(iNetwork.getAdapterAttribute(iface, "ip")))
         list.append(ConvertIP(iNetwork.getAdapterAttribute(iface, "netmask")))
@@ -153,26 +154,27 @@ class About( Source):
     
     list = property(command)
     lut = {"enigmaVersion": 0
-           ,"lanDHCP": 1
-           ,"lanIP": 2
-           ,"lanMask": 3
-           ,"lanGW": 4
-           ,"fpVersion": 5
-           ,"tunerInfo": 6
-           ,"hddInfo": 7
-           ,"serviceName": 8
-           ,"serviceProvider": 9
-           ,"serviceAspect": 10
-           ,"serviceVideosize": 11
-           ,"serviceNamespace": 12
-           ,"vPID": 13
-           ,"aPID": 14
-           ,"pcrID": 15
-           ,"pmtPID": 16
-           ,"txtPID": 17
-           ,"tsID": 18
-           ,"onID": 19
-           ,"sid": 20
-           ,"WebIfVersion": 21
-           ,"model": 22
+           ,"lanMac": 1
+           ,"lanDHCP": 2
+           ,"lanIP": 3
+           ,"lanMask": 4
+           ,"lanGW": 5
+           ,"fpVersion": 6
+           ,"tunerInfo": 7
+           ,"hddInfo": 8
+           ,"serviceName": 9
+           ,"serviceProvider": 10
+           ,"serviceAspect": 11
+           ,"serviceVideosize": 12
+           ,"serviceNamespace": 13
+           ,"vPID": 14
+           ,"aPID": 15
+           ,"pcrID": 16
+           ,"pmtPID": 17
+           ,"txtPID": 18
+           ,"tsID": 19
+           ,"onID": 20
+           ,"sid": 21
+           ,"WebIfVersion": 22
+           ,"model": 23
            }
\ No newline at end of file
index ae3ba74..7d0a27d 100644 (file)
@@ -148,7 +148,6 @@ class MP( Source):
         
     def command(self,param):
         print "command: ",param
-        param = int(param)
         
         # TODO: fix error handling
         if not self.tryOpenMP():
@@ -156,17 +155,17 @@ class MP( Source):
         
         mp = self.session.mediaplayer
         
-        if param == 0:
+        if param == "previous":
             mp.previousEntry()
-        elif param == 1:
+        elif param == "play":
             mp.playEntry()
-        elif param == 2:
+        elif param == "pause":
             mp.pauseEntry()
-        elif param == 3:
+        elif param == "next":
             mp.nextEntry()
-        elif param == 4:
+        elif param == "stop":
             mp.stopEntry()
-        elif param == 5:
+        elif param == "exit":
             mp.exit()
         
         return
index 5aabc65..8eca11b 100644 (file)
@@ -9,26 +9,47 @@ class PowerState(Source):
 
     def handleCommand(self, cmd):
         self.cmd = cmd
-        print "PowerState:",self.cmd
+    
+    def do_func(self):
+        print "PowerState:", self.cmd
         if self.cmd == "" or self.cmd is None:
             print "the PowerState was not defined (%s)" % self.cmd
             return [[False,"the PowerState was not defined"]]
         
+        #-1: get current state
+        # 0: toggle standby
         # 1: poweroff/deepstandby
         # 2: rebootdreambox
         # 3: rebootenigma
-        # 4: standby
+        try:
+            type = int(self.cmd)
+            if type == -1:
+                from Screens.Standby import inStandby
+                if inStandby == None:
+                    return "false"
+                else:
+                    return "true"
+                
+            elif type == 0:
+                print "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 "TryQuitMainloop if"
+                from Screens.Standby import TryQuitMainloop
+                self.session.open(TryQuitMainloop, type)
+                return "true"
+            else:
+                print "PowerState was not defined correctly (%s)" % type
+                return "error"
+        except ValueError:
+            return "error"
         
-        type = int(self.cmd)
-        if type == 0:
-            print "Standby if"
-            from Screens.Standby import Standby
-            self.session.open(Standby)
-        elif type < 4:
-            print "TryQuitMainloop if"
-            from Screens.Standby import TryQuitMainloop
-            self.session.open(TryQuitMainloop, type)
-        else:
-            print "PowerState was not defined correctly (%s)" % type
-
-        #quitMainloop(type)
\ No newline at end of file
+    text = property(do_func)
\ No newline at end of file
index 7eb660c..81ae67f 100644 (file)
@@ -13,7 +13,7 @@ class RequestData(Source):
        REMOTETYPE = 6
        URI = 7
        
-       def __init__(self,request, what = None):
+       def __init__(self, request, what = None):
                Source.__init__(self)
                self.request = request
                self.what = what
index ea142ce..babab55 100644 (file)
@@ -283,11 +283,10 @@ class Timer( Source):
         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)
+        (begin, end, name, description, eit) = parseEvent(event)
         
-        print "addTimerByEventID newtimer ",param['sRef'], (begin - (int(config.recording.margin_before.value)*60)), (end + (int(config.recording.margin_after.value)*60)), name, description, eit, False, justplay
-        newtimer = RecordTimerEntry(ServiceReference(param['sRef']), (begin - (int(config.recording.margin_before.value)*60)), (end + (int(config.recording.margin_after.value)*60)), name, description, eit, False, justplay, AFTEREVENT.NONE)
-                        #RecordTimerEntry(serviceref, begin, end, name, description, eit, disabled, justplay, afterevent)
+        print "addTimerByEventID newtimer ", param['sRef'], begin, end, name, description, eit, False, justplay
+        newtimer = RecordTimerEntry(ServiceReference(param['sRef']), begin , end, name, description, eit, False, justplay, AFTEREVENT.NONE)                        
                 
         self.recordtimer.record(newtimer)
         return True,"Timer added"    
index 13fd72d..ee2b979 100644 (file)
@@ -10,7 +10,7 @@ from Components.config import configfile
 from Components.config import ConfigYesNo
 from Components.Network import iNetwork
 
-__version__ = "0.99"
+__version__ = "1.5beta"
 
 config.plugins.Webinterface = ConfigSubsection()
 config.plugins.Webinterface.enable = ConfigYesNo(default = True)
index 1608fe3..61731b0 100644 (file)
@@ -2,4 +2,4 @@ installdir = /usr/lib/enigma2/python/Plugins/Extensions/WebInterface/web-data/
 
 install_DATA = *.js *.css *.html IEFixes.htc
 
-SUBDIRS = lib gfx
+SUBDIRS = lib gfx img tpl
index 0cf6710..7330a2a 100644 (file)
@@ -3,6 +3,8 @@
 var DBG = true;
 DBG = false;
 
+var url_getcurrent = '/web/getcurrent';
+
 var url_getvolume = '/web/vol?set=state'; 
 var url_setvolume = '/web/vol?set=set'; // plus new value eg: set=set15
 var url_volumeup = '/web/vol?set=up';
@@ -11,7 +13,8 @@ var url_volumemute = '/web/vol?set=mute';
 
 var url_epgservice = "/web/epgservice?sRef="; // plus serviceRef
 var url_epgsearch = "/web/epgsearch?search="; // plus serviceRef
-var url_epgnow = "/web/epgnow?bRef="; // plus bouqetRev
+var url_epgnow = "/web/epgnow?bRef="; // plus bouquetRev
+var url_epgnext = "/web/epgnext?bRef="; // plus bouquetRev
 
 var url_getServices = "/web/getservices?sRef="; // plus serviceref
 var url_subservices = "/web/subservices"; // subservices for current service
@@ -48,20 +51,16 @@ var url_messageanswer = "/web/messageanswer?getanswer=now";
 
 var url_powerstate = "/web/powerstate"; // plus new powerstate
 var url_remotecontrol = "/web/remotecontrol"; // plus command
+var url_signal = "/web/signal";
 
 var url_notelist = "/notes";
 var url_note = "/notes?show="; //plus filename
 
-var bouqet_tv = '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 bouqet_radio = '1:7:2:0:0:0:0:0:0:0:(type == 2)FROM BOUQUET "bouquets.radio" ORDER BY bouquet';
-var bouqet_provider_tv = '1:7:1:0:0:0:0:0:0:0:(type == 1) || (type == 17) || (type == 195) || (type == 25) FROM PROVIDERS ORDER BY name';
-var bouqet_provider_radio ='1:7:2:0:0:0:0:0:0:0:(type == 2) FROM PROVIDERS ORDER BY name';
+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 windowStyle = 'alphacube';
 
-var url_delfile = "/web/delfile?file="; // plus file
-
-var url_autotimerlist = "/web/autotimerlist?gl";
-var url_autotimerdelete = "/web/autotimerdelete"; 
-var url_autotimertoggledisable = "/web/autotimertoggledisable"; 
\ No newline at end of file
+var url_delfile = "/web/delfile?file="; // plus file
\ No newline at end of file
diff --git a/webinterface/src/web-data/gfx/ajaxload.gif b/webinterface/src/web-data/gfx/ajaxload.gif
new file mode 100644 (file)
index 0000000..7eca290
Binary files /dev/null and b/webinterface/src/web-data/gfx/ajaxload.gif differ
diff --git a/webinterface/src/web-data/gfx/arrow_down.png b/webinterface/src/web-data/gfx/arrow_down.png
deleted file mode 100644 (file)
index 146f72d..0000000
Binary files a/webinterface/src/web-data/gfx/arrow_down.png and /dev/null differ
diff --git a/webinterface/src/web-data/gfx/arrow_up.png b/webinterface/src/web-data/gfx/arrow_up.png
deleted file mode 100644 (file)
index c7b4069..0000000
Binary files a/webinterface/src/web-data/gfx/arrow_up.png and /dev/null differ
index d048f55..d096353 100644 (file)
Binary files a/webinterface/src/web-data/gfx/favicon.ico and b/webinterface/src/web-data/gfx/favicon.ico differ
diff --git a/webinterface/src/web-data/gfx/led_off.png b/webinterface/src/web-data/gfx/led_off.png
deleted file mode 100644 (file)
index 69ca2cd..0000000
Binary files a/webinterface/src/web-data/gfx/led_off.png and /dev/null differ
diff --git a/webinterface/src/web-data/gfx/led_on.png b/webinterface/src/web-data/gfx/led_on.png
deleted file mode 100644 (file)
index 3d3d29d..0000000
Binary files a/webinterface/src/web-data/gfx/led_on.png and /dev/null differ
index 6b1dcc4..573a53b 100644 (file)
Binary files a/webinterface/src/web-data/gfx/progress.gif and b/webinterface/src/web-data/gfx/progress.gif differ
diff --git a/webinterface/src/web-data/gfx/signal.png b/webinterface/src/web-data/gfx/signal.png
deleted file mode 100644 (file)
index 6723593..0000000
Binary files a/webinterface/src/web-data/gfx/signal.png and /dev/null differ
diff --git a/webinterface/src/web-data/gfx/speak_off.png b/webinterface/src/web-data/gfx/speak_off.png
deleted file mode 100644 (file)
index 8823ac3..0000000
Binary files a/webinterface/src/web-data/gfx/speak_off.png and /dev/null differ
diff --git a/webinterface/src/web-data/gfx/speak_on.png b/webinterface/src/web-data/gfx/speak_on.png
deleted file mode 100644 (file)
index 5ded98c..0000000
Binary files a/webinterface/src/web-data/gfx/speak_on.png and /dev/null differ
diff --git a/webinterface/src/web-data/img/Makefile.am b/webinterface/src/web-data/img/Makefile.am
new file mode 100644 (file)
index 0000000..cb9a544
--- /dev/null
@@ -0,0 +1,3 @@
+installdir = /usr/lib/enigma2/python/Plugins/Extensions/WebInterface/web-data/img/
+
+install_DATA = *.png
diff --git a/webinterface/src/web-data/img/arrow_down.png b/webinterface/src/web-data/img/arrow_down.png
new file mode 100644 (file)
index 0000000..312fb4d
Binary files /dev/null and b/webinterface/src/web-data/img/arrow_down.png differ
diff --git a/webinterface/src/web-data/img/arrow_up.png b/webinterface/src/web-data/img/arrow_up.png
new file mode 100644 (file)
index 0000000..62bf7f8
Binary files /dev/null and b/webinterface/src/web-data/img/arrow_up.png differ
diff --git a/webinterface/src/web-data/img/delete.png b/webinterface/src/web-data/img/delete.png
new file mode 100644 (file)
index 0000000..4a42ca5
Binary files /dev/null and b/webinterface/src/web-data/img/delete.png differ
diff --git a/webinterface/src/web-data/img/dreamboxweb.png b/webinterface/src/web-data/img/dreamboxweb.png
new file mode 100644 (file)
index 0000000..76d6c86
Binary files /dev/null and b/webinterface/src/web-data/img/dreamboxweb.png differ
diff --git a/webinterface/src/web-data/img/edit.png b/webinterface/src/web-data/img/edit.png
new file mode 100644 (file)
index 0000000..eba70ea
Binary files /dev/null and b/webinterface/src/web-data/img/edit.png differ
diff --git a/webinterface/src/web-data/img/led_off.png b/webinterface/src/web-data/img/led_off.png
new file mode 100644 (file)
index 0000000..bd52af4
Binary files /dev/null and b/webinterface/src/web-data/img/led_off.png differ
diff --git a/webinterface/src/web-data/img/led_on.png b/webinterface/src/web-data/img/led_on.png
new file mode 100644 (file)
index 0000000..cbf77e5
Binary files /dev/null and b/webinterface/src/web-data/img/led_on.png differ
diff --git a/webinterface/src/web-data/img/nok.png b/webinterface/src/web-data/img/nok.png
new file mode 100644 (file)
index 0000000..bc031d9
Binary files /dev/null and b/webinterface/src/web-data/img/nok.png differ
diff --git a/webinterface/src/web-data/img/off.png b/webinterface/src/web-data/img/off.png
new file mode 100644 (file)
index 0000000..bc031d9
Binary files /dev/null and b/webinterface/src/web-data/img/off.png differ
diff --git a/webinterface/src/web-data/img/ok.png b/webinterface/src/web-data/img/ok.png
new file mode 100644 (file)
index 0000000..5457963
Binary files /dev/null and b/webinterface/src/web-data/img/ok.png differ
diff --git a/webinterface/src/web-data/img/on.png b/webinterface/src/web-data/img/on.png
new file mode 100644 (file)
index 0000000..5457963
Binary files /dev/null and b/webinterface/src/web-data/img/on.png differ
diff --git a/webinterface/src/web-data/img/signal.png b/webinterface/src/web-data/img/signal.png
new file mode 100644 (file)
index 0000000..6723593
Binary files /dev/null and b/webinterface/src/web-data/img/signal.png differ
diff --git a/webinterface/src/web-data/img/speak_off.png b/webinterface/src/web-data/img/speak_off.png
new file mode 100644 (file)
index 0000000..8823ac3
Binary files /dev/null and b/webinterface/src/web-data/img/speak_off.png differ
diff --git a/webinterface/src/web-data/img/speak_on.png b/webinterface/src/web-data/img/speak_on.png
new file mode 100644 (file)
index 0000000..5ded98c
Binary files /dev/null and b/webinterface/src/web-data/img/speak_on.png differ
diff --git a/webinterface/src/web-data/img/stream.png b/webinterface/src/web-data/img/stream.png
new file mode 100644 (file)
index 0000000..62b9fa0
Binary files /dev/null and b/webinterface/src/web-data/img/stream.png differ
index 5fdc6f0..ffc436c 100644 (file)
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+       "http://www.w3.org/TR/html4/loose.dtd">
 <html>
+
 <head>
-<!-- 
- $Header$
--->
        <meta content="text/html; charset=UTF-8" http-equiv="content-type">
-       <title>Enigma 2 Webinterface</title>
+       <title>Dreambox WebControl</title>
        
-       <!-- load everything for prototype and prototype window //-->
-       <script type="text/javascript" src="/webdata/lib/ptwindow/javascripts/prototype.js" ></script>
-       <script type="text/javascript" src="/webdata/lib/ptwindow/javascripts/effects.js" ></script>
-       <script type="text/javascript" src="/webdata/lib/ptwindow/javascripts/window.js" ></script>
-       <script type="text/javascript" src="/webdata/lib/ptwindow/javascripts/debug.js"> </script>
-
-       <script type="text/javascript" src="/webdata/lib/rico.js"></script>
+       <script type="text/javascript" src="webdata/lib/prototype-1.6.0.3.js"></script>
+       <script type="text/javascript" src="webdata/lib/shadedborder.js"></script>
+       <script type="text/javascript" src="webdata/lib/trimpath-template-1.0.38.js"></script>
 
-       <link href="/webdata/lib/ptwindow/themes/default.css" rel="stylesheet" type="text/css" >
-       <link href="/webdata/lib/ptwindow/themes/alphacube.css" rel="stylesheet" type="text/css" >
-       
-       <!-- link href="/webdata/lib/ptwindow/themes/debug.css" rel="stylesheet" type="text/css" ></link -->
        
        <!-- our stuff //-->
-       <script type="text/javascript" src="/webdata/templates.js" ></script>
        <script type="text/javascript" src="/webdata/objects.js" ></script>
        <script type="text/javascript" src="/webdata/config.js" ></script>
        <script type="text/javascript" src="/webdata/tools.js" ></script>
        <script type="text/javascript" src="/webdata/timer.js" ></script>
        
-       <link href="/webdata/style.css" type="text/css" rel="stylesheet" >
-       <link rel="shortcut icon" type="image/x-icon" href="/webdata/gfx/favicon.ico">
+       <link href="/webdata/style.css" type="text/css" rel="stylesheet">
+       <link rel="shortcut icon" type="webdata/image/x-icon" href="/webdata/gfx/favicon.ico">
 
        <!-- Live RSS Feeds //-->
        <link rel="alternate" type="application/rss+xml" title="Movie List" href="/web/movielist.rss?tag" >
-</head>
 
-<body>
-<div id="Main">
-       <div id="nav">  
-               <div id="NavHd"><span id="RequestIndicator" style="display:none;"><img alt="R" src="/webdata/gfx/progress.gif" />loading... </span></div>
+
+       <script language="javascript" type="text/javascript">
                
-               <div id="navTable">
-                       <div class="NavEl">
-                               <!-- START BODY MENUE //-->
-                               <div id="accordionMenue">
-                                       <div class="navMenuPanel" id="accordionMenueBouquetPanelTV">
-                                               <div class="navMenuHeader" id="accordionMenueBouquetHeaderTV">TV</div>
-                                               <div class="navMenuContent" id="accordionMenueBouquetContentTV">please wait, loading...</div>
-                                       </div>
-                                       
-                                       <div class="navMenuPanel" id="accordionMenueBouquetPanelRadio">
-                                               <div class="navMenuHeader" id="accordionMenueBouquetHeaderRadio">Radio</div>
-                                               <div class="navMenuContent" id="accordionMenueBouquetContentRadio">please wait, loading...</div>
-                                       </div>
-                                       
-                                       <div class="navMenuPanel" id="accordionMenueBouquetPanelProviderTV">
-                                               <div class="navMenuHeader" id="accordionMenueBouquetHeaderProviderTV">Provider TV</div>
-                                               <div class="navMenuContent" id="accordionMenueBouquetContentProviderTV">please wait, loading...</div>
-                                       </div>
-                                       
-                                       <div class="navMenuPanel" id="accordionMenueBouquetPanelProviderRadio">
-                                               <div class="navMenuHeader" id="accordionMenueBouquetHeaderProviderRadio">Provider Radio</div>
-                                               <div class="navMenuContent" id="accordionMenueBouquetContentProviderRadio">please wait, loading...</div>
-                                       </div>
-                                       
-                                       <div class="navMenuPanel" id="accordionMenueBouquetPanelMovieTimer">
-                                               <div class="navMenuHeader" id="accordionMenueBouquetHeaderMovieTimer">Movie/Timer</div>
-                                               <div class="navMenuContent" id="accordionMenueBouquetContentMovieTimer">
-                                                       <div onclick="loadMovieList('')">Movies</div>
-                                                       <div onclick="loadTimerList()">Timers</div>
-                                                       <div onclick="loadTimerFormNow()">Add Timer</div>
-                                               </div>
-                                       </div>
-                                               
-                                       <div class="navMenuPanel" id="accordionMenueBouquetPanelExtras">
-                                               <div class="navMenuHeader" id="accordionMenueBouquetHeaderExtras">Extras</div>
-                                               <div class="navMenuContent" id="accordionMenueBouquetContentExtras">
-                                                       <div onclick="loadMediaPlayer('/media/hdd/')">MediaPlayer</div>
-                                                       <div onclick="showMessageSendForm()">Message</div>
-                                                       <div onclick="showRemoteControllSendForm()">Remote Control</div>
-                                                       <div onclick="showPowerStateSendForm()">Power</div>
-                                                       <div onclick="loadFileBrowser('/media/hdd/','any')">FileBrowser</div>
-                                                       <div onclick="showAbout()">About</div>
-                                                       <div onclick="showNotes()">Notes</div>
-                                               </div>
-                                       </div>          
-                               </div>
+               if (!window.$) {
+                       window.$ = function(id) { return document.getElementById(id); }
+               }
+               
+               function getWinSize(win) 
+               { 
+                       if(!win) win = window; 
+                       var s = new Object(); 
+                       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')">
+       <div id="container">
+               <div id="banner">
+                       <div id="bannerLeft">
+                               <div id="bannerText" style="font-size: 24px;"><img src="/webdata/img/dreamboxweb.png" alt="Dreambox Web"></div>
+                               <ul id="mainMenu">
+                                       <li><a href="#" onClick="switchMode('TV')">TeleVision</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('MediaPlayer')">MediaPlayer</a></li>  -->
+                                       <li><a href="#" onClick="switchMode('Extras')">Extras</a></li>
+                               </ul>
+                       </div>
+                       <div id="bannerRight">
+                               <div>
+                                       <a href="#" onClick="openSignalPanel()">
+                                               <img border="0" src="/webdata/img/signal.png" alt="Signal" title="Show Signal Panel">
+                                       </a>
+                               </div>                  
                        </div>
                </div>
-       </div>
-       
-       <div id="Content">
-               <div id="EventNowNext" class="bgMain">
-
-                   <div id="ServiceInfo">
-                               <div id="CurrentService"></div>
-                               <div id="VolumePanel"></div>
-                               <div id="RecordButton"><img alt="Record" src="/webdata/gfx/record.png" onclick="recordingPushed();" /></div>
-                       <div id="SignalPanel"><img src="/webdata/gfx/signal.png" alt="SP" onclick="openSignalDialog();" title="view Signal Info"></div>
-                               <div id="StreaminterfaceButton"><a href="/webdata/streaminterface.html" target="_blank" ><img alt="Streaminterface" border="0" src="/webdata/gfx/screen.png" /></a></div>
-                       <div id="CurrentTime" onclick="openHiddenFunctions();"></div>
+               <div id="current">
+                       <table id="currentTable">
+                               <tr>
+                                       <td id="currentName">N/A</td>
+                                       <td id="currentDuration">N/A</td>
+                               </tr>   
+                       </table>
+               </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;">
+                                               <img id='volume1' onclick='volumeSet(10)' src='/webdata/img/led_off.png' title="Volume to 10%" alt="10%">
+                                               <img id='volume2' onclick='volumeSet(20)' src='/webdata/img/led_off.png' title="Volume to 20%" alt="20%">
+                                               <img id='volume3' onclick='volumeSet(30)' src='/webdata/img/led_off.png' title="Volume to 30%" alt="30%">
+                                               <img id='volume4' onclick='volumeSet(40)' src='/webdata/img/led_off.png' title="Volume to 40%" alt="40%">
+                                               <img id='volume5' onclick='volumeSet(50)' src='/webdata/img/led_off.png' title="Volume to 50%" alt="50%">
+                                               <img id='volume6' onclick='volumeSet(60)' src='/webdata/img/led_off.png' title="Volume to 60%" alt="60%">
+                                               <img id='volume7' onclick='volumeSet(70)' src='/webdata/img/led_off.png' title="Volume to 70%" alt="70%">
+                                               <img id='volume8' onclick='volumeSet(80)' src='/webdata/img/led_off.png' title="Volume to 80%" alt="80%">
+                                               <img id='volume9' onclick='volumeSet(90)' src='/webdata/img/led_off.png' title="Volume to 90%" alt="90%">
+                                               <img id='volume10' onclick='volumeSet(100)' src='/webdata/img/led_off.png' title="Volume to 100%" alt="100%">
+                                               <br>
+                                               <img onclick='volumeUp()' src='/webdata/img/arrow_up.png'  title="Volume Up" alt="Up">
+                                               <img onclick='volumeDown()' src='/webdata/img/arrow_down.png'  title="Volume Down" alt="Down">
+                                               <img id='speaker' onclick='volumeMute()' src='/webdata/img/speak_on.png'  title="Mute" alt="Mute">
+                                               <br>                                            
+                                       </span>
+                               </div>
+                               <div id="navSearch">
+                                       <div id="searchHd" class="header"><div>EPG-Search</div></div>
+                                       <div class="boxContent">
+                                               <form action="" onSubmit="loadEPGBySearchString(document.getElementById('epgSearch').value); return false;">
+                                                       <input type="text" id="epgSearch" onfocus="this.value=''" value="Search EPG"/>
+                                                       <input style="vertical-align:middle" type="image" src="/webdata/gfx/search.png" alt="search..." title="Search EPG for term">
+                                               </form>                                         
+                                       </div>
+                               </div>
                        </div>
-                   
-                   <div class="divblock">
-                               <div style="width:5%; float:left;" onclick="showhide('Event_Now_Extended_Description')" class="event" id="Event_Now_Begin"></div>
-                               <div style="width:65%; float:left;" onclick="showhide('Event_Now_Extended_Description')" class="event" id="Event_Now_Name"></div>
-                               <div style="width:30%; float:left;" onclick="showhide('Event_Now_Extended_Description')" class="eventRA" id="Event_Now_Remaining"></div>
-                   </div>
-           
-                   <div class="divblock">
-                               <div class="eventExtDesc" id="Event_Now_Extended_Description"></div>
-                   </div>
-                   
-                   <div class="divblock" onclick="showhide('Event_Next_Extended_Description');">
-                               <div style="width:5%; float:left;" class="event" id="Event_Next_Begin"></div>
-                               <div style="width:65%; float:left;" class="event" id="Event_Next_Name"></div>
-                               <div style="width:30%; float:left;" class="eventRA" id="Event_Next_Remaining"></div>
-                   </div>
-                   
-                   <div class="divblock">
-                               <div class="eventExtDesc" id="Event_Next_Extended_Description"></div>
-                   </div>
+                       <div id="content">
+                               <div id="contentHd" class="header"><div>Content</div></div>
+                               <div id="contentMain">...</div>
+                       </div>  
                </div>
-               <hr />
-               
-               <div id="BodyContent" class="BodyContent"></div>
-
        </div>
+       <script language="javascript" type="text/javascript">                   
+               /****************
+               Rounded Corners 
+               *****************/
+               var menuBorder = RUZEE.ShadedBorder.create({ corner:5, border: 1 });
 
-</div>
-<div>
-<!-- START LIVEUPDATESTREAM  is used to enable the liveupdatestream in MS Internet Explorer //-->
-<div id="UpdateStreamReaderIEFixPanel"></div>
-<!-- END LIVEUPDATESTREAM//-->
-
-<div id="ServiceListBouqetReference"  style="display:none;" ></div>
-</div>
-<script type="text/javascript" >
+               var buttons = $('mainMenu').getElementsByTagName("li");
 
-var debugWin = null;
-if(DBG) { debugWin = openWindow("DEBUG", "", 300, 300, 920,140 , "debugWindow"); }
+               for (var i=0; i < buttons.length; ++i) {                        
+                       menuBorder.render(buttons[i]);
+               }
 
+               var bannerBorder = RUZEE.ShadedBorder.create({corner:5, shadow:10});
+               bannerBorder.render('banner');
+               bannerBorder.render('current');
 
-var accordionOptions = {
-       expandedBg : 'transparent',
-       hoverBg : 'CCCCCC',
-       collapsedBg : 'transparent',
-       expandedTextColor : '#000000',
-       expandedFontWeight : 'bold',
-       hoverTextColor : '#000000',
-       collapsedTextColor : '#000000',
-       collapsedFontWeight : 'normal',
-       borderColor : '#EEEEEE',
-       border : '0',
-       panelHeight : 150
-}
+               var contentBorder = RUZEE.ShadedBorder.create({corner:5, border: 2, shadow:10});
+               contentBorder.render('nav');
+               contentBorder.render('navSearch');
+               contentBorder.render('navVolume');
+               contentBorder.render('content');
 
-new Rico.Accordion( $('accordionMenue'), accordionOptions );
-
-// do things to do at startup
-initVolumePanel();
-initChannelList();
-getDreamboxSettings();
+               var hdBorder = RUZEE.ShadedBorder.create({corner:5, edges:"tlr"});
+               hdBorder.render('navHd');
+               hdBorder.render('searchHd');
+               hdBorder.render('volHd');
+               hdBorder.render('contentHd');
+               
+               function setNavHd(content){
+                       set("navHd", "<div>"+content+"</div>");
+                       hdBorder.render('navHd');
+               }
+               
+               function setContentHd(content){
+                       set("contentHd", "<div>"+content+"</div>");
+                       hdBorder.render('contentHd');
+               }
+               
+               function getAjaxLoad(){
+                       return ('<div>loading...</div>');
+               }
+               
+               setMaxHeight('contentMain');            
+               
+               init();
+       </script>
 
-//setBodyMainContent('BodyContentChannellist');
-UpdateStreamReaderStart();
-showhide('Event_Next_Extended_Description');
-</script>
 </body>
 </html>
\ No newline at end of file
index 77b2b3f..b726467 100644 (file)
@@ -1,5 +1,3 @@
 installdir = /usr/lib/enigma2/python/Plugins/Extensions/WebInterface/web-data/lib/
 
-install_DATA = rico.js
-
-SUBDIRS = ptwindow
+install_DATA = *.js
diff --git a/webinterface/src/web-data/lib/prototype-1.6.0.3.js b/webinterface/src/web-data/lib/prototype-1.6.0.3.js
new file mode 100644 (file)
index 0000000..dfe8ab4
--- /dev/null
@@ -0,0 +1,4320 @@
+/*  Prototype JavaScript framework, version 1.6.0.3
+ *  (c) 2005-2008 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.0.3',
+
+  Browser: {
+    IE:     !!(window.attachEvent &&
+      navigator.userAgent.indexOf('Opera') === -1),
+    Opera:  navigator.userAgent.indexOf('Opera') > -1,
+    WebKit: navigator.userAgent.indexOf('AppleWebKit/') > -1,
+    Gecko:  navigator.userAgent.indexOf('Gecko') > -1 &&
+      navigator.userAgent.indexOf('KHTML') === -1,
+    MobileSafari: !!navigator.userAgent.match(/Apple.*Mobile.*Safari/)
+  },
+
+  BrowserFeatures: {
+    XPath: !!document.evaluate,
+    SelectorsAPI: !!document.querySelector,
+    ElementExtensions: !!window.HTMLElement,
+    SpecificElementExtensions:
+      document.createElement('div')['__proto__'] &&
+      document.createElement('div')['__proto__'] !==
+        document.createElement('form')['__proto__']
+  },
+
+  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;
+
+
+/* Based on Alex Arnell's inheritance implementation. */
+var Class = {
+  create: function() {
+    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) {
+      var subclass = function() { };
+      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;
+  }
+};
+
+Class.Methods = {
+  addMethods: function(source) {
+    var ancestor   = this.superclass && this.superclass.prototype;
+    var properties = Object.keys(source);
+
+    if (!Object.keys({ toString: true }).length)
+      properties.push("toString", "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;
+  }
+};
+
+var Abstract = { };
+
+Object.extend = function(destination, source) {
+  for (var property in source)
+    destination[property] = source[property];
+  return destination;
+};
+
+Object.extend(Object, {
+  inspect: function(object) {
+    try {
+      if (Object.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;
+    }
+  },
+
+  toJSON: function(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 (Object.isElement(object)) return;
+
+    var results = [];
+    for (var property in object) {
+      var value = Object.toJSON(object[property]);
+      if (!Object.isUndefined(value))
+        results.push(property.toJSON() + ': ' + value);
+    }
+
+    return '{' + results.join(', ') + '}';
+  },
+
+  toQueryString: function(object) {
+    return $H(object).toQueryString();
+  },
+
+  toHTML: function(object) {
+    return object && object.toHTML ? object.toHTML() : String.interpret(object);
+  },
+
+  keys: function(object) {
+    var keys = [];
+    for (var property in object)
+      keys.push(property);
+    return keys;
+  },
+
+  values: function(object) {
+    var values = [];
+    for (var property in object)
+      values.push(object[property]);
+    return values;
+  },
+
+  clone: function(object) {
+    return Object.extend({ }, object);
+  },
+
+  isElement: function(object) {
+    return !!(object && object.nodeType == 1);
+  },
+
+  isArray: function(object) {
+    return object != null && typeof object == "object" &&
+      'splice' in object && 'join' in object;
+  },
+
+  isHash: function(object) {
+    return object instanceof Hash;
+  },
+
+  isFunction: function(object) {
+    return typeof object == "function";
+  },
+
+  isString: function(object) {
+    return typeof object == "string";
+  },
+
+  isNumber: function(object) {
+    return typeof object == "number";
+  },
+
+  isUndefined: function(object) {
+    return typeof object == "undefined";
+  }
+});
+
+Object.extend(Function.prototype, {
+  argumentNames: function() {
+    var names = this.toString().match(/^[\s\(]*function[^(]*\(([^\)]*)\)/)[1]
+      .replace(/\s+/g, '').split(',');
+    return names.length == 1 && !names[0] ? [] : names;
+  },
+
+  bind: function() {
+    if (arguments.length < 2 && Object.isUndefined(arguments[0])) return this;
+    var __method = this, args = $A(arguments), object = args.shift();
+    return function() {
+      return __method.apply(object, args.concat($A(arguments)));
+    }
+  },
+
+  bindAsEventListener: function() {
+    var __method = this, args = $A(arguments), object = args.shift();
+    return function(event) {
+      return __method.apply(object, [event || window.event].concat(args));
+    }
+  },
+
+  curry: function() {
+    if (!arguments.length) return this;
+    var __method = this, args = $A(arguments);
+    return function() {
+      return __method.apply(this, args.concat($A(arguments)));
+    }
+  },
+
+  delay: function() {
+    var __method = this, args = $A(arguments), timeout = args.shift() * 1000;
+    return window.setTimeout(function() {
+      return __method.apply(__method, args);
+    }, timeout);
+  },
+
+  defer: function() {
+    var args = [0.01].concat($A(arguments));
+    return this.delay.apply(this, args);
+  },
+
+  wrap: function(wrapper) {
+    var __method = this;
+    return function() {
+      return wrapper.apply(this, [__method.bind(this)].concat($A(arguments)));
+    }
+  },
+
+  methodize: function() {
+    if (this._methodized) return this._methodized;
+    var __method = this;
+    return this._methodized = function() {
+      return __method.apply(null, [this].concat($A(arguments)));
+    };
+  }
+});
+
+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"';
+};
+
+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;
+  }
+};
+
+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();
+      } finally {
+        this.currentlyExecuting = false;
+      }
+    }
+  }
+});
+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, {
+  gsub: function(pattern, replacement) {
+    var result = '', source = this, match;
+    replacement = arguments.callee.prepareReplacement(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;
+  },
+
+  sub: function(pattern, replacement, count) {
+    replacement = this.gsub.prepareReplacement(replacement);
+    count = Object.isUndefined(count) ? 1 : count;
+
+    return this.gsub(pattern, function(match) {
+      if (--count < 0) return match[0];
+      return replacement(match);
+    });
+  },
+
+  scan: function(pattern, iterator) {
+    this.gsub(pattern, iterator);
+    return String(this);
+  },
+
+  truncate: function(length, truncation) {
+    length = length || 30;
+    truncation = Object.isUndefined(truncation) ? '...' : truncation;
+    return this.length > length ?
+      this.slice(0, length - truncation.length) + truncation : String(this);
+  },
+
+  strip: function() {
+    return this.replace(/^\s+/, '').replace(/\s+$/, '');
+  },
+
+  stripTags: function() {
+    return this.replace(/<\/?[^>]+>/gi, '');
+  },
+
+  stripScripts: function() {
+    return this.replace(new RegExp(Prototype.ScriptFragment, 'img'), '');
+  },
+
+  extractScripts: function() {
+    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];
+    });
+  },
+
+  evalScripts: function() {
+    return this.extractScripts().map(function(script) { return eval(script) });
+  },
+
+  escapeHTML: function() {
+    var self = arguments.callee;
+    self.text.data = this;
+    return self.div.innerHTML;
+  },
+
+  unescapeHTML: function() {
+    var div = new Element('div');
+    div.innerHTML = this.stripTags();
+    return div.childNodes[0] ? (div.childNodes.length > 1 ?
+      $A(div.childNodes).inject('', function(memo, node) { return memo+node.nodeValue }) :
+      div.childNodes[0].nodeValue) : '';
+  },
+
+  toQueryParams: function(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;
+    });
+  },
+
+  toArray: function() {
+    return this.split('');
+  },
+
+  succ: function() {
+    return this.slice(0, this.length - 1) +
+      String.fromCharCode(this.charCodeAt(this.length - 1) + 1);
+  },
+
+  times: function(count) {
+    return count < 1 ? '' : new Array(count + 1).join(this);
+  },
+
+  camelize: function() {
+    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;
+  },
+
+  capitalize: function() {
+    return this.charAt(0).toUpperCase() + this.substring(1).toLowerCase();
+  },
+
+  underscore: function() {
+    return this.gsub(/::/, '/').gsub(/([A-Z]+)([A-Z][a-z])/,'#{1}_#{2}').gsub(/([a-z\d])([A-Z])/,'#{1}_#{2}').gsub(/-/,'_').toLowerCase();
+  },
+
+  dasherize: function() {
+    return this.gsub(/_/,'-');
+  },
+
+  inspect: function(useDoubleQuotes) {
+    var escapedString = this.gsub(/[\x00-\x1f\\]/, function(match) {
+      var character = String.specialChar[match[0]];
+      return character ? character : '\\u00' + match[0].charCodeAt().toPaddedString(2, 16);
+    });
+    if (useDoubleQuotes) return '"' + escapedString.replace(/"/g, '\\"') + '"';
+    return "'" + escapedString.replace(/'/g, '\\\'') + "'";
+  },
+
+  toJSON: function() {
+    return this.inspect(true);
+  },
+
+  unfilterJSON: function(filter) {
+    return this.sub(filter || Prototype.JSONFilter, '#{1}');
+  },
+
+  isJSON: function() {
+    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);
+  },
+
+  evalJSON: function(sanitize) {
+    var json = this.unfilterJSON();
+    try {
+      if (!sanitize || json.isJSON()) return eval('(' + json + ')');
+    } catch (e) { }
+    throw new SyntaxError('Badly formed JSON string: ' + this.inspect());
+  },
+
+  include: function(pattern) {
+    return this.indexOf(pattern) > -1;
+  },
+
+  startsWith: function(pattern) {
+    return this.indexOf(pattern) === 0;
+  },
+
+  endsWith: function(pattern) {
+    var d = this.length - pattern.length;
+    return d >= 0 && this.lastIndexOf(pattern) === d;
+  },
+
+  empty: function() {
+    return this == '';
+  },
+
+  blank: function() {
+    return /^\s*$/.test(this);
+  },
+
+  interpolate: function(object, pattern) {
+    return new Template(this, pattern).evaluate(object);
+  }
+});
+
+if (Prototype.Browser.WebKit || Prototype.Browser.IE) Object.extend(String.prototype, {
+  escapeHTML: function() {
+    return this.replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;');
+  },
+  unescapeHTML: function() {
+    return this.stripTags().replace(/&amp;/g,'&').replace(/&lt;/g,'<').replace(/&gt;/g,'>');
+  }
+});
+
+String.prototype.gsub.prepareReplacement = function(replacement) {
+  if (Object.isFunction(replacement)) return replacement;
+  var template = new Template(replacement);
+  return function(match) { return template.evaluate(match) };
+};
+
+String.prototype.parseQuery = String.prototype.toQueryParams;
+
+Object.extend(String.prototype.escapeHTML, {
+  div:  document.createElement('div'),
+  text: document.createTextNode('')
+});
+
+String.prototype.escapeHTML.div.appendChild(String.prototype.escapeHTML.text);
+
+var Template = Class.create({
+  initialize: function(template, pattern) {
+    this.template = template.toString();
+    this.pattern = pattern || Template.Pattern;
+  },
+
+  evaluate: function(object) {
+    if (Object.isFunction(object.toTemplateReplacements))
+      object = object.toTemplateReplacements();
+
+    return this.template.gsub(this.pattern, function(match) {
+      if (object == null) return '';
+
+      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].gsub('\\\\]', ']') : 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 = {
+  each: function(iterator, context) {
+    var index = 0;
+    try {
+      this._each(function(value) {
+        iterator.call(context, value, index++);
+      });
+    } catch (e) {
+      if (e != $break) throw e;
+    }
+    return this;
+  },
+
+  eachSlice: function(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);
+  },
+
+  all: function(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;
+  },
+
+  any: function(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;
+  },
+
+  collect: function(iterator, context) {
+    iterator = iterator || Prototype.K;
+    var results = [];
+    this.each(function(value, index) {
+      results.push(iterator.call(context, value, index));
+    });
+    return results;
+  },
+
+  detect: function(iterator, context) {
+    var result;
+    this.each(function(value, index) {
+      if (iterator.call(context, value, index)) {
+        result = value;
+        throw $break;
+      }
+    });
+    return result;
+  },
+
+  findAll: function(iterator, context) {
+    var results = [];
+    this.each(function(value, index) {
+      if (iterator.call(context, value, index))
+        results.push(value);
+    });
+    return results;
+  },
+
+  grep: function(filter, iterator, context) {
+    iterator = iterator || Prototype.K;
+    var results = [];
+
+    if (Object.isString(filter))
+      filter = new RegExp(filter);
+
+    this.each(function(value, index) {
+      if (filter.match(value))
+        results.push(iterator.call(context, value, index));
+    });
+    return results;
+  },
+
+  include: function(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;
+  },
+
+  inGroupsOf: function(number, fillWith) {
+    fillWith = Object.isUndefined(fillWith) ? null : fillWith;
+    return this.eachSlice(number, function(slice) {
+      while(slice.length < number) slice.push(fillWith);
+      return slice;
+    });
+  },
+
+  inject: function(memo, iterator, context) {
+    this.each(function(value, index) {
+      memo = iterator.call(context, memo, value, index);
+    });
+    return memo;
+  },
+
+  invoke: function(method) {
+    var args = $A(arguments).slice(1);
+    return this.map(function(value) {
+      return value[method].apply(value, args);
+    });
+  },
+
+  max: function(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;
+  },
+
+  min: function(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;
+  },
+
+  partition: function(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];
+  },
+
+  pluck: function(property) {
+    var results = [];
+    this.each(function(value) {
+      results.push(value[property]);
+    });
+    return results;
+  },
+
+  reject: function(iterator, context) {
+    var results = [];
+    this.each(function(value, index) {
+      if (!iterator.call(context, value, index))
+        results.push(value);
+    });
+    return results;
+  },
+
+  sortBy: function(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');
+  },
+
+  toArray: function() {
+    return this.map();
+  },
+
+  zip: function() {
+    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));
+    });
+  },
+
+  size: function() {
+    return this.toArray().length;
+  },
+
+  inspect: function() {
+    return '#<Enumerable:' + this.toArray().inspect() + '>';
+  }
+};
+
+Object.extend(Enumerable, {
+  map:     Enumerable.collect,
+  find:    Enumerable.detect,
+  select:  Enumerable.findAll,
+  filter:  Enumerable.findAll,
+  member:  Enumerable.include,
+  entries: Enumerable.toArray,
+  every:   Enumerable.all,
+  some:    Enumerable.any
+});
+function $A(iterable) {
+  if (!iterable) return [];
+  if (iterable.toArray) return iterable.toArray();
+  var length = iterable.length || 0, results = new Array(length);
+  while (length--) results[length] = iterable[length];
+  return results;
+}
+
+if (Prototype.Browser.WebKit) {
+  $A = function(iterable) {
+    if (!iterable) return [];
+    // In Safari, only use the `toArray` method if it's not a NodeList.
+    // A NodeList is a function, has an function `item` property, and a numeric
+    // `length` property. Adapted from Google Doctype.
+    if (!(typeof iterable === 'function' && typeof iterable.length ===
+        'number' && typeof iterable.item === 'function') && iterable.toArray)
+      return iterable.toArray();
+    var length = iterable.length || 0, results = new Array(length);
+    while (length--) results[length] = iterable[length];
+    return results;
+  };
+}
+
+Array.from = $A;
+
+Object.extend(Array.prototype, Enumerable);
+
+if (!Array.prototype._reverse) Array.prototype._reverse = Array.prototype.reverse;
+
+Object.extend(Array.prototype, {
+  _each: function(iterator) {
+    for (var i = 0, length = this.length; i < length; i++)
+      iterator(this[i]);
+  },
+
+  clear: function() {
+    this.length = 0;
+    return this;
+  },
+
+  first: function() {
+    return this[0];
+  },
+
+  last: function() {
+    return this[this.length - 1];
+  },
+
+  compact: function() {
+    return this.select(function(value) {
+      return value != null;
+    });
+  },
+
+  flatten: function() {
+    return this.inject([], function(array, value) {
+      return array.concat(Object.isArray(value) ?
+        value.flatten() : [value]);
+    });
+  },
+
+  without: function() {
+    var values = $A(arguments);
+    return this.select(function(value) {
+      return !values.include(value);
+    });
+  },
+
+  reverse: function(inline) {
+    return (inline !== false ? this : this.toArray())._reverse();
+  },
+
+  reduce: function() {
+    return this.length > 1 ? this : this[0];
+  },
+
+  uniq: function(sorted) {
+    return this.inject([], function(array, value, index) {
+      if (0 == index || (sorted ? array.last() != value : !array.include(value)))
+        array.push(value);
+      return array;
+    });
+  },
+
+  intersect: function(array) {
+    return this.uniq().findAll(function(item) {
+      return array.detect(function(value) { return item === value });
+    });
+  },
+
+  clone: function() {
+    return [].concat(this);
+  },
+
+  size: function() {
+    return this.length;
+  },
+
+  inspect: function() {
+    return '[' + this.map(Object.inspect).join(', ') + ']';
+  },
+
+  toJSON: function() {
+    var results = [];
+    this.each(function(object) {
+      var value = Object.toJSON(object);
+      if (!Object.isUndefined(value)) results.push(value);
+    });
+    return '[' + results.join(', ') + ']';
+  }
+});
+
+// use native browser JS 1.6 implementation if available
+if (Object.isFunction(Array.prototype.forEach))
+  Array.prototype._each = Array.prototype.forEach;
+
+if (!Array.prototype.indexOf) Array.prototype.indexOf = function(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;
+};
+
+if (!Array.prototype.lastIndexOf) Array.prototype.lastIndexOf = function(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;
+};
+
+Array.prototype.toArray = Array.prototype.clone;
+
+function $w(string) {
+  if (!Object.isString(string)) return [];
+  string = string.strip();
+  return string ? string.split(/\s+/) : [];
+}
+
+if (Prototype.Browser.Opera){
+  Array.prototype.concat = function() {
+    var array = [];
+    for (var i = 0, length = this.length; i < length; i++) array.push(this[i]);
+    for (var i = 0, length = arguments.length; i < length; i++) {
+      if (Object.isArray(arguments[i])) {
+        for (var j = 0, arrayLength = arguments[i].length; j < arrayLength; j++)
+          array.push(arguments[i][j]);
+      } else {
+        array.push(arguments[i]);
+      }
+    }
+    return array;
+  };
+}
+Object.extend(Number.prototype, {
+  toColorPart: function() {
+    return this.toPaddedString(2, 16);
+  },
+
+  succ: function() {
+    return this + 1;
+  },
+
+  times: function(iterator, context) {
+    $R(0, this, true).each(iterator, context);
+    return this;
+  },
+
+  toPaddedString: function(length, radix) {
+    var string = this.toString(radix || 10);
+    return '0'.times(length - string.length) + string;
+  },
+
+  toJSON: function() {
+    return isFinite(this) ? this.toString() : 'null';
+  }
+});
+
+$w('abs round ceil floor').each(function(method){
+  Number.prototype[method] = Math[method].methodize();
+});
+function $H(object) {
+  return new Hash(object);
+};
+
+var Hash = Class.create(Enumerable, (function() {
+
+  function toQueryPair(key, value) {
+    if (Object.isUndefined(value)) return key;
+    return key + '=' + encodeURIComponent(String.interpret(value));
+  }
+
+  return {
+    initialize: function(object) {
+      this._object = Object.isHash(object) ? object.toObject() : Object.clone(object);
+    },
+
+    _each: function(iterator) {
+      for (var key in this._object) {
+        var value = this._object[key], pair = [key, value];
+        pair.key = key;
+        pair.value = value;
+        iterator(pair);
+      }
+    },
+
+    set: function(key, value) {
+      return this._object[key] = value;
+    },
+
+    get: function(key) {
+      // simulating poorly supported hasOwnProperty
+      if (this._object[key] !== Object.prototype[key])
+        return this._object[key];
+    },
+
+    unset: function(key) {
+      var value = this._object[key];
+      delete this._object[key];
+      return value;
+    },
+
+    toObject: function() {
+      return Object.clone(this._object);
+    },
+
+    keys: function() {
+      return this.pluck('key');
+    },
+
+    values: function() {
+      return this.pluck('value');
+    },
+
+    index: function(value) {
+      var match = this.detect(function(pair) {
+        return pair.value === value;
+      });
+      return match && match.key;
+    },
+
+    merge: function(object) {
+      return this.clone().update(object);
+    },
+
+    update: function(object) {
+      return new Hash(object).inject(this, function(result, pair) {
+        result.set(pair.key, pair.value);
+        return result;
+      });
+    },
+
+    toQueryString: function() {
+      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('&');
+    },
+
+    inspect: function() {
+      return '#<Hash:{' + this.map(function(pair) {
+        return pair.map(Object.inspect).join(': ');
+      }).join(', ') + '}>';
+    },
+
+    toJSON: function() {
+      return Object.toJSON(this.toObject());
+    },
+
+    clone: function() {
+      return new Hash(this);
+    }
+  }
+})());
+
+Hash.prototype.toTemplateReplacements = Hash.prototype.toObject;
+Hash.from = $H;
+var ObjectRange = Class.create(Enumerable, {
+  initialize: function(start, end, exclusive) {
+    this.start = start;
+    this.end = end;
+    this.exclusive = exclusive;
+  },
+
+  _each: function(iterator) {
+    var value = this.start;
+    while (this.include(value)) {
+      iterator(value);
+      value = value.succ();
+    }
+  },
+
+  include: function(value) {
+    if (value < this.start)
+      return false;
+    if (this.exclusive)
+      return value < this.end;
+    return value <= this.end;
+  }
+});
+
+var $R = function(start, end, exclusive) {
+  return new ObjectRange(start, end, exclusive);
+};
+
+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)) {
+      // simulate other verbs over post
+      params['_method'] = this.method;
+      this.method = 'post';
+    }
+
+    this.parameters = params;
+
+    if (params = Object.toQueryString(params)) {
+      // when GET, append parameters to URL
+      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';
+    }
+
+    // user-defined headers
+    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') {
+      // avoid memory leak in MSIE: clean up
+      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) {
+  // DOM level 2 ECMAScript Language Binding
+  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() {
+  var element = this.Element;
+  this.Element = function(tagName, attributes) {
+    attributes = attributes || { };
+    tagName = tagName.toLowerCase();
+    var cache = Element.cache;
+    if (Prototype.Browser.IE && 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(this.Element, element || { });
+  if (element) this.Element.prototype = element.prototype;
+}).call(window);
+
+Element.cache = { };
+
+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(element, content) {
+    element = $(element);
+    if (content && content.toElement) content = content.toElement();
+    if (Object.isElement(content)) return element.update().insert(content);
+    content = Object.toHTML(content);
+    element.innerHTML = content.stripScripts();
+    content.evalScripts.bind(content).defer();
+    return element;
+  },
+
+  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('parentNode');
+  },
+
+  descendants: function(element) {
+    return $(element).select("*");
+  },
+
+  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('previousSibling');
+  },
+
+  nextSiblings: function(element) {
+    return $(element).recursivelyCollect('nextSibling');
+  },
+
+  siblings: function(element) {
+    element = $(element);
+    return element.previousSiblings().reverse().concat(element.nextSiblings());
+  },
+
+  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();
+    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();
+    return Object.isNumber(expression) ? element.descendants()[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();
+    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();
+    return Object.isNumber(expression) ? nextSiblings[expression] :
+      Selector.findElement(nextSiblings, expression, index);
+  },
+
+  select: function() {
+    var args = $A(arguments), element = $(args.shift());
+    return Selector.findChildElements(element, args);
+  },
+
+  adjacent: function() {
+    var args = $A(arguments), element = $(args.shift());
+    return Selector.findChildElements(element.parentNode, args).without(element);
+  },
+
+  identify: function(element) {
+    element = $(element);
+    var id = element.readAttribute('id'), self = arguments.callee;
+    if (id) return id;
+    do { id = 'anonymous_element_' + self.counter++ } while ($(id));
+    element.writeAttribute('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().height;
+  },
+
+  getWidth: function(element) {
+    return $(element).getDimensions().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(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(className) ?
+      'removeClassName' : 'addClassName'](className);
+  },
+
+  // removes whitespace-only text node children
+  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();
+    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('display');
+    if (display != 'none' && display != null) // Safari bug
+      return {width: element.offsetWidth, height: element.offsetHeight};
+
+    // All *Width and *Height properties give 0 on elements with display none,
+    // so enable the element temporarily
+    var els = element.style;
+    var originalVisibility = els.visibility;
+    var originalPosition = els.position;
+    var originalDisplay = els.display;
+    els.visibility = 'hidden';
+    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';
+      // Opera returns the offset relative to the positioning context, when an
+      // element is position relative but top and left have not been defined
+      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('position') == 'absolute') return element;
+    // Position.prepare(); // To be done manually by Scripty when it needs it.
+
+    var offsets = element.positionedOffset();
+    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('position') == 'relative') return element;
+    // Position.prepare(); // To be done manually by Scripty when it needs it.
+
+    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;
+
+      // Safari fix
+      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] || { });
+
+    // find page position of source
+    source = $(source);
+    var p = source.viewportOffset();
+
+    // find coordinate system to use
+    element = $(element);
+    var delta = [0, 0];
+    var parent = null;
+    // delta [0,0] will do fine with position: fixed elements,
+    // position:absolute needs offsetParent deltas
+    if (Element.getStyle(element, 'position') == 'absolute') {
+      parent = element.getOffsetParent();
+      delta = parent.viewportOffset();
+    }
+
+    // correct by body offsets (fixes Safari)
+    if (parent == document.body) {
+      delta[0] -= document.body.offsetLeft;
+      delta[1] -= document.body.offsetTop;
+    }
+
+    // set position
+    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;
+  }
+};
+
+Element.Methods.identify.counter = 1;
+
+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':
+          // returns '0px' for hidden elements; we want it to return null
+          if (!Element.visible(element)) return null;
+
+          // returns the border-box dimensions rather than the content-box
+          // dimensions, so we subtract padding and borders from the value
+          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) {
+  // IE doesn't report offsets correctly for static elements, so we change them
+  // to "relative" to get the values, then change them back.
+  Element.Methods.getOffsetParent = Element.Methods.getOffsetParent.wrap(
+    function(proceed, element) {
+      element = $(element);
+      // IE throws an error if element is not in document
+      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);
+        // Trigger hasLayout on the offset parent so that IE6 reports
+        // accurate offsetTop and offsetLeft values for position: fixed.
+        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 = {
+    read: {
+      names: {
+        'class': 'className',
+        'for':   'htmlFor'
+      },
+      values: {
+        _getAttr: function(element, attribute) {
+          return element.getAttribute(attribute, 2);
+        },
+        _getAttrNode: function(element, attribute) {
+          var node = element.getAttributeNode(attribute);
+          return node ? node.value : "";
+        },
+        _getEv: function(element, attribute) {
+          attribute = element.getAttribute(attribute);
+          return attribute ? attribute.toString().slice(23, -2) : null;
+        },
+        _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._getAttr,
+      src:         v._getAttr,
+      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);
+}
+
+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;
+  };
+
+  // Safari returns margins on body which is incorrect if the child is absolutely
+  // positioned.  For performance reasons, redefine Element#cumulativeOffset for
+  // KHTML/WebKit only.
+  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 (Prototype.Browser.IE || Prototype.Browser.Opera) {
+  // IE and Opera are missing .innerHTML support for TABLE-related and SELECT elements
+  Element.Methods.update = function(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 in Element._insertionTranslations.tags) {
+      $A(element.childNodes).each(function(node) { element.removeChild(node) });
+      Element._getContentFromAnonymousElement(tagName, content.stripScripts())
+        .each(function(node) { element.appendChild(node) });
+    }
+    else element.innerHTML = content.stripScripts();
+
+    content.evalScripts.bind(content).defer();
+    return element;
+  };
+}
+
+if ('outerHTML' in document.createElement('div')) {
+  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() {
+  Object.extend(this.tags, {
+    THEAD: this.tags.TBODY,
+    TFOOT: this.tags.TBODY,
+    TH:    this.tags.TD
+  });
+}).call(Element._insertionTranslations);
+
+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);
+
+if (!Prototype.BrowserFeatures.ElementExtensions &&
+    document.createElement('div')['__proto__']) {
+  window.HTMLElement = { };
+  window.HTMLElement.prototype = document.createElement('div')['__proto__'];
+  Prototype.BrowserFeatures.ElementExtensions = true;
+}
+
+Element.extend = (function() {
+  if (Prototype.BrowserFeatures.SpecificElementExtensions)
+    return Prototype.K;
+
+  var Methods = { }, ByTag = Element.Methods.ByTag;
+
+  var extend = Object.extend(function(element) {
+    if (!element || element._extendedByPrototype ||
+        element.nodeType != 1 || element == window) return element;
+
+    var methods = Object.clone(Methods),
+      tagName = element.tagName.toUpperCase(), property, value;
+
+    // extend methods for specific tags
+    if (ByTag[tagName]) Object.extend(methods, ByTag[tagName]);
+
+    for (property in methods) {
+      value = methods[property];
+      if (Object.isFunction(value) && !(property in element))
+        element[property] = value.methodize();
+    }
+
+    element._extendedByPrototype = Prototype.emptyFunction;
+    return element;
+
+  }, {
+    refresh: function() {
+      // extend methods for all tags (Safari doesn't need this)
+      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];
+
+    window[klass] = { };
+    window[klass].prototype = document.createElement(tagName)['__proto__'];
+    return window[klass];
+  }
+
+  if (F.ElementExtensions) {
+    copy(Element.Methods, HTMLElement.prototype);
+    copy(Element.Methods.Simulated, HTMLElement.prototype, 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() {
+    var dimensions = { }, B = Prototype.Browser;
+    $w('width height').each(function(d) {
+      var D = d.capitalize();
+      if (B.WebKit && !document.evaluate) {
+        // Safari <3.0 needs self.innerWidth/Height
+        dimensions[d] = self['inner' + D];
+      } else if (B.Opera && parseFloat(window.opera.version()) < 9.5) {
+        // Opera <9.5 needs document.body.clientWidth/Height
+        dimensions[d] = document.body['client' + D]
+      } else {
+        dimensions[d] = document.documentElement['client' + D];
+      }
+    });
+    return dimensions;
+  },
+
+  getWidth: function() {
+    return this.getDimensions().width;
+  },
+
+  getHeight: function() {
+    return this.getDimensions().height;
+  },
+
+  getScrollOffsets: function() {
+    return Element._returnOffset(
+      window.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft,
+      window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop);
+  }
+};
+/* 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() {
+    if (!Prototype.BrowserFeatures.XPath) return false;
+
+    var e = this.expression;
+
+    // Safari 3 chokes on :*-of-type and :empty
+    if (Prototype.Browser.WebKit &&
+     (e.include("-of-type") || e.include(":empty")))
+      return false;
+
+    // XPath can't do namespaced attributes, nor can it read
+    // the "checked" property from DOM nodes
+    if ((/(\[[\w-]*?:|:checked)/).test(e))
+      return false;
+
+    return true;
+  },
+
+  shouldUseSelectorsAPI: function() {
+    if (!Prototype.BrowserFeatures.SelectorsAPI) return false;
+
+    if (!Selector._div) Selector._div = new Element('div');
+
+    // Make sure the browser treats the selector as valid. Test on an
+    // isolated element to minimize cost of this check.
+    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;
+
+    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 in ps) {
+        p = ps[i];
+        if (m = e.match(p)) {
+          this.matcher.push(Object.isFunction(c[i]) ? c[i](m) :
+            new Template(c[i]).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;
+
+    if (Selector._cache[e]) {
+      this.xpath = Selector._cache[e]; return;
+    }
+
+    this.matcher = ['.//*'];
+    while (e && le != e && (/\S/).test(e)) {
+      le = e;
+      for (var i in ps) {
+        if (m = e.match(ps[i])) {
+          this.matcher.push(Object.isFunction(x[i]) ? x[i](m) :
+            new Template(x[i]).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':
+        // querySelectorAll queries document-wide, then filters to descendants
+        // of the context element. That's not what we want.
+        // Add an explicit context to the selector if necessary.
+        if (root !== document) {
+          var oldId = root.id, id = $(root).identify();
+          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;
+
+    while (e && le !== e && (/\S/).test(e)) {
+      le = e;
+      for (var i in ps) {
+        p = ps[i];
+        if (m = e.match(p)) {
+          // use the Selector.assertions methods unless the selector
+          // is too complex.
+          if (as[i]) {
+            this.tokens.push([i, Object.clone(m)]);
+            e = e.replace(m[0], '');
+          } else {
+            // reluctantly do a document-wide search
+            // and look for a match in the array
+            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() + ">";
+  }
+});
+
+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;
+
+        var exclusion = [];
+        while (e && le != e && (/\S/).test(e)) {
+          le = e;
+          for (var i in p) {
+            if (m = e.match(p[i])) {
+              v = Object.isFunction(x[i]) ? x[i](m) : new Template(x[i]).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: {
+    // combinators must be listed first
+    // (and descendant needs to be last combinator)
+    laterSibling: /^\s*~\s*/,
+    child:        /^\s*>\s*/,
+    adjacent:     /^\s*\+\s*/,
+    descendant:   /^\s/,
+
+    // selectors follow
+    tagName:      /^\s*(\*|[\w\-]+)(\b|$)?/,
+    id:           /^#([\w\-\*]+)(\b|$)/,
+    className:    /^\.([\w\-\*]+)(\b|$)/,
+    pseudo:
+/^:((first|last|nth|nth-last|only)(-child|-of-type)|empty|checked|(en|dis)abled|not)(\((.*?)\))?(\b|$|(?=\s|[:+~>]))/,
+    attrPresence: /^\[((?:[\w]+:)?[\w]+)\]/,
+    attr:         /\[((?:[\w-]*:)?[\w-]+)\s*(?:([!^$*~|]?=)\s*((['"])([^\4]*?)\4|([^'"][^\]]*?)))?\]/
+  },
+
+  // for Selector.match and Element#match
+  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: {
+    // UTILITY FUNCTIONS
+    // joins two collections
+    concat: function(a, b) {
+      for (var i = 0, node; node = b[i]; i++)
+        a.push(node);
+      return a;
+    },
+
+    // marks an array of nodes for counting
+    mark: function(nodes) {
+      var _true = Prototype.emptyFunction;
+      for (var i = 0, node; node = nodes[i]; i++)
+        node._countedByPrototype = _true;
+      return nodes;
+    },
+
+    unmark: function(nodes) {
+      for (var i = 0, node; node = nodes[i]; i++)
+        node._countedByPrototype = undefined;
+      return nodes;
+    },
+
+    // mark each child node with its position (for nth calls)
+    // "ofType" flag indicates whether we're indexing for nth-of-type
+    // rather than nth-child
+    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++;
+      }
+    },
+
+    // filters out duplicates and extends all nodes
+    unique: function(nodes) {
+      if (nodes.length == 0) return nodes;
+      var results = [], n;
+      for (var i = 0, l = nodes.length; i < l; i++)
+        if (!(n = nodes[i])._countedByPrototype) {
+          n._countedByPrototype = Prototype.emptyFunction;
+          results.push(Element.extend(n));
+        }
+      return Selector.handlers.unmark(results);
+    },
+
+    // COMBINATOR FUNCTIONS
+    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;
+    },
+
+    // TOKEN FUNCTIONS
+    tagName: function(nodes, root, tagName, combinator) {
+      var uTagName = tagName.toUpperCase();
+      var results = [], h = Selector.handlers;
+      if (nodes) {
+        if (combinator) {
+          // fastlane for ordinary descendant combinators
+          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 (!targetNode) return [];
+      if (!nodes && root == document) return [targetNode];
+      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);
+    },
+
+    // handles the an+b logic
+    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;
+      });
+    },
+
+    // handles nth(-last)-child, nth(-last)-of-type, and (first|last)-of-type
+    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++) {
+        // IE treats comments as element nodes
+        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.endsWith(v); },
+    '*=': function(nv, v) { return 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, {
+    // IE returns comment nodes on getElementsByTagName("*").
+    // Filter them out.
+    concat: function(a, b) {
+      for (var i = 0, node; node = b[i]; i++)
+        if (node.tagName !== "!") a.push(node);
+      return a;
+    },
+
+    // IE improperly serializes _countedByPrototype in (inner|outer)HTML.
+    unmark: function(nodes) {
+      for (var i = 0, node; node = nodes[i]; i++)
+        node.removeAttribute('_countedByPrototype');
+      return nodes;
+    }
+  });
+}
+
+function $$() {
+  return Selector.findChildElements(document, $A(arguments));
+}
+var Form = {
+  reset: function(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) {
+            // a key is already present; construct an array of values
+            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) {
+    return $A($(form).getElementsByTagName('*')).inject([],
+      function(elements, child) {
+        if (Form.Element.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'].include(element.tagName.toLowerCase());
+    });
+  },
+
+  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'].include(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) {
+    // extend element because hasAttribute may not be native
+    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);
+  }
+});
+if (!window.Event) var Event = { };
+
+Object.extend(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: { },
+
+  relatedTarget: function(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);
+  }
+});
+
+Event.Methods = (function() {
+  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);
+    };
+  }
+
+  return {
+    isLeftClick:   function(event) { return isButton(event, 0) },
+    isMiddleClick: function(event) { return isButton(event, 1) },
+    isRightClick:  function(event) { return isButton(event, 2) },
+
+    element: function(event) {
+      event = Event.extend(event);
+
+      var node          = event.target,
+          type          = event.type,
+          currentTarget = event.currentTarget;
+
+      if (currentTarget && currentTarget.tagName) {
+        // Firefox screws up the "click" event when moving between radio buttons
+        // via arrow keys. It also screws up the "load" and "error" events on images,
+        // reporting the document as the target instead of the original image.
+        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);
+    },
+
+    findElement: function(event, expression) {
+      var element = Event.element(event);
+      if (!expression) return element;
+      var elements = [element].concat(element.ancestors());
+      return Selector.findElement(elements, expression, 0);
+    },
+
+    pointer: function(event) {
+      var docElement = document.documentElement,
+      body = document.body || { scrollLeft: 0, scrollTop: 0 };
+      return {
+        x: event.pageX || (event.clientX +
+          (docElement.scrollLeft || body.scrollLeft) -
+          (docElement.clientLeft || 0)),
+        y: event.pageY || (event.clientY +
+          (docElement.scrollTop || body.scrollTop) -
+          (docElement.clientTop || 0))
+      };
+    },
+
+    pointerX: function(event) { return Event.pointer(event).x },
+    pointerY: function(event) { return Event.pointer(event).y },
+
+    stop: function(event) {
+      Event.extend(event);
+      event.preventDefault();
+      event.stopPropagation();
+      event.stopped = true;
+    }
+  };
+})();
+
+Event.extend = (function() {
+  var methods = Object.keys(Event.Methods).inject({ }, function(m, name) {
+    m[name] = Event.Methods[name].methodize();
+    return m;
+  });
+
+  if (Prototype.Browser.IE) {
+    Object.extend(methods, {
+      stopPropagation: function() { this.cancelBubble = true },
+      preventDefault:  function() { this.returnValue = false },
+      inspect: function() { return "[object Event]" }
+    });
+
+    return function(event) {
+      if (!event) return false;
+      if (event._extendedByPrototype) return event;
+
+      event._extendedByPrototype = Prototype.emptyFunction;
+      var pointer = Event.pointer(event);
+      Object.extend(event, {
+        target: event.srcElement,
+        relatedTarget: Event.relatedTarget(event),
+        pageX:  pointer.x,
+        pageY:  pointer.y
+      });
+      return Object.extend(event, methods);
+    };
+
+  } else {
+    Event.prototype = Event.prototype || document.createEvent("HTMLEvents")['__proto__'];
+    Object.extend(Event.prototype, methods);
+    return Prototype.K;
+  }
+})();
+
+Object.extend(Event, (function() {
+  var cache = Event.cache;
+
+  function getEventID(element) {
+    if (element._prototypeEventID) return element._prototypeEventID[0];
+    arguments.callee.id = arguments.callee.id || 1;
+    return element._prototypeEventID = [++arguments.callee.id];
+  }
+
+  function getDOMEventName(eventName) {
+    if (eventName && eventName.include(':')) return "dataavailable";
+    return eventName;
+  }
+
+  function getCacheForID(id) {
+    return cache[id] = cache[id] || { };
+  }
+
+  function getWrappersForEventName(id, eventName) {
+    var c = getCacheForID(id);
+    return c[eventName] = c[eventName] || [];
+  }
+
+  function createWrapper(element, eventName, handler) {
+    var id = getEventID(element);
+    var c = getWrappersForEventName(id, eventName);
+    if (c.pluck("handler").include(handler)) return false;
+
+    var wrapper = function(event) {
+      if (!Event || !Event.extend ||
+        (event.eventName && event.eventName != eventName))
+          return false;
+
+      Event.extend(event);
+      handler.call(element, event);
+    };
+
+    wrapper.handler = handler;
+    c.push(wrapper);
+    return wrapper;
+  }
+
+  function findWrapper(id, eventName, handler) {
+    var c = getWrappersForEventName(id, eventName);
+    return c.find(function(wrapper) { return wrapper.handler == handler });
+  }
+
+  function destroyWrapper(id, eventName, handler) {
+    var c = getCacheForID(id);
+    if (!c[eventName]) return false;
+    c[eventName] = c[eventName].without(findWrapper(id, eventName, handler));
+  }
+
+  function destroyCache() {
+    for (var id in cache)
+      for (var eventName in cache[id])
+        cache[id][eventName] = null;
+  }
+
+
+  // Internet Explorer needs to remove event handlers on page unload
+  // in order to avoid memory leaks.
+  if (window.attachEvent) {
+    window.attachEvent("onunload", destroyCache);
+  }
+
+  // Safari has a dummy event handler on page unload so that it won't
+  // use its bfcache. Safari <= 3.1 has an issue with restoring the "document"
+  // object when page is returned to via the back button using its bfcache.
+  if (Prototype.Browser.WebKit) {
+    window.addEventListener('unload', Prototype.emptyFunction, false);
+  }
+
+  return {
+    observe: function(element, eventName, handler) {
+      element = $(element);
+      var name = getDOMEventName(eventName);
+
+      var wrapper = createWrapper(element, eventName, handler);
+      if (!wrapper) return element;
+
+      if (element.addEventListener) {
+        element.addEventListener(name, wrapper, false);
+      } else {
+        element.attachEvent("on" + name, wrapper);
+      }
+
+      return element;
+    },
+
+    stopObserving: function(element, eventName, handler) {
+      element = $(element);
+      var id = getEventID(element), name = getDOMEventName(eventName);
+
+      if (!handler && eventName) {
+        getWrappersForEventName(id, eventName).each(function(wrapper) {
+          element.stopObserving(eventName, wrapper.handler);
+        });
+        return element;
+
+      } else if (!eventName) {
+        Object.keys(getCacheForID(id)).each(function(eventName) {
+          element.stopObserving(eventName);
+        });
+        return element;
+      }
+
+      var wrapper = findWrapper(id, eventName, handler);
+      if (!wrapper) return element;
+
+      if (element.removeEventListener) {
+        element.removeEventListener(name, wrapper, false);
+      } else {
+        element.detachEvent("on" + name, wrapper);
+      }
+
+      destroyWrapper(id, eventName, handler);
+
+      return element;
+    },
+
+    fire: function(element, eventName, memo) {
+      element = $(element);
+      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 = "ondataavailable";
+      }
+
+      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);
+
+Element.addMethods({
+  fire:          Event.fire,
+  observe:       Event.observe,
+  stopObserving: Event.stopObserving
+});
+
+Object.extend(document, {
+  fire:          Element.Methods.fire.methodize(),
+  observe:       Element.Methods.observe.methodize(),
+  stopObserving: Element.Methods.stopObserving.methodize(),
+  loaded:        false
+});
+
+(function() {
+  /* Support for the DOMContentLoaded event is based on work by Dan Webb,
+     Matthias Miller, Dean Edwards and John Resig. */
+
+  var timer;
+
+  function fireContentLoadedEvent() {
+    if (document.loaded) return;
+    if (timer) window.clearInterval(timer);
+    document.fire("dom:loaded");
+    document.loaded = true;
+  }
+
+  if (document.addEventListener) {
+    if (Prototype.Browser.WebKit) {
+      timer = window.setInterval(function() {
+        if (/loaded|complete/.test(document.readyState))
+          fireContentLoadedEvent();
+      }, 0);
+
+      Event.observe(window, "load", fireContentLoadedEvent);
+
+    } else {
+      document.addEventListener("DOMContentLoaded",
+        fireContentLoadedEvent, false);
+    }
+
+  } else {
+    document.write("<script id=__onDOMContentLoaded defer src=//:><\/script>");
+    $("__onDOMContentLoaded").onreadystatechange = function() {
+      if (this.readyState == "complete") {
+        this.onreadystatechange = null;
+        fireContentLoadedEvent();
+      }
+    };
+  }
+})();
+/*------------------------------- 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');
+
+// This should be moved to script.aculo.us; notice the deprecated methods
+// further below, that map to the newer Element methods.
+var Position = {
+  // set to true if needed, warning: firefox performance problems
+  // NOT neeeded for page scrolling, only if draggable contained in
+  // scrollable elements
+  includeScrollOffsets: false,
+
+  // must be called before calling withinIncludingScrolloffset, every time the
+  // page is scrolled
+  prepare: function() {
+    this.deltaX =  window.pageXOffset
+                || document.documentElement.scrollLeft
+                || document.body.scrollLeft
+                || 0;
+    this.deltaY =  window.pageYOffset
+                || document.documentElement.scrollTop
+                || document.body.scrollTop
+                || 0;
+  },
+
+  // caches x/y coordinate pair to use with overlap
+  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);
+  },
+
+  // within must be called directly before
+  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;
+  },
+
+  // Deprecation layer -- use newer Element methods now (1.5.2).
+
+  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);
+
+/*--------------------------------------------------------------------------*/
+
+Element.addMethods();
\ No newline at end of file
diff --git a/webinterface/src/web-data/lib/ptwindow/Makefile.am b/webinterface/src/web-data/lib/ptwindow/Makefile.am
deleted file mode 100644 (file)
index e2c71a5..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-installdir = /usr/lib/enigma2/python/Plugins/Extensions/WebInterface/web-data/lib/ptwindow/
-
-SUBDIRS = themes javascripts
diff --git a/webinterface/src/web-data/lib/ptwindow/javascripts/Makefile.am b/webinterface/src/web-data/lib/ptwindow/javascripts/Makefile.am
deleted file mode 100644 (file)
index 7a8df0a..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-installdir = /usr/lib/enigma2/python/Plugins/Extensions/WebInterface/web-data/lib/ptwindow/javascripts/
-
-install_DATA = *.js
diff --git a/webinterface/src/web-data/lib/ptwindow/javascripts/debug.js b/webinterface/src/web-data/lib/ptwindow/javascripts/debug.js
deleted file mode 100644 (file)
index 3d8f338..0000000
+++ /dev/null
@@ -1,137 +0,0 @@
-var debugWindow = null;
-function debug(text, reverse) {
-       if (debugWindow == null)
-               return;
-
-       time = "-"; //new Date();
-       if (reverse) {
-               $('debug').innerHTML = time + " " + text + "<br>"+      $('debug').innerHTML;
-               debugWindow.getContent().scrollTop=0;
-       }
-       else {
-               $('debug').innerHTML +=  time + " " + text + "<br>";
-               debugWindow.getContent().scrollTop=10000; // Far away 
-       }
-}
-
-function hideDebug() {
-       if (debugWindow) {
-               debugWindow.destroy();
-               debugWindow = null;
-       }
-}
-
-function showDebug(bShow) {
- if (debugWindow == null) {
-  debugWindow = new Window('debug_window', {className: 'dialog',width:250, height:100, right:4, bottom:42, zIndex:1000, opacity:1, showEffect: Element.show, resizable: true, title: "Debug"})
-  debugWindow.getContent().innerHTML = "<style>#debug_window .dialog_content {background:#000;}</style> <div id='debug'></div>";
-  date=new Date;
-    date.setMonth(date.getMonth()+3);
-    
-  //debugWindow.setCookie(null, date);
- }
- if( typeof bShow == 'undefined' || bShow)debugWindow.show()
-}
-
-
-function clearDebug() {
-       if (debugWindow == null)
-               return;
-       $('debug').innerHTML = "";
-}
-
-/**
- * document.createElement convenience wrapper
- *
- * The data parameter is an object that must have the "tag" key, containing
- * a string with the tagname of the element to create.  It can optionally have
- * a "children" key which can be: a string, "data" object, or an array of "data"
- * objects to append to this element as children.  Any other key is taken as an
- * attribute to be applied to this tag.
- *
- * Available under an MIT license:
- * http://www.opensource.org/licenses/mit-license.php
- *
- * @param {Object} data The data representing the element to create
- * @return {Element} The element created.
- */
-function $E(data) {
-  var el;
-  if ('string'==typeof data) {
-      el=document.createTextNode(data);
-  } else {
-    //create the element
-    el=document.createElement(data.tag);
-    delete(data.tag);
-
-    //append the children
-    if ('undefined'!=typeof data.children) {
-      if ('string'==typeof data.children ||'undefined'==typeof data.children.length) {
-        //strings and single elements
-        el.appendChild($E(data.children));
-      } else {
-        //arrays of elements
-        for (var i=0, child=null; 'undefined'!=typeof (child=data.children[i]); i++) {
-            el.appendChild($E(child));
-        }
-      }
-      delete(data.children);
-    }
-
-    //any other data is attributes
-    for (attr in data) {
-      el[attr]=data[attr];
-    }
-  }
-
-  return el;
-}
-
-// FROM Nick Hemsley
-var Debug = {
-       inspectOutput: function (container, within) {
-               within = within || debugWindow.getContent()
-               
-               if (debugWindow == null)
-                       return;
-
-               within.appendChild(container)
-       },
-       
-       inspect: function(object) {
-               var cont = $E({tag: "div", className: "inspector"})
-               Debug.inspectObj(object, cont)
-               debugWindow.getContent().appendChild(cont)
-       },
-       
-       inspectObj: function (object, container) {
-               for (prop in object) {
-                       Debug.inspectOutput(Debug.inspectable(object, prop), container)
-               }
-       },
-       
-       inspectable: function(object, prop) {
-               cont = $E({tag: 'div', className: 'inspectable', children: [prop + " value: " + object[prop] ]})
-               cont.toInspect = object[prop]
-               Event.observe(cont, 'click', Debug.inspectClicked, false)
-               return cont
-       },
-       
-       inspectClicked: function(e) {
-               Debug.inspectContained(Event.element(e))
-               Event.stop(e)
-       },
-       
-       inspectContained: function(container) {
-               if (container.opened) {
-                       container.parentNode.removeChild(container.opened)
-                       delete(container.opened)
-               } else {
-                       sibling = container.parentNode.insertBefore($E({tag: "div", className: "child"}), container.nextSibling)
-                       if (container.toInspect)
-                               Debug.inspectObj(container.toInspect, sibling)
-                       container.opened = sibling
-               }
-       }
-}
-var inspect = Debug.inspect;
diff --git a/webinterface/src/web-data/lib/ptwindow/javascripts/effects.js b/webinterface/src/web-data/lib/ptwindow/javascripts/effects.js
deleted file mode 100644 (file)
index 8a4a4f9..0000000
+++ /dev/null
@@ -1,1094 +0,0 @@
-// script.aculo.us effects.js v1.7.1_beta1, Mon Mar 12 14:40:50 +0100 2007
-
-// Copyright (c) 2005-2007 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) { }
-};
-
-/*--------------------------------------------------------------------------*/
-
-Array.prototype.call = function() {
-  var args = arguments;
-  this.each(function(f){ f.apply(this, args) });
-}
-
-/*--------------------------------------------------------------------------*/
-
-var Effect = {
-  _elementDoesNotExistError: {
-    name: 'ElementDoesNotExistError',
-    message: 'The specified DOM element does not exist, but is required for this effect to operate'
-  },
-  tagifyText: function(element) {
-    if(typeof Builder == 'undefined')
-      throw("Effect.tagifyText requires including script.aculo.us' builder.js library");
-      
-    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(
-            Builder.node('span',{style: tagifyStyle},
-              character == ' ' ? String.fromCharCode(160) : character), 
-              child);
-        });
-        Element.remove(child);
-      }
-    });
-  },
-  multiple: function(element, effect) {
-    var elements;
-    if(((typeof element == 'object') || 
-        (typeof element == 'function')) && 
-       (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);
-  }
-};
-
-var Effect2 = Effect; // deprecated
-
-/* ------------- transitions ------------- */
-
-Effect.Transitions = {
-  linear: Prototype.K,
-  sinoidal: function(pos) {
-    return (-Math.cos(pos*Math.PI)/2) + 0.5;
-  },
-  reverse: function(pos) {
-    return 1-pos;
-  },
-  flicker: function(pos) {
-    var pos = ((-Math.cos(pos*Math.PI)/4) + 0.75) + Math.random()/4;
-    return (pos > 1 ? 1 : pos);
-  },
-  wobble: function(pos) {
-    return (-Math.cos(pos*Math.PI*(9*pos))/2) + 0.5;
-  },
-  pulse: function(pos, pulses) { 
-    pulses = pulses || 5; 
-    return (
-      Math.round((pos % (1/pulses)) * pulses) == 0 ? 
-            ((pos * pulses * 2) - Math.floor(pos * pulses * 2)) : 
-        1 - ((pos * pulses * 2) - Math.floor(pos * pulses * 2))
-      );
-  },
-  none: function(pos) {
-    return 0;
-  },
-  full: function(pos) {
-    return 1;
-  }
-};
-
-/* ------------- core effects ------------- */
-
-Effect.ScopedQueue = Class.create();
-Object.extend(Object.extend(Effect.ScopedQueue.prototype, 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 = (typeof effect.options.queue == 'string') ? 
-      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(typeof queueName != 'string') return queueName;
-    
-    if(!this.instances[queueName])
-      this.instances[queueName] = new Effect.ScopedQueue();
-      
-    return this.instances[queueName];
-  }
-}
-Effect.Queue = Effect.Queues.get('global');
-
-Effect.DefaultOptions = {
-  transition: Effect.Transitions.sinoidal,
-  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'
-}
-
-Effect.Base = function() {};
-Effect.Base.prototype = {
-  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.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;
-    
-    eval('this.render = function(pos){ '+
-      'if(this.state=="idle"){this.state="running";'+
-      codeForEvent(options,'beforeSetup')+
-      (this.setup ? 'this.setup();':'')+ 
-      codeForEvent(options,'afterSetup')+
-      '};if(this.state=="running"){'+
-      'pos=this.options.transition(pos)*'+this.fromToDelta+'+'+this.options.from+';'+
-      'this.position=pos;'+
-      codeForEvent(options,'beforeUpdate')+
-      (this.update ? 'this.update(pos);':'')+
-      codeForEvent(options,'afterUpdate')+
-      '}}');
-    
-    this.event('beforeStart');
-    if(!this.options.sync)
-      Effect.Queues.get(typeof this.options.queue == 'string' ? 
-        '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 = Math.round(pos * this.totalFrames);
-      if(frame > this.currentFrame) {
-        this.render(pos);
-        this.currentFrame = frame;
-      }
-    }
-  },
-  cancel: function() {
-    if(!this.options.sync)
-      Effect.Queues.get(typeof this.options.queue == 'string' ? 
-        '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(typeof this[property] != 'function') data[property] = this[property];
-    return '#<Effect:' + data.inspect() + ',options:' + $H(this.options).inspect() + '>';
-  }
-}
-
-Effect.Parallel = Class.create();
-Object.extend(Object.extend(Effect.Parallel.prototype, Effect.Base.prototype), {
-  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.Event = Class.create();
-Object.extend(Object.extend(Effect.Event.prototype, Effect.Base.prototype), {
-  initialize: function() {
-    var options = Object.extend({
-      duration: 0
-    }, arguments[0] || {});
-    this.start(options);
-  },
-  update: Prototype.emptyFunction
-});
-
-Effect.Opacity = Class.create();
-Object.extend(Object.extend(Effect.Opacity.prototype, Effect.Base.prototype), {
-  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();
-Object.extend(Object.extend(Effect.Move.prototype, Effect.Base.prototype), {
-  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() {
-    // Bug in Opera: Opera returns the "real" position of a static element or
-    // relative element that does not have top/left explicitly set.
-    // ==> Always set top and left for position relative elements in your stylesheets 
-    // (to 0 if you do not need them) 
-    this.element.makePositioned();
-    this.originalLeft = parseFloat(this.element.getStyle('left') || '0');
-    this.originalTop  = parseFloat(this.element.getStyle('top')  || '0');
-    if(this.options.mode == 'absolute') {
-      // absolute movement, so we need to calc deltaX and deltaY
-      this.options.x = this.options.x - this.originalLeft;
-      this.options.y = this.options.y - this.originalTop;
-    }
-  },
-  update: function(position) {
-    this.element.setStyle({
-      left: Math.round(this.options.x  * position + this.originalLeft) + 'px',
-      top:  Math.round(this.options.y  * position + this.originalTop)  + '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();
-Object.extend(Object.extend(Effect.Scale.prototype, Effect.Base.prototype), {
-  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 = Math.round(width) + 'px';
-    if(this.options.scaleY) d.height = Math.round(height) + '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();
-Object.extend(Object.extend(Effect.Highlight.prototype, Effect.Base.prototype), {
-  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+(Math.round(this._base[i]+(this._delta[i]*position)).toColorPart()); }.bind(this)) });
-  },
-  finish: function() {
-    this.element.setStyle(Object.extend(this.oldStyle, {
-      backgroundColor: this.options.restorecolor
-    }));
-  }
-});
-
-Effect.ScrollTo = Class.create();
-Object.extend(Object.extend(Effect.ScrollTo.prototype, Effect.Base.prototype), {
-  initialize: function(element) {
-    this.element = $(element);
-    this.start(arguments[1] || {});
-  },
-  setup: function() {
-    Position.prepare();
-    var offsets = Position.cumulativeOffset(this.element);
-    if(this.options.offset) offsets[1] += this.options.offset;
-    var max = window.innerHeight ? 
-      window.height - window.innerHeight :
-      document.body.scrollHeight - 
-        (document.documentElement.clientHeight ? 
-          document.documentElement.clientHeight : document.body.clientHeight);
-    this.scrollStart = Position.deltaY;
-    this.delta = (offsets[1] > max ? max : offsets[1]) - this.scrollStart;
-  },
-  update: function(position) {
-    Position.prepare();
-    window.scrollTo(Position.deltaX, 
-      this.scrollStart + (position*this.delta));
-  }
-});
-
-/* ------------- 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 oldStyle = {
-    top: element.getStyle('top'),
-    left: element.getStyle('left') };
-    return new Effect.Move(element, 
-      { x:  20, y: 0, duration: 0.05, afterFinishInternal: function(effect) {
-    new Effect.Move(effect.element,
-      { x: -40, y: 0, duration: 0.1,  afterFinishInternal: function(effect) {
-    new Effect.Move(effect.element,
-      { x:  40, y: 0, duration: 0.1,  afterFinishInternal: function(effect) {
-    new Effect.Move(effect.element,
-      { x: -40, y: 0, duration: 0.1,  afterFinishInternal: function(effect) {
-    new Effect.Move(effect.element,
-      { x:  40, y: 0, duration: 0.1,  afterFinishInternal: function(effect) {
-    new Effect.Move(effect.element,
-      { x: -20, y: 0, duration: 0.05, 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');
-  return new Effect.Scale(element, window.opera ? 0 : 1,
-   Object.extend({ scaleContent: false, 
-    scaleX: false, 
-    scaleMode: 'box',
-    scaleFrom: 100,
-    restoreAfterFinish: true,
-    beforeStartInternal: 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().setStyle({bottom: oldInnerBottom});
-      effect.element.down().undoPositioned();
-    }
-   }, 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] || {};
-  var oldOpacity = element.getInlineOpacity();
-  var transition = options.transition || Effect.Transitions.sinoidal;
-  var reverser   = function(pos){ return transition(1-Effect.Transitions.pulse(pos, options.pulses)) };
-  reverser.bind(transition);
-  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();
-Object.extend(Object.extend(Effect.Morph.prototype, Effect.Base.prototype), {
-  initialize: function(element) {
-    this.element = $(element);
-    if(!this.element) throw(Effect._elementDoesNotExistError);
-    var options = Object.extend({
-      style: {}
-    }, arguments[1] || {});
-    if (typeof options.style == 'string') {
-      if(options.style.indexOf(':') == -1) {
-        var cssText = '', selector = '.' + options.style;
-        $A(document.styleSheets).reverse().each(function(styleSheet) {
-          if (styleSheet.cssRules) cssRules = styleSheet.cssRules;
-          else if (styleSheet.rules) cssRules = styleSheet.rules;
-          $A(cssRules).reverse().each(function(rule) {
-            if (selector == rule.selectorText) {
-              cssText = rule.style.cssText;
-              throw $break;
-            }
-          });
-          if (cssText) throw $break;
-        });
-        this.style = cssText.parseStyle();
-        options.afterFinishInternal = function(effect){
-          effect.element.addClassName(effect.options.style);
-          effect.transforms.each(function(transform) {
-            if(transform.style != 'opacity')
-              effect.element.style[transform.style] = '';
-          });
-        }
-      } else this.style = options.style.parseStyle();
-    } else this.style = $H(options.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 + Math.round(
-          ((transform.targetValue - transform.originalValue) * position) * 1000)/1000 + transform.unit;
-    this.element.setStyle(style, true);
-  }
-});
-
-Effect.Transform = Class.create();
-Object.extend(Effect.Transform.prototype, {
-  initialize: function(tracks){
-    this.tracks  = [];
-    this.options = arguments[1] || {};
-    this.addTracks(tracks);
-  },
-  addTracks: function(tracks){
-    tracks.each(function(track){
-      var data = $H(track).values().first();
-      this.tracks.push($H({
-        ids:     $H(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 elements = [$(track.ids) || $$(track.ids)].flatten();
-        return elements.map(function(e){ return new track.effect(e, Object.extend({ sync:true }, track.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.prototype.parseStyle = function(){
-  var element = document.createElement('div');
-  element.innerHTML = '<div style="' + this + '"></div>';
-  var style = element.childNodes[0].style, styleRules = $H();
-  
-  Element.CSS_PROPERTIES.each(function(property){
-    if(style[property]) styleRules[property] = style[property]; 
-  });
-  if(Prototype.Browser.IE && this.indexOf('opacity') > -1) {
-    styleRules.opacity = this.match(/opacity:\s*((?:0|1)?(?:\.\d*)?)/)[1];
-  }
-  return styleRules;
-};
-
-Element.morph = function(element, style) {
-  new Effect.Morph(element, Object.extend({ style: style }, arguments[2] || {}));
-  return element;
-};
-
-['getInlineOpacity','forceRerendering','setContentZoom',
- 'collectTextNodes','collectTextNodesIgnoreClass','morph'].each( 
-  function(f) { Element.Methods[f] = Element[f]; }
-);
-
-Element.Methods.visualEffect = function(element, effect, options) {
-  s = effect.dasherize().camelize();
-  effect_class = s.charAt(0).toUpperCase() + s.substring(1);
-  new Effect[effect_class](element, options);
-  return $(element);
-};
-
-Element.addMethods();
\ No newline at end of file
diff --git a/webinterface/src/web-data/lib/ptwindow/javascripts/extended_debug.js b/webinterface/src/web-data/lib/ptwindow/javascripts/extended_debug.js
deleted file mode 100644 (file)
index 2b935b1..0000000
+++ /dev/null
@@ -1,113 +0,0 @@
-var commandHistory;
-var historyIndex;
-
-function showExtendedDebug() {
-       if (debugWindow != null) {
-         hideDebug();
-  }
-  
-       if (debugWindow == null) {
-               commandHistory = new Array();
-               historyIndex = 0;
-               
-               debugWindow = new Window('debug_window', {className: 'dialog',width:250, height:100, right:4, minWidth:250, bottom:42, zIndex:1000, opacity:1, showEffect: Element.show, resizable: true, title: "Debug"})
-               debugWindow.getContent().innerHTML = "<style>#debug_window .dialog_content {background:#000;}</style> <div font='monaco' id='debug' style='padding:3px;color:#0F0;font-family:monaco'></div>";
-
-               //create hourglass icon and attach events to it.
-               var cont = "<div id=\"debug_window_inspect\" style=\"width: 15px; height: 15px; background: transparent url(themes/default/inspect.gif) no-repeat 0 0; position:absolute; top:5px; left:70px; cursor:pointer; z-index:3000;\"></div>";
-
-               new Insertion.After('debug_window_maximize', cont);
-               Event.observe('debug_window_inspect', 'click', enterInspectionMode, false);
-
-               //create command text box
-               cont = "Eval:<input id=\"debug_window_command\" type=\"textbox\" style=\"width:150px; height: 12px; color: black;\">"
-               debugWindow.setStatusBar(cont);
-
-               Event.observe('debug_window_command', 'mousedown', donothing);
-               Event.observe('debug_window_command', 'keypress', evalJS, false);
-       }
-       debugWindow.show();             
-}
-
-function donothing(evt){
-               Field.activate('debug_window_command');
-               return false;
-}
-
-function evalJS(evt){
-       if(evt.keyCode == Event.KEY_RETURN){
-               var js = $F('debug_window_command');
-               try{
-                       var ret = eval(js);
-                       if(ret != null)
-                               debug(ret);
-               }catch(e){
-                       debug(e);
-               }
-               $('debug_window_command').value = '';
-
-               Field.activate('debug_window_command');
-               commandHistory.push(js);
-               historyIndex = 0;
-       }
-
-       if(evt.keyCode == Event.KEY_UP){
-               if(commandHistory.length > historyIndex){
-                       historyIndex++;
-                       var js = commandHistory[commandHistory.length-historyIndex];
-                       $('debug_window_command').value = js;
-                       Event.stop(evt);
-                       Field.activate('debug_window_command');
-               }
-       }
-
-       if(evt.keyCode == Event.KEY_DOWN){
-               if(commandHistory.length >= historyIndex && historyIndex > 1){
-                       historyIndex--;
-                       var js = commandHistory[commandHistory.length-historyIndex];
-                       $('debug_window_command').value = js;
-                       Event.stop(evt);
-                       Field.activate('debug_window_command');
-               }
-       }       
-}
-
-function enterInspectionMode(evt){
-       //stop observing magnifying glass
-       Event.stopObserving('debug_window_inspect', 'click', enterInspectionMode, false);
-       //change pointer
-       document.body.style.cursor='help';
-       //start observing mouse clicks
-       Event.observe(window, 'click', inspectItem, false);             
-}
-
-function inspectItem(evt){
-       // the element that triggered the event
-       var element = Event.element(evt);
-       if(element.id!="debug_window_inspect"){
-               clearDebug()
-               //change pointer
-               document.body.style.cursor='default';
-               debug(element.id);
-               inspect(element);
-               //stop observing mouse clicks
-               Event.stopObserving(window, 'click', inspectItem, false);
-               //alert('doing something');
-               //start observing mag
-               Event.observe('debug_window_inspect', 'click', enterInspectionMode, false);
-       }
-}
-
-function clearDebug() {
-       var win = $('debug');
-       if (win == null)
-               return;
-               
-       win.innerHTML=" ";
-       //clear inspections too
-       var divs = document.getElementsByClassName('inspector');
-       divs.each(function(div){
-               Element.remove(div);
-       });
-}
-
diff --git a/webinterface/src/web-data/lib/ptwindow/javascripts/prototype.js b/webinterface/src/web-data/lib/ptwindow/javascripts/prototype.js
deleted file mode 100644 (file)
index 3217cea..0000000
+++ /dev/null
@@ -1,3270 +0,0 @@
-/*  Prototype JavaScript framework, version 1.5.1_rc3
- *  (c) 2005-2007 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.5.1_rc3',
-
-  Browser: {
-    IE:     !!(window.attachEvent && !window.opera),
-    Opera:  !!window.opera,
-    WebKit: navigator.userAgent.indexOf('AppleWebKit/') > -1,
-    Gecko:  navigator.userAgent.indexOf('Gecko') > -1 && navigator.userAgent.indexOf('KHTML') == -1
-  },
-
-  BrowserFeatures: {
-    XPath: !!document.evaluate,
-    ElementExtensions: !!window.HTMLElement,
-    SpecificElementExtensions:
-      (document.createElement('div').__proto__ !==
-       document.createElement('form').__proto__)
-  },
-
-  ScriptFragment: '<script[^>]*>([\u0001-\uFFFF]*?)</script>',
-  JSONFilter: /^\/\*-secure-\s*(.*)\s*\*\/\s*$/,
-
-  emptyFunction: function() { },
-  K: function(x) { return x }
-}
-
-var Class = {
-  create: function() {
-    return function() {
-      this.initialize.apply(this, arguments);
-    }
-  }
-}
-
-var Abstract = new Object();
-
-Object.extend = function(destination, source) {
-  for (var property in source) {
-    destination[property] = source[property];
-  }
-  return destination;
-}
-
-Object.extend(Object, {
-  inspect: function(object) {
-    try {
-      if (object === undefined) return 'undefined';
-      if (object === null) return 'null';
-      return object.inspect ? object.inspect() : object.toString();
-    } catch (e) {
-      if (e instanceof RangeError) return '...';
-      throw e;
-    }
-  },
-
-  toJSON: function(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 (object.ownerDocument === document) return;
-    var results = [];
-    for (var property in object) {
-      var value = Object.toJSON(object[property]);
-      if (value !== undefined)
-        results.push(property.toJSON() + ': ' + value);
-    }
-    return '{' + results.join(', ') + '}';
-  },
-
-  keys: function(object) {
-    var keys = [];
-    for (var property in object)
-      keys.push(property);
-    return keys;
-  },
-
-  values: function(object) {
-    var values = [];
-    for (var property in object)
-      values.push(object[property]);
-    return values;
-  },
-
-  clone: function(object) {
-    return Object.extend({}, object);
-  }
-});
-
-Function.prototype.bind = function() {
-  var __method = this, args = $A(arguments), object = args.shift();
-  return function() {
-    return __method.apply(object, args.concat($A(arguments)));
-  }
-}
-
-Function.prototype.bindAsEventListener = function(object) {
-  var __method = this, args = $A(arguments), object = args.shift();
-  return function(event) {
-    return __method.apply(object, [( event || window.event)].concat(args).concat($A(arguments)));
-  }
-}
-
-Object.extend(Number.prototype, {
-  toColorPart: function() {
-    return this.toPaddedString(2, 16);
-  },
-
-  succ: function() {
-    return this + 1;
-  },
-
-  times: function(iterator) {
-    $R(0, this, true).each(iterator);
-    return this;
-  },
-
-  toPaddedString: function(length, radix) {
-    var string = this.toString(radix || 10);
-    return '0'.times(length - string.length) + string;
-  },
-
-  toJSON: function() {
-    return isFinite(this) ? this.toString() : 'null';
-  }
-});
-
-Date.prototype.toJSON = function() {
-  return '"' + this.getFullYear() + '-' +
-    (this.getMonth() + 1).toPaddedString(2) + '-' +
-    this.getDate().toPaddedString(2) + 'T' +
-    this.getHours().toPaddedString(2) + ':' +
-    this.getMinutes().toPaddedString(2) + ':' +
-    this.getSeconds().toPaddedString(2) + '"';
-};
-
-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 PeriodicalExecuter = Class.create();
-PeriodicalExecuter.prototype = {
-  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);
-  },
-
-  stop: function() {
-    if (!this.timer) return;
-    clearInterval(this.timer);
-    this.timer = null;
-  },
-
-  onTimerEvent: function() {
-    if (!this.currentlyExecuting) {
-      try {
-        this.currentlyExecuting = true;
-        this.callback(this);
-      } finally {
-        this.currentlyExecuting = false;
-      }
-    }
-  }
-}
-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, {
-  gsub: function(pattern, replacement) {
-    var result = '', source = this, match;
-    replacement = arguments.callee.prepareReplacement(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;
-  },
-
-  sub: function(pattern, replacement, count) {
-    replacement = this.gsub.prepareReplacement(replacement);
-    count = count === undefined ? 1 : count;
-
-    return this.gsub(pattern, function(match) {
-      if (--count < 0) return match[0];
-      return replacement(match);
-    });
-  },
-
-  scan: function(pattern, iterator) {
-    this.gsub(pattern, iterator);
-    return this;
-  },
-
-  truncate: function(length, truncation) {
-    length = length || 30;
-    truncation = truncation === undefined ? '...' : truncation;
-    return this.length > length ?
-      this.slice(0, length - truncation.length) + truncation : this;
-  },
-
-  strip: function() {
-    return this.replace(/^\s+/, '').replace(/\s+$/, '');
-  },
-
-  stripTags: function() {
-    return this.replace(/<\/?[^>]+>/gi, '');
-  },
-
-  stripScripts: function() {
-    return this.replace(new RegExp(Prototype.ScriptFragment, 'img'), '');
-  },
-
-  extractScripts: function() {
-    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];
-    });
-  },
-
-  evalScripts: function() {
-    return this.extractScripts().map(function(script) { return eval(script) });
-  },
-
-  escapeHTML: function() {
-    var self = arguments.callee;
-    self.text.data = this;
-    return self.div.innerHTML;
-  },
-
-  unescapeHTML: function() {
-    var div = document.createElement('div');
-    div.innerHTML = this.stripTags();
-    return div.childNodes[0] ? (div.childNodes.length > 1 ?
-      $A(div.childNodes).inject('', function(memo, node) { return memo+node.nodeValue }) :
-      div.childNodes[0].nodeValue) : '';
-  },
-
-  toQueryParams: function(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 (hash[key].constructor != Array) hash[key] = [hash[key]];
-          hash[key].push(value);
-        }
-        else hash[key] = value;
-      }
-      return hash;
-    });
-  },
-
-  toArray: function() {
-    return this.split('');
-  },
-
-  succ: function() {
-    return this.slice(0, this.length - 1) +
-      String.fromCharCode(this.charCodeAt(this.length - 1) + 1);
-  },
-
-  times: function(count) {
-    var result = '';
-    for (var i = 0; i < count; i++) result += this;
-    return result;
-  },
-
-  camelize: function() {
-    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;
-  },
-
-  capitalize: function() {
-    return this.charAt(0).toUpperCase() + this.substring(1).toLowerCase();
-  },
-
-  underscore: function() {
-    return this.gsub(/::/, '/').gsub(/([A-Z]+)([A-Z][a-z])/,'#{1}_#{2}').gsub(/([a-z\d])([A-Z])/,'#{1}_#{2}').gsub(/-/,'_').toLowerCase();
-  },
-
-  dasherize: function() {
-    return this.gsub(/_/,'-');
-  },
-
-  inspect: function(useDoubleQuotes) {
-    var escapedString = this.gsub(/[\x00-\x1f\\]/, function(match) {
-      var character = String.specialChar[match[0]];
-      return character ? character : '\\u00' + match[0].charCodeAt().toPaddedString(2, 16);
-    });
-    if (useDoubleQuotes) return '"' + escapedString.replace(/"/g, '\\"') + '"';
-    return "'" + escapedString.replace(/'/g, '\\\'') + "'";
-  },
-
-  toJSON: function() {
-    return this.inspect(true);
-  },
-
-  unfilterJSON: function(filter) {
-    return this.sub(filter || Prototype.JSONFilter, '#{1}');
-  },
-
-  evalJSON: function(sanitize) {
-    var json = this.unfilterJSON();
-    try {
-      if (!sanitize || (/^("(\\.|[^"\\\n\r])*?"|[,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t])+?$/.test(json)))
-        return eval('(' + json + ')');
-    } catch (e) { }
-    throw new SyntaxError('Badly formed JSON string: ' + this.inspect());
-  },
-
-  include: function(pattern) {
-    return this.indexOf(pattern) > -1;
-  },
-
-  startsWith: function(pattern) {
-    return this.indexOf(pattern) === 0;
-  },
-
-  endsWith: function(pattern) {
-    var d = this.length - pattern.length;
-    return d >= 0 && this.lastIndexOf(pattern) === d;
-  },
-
-  empty: function() {
-    return this == '';
-  },
-
-  blank: function() {
-    return /^\s*$/.test(this);
-  }
-});
-
-if (Prototype.Browser.WebKit || Prototype.Browser.IE) Object.extend(String.prototype, {
-  escapeHTML: function() {
-    return this.replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;');
-  },
-  unescapeHTML: function() {
-    return this.replace(/&amp;/g,'&').replace(/&lt;/g,'<').replace(/&gt;/g,'>');
-  }
-});
-
-String.prototype.gsub.prepareReplacement = function(replacement) {
-  if (typeof replacement == 'function') return replacement;
-  var template = new Template(replacement);
-  return function(match) { return template.evaluate(match) };
-}
-
-String.prototype.parseQuery = String.prototype.toQueryParams;
-
-Object.extend(String.prototype.escapeHTML, {
-  div:  document.createElement('div'),
-  text: document.createTextNode('')
-});
-
-with (String.prototype.escapeHTML) div.appendChild(text);
-
-var Template = Class.create();
-Template.Pattern = /(^|.|\r|\n)(#\{(.*?)\})/;
-Template.prototype = {
-  initialize: function(template, pattern) {
-    this.template = template.toString();
-    this.pattern  = pattern || Template.Pattern;
-  },
-
-  evaluate: function(object) {
-    return this.template.gsub(this.pattern, function(match) {
-      var before = match[1];
-      if (before == '\\') return match[2];
-      return before + String.interpret(object[match[3]]);
-    });
-  }
-}
-
-var $break    = new Object();
-var $continue = new Object();
-
-var Enumerable = {
-  each: function(iterator) {
-    var index = 0;
-    try {
-      this._each(function(value) {
-        iterator(value, index++);
-      });
-    } catch (e) {
-      if (e != $break) throw e;
-    }
-    return this;
-  },
-
-  eachSlice: function(number, iterator) {
-    var index = -number, slices = [], array = this.toArray();
-    while ((index += number) < array.length)
-      slices.push(array.slice(index, index+number));
-    return slices.map(iterator);
-  },
-
-  all: function(iterator) {
-    var result = true;
-    this.each(function(value, index) {
-      result = result && !!(iterator || Prototype.K)(value, index);
-      if (!result) throw $break;
-    });
-    return result;
-  },
-
-  any: function(iterator) {
-    var result = false;
-    this.each(function(value, index) {
-      if (result = !!(iterator || Prototype.K)(value, index))
-        throw $break;
-    });
-    return result;
-  },
-
-  collect: function(iterator) {
-    var results = [];
-    this.each(function(value, index) {
-      results.push((iterator || Prototype.K)(value, index));
-    });
-    return results;
-  },
-
-  detect: function(iterator) {
-    var result;
-    this.each(function(value, index) {
-      if (iterator(value, index)) {
-        result = value;
-        throw $break;
-      }
-    });
-    return result;
-  },
-
-  findAll: function(iterator) {
-    var results = [];
-    this.each(function(value, index) {
-      if (iterator(value, index))
-        results.push(value);
-    });
-    return results;
-  },
-
-  grep: function(pattern, iterator) {
-    var results = [];
-    this.each(function(value, index) {
-      var stringValue = value.toString();
-      if (stringValue.match(pattern))
-        results.push((iterator || Prototype.K)(value, index));
-    })
-    return results;
-  },
-
-  include: function(object) {
-    var found = false;
-    this.each(function(value) {
-      if (value == object) {
-        found = true;
-        throw $break;
-      }
-    });
-    return found;
-  },
-
-  inGroupsOf: function(number, fillWith) {
-    fillWith = fillWith === undefined ? null : fillWith;
-    return this.eachSlice(number, function(slice) {
-      while(slice.length < number) slice.push(fillWith);
-      return slice;
-    });
-  },
-
-  inject: function(memo, iterator) {
-    this.each(function(value, index) {
-      memo = iterator(memo, value, index);
-    });
-    return memo;
-  },
-
-  invoke: function(method) {
-    var args = $A(arguments).slice(1);
-    return this.map(function(value) {
-      return value[method].apply(value, args);
-    });
-  },
-
-  max: function(iterator) {
-    var result;
-    this.each(function(value, index) {
-      value = (iterator || Prototype.K)(value, index);
-      if (result == undefined || value >= result)
-        result = value;
-    });
-    return result;
-  },
-
-  min: function(iterator) {
-    var result;
-    this.each(function(value, index) {
-      value = (iterator || Prototype.K)(value, index);
-      if (result == undefined || value < result)
-        result = value;
-    });
-    return result;
-  },
-
-  partition: function(iterator) {
-    var trues = [], falses = [];
-    this.each(function(value, index) {
-      ((iterator || Prototype.K)(value, index) ?
-        trues : falses).push(value);
-    });
-    return [trues, falses];
-  },
-
-  pluck: function(property) {
-    var results = [];
-    this.each(function(value, index) {
-      results.push(value[property]);
-    });
-    return results;
-  },
-
-  reject: function(iterator) {
-    var results = [];
-    this.each(function(value, index) {
-      if (!iterator(value, index))
-        results.push(value);
-    });
-    return results;
-  },
-
-  sortBy: function(iterator) {
-    return this.map(function(value, index) {
-      return {value: value, criteria: iterator(value, index)};
-    }).sort(function(left, right) {
-      var a = left.criteria, b = right.criteria;
-      return a < b ? -1 : a > b ? 1 : 0;
-    }).pluck('value');
-  },
-
-  toArray: function() {
-    return this.map();
-  },
-
-  zip: function() {
-    var iterator = Prototype.K, args = $A(arguments);
-    if (typeof args.last() == 'function')
-      iterator = args.pop();
-
-    var collections = [this].concat(args).map($A);
-    return this.map(function(value, index) {
-      return iterator(collections.pluck(index));
-    });
-  },
-
-  size: function() {
-    return this.toArray().length;
-  },
-
-  inspect: function() {
-    return '#<Enumerable:' + this.toArray().inspect() + '>';
-  }
-}
-
-Object.extend(Enumerable, {
-  map:     Enumerable.collect,
-  find:    Enumerable.detect,
-  select:  Enumerable.findAll,
-  member:  Enumerable.include,
-  entries: Enumerable.toArray
-});
-var $A = Array.from = function(iterable) {
-  if (!iterable) return [];
-  if (iterable.toArray) {
-    return iterable.toArray();
-  } else {
-    var results = [];
-    for (var i = 0, length = iterable.length; i < length; i++)
-      results.push(iterable[i]);
-    return results;
-  }
-}
-
-if (Prototype.Browser.WebKit) {
-  $A = Array.from = function(iterable) {
-    if (!iterable) return [];
-    if (!(typeof iterable == 'function' && iterable == '[object NodeList]') &&
-      iterable.toArray) {
-      return iterable.toArray();
-    } else {
-      var results = [];
-      for (var i = 0, length = iterable.length; i < length; i++)
-        results.push(iterable[i]);
-      return results;
-    }
-  }
-}
-
-Object.extend(Array.prototype, Enumerable);
-
-if (!Array.prototype._reverse)
-  Array.prototype._reverse = Array.prototype.reverse;
-
-Object.extend(Array.prototype, {
-  _each: function(iterator) {
-    for (var i = 0, length = this.length; i < length; i++)
-      iterator(this[i]);
-  },
-
-  clear: function() {
-    this.length = 0;
-    return this;
-  },
-
-  first: function() {
-    return this[0];
-  },
-
-  last: function() {
-    return this[this.length - 1];
-  },
-
-  compact: function() {
-    return this.select(function(value) {
-      return value != null;
-    });
-  },
-
-  flatten: function() {
-    return this.inject([], function(array, value) {
-      return array.concat(value && value.constructor == Array ?
-        value.flatten() : [value]);
-    });
-  },
-
-  without: function() {
-    var values = $A(arguments);
-    return this.select(function(value) {
-      return !values.include(value);
-    });
-  },
-
-  indexOf: function(object) {
-    for (var i = 0, length = this.length; i < length; i++)
-      if (this[i] == object) return i;
-    return -1;
-  },
-
-  reverse: function(inline) {
-    return (inline !== false ? this : this.toArray())._reverse();
-  },
-
-  reduce: function() {
-    return this.length > 1 ? this : this[0];
-  },
-
-  uniq: function(sorted) {
-    return this.inject([], function(array, value, index) {
-      if (0 == index || (sorted ? array.last() != value : !array.include(value)))
-        array.push(value);
-      return array;
-    });
-  },
-
-  clone: function() {
-    return [].concat(this);
-  },
-
-  size: function() {
-    return this.length;
-  },
-
-  inspect: function() {
-    return '[' + this.map(Object.inspect).join(', ') + ']';
-  },
-
-  toJSON: function() {
-    var results = [];
-    this.each(function(object) {
-      var value = Object.toJSON(object);
-      if (value !== undefined) results.push(value);
-    });
-    return '[' + results.join(', ') + ']';
-  }
-});
-
-Array.prototype.toArray = Array.prototype.clone;
-
-function $w(string) {
-  string = string.strip();
-  return string ? string.split(/\s+/) : [];
-}
-
-if (Prototype.Browser.Opera){
-  Array.prototype.concat = function() {
-    var array = [];
-    for (var i = 0, length = this.length; i < length; i++) array.push(this[i]);
-    for (var i = 0, length = arguments.length; i < length; i++) {
-      if (arguments[i].constructor == Array) {
-        for (var j = 0, arrayLength = arguments[i].length; j < arrayLength; j++)
-          array.push(arguments[i][j]);
-      } else {
-        array.push(arguments[i]);
-      }
-    }
-    return array;
-  }
-}
-var Hash = function(object) {
-  if (object instanceof Hash) this.merge(object);
-  else Object.extend(this, object || {});
-};
-
-Object.extend(Hash, {
-  toQueryString: function(obj) {
-    var parts = [];
-    parts.add = arguments.callee.addPair;
-
-    this.prototype._each.call(obj, function(pair) {
-      if (!pair.key) return;
-      var value = pair.value;
-
-      if (value && typeof value == 'object') {
-        if (value.constructor == Array) value.each(function(value) {
-          parts.add(pair.key, value);
-        });
-        return;
-      }
-      parts.add(pair.key, value);
-    });
-
-    return parts.join('&');
-  },
-
-  toJSON: function(object) {
-    var results = [];
-    this.prototype._each.call(object, function(pair) {
-      var value = Object.toJSON(pair.value);
-      if (value !== undefined) results.push(pair.key.toJSON() + ': ' + value);
-    });
-    return '{' + results.join(', ') + '}';
-  }
-});
-
-Hash.toQueryString.addPair = function(key, value, prefix) {
-  key = encodeURIComponent(key);
-  if (value === undefined) this.push(key);
-  else this.push(key + '=' + (value == null ? '' : encodeURIComponent(value)));
-}
-
-Object.extend(Hash.prototype, Enumerable);
-Object.extend(Hash.prototype, {
-  _each: function(iterator) {
-    for (var key in this) {
-      var value = this[key];
-      if (value && value == Hash.prototype[key]) continue;
-
-      var pair = [key, value];
-      pair.key = key;
-      pair.value = value;
-      iterator(pair);
-    }
-  },
-
-  keys: function() {
-    return this.pluck('key');
-  },
-
-  values: function() {
-    return this.pluck('value');
-  },
-
-  merge: function(hash) {
-    return $H(hash).inject(this, function(mergedHash, pair) {
-      mergedHash[pair.key] = pair.value;
-      return mergedHash;
-    });
-  },
-
-  remove: function() {
-    var result;
-    for(var i = 0, length = arguments.length; i < length; i++) {
-      var value = this[arguments[i]];
-      if (value !== undefined){
-        if (result === undefined) result = value;
-        else {
-          if (result.constructor != Array) result = [result];
-          result.push(value)
-        }
-      }
-      delete this[arguments[i]];
-    }
-    return result;
-  },
-
-  toQueryString: function() {
-    return Hash.toQueryString(this);
-  },
-
-  inspect: function() {
-    return '#<Hash:{' + this.map(function(pair) {
-      return pair.map(Object.inspect).join(': ');
-    }).join(', ') + '}>';
-  },
-
-  toJSON: function() {
-    return Hash.toJSON(this);
-  }
-});
-
-function $H(object) {
-  if (object instanceof Hash) return object;
-  return new Hash(object);
-};
-
-// Safari iterates over shadowed properties
-if (function() {
-  var i = 0, Test = function(value) { this.key = value };
-  Test.prototype.key = 'foo';
-  for (var property in new Test('bar')) i++;
-  return i > 1;
-}()) Hash.prototype._each = function(iterator) {
-  var cache = [];
-  for (var key in this) {
-    var value = this[key];
-    if ((value && value == Hash.prototype[key]) || cache.include(key)) continue;
-    cache.push(key);
-    var pair = [key, value];
-    pair.key = key;
-    pair.value = value;
-    iterator(pair);
-  }
-};
-ObjectRange = Class.create();
-Object.extend(ObjectRange.prototype, Enumerable);
-Object.extend(ObjectRange.prototype, {
-  initialize: function(start, end, exclusive) {
-    this.start = start;
-    this.end = end;
-    this.exclusive = exclusive;
-  },
-
-  _each: function(iterator) {
-    var value = this.start;
-    while (this.include(value)) {
-      iterator(value);
-      value = value.succ();
-    }
-  },
-
-  include: function(value) {
-    if (value < this.start)
-      return false;
-    if (this.exclusive)
-      return value < this.end;
-    return value <= this.end;
-  }
-});
-
-var $R = function(start, end, exclusive) {
-  return new ObjectRange(start, end, exclusive);
-}
-
-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 (typeof responder[callback] == 'function') {
-        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 = function() {};
-Ajax.Base.prototype = {
-  setOptions: function(options) {
-    this.options = {
-      method:       'post',
-      asynchronous: true,
-      contentType:  'application/x-www-form-urlencoded',
-      encoding:     'UTF-8',
-      parameters:   ''
-    }
-    Object.extend(this.options, options || {});
-
-    this.options.method = this.options.method.toLowerCase();
-    if (typeof this.options.parameters == 'string')
-      this.options.parameters = this.options.parameters.toQueryParams();
-  }
-}
-
-Ajax.Request = Class.create();
-Ajax.Request.Events =
-  ['Uninitialized', 'Loading', 'Loaded', 'Interactive', 'Complete'];
-
-Ajax.Request.prototype = Object.extend(new Ajax.Base(), {
-  _complete: false,
-
-  initialize: function(url, options) {
-    this.transport = Ajax.getTransport();
-    this.setOptions(options);
-    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)) {
-      // simulate other verbs over post
-      params['_method'] = this.method;
-      this.method = 'post';
-    }
-
-    this.parameters = params;
-
-    if (params = Hash.toQueryString(params)) {
-      // when GET, append parameters to URL
-      if (this.method == 'get')
-        this.url += (this.url.include('?') ? '&' : '?') + params;
-      else if (/Konqueror|Safari|KHTML/.test(navigator.userAgent))
-        params += '&_=';
-    }
-
-    try {
-      if (this.options.onCreate) this.options.onCreate(this.transport);
-      Ajax.Responders.dispatch('onCreate', this, this.transport);
-
-      this.transport.open(this.method.toUpperCase(), this.url,
-        this.options.asynchronous);
-
-      if (this.options.asynchronous)
-        setTimeout(function() { this.respondToReadyState(1) }.bind(this), 10);
-
-      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';
-    }
-
-    // user-defined headers
-    if (typeof this.options.requestHeaders == 'object') {
-      var extras = this.options.requestHeaders;
-
-      if (typeof extras.push == 'function')
-        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) {
-               if (name == 'extend') { continue; } this.transport.setRequestHeader(name, headers[name]);
-       } 
-  },
-
-  success: function() {
-    return !this.transport.status
-        || (this.transport.status >= 200 && this.transport.status < 300);
-  },
-
-  respondToReadyState: function(readyState) {
-    var state = Ajax.Request.Events[readyState];
-    var transport = this.transport, json = this.evalJSON();
-
-    if (state == 'Complete') {
-      try {
-        this._complete = true;
-        (this.options['on' + this.transport.status]
-         || this.options['on' + (this.success() ? 'Success' : 'Failure')]
-         || Prototype.emptyFunction)(transport, json);
-      } catch (e) {
-        this.dispatchException(e);
-      }
-
-      var contentType = this.getHeader('Content-type');
-      if (contentType && contentType.strip().
-        match(/^(text|application)\/(x-)?(java|ecma)script(;.*)?$/i))
-          this.evalResponse();
-    }
-
-    try {
-      (this.options['on' + state] || Prototype.emptyFunction)(transport, json);
-      Ajax.Responders.dispatch('on' + state, this, transport, json);
-    } catch (e) {
-      this.dispatchException(e);
-    }
-
-    if (state == 'Complete') {
-      // avoid memory leak in MSIE: clean up
-      this.transport.onreadystatechange = Prototype.emptyFunction;
-    }
-  },
-
-  getHeader: function(name) {
-    try {
-      return this.transport.getResponseHeader(name);
-    } catch (e) { return null }
-  },
-
-  evalJSON: function() {
-    try {
-      var json = this.getHeader('X-JSON');
-      return json ? json.evalJSON() : 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.Updater = Class.create();
-
-Object.extend(Object.extend(Ajax.Updater.prototype, Ajax.Request.prototype), {
-  initialize: function(container, url, options) {
-    this.container = {
-      success: (container.success || container),
-      failure: (container.failure || (container.success ? null : container))
-    }
-
-    this.transport = Ajax.getTransport();
-    this.setOptions(options);
-
-    var onComplete = this.options.onComplete || Prototype.emptyFunction;
-    this.options.onComplete = (function(transport, param) {
-      this.updateContent();
-      onComplete(transport, param);
-    }).bind(this);
-
-    this.request(url);
-  },
-
-  updateContent: function() {
-    var receiver = this.container[this.success() ? 'success' : 'failure'];
-    var response = this.transport.responseText;
-
-    if (!this.options.evalScripts) response = response.stripScripts();
-
-    if (receiver = $(receiver)) {
-      if (this.options.insertion)
-        new this.options.insertion(receiver, response);
-      else
-        receiver.update(response);
-    }
-
-    if (this.success()) {
-      if (this.onComplete)
-        setTimeout(this.onComplete.bind(this), 10);
-    }
-  }
-});
-
-Ajax.PeriodicalUpdater = Class.create();
-Ajax.PeriodicalUpdater.prototype = Object.extend(new Ajax.Base(), {
-  initialize: function(container, url, options) {
-    this.setOptions(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(request) {
-    if (this.options.decay) {
-      this.decay = (request.responseText == this.lastText ?
-        this.decay * this.options.decay : 1);
-
-      this.lastText = request.responseText;
-    }
-    this.timer = setTimeout(this.onTimerEvent.bind(this),
-      this.decay * this.frequency * 1000);
-  },
-
-  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 (typeof element == 'string')
-    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(query.snapshotItem(i));
-    return results;
-  };
-
-  document.getElementsByClassName = function(className, parentElement) {
-    var q = ".//*[contains(concat(' ', @class, ' '), ' " + className + " ')]";
-    return document._getElementsByXPath(q, parentElement);
-  }
-
-} else document.getElementsByClassName = function(className, parentElement) {
-  var children = ($(parentElement) || document.body).getElementsByTagName('*');
-  var elements = [], child;
-  for (var i = 0, length = children.length; i < length; i++) {
-    child = children[i];
-    if (Element.hasClassName(child, className))
-      elements.push(Element.extend(child));
-  }
-  return elements;
-};
-
-/*--------------------------------------------------------------------------*/
-
-if (!window.Element) var Element = {};
-
-Element.extend = function(element) {
-  var F = Prototype.BrowserFeatures;
-  if (!element || !element.tagName || element.nodeType == 3 ||
-   element._extended || F.SpecificElementExtensions || element == window)
-    return element;
-
-  var methods = {}, tagName = element.tagName, cache = Element.extend.cache,
-   T = Element.Methods.ByTag;
-
-  // extend methods for all tags (Safari doesn't need this)
-  if (!F.ElementExtensions) {
-    Object.extend(methods, Element.Methods),
-    Object.extend(methods, Element.Methods.Simulated);
-  }
-
-  // extend methods for specific tags
-  if (T[tagName]) Object.extend(methods, T[tagName]);
-
-  for (var property in methods) {
-    var value = methods[property];
-    if (typeof value == 'function' && !(property in element))
-      element[property] = cache.findOrStore(value);
-  }
-
-  element._extended = Prototype.emptyFunction;
-  return element;
-};
-
-Element.extend.cache = {
-  findOrStore: function(value) {
-    return this[value] = this[value] || function() {
-      return value.apply(null, [this].concat($A(arguments)));
-    }
-  }
-};
-
-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).style.display = 'none';
-    return element;
-  },
-
-  show: function(element) {
-    $(element).style.display = '';
-    return element;
-  },
-
-  remove: function(element) {
-    element = $(element);
-    element.parentNode.removeChild(element);
-    return element;
-  },
-
-  update: function(element, html) {
-    html = typeof html == 'undefined' ? '' : html.toString();
-    $(element).innerHTML = html.stripScripts();
-    setTimeout(function() {html.evalScripts()}, 10);
-    return element;
-  },
-
-  replace: function(element, html) {
-    element = $(element);
-    html = typeof html == 'undefined' ? '' : html.toString();
-    if (element.outerHTML) {
-      element.outerHTML = html.stripScripts();
-    } else {
-      var range = element.ownerDocument.createRange();
-      range.selectNodeContents(element);
-      element.parentNode.replaceChild(
-        range.createContextualFragment(html.stripScripts()), element);
-    }
-    setTimeout(function() {html.evalScripts()}, 10);
-    return element;
-  },
-
-  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('parentNode');
-  },
-
-  descendants: function(element) {
-    return $A($(element).getElementsByTagName('*')).each(Element.extend);
-  },
-
-  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('previousSibling');
-  },
-
-  nextSiblings: function(element) {
-    return $(element).recursivelyCollect('nextSibling');
-  },
-
-  siblings: function(element) {
-    element = $(element);
-    return element.previousSiblings().reverse().concat(element.nextSiblings());
-  },
-
-  match: function(element, selector) {
-    if (typeof selector == 'string')
-      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();
-    return expression ? Selector.findElement(ancestors, expression, index) :
-      ancestors[index || 0];
-  },
-
-  down: function(element, expression, index) {
-    element = $(element);
-    if (arguments.length == 1) return element.firstDescendant();
-    var descendants = element.descendants();
-    return expression ? Selector.findElement(descendants, expression, index) :
-      descendants[index || 0];
-  },
-
-  previous: function(element, expression, index) {
-    element = $(element);
-    if (arguments.length == 1) return $(Selector.handlers.previousElementSibling(element));
-    var previousSiblings = element.previousSiblings();
-    return expression ? Selector.findElement(previousSiblings, expression, index) :
-      previousSiblings[index || 0];
-  },
-
-  next: function(element, expression, index) {
-    element = $(element);
-    if (arguments.length == 1) return $(Selector.handlers.nextElementSibling(element));
-    var nextSiblings = element.nextSiblings();
-    return expression ? Selector.findElement(nextSiblings, expression, index) :
-      nextSiblings[index || 0];
-  },
-
-  getElementsBySelector: function() {
-    var args = $A(arguments), element = $(args.shift());
-    return Selector.findChildElements(element, args);
-  },
-
-  getElementsByClassName: function(element, className) {
-    return document.getElementsByClassName(className, element);
-  },
-
-  readAttribute: function(element, name) {
-    element = $(element);
-    if (Prototype.Browser.IE) {
-      if (!element.attributes) return null;
-      var t = Element._attributeTranslations;
-      if (t.values[name]) return t.values[name](element, name);
-      if (t.names[name])  name = t.names[name];
-      var attribute = element.attributes[name];
-      return attribute ? attribute.nodeValue : null;
-    }
-    return element.getAttribute(name);
-  },
-
-  getHeight: function(element) {
-    return $(element).getDimensions().height;
-  },
-
-  getWidth: function(element) {
-    return $(element).getDimensions().width;
-  },
-
-  classNames: function(element) {
-    return new Element.ClassNames(element);
-  },
-
-  hasClassName: function(element, className) {
-    if (!(element = $(element))) return;
-    var elementClassName = element.className;
-    if (elementClassName.length == 0) return false;
-    if (elementClassName == className ||
-        elementClassName.match(new RegExp("(^|\\s)" + className + "(\\s|$)")))
-      return true;
-    return false;
-  },
-
-  addClassName: function(element, className) {
-    if (!(element = $(element))) return;
-    Element.classNames(element).add(className);
-    return element;
-  },
-
-  removeClassName: function(element, className) {
-    if (!(element = $(element))) return;
-    Element.classNames(element).remove(className);
-    return element;
-  },
-
-  toggleClassName: function(element, className) {
-    if (!(element = $(element))) return;
-    Element.classNames(element)[element.hasClassName(className) ? 'remove' : 'add'](className);
-    return element;
-  },
-
-  observe: function() {
-    Event.observe.apply(Event, arguments);
-    return $A(arguments).first();
-  },
-
-  stopObserving: function() {
-    Event.stopObserving.apply(Event, arguments);
-    return $A(arguments).first();
-  },
-
-  // removes whitespace-only text node children
-  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);
-    while (element = element.parentNode)
-      if (element == ancestor) return true;
-    return false;
-  },
-
-  scrollTo: function(element) {
-    element = $(element);
-    var pos = Position.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) {
-      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, camelized) {
-    element = $(element);
-    var elementStyle = element.style;
-
-    for (var property in styles)
-      if (property == 'opacity') element.setOpacity(styles[property])
-      else
-        elementStyle[(property == 'float' || property == 'cssFloat') ?
-          (elementStyle.styleFloat === undefined ? 'cssFloat' : 'styleFloat') :
-          (camelized ? property : property.camelize())] = 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('display');
-    if (display != 'none' && display != null) // Safari bug
-      return {width: element.offsetWidth, height: element.offsetHeight};
-
-    // All *Width and *Height properties give 0 on elements with display none,
-    // so enable the element temporarily
-    var els = element.style;
-    var originalVisibility = els.visibility;
-    var originalPosition = els.position;
-    var originalDisplay = els.display;
-    els.visibility = 'hidden';
-    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';
-      // Opera returns the offset relative to the positioning context, when an
-      // element is position relative but top and left have not been defined
-      if (window.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.style.overflow || 'auto';
-    if ((Element.getStyle(element, 'overflow') || 'visible') != '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;
-  }
-};
-
-Object.extend(Element.Methods, {
-  childOf: Element.Methods.descendantOf,
-  childElements: Element.Methods.immediateDescendants
-});
-
-if (Prototype.Browser.Opera) {
-  Element.Methods._getStyle = Element.Methods.getStyle;
-  Element.Methods.getStyle = function(element, style) {
-    switch(style) {
-      case 'left':
-      case 'top':
-      case 'right':
-      case 'bottom':
-        if (Element._getStyle(element, 'position') == 'static') return null;
-      default: return Element._getStyle(element, style);
-    }
-  };
-}
-else if (Prototype.Browser.IE) {
-  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) {
-    element = $(element);
-    var filter = element.getStyle('filter'), style = element.style;
-    if (value == 1 || value === '') {
-      style.filter = filter.replace(/alpha\([^\)]*\)/gi,'');
-      return element;
-    } else if (value < 0.00001) value = 0;
-    style.filter = filter.replace(/alpha\([^\)]*\)/gi, '') +
-      'alpha(opacity=' + (value * 100) + ')';
-    return element;
-  };
-
-  // IE is missing .innerHTML support for TABLE-related elements
-  Element.Methods.update = function(element, html) {
-    element = $(element);
-    html = typeof html == 'undefined' ? '' : html.toString();
-    var tagName = element.tagName.toUpperCase();
-    if (['THEAD','TBODY','TR','TD'].include(tagName)) {
-      var div = document.createElement('div');
-      switch (tagName) {
-        case 'THEAD':
-        case 'TBODY':
-          div.innerHTML = '<table><tbody>' +  html.stripScripts() + '</tbody></table>';
-          depth = 2;
-          break;
-        case 'TR':
-          div.innerHTML = '<table><tbody><tr>' +  html.stripScripts() + '</tr></tbody></table>';
-          depth = 3;
-          break;
-        case 'TD':
-          div.innerHTML = '<table><tbody><tr><td>' +  html.stripScripts() + '</td></tr></tbody></table>';
-          depth = 4;
-      }
-      $A(element.childNodes).each(function(node) { element.removeChild(node) });
-      depth.times(function() { div = div.firstChild });
-      $A(div.childNodes).each(function(node) { element.appendChild(node) });
-    } else {
-      element.innerHTML = html.stripScripts();
-    }
-    setTimeout(function() { html.evalScripts() }, 10);
-    return element;
-  }
-}
-else if (Prototype.Browser.Gecko) {
-  Element.Methods.setOpacity = function(element, value) {
-    element = $(element);
-    element.style.opacity = (value == 1) ? 0.999999 :
-      (value === '') ? '' : (value < 0.00001) ? 0 : value;
-    return element;
-  };
-}
-
-Element._attributeTranslations = {
-  names: {
-    colspan:   "colSpan",
-    rowspan:   "rowSpan",
-    valign:    "vAlign",
-    datetime:  "dateTime",
-    accesskey: "accessKey",
-    tabindex:  "tabIndex",
-    enctype:   "encType",
-    maxlength: "maxLength",
-    readonly:  "readOnly",
-    longdesc:  "longDesc"
-  },
-  values: {
-    _getAttr: function(element, attribute) {
-      return element.getAttribute(attribute, 2);
-    },
-    _flag: function(element, attribute) {
-      return $(element).hasAttribute(attribute) ? attribute : null;
-    },
-    style: function(element) {
-      return element.style.cssText.toLowerCase();
-    },
-    title: function(element) {
-      var node = element.getAttributeNode('title');
-      return node.specified ? node.nodeValue : null;
-    }
-  }
-};
-
-(function() {
-  Object.extend(this, {
-    href: this._getAttr,
-    src:  this._getAttr,
-    disabled: this._flag,
-    checked:  this._flag,
-    readonly: this._flag,
-    multiple: this._flag
-  });
-}).call(Element._attributeTranslations.values);
-
-Element.Methods.Simulated = {
-  hasAttribute: function(element, attribute) {
-    var t = Element._attributeTranslations, node;
-    attribute = t.names[attribute] || attribute;
-    node = $(element).getAttributeNode(attribute);
-    return node && node.specified;
-  }
-};
-
-Element.Methods.ByTag = {};
-
-Object.extend(Element, Element.Methods);
-
-if (!Prototype.BrowserFeatures.ElementExtensions &&
- document.createElement('div').__proto__) {
-  window.HTMLElement = {};
-  window.HTMLElement.prototype = document.createElement('div').__proto__;
-  Prototype.BrowserFeatures.ElementExtensions = true;
-}
-
-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 (arguments.length == 2) {
-    var tagName = methods;
-    methods = arguments[1];
-  }
-
-  if (!tagName) Object.extend(Element.Methods, methods || {});
-  else {
-    if (tagName.constructor == Array) 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;
-    var cache = Element.extend.cache;
-    for (var property in methods) {
-      var value = methods[property];
-      if (!onlyIfAbsent || !(property in destination))
-        destination[property] = cache.findOrStore(value);
-    }
-  }
-
-  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];
-
-    window[klass] = {};
-    window[klass].prototype = document.createElement(tagName).__proto__;
-    return window[klass];
-  }
-
-  if (F.ElementExtensions) {
-    copy(Element.Methods, HTMLElement.prototype);
-    copy(Element.Methods.Simulated, HTMLElement.prototype, true);
-  }
-
-  if (F.SpecificElementExtensions) {
-    for (var tag in Element.Methods.ByTag) {
-      var klass = findDOMClass(tag);
-      if (typeof klass == "undefined") continue;
-      copy(T[tag], klass.prototype);
-    }
-  }
-
-  Object.extend(Element, Element.Methods);
-  delete Element.ByTag;
-};
-
-var Toggle = { display: Element.toggle };
-
-/*--------------------------------------------------------------------------*/
-
-Abstract.Insertion = function(adjacency) {
-  this.adjacency = adjacency;
-}
-
-Abstract.Insertion.prototype = {
-  initialize: function(element, content) {
-    this.element = $(element);
-    this.content = content.stripScripts();
-
-    if (this.adjacency && this.element.insertAdjacentHTML) {
-      try {
-        this.element.insertAdjacentHTML(this.adjacency, this.content);
-      } catch (e) {
-        var tagName = this.element.tagName.toUpperCase();
-        if (['TBODY', 'TR'].include(tagName)) {
-          this.insertContent(this.contentFromAnonymousTable());
-        } else {
-          throw e;
-        }
-      }
-    } else {
-      this.range = this.element.ownerDocument.createRange();
-      if (this.initializeRange) this.initializeRange();
-      this.insertContent([this.range.createContextualFragment(this.content)]);
-    }
-
-    setTimeout(function() {content.evalScripts()}, 10);
-  },
-
-  contentFromAnonymousTable: function() {
-    var div = document.createElement('div');
-    div.innerHTML = '<table><tbody>' + this.content + '</tbody></table>';
-    return $A(div.childNodes[0].childNodes[0].childNodes);
-  }
-}
-
-var Insertion = new Object();
-
-Insertion.Before = Class.create();
-Insertion.Before.prototype = Object.extend(new Abstract.Insertion('beforeBegin'), {
-  initializeRange: function() {
-    this.range.setStartBefore(this.element);
-  },
-
-  insertContent: function(fragments) {
-    fragments.each((function(fragment) {
-      this.element.parentNode.insertBefore(fragment, this.element);
-    }).bind(this));
-  }
-});
-
-Insertion.Top = Class.create();
-Insertion.Top.prototype = Object.extend(new Abstract.Insertion('afterBegin'), {
-  initializeRange: function() {
-    this.range.selectNodeContents(this.element);
-    this.range.collapse(true);
-  },
-
-  insertContent: function(fragments) {
-    fragments.reverse(false).each((function(fragment) {
-      this.element.insertBefore(fragment, this.element.firstChild);
-    }).bind(this));
-  }
-});
-
-Insertion.Bottom = Class.create();
-Insertion.Bottom.prototype = Object.extend(new Abstract.Insertion('beforeEnd'), {
-  initializeRange: function() {
-    this.range.selectNodeContents(this.element);
-    this.range.collapse(this.element);
-  },
-
-  insertContent: function(fragments) {
-    fragments.each((function(fragment) {
-      this.element.appendChild(fragment);
-    }).bind(this));
-  }
-});
-
-Insertion.After = Class.create();
-Insertion.After.prototype = Object.extend(new Abstract.Insertion('afterEnd'), {
-  initializeRange: function() {
-    this.range.setStartAfter(this.element);
-  },
-
-  insertContent: function(fragments) {
-    fragments.each((function(fragment) {
-      this.element.parentNode.insertBefore(fragment,
-        this.element.nextSibling);
-    }).bind(this));
-  }
-});
-
-/*--------------------------------------------------------------------------*/
-
-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);
-/* 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();
-
-Selector.prototype = {
-  initialize: function(expression) {
-    this.expression = expression.strip();
-    this.compileMatcher();
-  },
-
-  compileMatcher: function() {
-    // Selectors with namespaced attributes can't use the XPath version
-    if (Prototype.BrowserFeatures.XPath && !(/\[[\w-]*?:/).test(this.expression))
-      return this.compileXPathMatcher();
-
-    var e = this.expression, ps = Selector.patterns, h = Selector.handlers,
-        c = Selector.criteria, le, p, m;
-
-    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 in ps) {
-        p = ps[i];
-        if (m = e.match(p)) {
-          this.matcher.push(typeof c[i] == 'function' ? c[i](m) :
-             new Template(c[i]).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;
-
-    if (Selector._cache[e]) {
-      this.xpath = Selector._cache[e]; return;
-    }
-
-    this.matcher = ['.//*'];
-    while (e && le != e && (/\S/).test(e)) {
-      le = e;
-      for (var i in ps) {
-        if (m = e.match(ps[i])) {
-          this.matcher.push(typeof x[i] == 'function' ? x[i](m) :
-            new Template(x[i]).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;
-    if (this.xpath) return document._getElementsByXPath(this.xpath, root);
-    return this.matcher(root);
-  },
-
-  match: function(element) {
-    return this.findElements(document).include(element);
-  },
-
-  toString: function() {
-    return this.expression;
-  },
-
-  inspect: function() {
-    return "#<Selector:" + this.expression.inspect() + ">";
-  }
-};
-
-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: "[@#{1}]",
-    attr: function(m) {
-      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 (typeof h === 'function') 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 or translate(text(), ' \t\r\n', '') = '')]",
-      'checked':     "[@checked]",
-      'disabled':    "[@disabled]",
-      'enabled':     "[not(@disabled)]",
-      'not': function(m) {
-        var e = m[6], p = Selector.patterns,
-            x = Selector.xpath, le, m, v;
-
-        var exclusion = [];
-        while (e && le != e && (/\S/).test(e)) {
-          le = e;
-          for (var i in p) {
-            if (m = e.match(p[i])) {
-              v = typeof x[i] == 'function' ? x[i](m) : new Template(x[i]).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 = false;',
-    attr: function(m) {
-      m[3] = (m[5] || m[6]);
-      return new Template('n = h.attr(n, r, "#{1}", "#{3}", "#{2}"); 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: {
-    // combinators must be listed first
-    // (and descendant needs to be last combinator)
-    laterSibling: /^\s*~\s*/,
-    child:        /^\s*>\s*/,
-    adjacent:     /^\s*\+\s*/,
-    descendant:   /^\s/,
-
-    // selectors follow
-    tagName:      /^\s*(\*|[\w\-]+)(\b|$)?/,
-    id:           /^#([\w\-\*]+)(\b|$)/,
-    className:    /^\.([\w\-\*]+)(\b|$)/,
-    pseudo:       /^:((first|last|nth|nth-last|only)(-child|-of-type)|empty|checked|(en|dis)abled|not)(\((.*?)\))?(\b|$|\s)/,
-    attrPresence: /^\[([\w]+)\]/,
-    attr:         /\[((?:[\w-]*:)?[\w-]+)\s*(?:([!^$*~|]?=)\s*((['"])([^\]]*?)\4|([^'"][^\]]*?)))?\]/
-  },
-
-  handlers: {
-    // UTILITY FUNCTIONS
-    // joins two collections
-    concat: function(a, b) {
-      for (var i = 0, node; node = b[i]; i++)
-        a.push(node);
-      return a;
-    },
-
-    // marks an array of nodes for counting
-    mark: function(nodes) {
-      for (var i = 0, node; node = nodes[i]; i++)
-        node._counted = true;
-      return nodes;
-    },
-
-    unmark: function(nodes) {
-      for (var i = 0, node; node = nodes[i]; i++)
-        node._counted = undefined;
-      return nodes;
-    },
-
-    // mark each child node with its position (for nth calls)
-    // "ofType" flag indicates whether we're indexing for nth-of-type
-    // rather than nth-child
-    index: function(parentNode, reverse, ofType) {
-      parentNode._counted = true;
-      if (reverse) {
-        for (var nodes = parentNode.childNodes, i = nodes.length - 1, j = 1; i >= 0; i--) {
-          node = nodes[i];
-          if (node.nodeType == 1 && (!ofType || node._counted)) node.nodeIndex = j++;
-        }
-      } else {
-        for (var i = 0, j = 1, nodes = parentNode.childNodes; node = nodes[i]; i++)
-          if (node.nodeType == 1 && (!ofType || node._counted)) node.nodeIndex = j++;
-      }
-    },
-
-    // filters out duplicates and extends all nodes
-    unique: function(nodes) {
-      if (nodes.length == 0) return nodes;
-      var results = [], n;
-      for (var i = 0, l = nodes.length; i < l; i++)
-        if (!(n = nodes[i])._counted) {
-          n._counted = true;
-          results.push(Element.extend(n));
-        }
-      return Selector.handlers.unmark(results);
-    },
-
-    // COMBINATOR FUNCTIONS
-    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, children = [], 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;
-    },
-
-    // TOKEN FUNCTIONS
-    tagName: function(nodes, root, tagName, combinator) {
-      tagName = tagName.toUpperCase();
-      var results = [], h = Selector.handlers;
-      if (nodes) {
-        if (combinator) {
-          // fastlane for ordinary descendant combinators
-          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() == tagName) results.push(node);
-        return results;
-      } else return root.getElementsByTagName(tagName);
-    },
-
-    id: function(nodes, root, id, combinator) {
-      var targetNode = $(id), h = Selector.handlers;
-      if (!nodes && root == document) return targetNode ? [targetNode] : [];
-      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) {
-      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) {
-      if (!nodes) nodes = root.getElementsByTagName("*");
-      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);
-    },
-
-    // handles the an+b logic
-    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;
-      });
-    },
-
-    // handles nth(-last)-child, nth(-last)-of-type, and (first|last)-of-type
-    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._counted) {
-          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++) {
-        // IE treats comments as element nodes
-        if (node.tagName == '!' || (node.firstChild && !node.innerHTML.match(/^\s*$/))) 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._counted) 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) 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.startsWith(v); },
-    '$=': function(nv, v) { return nv.endsWith(v); },
-    '*=': function(nv, v) { return nv.include(v); },
-    '~=': function(nv, v) { return (' ' + nv + ' ').include(' ' + v + ' '); },
-    '|=': function(nv, v) { return ('-' + nv.toUpperCase() + '-').include('-' + v.toUpperCase() + '-'); }
-  },
-
-  matchElements: function(elements, expression) {
-    var matches = new Selector(expression).findElements(), h = Selector.handlers;
-    h.mark(matches);
-    for (var i = 0, results = [], element; element = elements[i]; i++)
-      if (element._counted) results.push(element);
-    h.unmark(matches);
-    return results;
-  },
-
-  findElement: function(elements, expression, index) {
-    if (typeof expression == 'number') {
-      index = expression; expression = false;
-    }
-    return Selector.matchElements(elements, expression || '*')[index || 0];
-  },
-
-  findChildElements: function(element, expressions) {
-    var exprs = expressions.join(','), expressions = [];
-    exprs.scan(/(([\w#:.~>+()\s-]+|\*|\[.*?\])+)\s*(,|$)/, function(m) {
-      expressions.push(m[1].strip());
-    });
-    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;
-  }
-});
-
-function $$() {
-  return Selector.findChildElements(document, $A(arguments));
-}
-var Form = {
-  reset: function(form) {
-    $(form).reset();
-    return form;
-  },
-
-  serializeElements: function(elements, getHash) {
-    var data = elements.inject({}, function(result, element) {
-      if (!element.disabled && element.name) {
-        var key = element.name, value = $(element).getValue();
-        if (value != null) {
-               if (key in result) {
-            if (result[key].constructor != Array) result[key] = [result[key]];
-            result[key].push(value);
-          }
-          else result[key] = value;
-        }
-      }
-      return result;
-    });
-
-    return getHash ? data : Hash.toQueryString(data);
-  }
-};
-
-Form.Methods = {
-  serialize: function(form, getHash) {
-    return Form.serializeElements(Form.getElements(form), getHash);
-  },
-
-  getElements: function(form) {
-    return $A($(form).getElementsByTagName('*')).inject([],
-      function(elements, child) {
-        if (Form.Element.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) {
-    return $(form).getElements().find(function(element) {
-      return element.type != 'hidden' && !element.disabled &&
-        ['input', 'select', 'textarea'].include(element.tagName.toLowerCase());
-    });
-  },
-
-  focusFirstElement: function(form) {
-    form = $(form);
-    form.findFirstElement().activate();
-    return form;
-  },
-
-  request: function(form, options) {
-    form = $(form), options = Object.clone(options || {});
-
-    var params = options.parameters;
-    options.parameters = form.serialize(true);
-
-    if (params) {
-      if (typeof params == 'string') params = params.toQueryParams();
-      Object.extend(options.parameters, params);
-    }
-
-    if (form.hasAttribute('method') && !options.method)
-      options.method = form.method;
-
-    return new Ajax.Request(form.readAttribute('action'), options);
-  }
-}
-
-Object.extend(Form, Form.Methods);
-
-/*--------------------------------------------------------------------------*/
-
-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 Hash.toQueryString(pair);
-      }
-    }
-    return '';
-  },
-
-  getValue: function(element) {
-    element = $(element);
-    var method = element.tagName.toLowerCase();
-    return Form.Element.Serializers[method](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'].include(element.type)))
-        element.select();
-    } catch (e) {}
-    return element;
-  },
-
-  disable: function(element) {
-    element = $(element);
-    element.blur();
-    element.disabled = true;
-    return element;
-  },
-
-  enable: function(element) {
-    element = $(element);
-    element.disabled = false;
-    return element;
-  }
-}
-
-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)
-});
-
-/*--------------------------------------------------------------------------*/
-
-var Field = Form.Element;
-var $F = Form.Element.getValue;
-
-/*--------------------------------------------------------------------------*/
-
-Form.Element.Serializers = {
-  input: function(element) {
-    switch (element.type.toLowerCase()) {
-      case 'checkbox':
-      case 'radio':
-        return Form.Element.Serializers.inputSelector(element);
-      default:
-        return Form.Element.Serializers.textarea(element);
-    }
-  },
-
-  inputSelector: function(element) {
-    return element.checked ? element.value : null;
-  },
-
-  textarea: function(element) {
-    return element.value;
-  },
-
-  select: function(element) {
-    return this[element.type == 'select-one' ?
-      'selectOne' : 'selectMany'](element);
-  },
-
-  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) {
-    // extend element because hasAttribute may not be native
-    return Element.extend(opt).hasAttribute('value') ? opt.value : opt.text;
-  }
-}
-
-/*--------------------------------------------------------------------------*/
-
-Abstract.TimedObserver = function() {}
-Abstract.TimedObserver.prototype = {
-  initialize: function(element, frequency, callback) {
-    this.frequency = frequency;
-    this.element   = $(element);
-    this.callback  = callback;
-
-    this.lastValue = this.getValue();
-    this.registerCallback();
-  },
-
-  registerCallback: function() {
-    setInterval(this.onTimerEvent.bind(this), this.frequency * 1000);
-  },
-
-  onTimerEvent: function() {
-    var value = this.getValue();
-    var changed = ('string' == typeof this.lastValue && 'string' == typeof value
-      ? this.lastValue != value : String(this.lastValue) != String(value));
-    if (changed) {
-      this.callback(this.element, value);
-      this.lastValue = value;
-    }
-  }
-}
-
-Form.Element.Observer = Class.create();
-Form.Element.Observer.prototype = Object.extend(new Abstract.TimedObserver(), {
-  getValue: function() {
-    return Form.Element.getValue(this.element);
-  }
-});
-
-Form.Observer = Class.create();
-Form.Observer.prototype = Object.extend(new Abstract.TimedObserver(), {
-  getValue: function() {
-    return Form.serialize(this.element);
-  }
-});
-
-/*--------------------------------------------------------------------------*/
-
-Abstract.EventObserver = function() {}
-Abstract.EventObserver.prototype = {
-  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.bind(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();
-Form.Element.EventObserver.prototype = Object.extend(new Abstract.EventObserver(), {
-  getValue: function() {
-    return Form.Element.getValue(this.element);
-  }
-});
-
-Form.EventObserver = Class.create();
-Form.EventObserver.prototype = Object.extend(new Abstract.EventObserver(), {
-  getValue: function() {
-    return Form.serialize(this.element);
-  }
-});
-if (!window.Event) {
-  var Event = new Object();
-}
-
-Object.extend(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,
-
-  element: function(event) {
-    return $(event.target || event.srcElement);
-  },
-
-  isLeftClick: function(event) {
-    return (((event.which) && (event.which == 1)) ||
-            ((event.button) && (event.button == 1)));
-  },
-
-  pointerX: function(event) {
-    return event.pageX || (event.clientX +
-      (document.documentElement.scrollLeft || document.body.scrollLeft));
-  },
-
-  pointerY: function(event) {
-    return event.pageY || (event.clientY +
-      (document.documentElement.scrollTop || document.body.scrollTop));
-  },
-
-  stop: function(event) {
-    if (event.preventDefault) {
-      event.preventDefault();
-      event.stopPropagation();
-    } else {
-      event.returnValue = false;
-      event.cancelBubble = true;
-    }
-  },
-
-  // find the first node with the given tagName, starting from the
-  // node the event was triggered on; traverses the DOM upwards
-  findElement: function(event, tagName) {
-    var element = Event.element(event);
-    while (element.parentNode && (!element.tagName ||
-        (element.tagName.toUpperCase() != tagName.toUpperCase())))
-      element = element.parentNode;
-    return element;
-  },
-
-  observers: false,
-
-  _observeAndCache: function(element, name, observer, useCapture) {
-    if (!this.observers) this.observers = [];
-    if (element.addEventListener) {
-      this.observers.push([element, name, observer, useCapture]);
-      element.addEventListener(name, observer, useCapture);
-    } else if (element.attachEvent) {
-      this.observers.push([element, name, observer, useCapture]);
-      element.attachEvent('on' + name, observer);
-    }
-  },
-
-  unloadCache: function() {
-    if (!Event.observers) return;
-    for (var i = 0, length = Event.observers.length; i < length; i++) {
-      Event.stopObserving.apply(this, Event.observers[i]);
-      Event.observers[i][0] = null;
-    }
-    Event.observers = false;
-  },
-
-  observe: function(element, name, observer, useCapture) {
-    element = $(element);
-    useCapture = useCapture || false;
-
-    if (name == 'keypress' &&
-      (Prototype.Browser.WebKit || element.attachEvent))
-      name = 'keydown';
-
-    Event._observeAndCache(element, name, observer, useCapture);
-  },
-
-  stopObserving: function(element, name, observer, useCapture) {
-    element = $(element);
-    useCapture = useCapture || false;
-
-    if (name == 'keypress' &&
-        (Prototype.Browser.WebKit || element.attachEvent))
-      name = 'keydown';
-
-    if (element.removeEventListener) {
-      element.removeEventListener(name, observer, useCapture);
-    } else if (element.detachEvent) {
-      try {
-        element.detachEvent('on' + name, observer);
-      } catch (e) {}
-    }
-  }
-});
-
-/* prevent memory leaks in IE */
-if (Prototype.Browser.IE)
-  Event.observe(window, 'unload', Event.unloadCache, false);
-var Position = {
-  // set to true if needed, warning: firefox performance problems
-  // NOT neeeded for page scrolling, only if draggable contained in
-  // scrollable elements
-  includeScrollOffsets: false,
-
-  // must be called before calling withinIncludingScrolloffset, every time the
-  // page is scrolled
-  prepare: function() {
-    this.deltaX =  window.pageXOffset
-                || document.documentElement.scrollLeft
-                || document.body.scrollLeft
-                || 0;
-    this.deltaY =  window.pageYOffset
-                || document.documentElement.scrollTop
-                || document.body.scrollTop
-                || 0;
-  },
-
-  realOffset: function(element) {
-    var valueT = 0, valueL = 0;
-    do {
-      valueT += element.scrollTop  || 0;
-      valueL += element.scrollLeft || 0;
-      element = element.parentNode;
-    } while (element);
-    return [valueL, valueT];
-  },
-
-  cumulativeOffset: function(element) {
-    var valueT = 0, valueL = 0;
-    do {
-      valueT += element.offsetTop  || 0;
-      valueL += element.offsetLeft || 0;
-      element = element.offsetParent;
-    } while (element);
-    return [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=='BODY') break;
-        var p = Element.getStyle(element, 'position');
-        if (p == 'relative' || p == 'absolute') break;
-      }
-    } while (element);
-    return [valueL, valueT];
-  },
-
-  offsetParent: 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;
-  },
-
-  // caches x/y coordinate pair to use with overlap
-  within: function(element, x, y) {
-    if (this.includeScrollOffsets)
-      return this.withinIncludingScrolloffsets(element, x, y);
-    this.xcomp = x;
-    this.ycomp = y;
-    this.offset = this.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 = this.realOffset(element);
-
-    this.xcomp = x + offsetcache[0] - this.deltaX;
-    this.ycomp = y + offsetcache[1] - this.deltaY;
-    this.offset = this.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);
-  },
-
-  // within must be called directly before
-  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;
-  },
-
-  page: function(forElement) {
-    var valueT = 0, valueL = 0;
-
-    var element = forElement;
-    do {
-      valueT += element.offsetTop  || 0;
-      valueL += element.offsetLeft || 0;
-
-      // Safari fix
-      if (element.offsetParent == document.body)
-        if (Element.getStyle(element,'position')=='absolute') break;
-
-    } while (element = element.offsetParent);
-
-    element = forElement;
-    do {
-      if (!window.opera || element.tagName=='BODY') {
-        valueT -= element.scrollTop  || 0;
-        valueL -= element.scrollLeft || 0;
-      }
-    } while (element = element.parentNode);
-
-    return [valueL, valueT];
-  },
-
-  clone: function(source, target) {
-    var options = Object.extend({
-      setLeft:    true,
-      setTop:     true,
-      setWidth:   true,
-      setHeight:  true,
-      offsetTop:  0,
-      offsetLeft: 0
-    }, arguments[2] || {})
-
-    // find page position of source
-    source = $(source);
-    var p = Position.page(source);
-
-    // find coordinate system to use
-    target = $(target);
-    var delta = [0, 0];
-    var parent = null;
-    // delta [0,0] will do fine with position: fixed elements,
-    // position:absolute needs offsetParent deltas
-    if (Element.getStyle(target,'position') == 'absolute') {
-      parent = Position.offsetParent(target);
-      delta = Position.page(parent);
-    }
-
-    // correct by body offsets (fixes Safari)
-    if (parent == document.body) {
-      delta[0] -= document.body.offsetLeft;
-      delta[1] -= document.body.offsetTop;
-    }
-
-    // set position
-    if(options.setLeft)   target.style.left  = (p[0] - delta[0] + options.offsetLeft) + 'px';
-    if(options.setTop)    target.style.top   = (p[1] - delta[1] + options.offsetTop) + 'px';
-    if(options.setWidth)  target.style.width = source.offsetWidth + 'px';
-    if(options.setHeight) target.style.height = source.offsetHeight + 'px';
-  },
-
-  absolutize: function(element) {
-    element = $(element);
-    if (element.style.position == 'absolute') return;
-    Position.prepare();
-
-    var offsets = Position.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';
-  },
-
-  relativize: function(element) {
-    element = $(element);
-    if (element.style.position == 'relative') return;
-    Position.prepare();
-
-    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;
-  }
-}
-
-// Safari returns margins on body which is incorrect if the child is absolutely
-// positioned.  For performance reasons, redefine Position.cumulativeOffset for
-// KHTML/WebKit only.
-if (Prototype.Browser.WebKit) {
-  Position.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 [valueL, valueT];
-  }
-}
-
-Element.addMethods();
\ No newline at end of file
diff --git a/webinterface/src/web-data/lib/ptwindow/javascripts/tooltip.js b/webinterface/src/web-data/lib/ptwindow/javascripts/tooltip.js
deleted file mode 100644 (file)
index 65e6106..0000000
+++ /dev/null
@@ -1,241 +0,0 @@
-// Singleton class TooltipWindow
-// This class works with special className. The tooltip content could be in your HTML page as an hidden element or
-// can be retreive by an AJAX call.
-//
-// To work, You just need to set two class name on elements that should show tooltips
-// - One to say to TooltipManager that this element must have a tooltip ('tooltip' by default)
-// - Another to indicate how to find the tooltip content
-//   It could be html_XXXX if tootltip content is somewhere hidden in your page, XXX must be DOM ID of this hidden element
-//   It could be ajax_XXXX if tootltip content must be find by an ajax request, XXX will be the string send as id parameter to your server. 
-// Check samples/tooltips/tooltip.html to see how it works
-//
-TooltipManager = {
-  options: {cssClassName: 'tooltip', delayOver: 200, delayOut: 1000, shiftX: 10, shiftY: 10,
-            className: 'alphacube', width: 200, height: null, 
-            draggable: false, minimizable: false, maximizable: false, showEffect: Element.show, hideEffect: Element.hide},
-  ajaxInfo: null,
-  elements: null,
-  showTimer: null,
-  hideTimer: null,
-
-  // Init tooltip manager
-  // parameters:
-  // - cssClassName (string) : CSS class name where tooltip should be shown. 
-  // - ajaxOptions  (hash)   : Ajax options for ajax tooltip. 
-  //                           For examples {url: "/tooltip/get.php", options: {method: 'get'}} 
-  //                           see Ajax.Request documentation for details
-  //- tooltipOptions (hash)  : available keys
-  //                           - delayOver: int in ms (default 10) delay before showing tooltip
-  //                           - delayOut:  int in ms (default 1000) delay before hidding tooltip
-  //                           - shiftX:    int in pixels (default 10) left shift of the tooltip window 
-  //                           - shiftY:    int in pixels (default 10) top shift of the tooltip window 
-  //                           and All window options like showEffect: Element.show, hideEffect: Element.hide to remove animation
-  //                           default: {className: 'alphacube', width: 200, height: null, draggable: false, minimizable: false, maximizable: false}
-  
-  init: function(cssClassName, ajaxInfo, tooltipOptions) {
-    TooltipManager.options = Object.extend(TooltipManager.options, tooltipOptions || {});
-    
-    cssClassName = TooltipManager.options.cssClassName || "tooltip";
-    TooltipManager.ajaxInfo = ajaxInfo;
-    TooltipManager.elements = $$("." + cssClassName);
-    TooltipManager.elements.each(function(element) {
-      element = $(element)
-      var info = TooltipManager._getInfo(element);
-      if (info.ajax) {
-        element.ajaxId = info.id;
-        element.ajaxInfo = ajaxInfo;
-      }
-      else {
-        element.tooltipElement = $(info.id);
-      }
-      element.observe("mouseover", TooltipManager._mouseOver);
-      element.observe("mouseout", TooltipManager._mouseOut);
-    });
-    Windows.addObserver(this);
-  },
-  
-  addHTML: function(element, tooltipElement) {
-    element = $(element);
-    tooltipElement = $(tooltipElement);
-    element.tooltipElement = tooltipElement;
-    
-    element.observe("mouseover", TooltipManager._mouseOver);
-    element.observe("mouseout", TooltipManager._mouseOut);
-  },
-  
-  addAjax: function(element, ajaxInfo) {
-    element = $(element);
-    element.ajaxInfo = ajaxInfo;
-    element.observe("mouseover", TooltipManager._mouseOver);
-    element.observe("mouseout", TooltipManager._mouseOut);    
-  },
-    
-  addURL: function(element, url, width, height) {
-    element = $(element);
-    element.url = url;
-    element.frameWidth = width;
-    element.frameHeight = height;
-    element.observe("mouseover", TooltipManager._mouseOver);
-    element.observe("mouseout", TooltipManager._mouseOut);    
-  },
-    
-  close: function() {
-    if (TooltipManager.tooltipWindow)
-      TooltipManager.tooltipWindow.hide();
-  },
-  
-  preloadImages: function(path, images, extension) {
-    if (!extension)
-      extension = ".gif";
-      
-    //preload images
-    $A(images).each(function(i) {
-      var image = new Image(); 
-      image.src= path + "/" + i + extension; 
-    });
-  },
-  
-  _showTooltip: function(element) {
-    if (this.element == element)
-      return;
-    // Get original element
-    while (element && (!element.tooltipElement && !element.ajaxInfo && !element.url)) 
-      element = element.parentNode;
-    this.element = element;
-    
-    TooltipManager.showTimer = null;
-    if (TooltipManager.hideTimer)
-      clearTimeout(TooltipManager.hideTimer);
-    
-    var position = Position.cumulativeOffset(element);
-    var dimension = element.getDimensions();
-
-    if (! this.tooltipWindow)
-      this.tooltipWindow = new Window("__tooltip__", TooltipManager.options);
-      
-    this.tooltipWindow.hide();
-    this.tooltipWindow.setLocation(position[1] + dimension.height + TooltipManager.options.shiftY, position[0] + TooltipManager.options.shiftX);
-
-    Event.observe(this.tooltipWindow.element, "mouseover", function(event) {TooltipManager._tooltipOver(event, element)});
-    Event.observe(this.tooltipWindow.element, "mouseout", function(event) {TooltipManager._tooltipOut(event, element)});
-
-    // Reset width/height for computation
-    this.tooltipWindow.height = TooltipManager.options.height;
-    this.tooltipWindow.width = TooltipManager.options.width;
-
-    // Ajax content
-    if (element.ajaxInfo) {
-      var p = element.ajaxInfo.options.parameters;
-      var saveParam = p;
-      
-      // Set by CSS
-      if (element.ajaxId) {
-        if (p)
-          p += "&id=" + element.ajaxId;
-        else
-          p = "id=" + element.ajaxId;
-      }
-      element.ajaxInfo.options.parameters = p || "";
-      this.tooltipWindow.setHTMLContent("");
-      this.tooltipWindow.setAjaxContent(element.ajaxInfo.url, element.ajaxInfo.options);
-      element.ajaxInfo.options.parameters = saveParam;    
-    } 
-    // URL content
-    else if (element.url) {
-      this.tooltipWindow.setURL(element.url);
-      this.tooltipWindow.setSize(element.frameWidth, element.frameHeight);
-
-      // Set tooltip size
-      this.tooltipWindow.height = element.frameHeight;
-      this.tooltipWindow.width = element.frameWidth;
-    }
-    // HTML content
-    else
-      this.tooltipWindow.setHTMLContent(element.tooltipElement.innerHTML);
-
-    if (!element.ajaxInfo) {
-      this.tooltipWindow.show();
-      this.tooltipWindow.toFront();
-    }
-  },
-  
-  _hideTooltip: function(element) {
-    if (this.tooltipWindow) {
-      this.tooltipWindow.hide();
-      this.element = null;
-    }
-  },
-  
-  _mouseOver: function (event) {
-    var element = Event.element(event);
-    if (TooltipManager.showTimer) 
-      clearTimeout(TooltipManager.showTimer);
-    
-    TooltipManager.showTimer = setTimeout(function() {TooltipManager._showTooltip(element)}, TooltipManager.options.delayOver)
-  },
-  
-  _mouseOut: function(event) {
-    var element = Event.element(event);
-    if (TooltipManager.showTimer) {
-      clearTimeout(TooltipManager.showTimer);
-      TooltipManager.showTimer = null;
-      return;
-    }
-    if (TooltipManager.tooltipWindow)
-      TooltipManager.hideTimer = setTimeout(function() {TooltipManager._hideTooltip(element)}, TooltipManager.options.delayOut)
-  },
-  
-  _tooltipOver: function(event, element) {
-    if (TooltipManager.hideTimer) {
-      clearTimeout(TooltipManager.hideTimer);
-      TooltipManager.hideTimer = null;
-    }
-  },
-  
-  _tooltipOut: function(event, element) {
-    if (TooltipManager.hideTimer == null)
-      TooltipManager.hideTimer = setTimeout(function() {TooltipManager._hideTooltip(element)}, TooltipManager.options.delayOut)
-  },
-  
-  _getInfo: function(element) {
-    // Find html_ for static content
-    var id = element.className.split(' ').detect(function(name) {return name.indexOf("html_") == 0});
-    var ajax = true;
-    if (id)
-      ajax = false;
-    else 
-      // Find ajax_ for ajax content
-      id = element.className.split(' ').detect(function(name) {return name.indexOf("ajax_") == 0});
-    
-    id = id.substr(id.indexOf('_')+1, id.length)
-    return id ? {ajax: ajax, id: id} : null;
-  },
-  
-  onBeforeShow: function(eventName, win) {
-     var top = parseFloat(win.getLocation().top);
-     var dim = win.element.getDimensions();
-    
-     if (top + dim.height > TooltipManager._getScrollTop() + TooltipManager._getPageHeight()) {
-       var position = Position.cumulativeOffset(this.element);
-
-       var top = position[1] - TooltipManager.options.shiftY - dim.height;
-       win.setLocation(top, position[0] + TooltipManager.options.shiftX)
-     }
-   },
-
-       _getPageWidth: function(){
-               return window.innerWidth || document.documentElement.clientWidth || 0;
-       },
-       
-       _getPageHeight: function(){
-               return window.innerHeight || document.documentElement.clientHeight || 0;
-       },
-
-       _getScrollTop: function(){
-               return document.documentElement.scrollTop || window.pageYOffset || 0;
-       },
-
-       _getScrollLeft: function(){
-               return document.documentElement.scrollLeft || window.pageXOffset || 0;
-       }       
-};
diff --git a/webinterface/src/web-data/lib/ptwindow/javascripts/window.js b/webinterface/src/web-data/lib/ptwindow/javascripts/window.js
deleted file mode 100644 (file)
index 5fc2533..0000000
+++ /dev/null
@@ -1,1843 +0,0 @@
-// Copyright (c) 2006 Sébastien Gruhier (http://xilinus.com, http://itseb.com)
-// 
-// 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.
-//
-// VERSION 1.3
-
-var Window = Class.create();
-
-Window.keepMultiModalWindow = false;
-Window.hasEffectLib = (typeof Effect != 'undefined');
-Window.resizeEffectDuration = 0.4;
-
-Window.prototype = {
-  // Constructor
-  // Available parameters : className, blurClassName, title, minWidth, minHeight, maxWidth, maxHeight, width, height, top, left, bottom, right, resizable, zIndex, opacity, recenterAuto, wiredDrag
-  //                        hideEffect, showEffect, showEffectOptions, hideEffectOptions, effectOptions, url, draggable, closable, minimizable, maximizable, parent, onload
-  //                        add all callbacks (if you do not use an observer)
-  //                        onDestroy onStartResize onStartMove onResize onMove onEndResize onEndMove onFocus onBlur onBeforeShow onShow onHide onMinimize onMaximize onClose
-  
-  initialize: function() {
-    var id;
-    var optionIndex = 0;
-    // For backward compatibility like win= new Window("id", {...}) instead of win = new Window({id: "id", ...})
-    if (arguments.length > 0) {
-      if (typeof arguments[0] == "string" ) {
-        id = arguments[0];
-        optionIndex = 1;
-      }
-      else
-        id = arguments[0] ? arguments[0].id : null;
-    }
-    
-    // Generate unique ID if not specified
-    if (!id)
-      id = "window_" + new Date().getTime();
-      
-    if ($(id))
-      alert("Window " + id + " is already registered in the DOM! Make sure you use setDestroyOnClose() or destroyOnClose: true in the constructor");
-
-    this.options = Object.extend({
-      className:         "dialog",
-      blurClassName:     null,
-      minWidth:          100, 
-      minHeight:         20,
-      resizable:         true,
-      closable:          true,
-      minimizable:       true,
-      maximizable:       true,
-      draggable:         true,
-      userData:          null,
-      showEffect:        (Window.hasEffectLib ? Effect.Appear : Element.show),
-      hideEffect:        (Window.hasEffectLib ? Effect.Fade : Element.hide),
-      showEffectOptions: {},
-      hideEffectOptions: {},
-      effectOptions:     null,
-      parent:            document.body,
-      title:             "&nbsp;",
-      url:               null,
-      onload:            Prototype.emptyFunction,
-      width:             200,
-      height:            300,
-      opacity:           1,
-      recenterAuto:      true,
-      wiredDrag:         false,
-      closeCallback:     null,
-      destroyOnClose:    false,
-      gridX:             1, 
-      gridY:             1      
-    }, arguments[optionIndex] || {});
-    if (this.options.blurClassName)
-      this.options.focusClassName = this.options.className;
-      
-    if (typeof this.options.top == "undefined" &&  typeof this.options.bottom ==  "undefined") 
-      this.options.top = this._round(Math.random()*500, this.options.gridY);
-    if (typeof this.options.left == "undefined" &&  typeof this.options.right ==  "undefined") 
-      this.options.left = this._round(Math.random()*500, this.options.gridX);
-
-    if (this.options.effectOptions) {
-      Object.extend(this.options.hideEffectOptions, this.options.effectOptions);
-      Object.extend(this.options.showEffectOptions, this.options.effectOptions);
-      if (this.options.showEffect == Element.Appear)
-        this.options.showEffectOptions.to = this.options.opacity;
-    }
-    if (Window.hasEffectLib) {
-      if (this.options.showEffect == Effect.Appear)
-        this.options.showEffectOptions.to = this.options.opacity;
-    
-      if (this.options.hideEffect == Effect.Fade)
-        this.options.hideEffectOptions.from = this.options.opacity;
-    }
-    if (this.options.hideEffect == Element.hide)
-      this.options.hideEffect = function(){ Element.hide(this.element); if (this.options.destroyOnClose) this.destroy(); }.bind(this)
-    
-    if (this.options.parent != document.body)  
-      this.options.parent = $(this.options.parent);
-      
-    this.element = this._createWindow(id);       
-    this.element.win = this;
-    
-    // Bind event listener
-    this.eventMouseDown = this._initDrag.bindAsEventListener(this);
-    this.eventMouseUp   = this._endDrag.bindAsEventListener(this);
-    this.eventMouseMove = this._updateDrag.bindAsEventListener(this);
-    this.eventOnLoad    = this._getWindowBorderSize.bindAsEventListener(this);
-    this.eventMouseDownContent = this.toFront.bindAsEventListener(this);
-    this.eventResize = this._recenter.bindAsEventListener(this);
-    this.topbar = $(this.element.id + "_top");
-    this.bottombar = $(this.element.id + "_bottom");
-    this.content = $(this.element.id + "_content");
-    
-    Event.observe(this.topbar, "mousedown", this.eventMouseDown);
-    Event.observe(this.bottombar, "mousedown", this.eventMouseDown);
-    Event.observe(this.content, "mousedown", this.eventMouseDownContent);
-    Event.observe(window, "load", this.eventOnLoad);
-    Event.observe(window, "resize", this.eventResize);
-    Event.observe(window, "scroll", this.eventResize);
-    Event.observe(this.options.parent, "scroll", this.eventResize);
-    
-    if (this.options.draggable)  {
-      var that = this;
-      [this.topbar, this.topbar.up().previous(), this.topbar.up().next()].each(function(element) {
-        element.observe("mousedown", that.eventMouseDown);
-        element.addClassName("top_draggable");
-      });
-      [this.bottombar.up(), this.bottombar.up().previous(), this.bottombar.up().next()].each(function(element) {
-        element.observe("mousedown", that.eventMouseDown);
-        element.addClassName("bottom_draggable");
-      });
-      
-    }    
-    
-    if (this.options.resizable) {
-      this.sizer = $(this.element.id + "_sizer");
-      Event.observe(this.sizer, "mousedown", this.eventMouseDown);
-    }  
-    
-    this.useLeft = null;
-    this.useTop = null;
-    if (typeof this.options.left != "undefined") {
-      this.element.setStyle({left: parseFloat(this.options.left) + 'px'});
-      this.useLeft = true;
-    }
-    else {
-      this.element.setStyle({right: parseFloat(this.options.right) + 'px'});
-      this.useLeft = false;
-    }
-    
-    if (typeof this.options.top != "undefined") {
-      this.element.setStyle({top: parseFloat(this.options.top) + 'px'});
-      this.useTop = true;
-    }
-    else {
-      this.element.setStyle({bottom: parseFloat(this.options.bottom) + 'px'});      
-      this.useTop = false;
-    }
-      
-    this.storedLocation = null;
-    
-    this.setOpacity(this.options.opacity);
-    if (this.options.zIndex)
-      this.setZIndex(this.options.zIndex)
-
-    if (this.options.destroyOnClose)
-      this.setDestroyOnClose(true);
-
-    this._getWindowBorderSize();
-    this.width = this.options.width;
-    this.height = this.options.height;
-    this.visible = false;
-    
-    this.constraint = false;
-    this.constraintPad = {top: 0, left:0, bottom:0, right:0};
-    
-    if (this.width && this.height)
-      this.setSize(this.options.width, this.options.height);
-    this.setTitle(this.options.title)
-    Windows.register(this);      
-  },
-  
-  // Destructor
-  destroy: function() {
-    this._notify("onDestroy");
-    Event.stopObserving(this.topbar, "mousedown", this.eventMouseDown);
-    Event.stopObserving(this.bottombar, "mousedown", this.eventMouseDown);
-    Event.stopObserving(this.content, "mousedown", this.eventMouseDownContent);
-    
-    Event.stopObserving(window, "load", this.eventOnLoad);
-    Event.stopObserving(window, "resize", this.eventResize);
-    Event.stopObserving(window, "scroll", this.eventResize);
-    
-    Event.stopObserving(this.content, "load", this.options.onload);
-
-    if (this._oldParent) {
-      var content = this.getContent();
-      var originalContent = null;
-      for(var i = 0; i < content.childNodes.length; i++) {
-        originalContent = content.childNodes[i];
-        if (originalContent.nodeType == 1) 
-          break;
-        originalContent = null;
-      }
-      if (originalContent)
-        this._oldParent.appendChild(originalContent);
-      this._oldParent = null;
-    }
-
-    if (this.sizer)
-        Event.stopObserving(this.sizer, "mousedown", this.eventMouseDown);
-
-    if (this.options.url) 
-      this.content.src = null
-
-     if(this.iefix) 
-      Element.remove(this.iefix);
-
-    Element.remove(this.element);
-    Windows.unregister(this);      
-  },
-    
-  // Sets close callback, if it sets, it should return true to be able to close the window.
-  setCloseCallback: function(callback) {
-    this.options.closeCallback = callback;
-  },
-  
-  // Gets window content
-  getContent: function () {
-    return this.content;
-  },
-  
-  // Sets the content with an element id
-  setContent: function(id, autoresize, autoposition) {
-    var element = $(id);
-    if (null == element) throw "Unable to find element '" + id + "' in DOM";
-    this._oldParent = element.parentNode;
-
-    var d = null;
-    var p = null;
-
-    if (autoresize) 
-      d = Element.getDimensions(element);
-    if (autoposition) 
-      p = Position.cumulativeOffset(element);
-
-    var content = this.getContent();
-    // Clear HTML (and even iframe)
-    this.setHTMLContent("");
-    content = this.getContent();
-    
-    content.appendChild(element);
-    element.show();
-    if (autoresize) 
-      this.setSize(d.width, d.height);
-    if (autoposition) 
-      this.setLocation(p[1] - this.heightN, p[0] - this.widthW);    
-  },
-  
-  setHTMLContent: function(html) {
-    // It was an url (iframe), recreate a div content instead of iframe content
-    if (this.options.url) {
-      this.content.src = null;
-      this.options.url = null;
-      
-         var content ="<div id=\"" + this.getId() + "_content\" class=\"" + this.options.className + "_content\"> </div>";
-      $(this.getId() +"_table_content").innerHTML = content;
-      
-      this.content = $(this.element.id + "_content");
-    }
-      
-    this.getContent().innerHTML = html;
-  },
-  
-  setAjaxContent: function(url, options, showCentered, showModal) {
-    this.showFunction = showCentered ? "showCenter" : "show";
-    this.showModal = showModal || false;
-  
-    options = options || {};
-
-    // Clear HTML (and even iframe)
-    this.setHTMLContent("");
-    this.onComplete = options.onComplete;
-    if (! this._onCompleteHandler)
-      this._onCompleteHandler = this._setAjaxContent.bind(this);
-    options.onComplete = this._onCompleteHandler;
-
-    new Ajax.Request(url, options);    
-    options.onComplete = this.onComplete;
-  },
-  
-  _setAjaxContent: function(originalRequest) {
-    Element.update(this.getContent(), originalRequest.responseText);
-    if (this.onComplete)
-      this.onComplete(originalRequest);
-    this.onComplete = null;
-    this[this.showFunction](this.showModal)
-  },
-  
-  setURL: function(url) {
-    // Not an url content, change div to iframe
-    if (this.options.url) 
-      this.content.src = null;
-    this.options.url = url;
-    var content= "<iframe frameborder='0' name='" + this.getId() + "_content'  id='" + this.getId() + "_content' src='" + url + "' width='" + this.width + "' height='" + this.height + "'> </iframe>";
-    $(this.getId() +"_table_content").innerHTML = content;
-    
-    this.content = $(this.element.id + "_content");
-  },
-
-  getURL: function() {
-       return this.options.url ? this.options.url : null;
-  },
-
-  refresh: function() {
-    if (this.options.url)
-           $(this.element.getAttribute('id') + '_content').src = this.options.url;
-  },
-  
-  // Stores position/size in a cookie, by default named with window id
-  setCookie: function(name, expires, path, domain, secure) {
-    name = name || this.element.id;
-    this.cookie = [name, expires, path, domain, secure];
-    
-    // Get cookie
-    var value = WindowUtilities.getCookie(name)
-    // If exists
-    if (value) {
-      var values = value.split(',');
-      var x = values[0].split(':');
-      var y = values[1].split(':');
-
-      var w = parseFloat(values[2]), h = parseFloat(values[3]);
-      var mini = values[4];
-      var maxi = values[5];
-
-      this.setSize(w, h);
-      if (mini == "true")
-        this.doMinimize = true; // Minimize will be done at onload window event
-      else if (maxi == "true")
-        this.doMaximize = true; // Maximize will be done at onload window event
-
-      this.useLeft = x[0] == "l";
-      this.useTop = y[0] == "t";
-
-      this.element.setStyle(this.useLeft ? {left: x[1]} : {right: x[1]});
-      this.element.setStyle(this.useTop ? {top: y[1]} : {bottom: y[1]});
-    }
-  },
-  
-  // Gets window ID
-  getId: function() {
-    return this.element.id;
-  },
-  
-  // Detroys itself when closing 
-  setDestroyOnClose: function() {
-    this.options.destroyOnClose = true;
-  },
-  
-  setConstraint: function(bool, padding) {
-    this.constraint = bool;
-    this.constraintPad = Object.extend(this.constraintPad, padding || {});
-    // Reset location to apply constraint
-    if (this.useTop && this.useLeft)
-      this.setLocation(parseFloat(this.element.style.top), parseFloat(this.element.style.left));
-  },
-  
-  // initDrag event
-
-  _initDrag: function(event) {
-    // No resize on minimized window
-    if (Event.element(event) == this.sizer && this.isMinimized())
-      return;
-
-    // No move on maximzed window
-    if (Event.element(event) != this.sizer && this.isMaximized())
-      return;
-      
-    if (Prototype.Browser.IE && this.heightN == 0)
-      this._getWindowBorderSize();
-    
-    // Get pointer X,Y
-    this.pointer = [this._round(Event.pointerX(event), this.options.gridX), this._round(Event.pointerY(event), this.options.gridY)];
-    if (this.options.wiredDrag) 
-      this.currentDrag = this._createWiredElement();
-    else
-      this.currentDrag = this.element;
-      
-    // Resize
-    if (Event.element(event) == this.sizer) {
-      this.doResize = true;
-      this.widthOrg = this.width;
-      this.heightOrg = this.height;
-      this.bottomOrg = parseFloat(this.element.getStyle('bottom'));
-      this.rightOrg = parseFloat(this.element.getStyle('right'));
-      this._notify("onStartResize");
-    }
-    else {
-      this.doResize = false;
-
-      // Check if click on close button, 
-      var closeButton = $(this.getId() + '_close');
-      if (closeButton && Position.within(closeButton, this.pointer[0], this.pointer[1])) {
-        this.currentDrag = null;
-        return;
-      }
-
-      this.toFront();
-
-      if (! this.options.draggable) 
-        return;
-      this._notify("onStartMove");
-    }    
-    // Register global event to capture mouseUp and mouseMove
-    Event.observe(document, "mouseup", this.eventMouseUp, false);
-    Event.observe(document, "mousemove", this.eventMouseMove, false);
-    
-    // Add an invisible div to keep catching mouse event over iframes
-    WindowUtilities.disableScreen('__invisible__', '__invisible__', this.overlayOpacity);
-
-    // Stop selection while dragging
-    document.body.ondrag = function () { return false; };
-    document.body.onselectstart = function () { return false; };
-    
-    this.currentDrag.show();
-    Event.stop(event);
-  },
-  
-  _round: function(val, round) {
-    return round == 1 ? val  : val = Math.floor(val / round) * round;
-  },
-
-  // updateDrag event
-  _updateDrag: function(event) {
-    var pointer =  [this._round(Event.pointerX(event), this.options.gridX), this._round(Event.pointerY(event), this.options.gridY)];  
-    var dx = pointer[0] - this.pointer[0];
-    var dy = pointer[1] - this.pointer[1];
-    
-    // Resize case, update width/height
-    if (this.doResize) {
-      var w = this.widthOrg + dx;
-      var h = this.heightOrg + dy;
-      
-      dx = this.width - this.widthOrg
-      dy = this.height - this.heightOrg
-      
-      // Check if it's a right position, update it to keep upper-left corner at the same position
-      if (this.useLeft) 
-        w = this._updateWidthConstraint(w)
-      else 
-        this.currentDrag.setStyle({right: (this.rightOrg -dx) + 'px'});
-      // Check if it's a bottom position, update it to keep upper-left corner at the same position
-      if (this.useTop) 
-        h = this._updateHeightConstraint(h)
-      else
-        this.currentDrag.setStyle({bottom: (this.bottomOrg -dy) + 'px'});
-        
-      this.setSize(w , h);
-      this._notify("onResize");
-    }
-    // Move case, update top/left
-    else {
-      this.pointer = pointer;
-      
-      if (this.useLeft) {
-        var left =  parseFloat(this.currentDrag.getStyle('left')) + dx;
-        var newLeft = this._updateLeftConstraint(left);
-        // Keep mouse pointer correct
-        this.pointer[0] += newLeft-left;
-        this.currentDrag.setStyle({left: newLeft + 'px'});
-      }
-      else 
-        this.currentDrag.setStyle({right: parseFloat(this.currentDrag.getStyle('right')) - dx + 'px'});
-      
-      if (this.useTop) {
-        var top =  parseFloat(this.currentDrag.getStyle('top')) + dy;
-        var newTop = this._updateTopConstraint(top);
-        // Keep mouse pointer correct
-        this.pointer[1] += newTop - top;
-        this.currentDrag.setStyle({top: newTop + 'px'});
-      }
-      else 
-        this.currentDrag.setStyle({bottom: parseFloat(this.currentDrag.getStyle('bottom')) - dy + 'px'});
-
-      this._notify("onMove");
-    }
-    if (this.iefix) 
-      this._fixIEOverlapping(); 
-      
-    this._removeStoreLocation();
-    Event.stop(event);
-  },
-
-   // endDrag callback
-   _endDrag: function(event) {
-    // Remove temporary div over iframes
-     WindowUtilities.enableScreen('__invisible__');
-    
-    if (this.doResize)
-      this._notify("onEndResize");
-    else
-      this._notify("onEndMove");
-    
-    // Release event observing
-    Event.stopObserving(document, "mouseup", this.eventMouseUp,false);
-    Event.stopObserving(document, "mousemove", this.eventMouseMove, false);
-
-    Event.stop(event);
-    
-    this._hideWiredElement();
-
-    // Store new location/size if need be
-    this._saveCookie()
-      
-    // Restore selection
-    document.body.ondrag = null;
-    document.body.onselectstart = null;
-  },
-
-  _updateLeftConstraint: function(left) {
-    if (this.constraint && this.useLeft && this.useTop) {
-      var width = this.options.parent == document.body ? WindowUtilities.getPageSize().windowWidth : this.options.parent.getDimensions().width;
-
-      if (left < this.constraintPad.left)
-        left = this.constraintPad.left;
-      if (left + this.width + this.widthE + this.widthW > width - this.constraintPad.right) 
-        left = width - this.constraintPad.right - this.width - this.widthE - this.widthW;
-    }
-    return left;
-  },
-  
-  _updateTopConstraint: function(top) {
-    if (this.constraint && this.useLeft && this.useTop) {        
-      var height = this.options.parent == document.body ? WindowUtilities.getPageSize().windowHeight : this.options.parent.getDimensions().height;
-      
-      var h = this.height + this.heightN + this.heightS;
-
-      if (top < this.constraintPad.top)
-        top = this.constraintPad.top;
-      if (top + h > height - this.constraintPad.bottom) 
-        top = height - this.constraintPad.bottom - h;
-    }
-    return top;
-  },
-  
-  _updateWidthConstraint: function(w) {
-    if (this.constraint && this.useLeft && this.useTop) {
-      var width = this.options.parent == document.body ? WindowUtilities.getPageSize().windowWidth : this.options.parent.getDimensions().width;
-      var left =  parseFloat(this.element.getStyle("left"));
-
-      if (left + w + this.widthE + this.widthW > width - this.constraintPad.right) 
-        w = width - this.constraintPad.right - left - this.widthE - this.widthW;
-    }
-    return w;
-  },
-  
-  _updateHeightConstraint: function(h) {
-    if (this.constraint && this.useLeft && this.useTop) {
-      var height = this.options.parent == document.body ? WindowUtilities.getPageSize().windowHeight : this.options.parent.getDimensions().height;
-      var top =  parseFloat(this.element.getStyle("top"));
-
-      if (top + h + this.heightN + this.heightS > height - this.constraintPad.bottom) 
-        h = height - this.constraintPad.bottom - top - this.heightN - this.heightS;
-    }
-    return h;
-  },
-  
-  
-  // Creates HTML window code
-  _createWindow: function(id) {
-    var className = this.options.className;
-    var win = document.createElement("div");
-    win.setAttribute('id', id);
-    win.className = "dialog";
-
-    var content;
-    if (this.options.url)
-      content= "<iframe frameborder=\"0\" name=\"" + id + "_content\"  id=\"" + id + "_content\" src=\"" + this.options.url + "\"> </iframe>";
-    else
-      content ="<div id=\"" + id + "_content\" class=\"" +className + "_content\"> </div>";
-
-    var closeDiv = this.options.closable ? "<div class='"+ className +"_close' id='"+ id +"_close' onclick='Windows.close(\""+ id +"\", event)'> </div>" : "";
-    var minDiv = this.options.minimizable ? "<div class='"+ className + "_minimize' id='"+ id +"_minimize' onclick='Windows.minimize(\""+ id +"\", event)'> </div>" : "";
-    var maxDiv = this.options.maximizable ? "<div class='"+ className + "_maximize' id='"+ id +"_maximize' onclick='Windows.maximize(\""+ id +"\", event)'> </div>" : "";
-    var seAttributes = this.options.resizable ? "class='" + className + "_sizer' id='" + id + "_sizer'" : "class='"  + className + "_se'";
-    var blank = "../themes/default/blank.gif";
-    
-    win.innerHTML = closeDiv + minDiv + maxDiv + "\
-      <table id='"+ id +"_row1' class=\"top table_window\">\
-        <tr>\
-          <td class='"+ className +"_nw'></td>\
-          <td class='"+ className +"_n'><div id='"+ id +"_top' class='"+ className +"_title title_window'>"+ this.options.title +"</div></td>\
-          <td class='"+ className +"_ne'></td>\
-        </tr>\
-      </table>\
-      <table id='"+ id +"_row2' class=\"mid table_window\">\
-        <tr>\
-          <td class='"+ className +"_w'></td>\
-            <td id='"+ id +"_table_content' class='"+ className +"_content' valign='top'>" + content + "</td>\
-          <td class='"+ className +"_e'></td>\
-        </tr>\
-      </table>\
-        <table id='"+ id +"_row3' class=\"bot table_window\">\
-        <tr>\
-          <td class='"+ className +"_sw'></td>\
-            <td class='"+ className +"_s'><div id='"+ id +"_bottom' class='status_bar'><span style='float:left; width:1px; height:1px'></span></div></td>\
-            <td " + seAttributes + "></td>\
-        </tr>\
-      </table>\
-    ";
-    Element.hide(win);
-    this.options.parent.insertBefore(win, this.options.parent.firstChild);
-    Event.observe($(id + "_content"), "load", this.options.onload);
-    return win;
-  },
-  
-  
-  changeClassName: function(newClassName) {    
-    var className = this.options.className;
-    var id = this.getId();
-    $A(["_close", "_minimize", "_maximize", "_sizer", "_content"]).each(function(value) { this._toggleClassName($(id + value), className + value, newClassName + value) }.bind(this));
-    this._toggleClassName($(id + "_top"), className + "_title", newClassName + "_title");
-    $$("#" + id + " td").each(function(td) {td.className = td.className.sub(className,newClassName); });
-    this.options.className = newClassName;
-  },
-  
-  _toggleClassName: function(element, oldClassName, newClassName) { 
-    if (element) {
-      element.removeClassName(oldClassName);
-      element.addClassName(newClassName);
-    }
-  },
-  
-  // Sets window location
-  setLocation: function(top, left) {
-    top = this._updateTopConstraint(top);
-    left = this._updateLeftConstraint(left);
-
-    var e = this.currentDrag || this.element;
-    e.setStyle({top: top + 'px'});
-    e.setStyle({left: left + 'px'});
-
-    this.useLeft = true;
-    this.useTop = true;
-  },
-    
-  getLocation: function() {
-    var location = {};
-    if (this.useTop)
-      location = Object.extend(location, {top: this.element.getStyle("top")});
-    else
-      location = Object.extend(location, {bottom: this.element.getStyle("bottom")});
-    if (this.useLeft)
-      location = Object.extend(location, {left: this.element.getStyle("left")});
-    else
-      location = Object.extend(location, {right: this.element.getStyle("right")});
-    
-    return location;
-  },
-  
-  // Gets window size
-  getSize: function() {
-    return {width: this.width, height: this.height};
-  },
-    
-  // Sets window size
-  setSize: function(width, height, useEffect) {    
-    width = parseFloat(width);
-    height = parseFloat(height);
-    
-    // Check min and max size
-    if (!this.minimized && width < this.options.minWidth)
-      width = this.options.minWidth;
-
-    if (!this.minimized && height < this.options.minHeight)
-      height = this.options.minHeight;
-      
-    if (this.options. maxHeight && height > this.options. maxHeight)
-      height = this.options. maxHeight;
-
-    if (this.options. maxWidth && width > this.options. maxWidth)
-      width = this.options. maxWidth;
-
-    
-    if (this.useTop && this.useLeft && Window.hasEffectLib && Effect.ResizeWindow && useEffect) {
-      new Effect.ResizeWindow(this, null, null, width, height, {duration: Window.resizeEffectDuration});
-    } else {
-      this.width = width;
-      this.height = height;
-      var e = this.currentDrag ? this.currentDrag : this.element;
-
-      e.setStyle({width: width + this.widthW + this.widthE + "px"})
-      e.setStyle({height: height  + this.heightN + this.heightS + "px"})
-
-      // Update content size
-      if (!this.currentDrag || this.currentDrag == this.element) {
-        var content = $(this.element.id + '_content');
-        content.setStyle({height: height  + 'px'});
-        content.setStyle({width: width  + 'px'});
-      }
-    }
-  },
-  
-  updateHeight: function() {
-    this.setSize(this.width, this.content.scrollHeight, true);
-  },
-  
-  updateWidth: function() {
-    this.setSize(this.content.scrollWidth, this.height, true);
-  },
-  
-  // Brings window to front
-  toFront: function() {
-    if (this.element.style.zIndex < Windows.maxZIndex)  
-      this.setZIndex(Windows.maxZIndex + 1);
-    if (this.iefix) 
-      this._fixIEOverlapping(); 
-  },
-   
-  getBounds: function(insideOnly) {
-    if (! this.width || !this.height || !this.visible)  
-      this.computeBounds();
-    var w = this.width;
-    var h = this.height;
-
-    if (!insideOnly) {
-      w += this.widthW + this.widthE;
-      h += this.heightN + this.heightS;
-    }
-    var bounds = Object.extend(this.getLocation(), {width: w + "px", height: h + "px"});
-    return bounds;
-  },
-      
-  computeBounds: function() {
-     if (! this.width || !this.height) {
-      var size = WindowUtilities._computeSize(this.content.innerHTML, this.content.id, this.width, this.height, 0, this.options.className)
-      if (this.height)
-        this.width = size + 5
-      else
-        this.height = size + 5
-    }
-
-    this.setSize(this.width, this.height);
-    if (this.centered)
-      this._center(this.centerTop, this.centerLeft);    
-  },
-  
-  // Displays window modal state or not
-  show: function(modal) {
-    this.visible = true;
-    if (modal) {
-      // Hack for Safari !!
-      if (typeof this.overlayOpacity == "undefined") {
-        var that = this;
-        setTimeout(function() {that.show(modal)}, 10);
-        return;
-      }
-      Windows.addModalWindow(this);
-      
-      this.modal = true;      
-      this.setZIndex(Windows.maxZIndex + 1);
-      Windows.unsetOverflow(this);
-    }
-    else    
-      if (!this.element.style.zIndex) 
-        this.setZIndex(Windows.maxZIndex + 1);        
-      
-    // To restore overflow if need be
-    if (this.oldStyle)
-      this.getContent().setStyle({overflow: this.oldStyle});
-      
-    this.computeBounds();
-    
-    this._notify("onBeforeShow");   
-    if (this.options.showEffect != Element.show && this.options.showEffectOptions)
-      this.options.showEffect(this.element, this.options.showEffectOptions);  
-    else
-      this.options.showEffect(this.element);  
-      
-    this._checkIEOverlapping();
-    WindowUtilities.focusedWindow = this
-    this._notify("onShow");   
-  },
-  
-  // Displays window modal state or not at the center of the page
-  showCenter: function(modal, top, left) {
-    this.centered = true;
-    this.centerTop = top;
-    this.centerLeft = left;
-
-    this.show(modal);
-  },
-  
-  isVisible: function() {
-    return this.visible;
-  },
-  
-  _center: function(top, left) {    
-    var windowScroll = WindowUtilities.getWindowScroll(this.options.parent);    
-    var pageSize = WindowUtilities.getPageSize(this.options.parent);    
-    if (typeof top == "undefined")
-      top = (pageSize.windowHeight - (this.height + this.heightN + this.heightS))/2;
-    top += windowScroll.top
-    
-    if (typeof left == "undefined")
-      left = (pageSize.windowWidth - (this.width + this.widthW + this.widthE))/2;
-    left += windowScroll.left      
-    this.setLocation(top, left);
-    this.toFront();
-  },
-  
-  _recenter: function(event) {     
-    if (this.centered) {
-      var pageSize = WindowUtilities.getPageSize(this.options.parent);
-      var windowScroll = WindowUtilities.getWindowScroll(this.options.parent);    
-
-      // Check for this stupid IE that sends dumb events
-      if (this.pageSize && this.pageSize.windowWidth == pageSize.windowWidth && this.pageSize.windowHeight == pageSize.windowHeight && 
-          this.windowScroll.left == windowScroll.left && this.windowScroll.top == windowScroll.top) 
-        return;
-      this.pageSize = pageSize;
-      this.windowScroll = windowScroll;
-      // set height of Overlay to take up whole page and show
-      if ($('overlay_modal')) 
-        $('overlay_modal').setStyle({height: (pageSize.pageHeight + 'px')});
-      
-      if (this.options.recenterAuto)
-        this._center(this.centerTop, this.centerLeft);    
-    }
-  },
-  
-  // Hides window
-  hide: function() {
-    this.visible = false;
-    if (this.modal) {
-      Windows.removeModalWindow(this);
-      Windows.resetOverflow();
-    }
-    // To avoid bug on scrolling bar
-    this.oldStyle = this.getContent().getStyle('overflow') || "auto"
-    this.getContent().setStyle({overflow: "hidden"});
-
-    this.options.hideEffect(this.element, this.options.hideEffectOptions);  
-
-     if(this.iefix) 
-      this.iefix.hide();
-
-    if (!this.doNotNotifyHide)
-      this._notify("onHide");
-  },
-
-  close: function() {
-    // Asks closeCallback if exists
-    if (this.visible) {
-      if (this.options.closeCallback && ! this.options.closeCallback(this)) 
-        return;
-
-      if (this.options.destroyOnClose) {
-        var destroyFunc = this.destroy.bind(this);
-        if (this.options.hideEffectOptions.afterFinish) {
-          var func = this.options.hideEffectOptions.afterFinish;
-          this.options.hideEffectOptions.afterFinish = function() {func();destroyFunc() }
-        }
-        else 
-          this.options.hideEffectOptions.afterFinish = function() {destroyFunc() }
-      }
-      Windows.updateFocusedWindow();
-      
-      this.doNotNotifyHide = true;
-      this.hide();
-      this.doNotNotifyHide = false;
-      this._notify("onClose");
-    }
-  },
-  
-  minimize: function() {
-    if (this.resizing)
-      return;
-    
-    var r2 = $(this.getId() + "_row2");
-    
-    if (!this.minimized) {
-      this.minimized = true;
-
-      var dh = r2.getDimensions().height;
-      this.r2Height = dh;
-      var h  = this.element.getHeight() - dh;
-
-      if (this.useLeft && this.useTop && Window.hasEffectLib && Effect.ResizeWindow) {
-        new Effect.ResizeWindow(this, null, null, null, this.height -dh, {duration: Window.resizeEffectDuration});
-      } else  {
-        this.height -= dh;
-        this.element.setStyle({height: h + "px"});
-        r2.hide();
-      }
-
-      if (! this.useTop) {
-        var bottom = parseFloat(this.element.getStyle('bottom'));
-        this.element.setStyle({bottom: (bottom + dh) + 'px'});
-      }
-    } 
-    else {      
-      this.minimized = false;
-      
-      var dh = this.r2Height;
-      this.r2Height = null;
-      if (this.useLeft && this.useTop && Window.hasEffectLib && Effect.ResizeWindow) {
-        new Effect.ResizeWindow(this, null, null, null, this.height + dh, {duration: Window.resizeEffectDuration});
-      }
-      else {
-        var h  = this.element.getHeight() + dh;
-        this.height += dh;
-        this.element.setStyle({height: h + "px"})
-        r2.show();
-      }
-      if (! this.useTop) {
-        var bottom = parseFloat(this.element.getStyle('bottom'));
-        this.element.setStyle({bottom: (bottom - dh) + 'px'});
-      }
-      this.toFront();
-    }
-    this._notify("onMinimize");
-    
-    // Store new location/size if need be
-    this._saveCookie()
-  },
-  
-  maximize: function() {
-    if (this.isMinimized() || this.resizing)
-      return;
-  
-    if (Prototype.Browser.IE && this.heightN == 0)
-      this._getWindowBorderSize();
-      
-    if (this.storedLocation != null) {
-      this._restoreLocation();
-      if(this.iefix) 
-        this.iefix.hide();
-    }
-    else {
-      this._storeLocation();
-      Windows.unsetOverflow(this);
-      
-      var windowScroll = WindowUtilities.getWindowScroll(this.options.parent);
-      var pageSize = WindowUtilities.getPageSize(this.options.parent);    
-      var left = windowScroll.left;
-      var top = windowScroll.top;
-      
-      if (this.options.parent != document.body) {
-        windowScroll =  {top:0, left:0, bottom:0, right:0};
-        var dim = this.options.parent.getDimensions();
-        pageSize.windowWidth = dim.width;
-        pageSize.windowHeight = dim.height;
-        top = 0; 
-        left = 0;
-      }
-      
-      if (this.constraint) {
-        pageSize.windowWidth -= Math.max(0, this.constraintPad.left) + Math.max(0, this.constraintPad.right);
-        pageSize.windowHeight -= Math.max(0, this.constraintPad.top) + Math.max(0, this.constraintPad.bottom);
-        left +=  Math.max(0, this.constraintPad.left);
-        top +=  Math.max(0, this.constraintPad.top);
-      }
-      
-      var width = pageSize.windowWidth - this.widthW - this.widthE;
-      var height= pageSize.windowHeight - this.heightN - this.heightS;
-
-      if (this.useLeft && this.useTop && Window.hasEffectLib && Effect.ResizeWindow) {
-        new Effect.ResizeWindow(this, top, left, width, height, {duration: Window.resizeEffectDuration});
-      }
-      else {
-        this.setSize(width, height);
-        this.element.setStyle(this.useLeft ? {left: left} : {right: left});
-        this.element.setStyle(this.useTop ? {top: top} : {bottom: top});
-      }
-        
-      this.toFront();
-      if (this.iefix) 
-        this._fixIEOverlapping(); 
-    }
-    this._notify("onMaximize");
-
-    // Store new location/size if need be
-    this._saveCookie()
-  },
-  
-  isMinimized: function() {
-    return this.minimized;
-  },
-  
-  isMaximized: function() {
-    return (this.storedLocation != null);
-  },
-  
-  setOpacity: function(opacity) {
-    if (Element.setOpacity)
-      Element.setOpacity(this.element, opacity);
-  },
-  
-  setZIndex: function(zindex) {
-    this.element.setStyle({zIndex: zindex});
-    Windows.updateZindex(zindex, this);
-  },
-
-  setTitle: function(newTitle) {
-    if (!newTitle || newTitle == "") 
-      newTitle = "&nbsp;";
-      
-    Element.update(this.element.id + '_top', newTitle);
-  },
-   
-  getTitle: function() {
-    return $(this.element.id + '_top').innerHTML;
-  },
-  
-  setStatusBar: function(element) {
-    var statusBar = $(this.getId() + "_bottom");
-
-    if (typeof(element) == "object") {
-      if (this.bottombar.firstChild)
-        this.bottombar.replaceChild(element, this.bottombar.firstChild);
-      else
-        this.bottombar.appendChild(element);
-    }
-    else
-      this.bottombar.innerHTML = element;
-  },
-
-  _checkIEOverlapping: function() {
-    if(!this.iefix && (navigator.appVersion.indexOf('MSIE')>0) && (navigator.userAgent.indexOf('Opera')<0) && (this.element.getStyle('position')=='absolute')) {
-        new Insertion.After(this.element.id, '<iframe id="' + this.element.id + '_iefix" '+ 'style="display:none;position:absolute;filter:progid:DXImageTransform.Microsoft.Alpha(opacity=0);" ' + 'src="javascript:false;" frameborder="0" scrolling="no"></iframe>');
-        this.iefix = $(this.element.id+'_iefix');
-    }
-    if(this.iefix) 
-      setTimeout(this._fixIEOverlapping.bind(this), 50);
-  },
-
-  _fixIEOverlapping: function() {
-      Position.clone(this.element, this.iefix);
-      this.iefix.style.zIndex = this.element.style.zIndex - 1;
-      this.iefix.show();
-  },
-  
-  _getWindowBorderSize: function(event) {
-    // Hack to get real window border size!!
-    var div = this._createHiddenDiv(this.options.className + "_n")
-    this.heightN = Element.getDimensions(div).height;    
-    div.parentNode.removeChild(div)
-
-    var div = this._createHiddenDiv(this.options.className + "_s")
-    this.heightS = Element.getDimensions(div).height;    
-    div.parentNode.removeChild(div)
-
-    var div = this._createHiddenDiv(this.options.className + "_e")
-    this.widthE = Element.getDimensions(div).width;    
-    div.parentNode.removeChild(div)
-
-    var div = this._createHiddenDiv(this.options.className + "_w")
-    this.widthW = Element.getDimensions(div).width;
-    div.parentNode.removeChild(div);
-    
-    var div = document.createElement("div");
-    div.className = "overlay_" + this.options.className ;
-    document.body.appendChild(div);
-    //alert("no timeout:\nopacity: " + div.getStyle("opacity") + "\nwidth: " + document.defaultView.getComputedStyle(div, null).width);
-    var that = this;
-    
-    // Workaround for Safari!!
-    setTimeout(function() {that.overlayOpacity = ($(div).getStyle("opacity")); div.parentNode.removeChild(div);}, 10);
-    
-    // Workaround for IE!!
-    if (Prototype.Browser.IE) {
-      this.heightS = $(this.getId() +"_row3").getDimensions().height;
-      this.heightN = $(this.getId() +"_row1").getDimensions().height;
-    }
-
-    // Safari size fix
-    if (Prototype.Browser.WebKit && Prototype.Browser.WebKitVersion < 420)
-      this.setSize(this.width, this.height);
-    if (this.doMaximize)
-      this.maximize();
-    if (this.doMinimize)
-      this.minimize();
-  },
-  _createHiddenDiv: function(className) {
-    var objBody = document.body;
-    var win = document.createElement("div");
-    win.setAttribute('id', this.element.id+ "_tmp");
-    win.className = className;
-    win.style.display = 'none';
-    win.innerHTML = '';
-    objBody.insertBefore(win, objBody.firstChild);
-    return win;
-  },
-  
-  _storeLocation: function() {
-    if (this.storedLocation == null) {
-      this.storedLocation = {useTop: this.useTop, useLeft: this.useLeft, 
-                             top: this.element.getStyle('top'), bottom: this.element.getStyle('bottom'),
-                             left: this.element.getStyle('left'), right: this.element.getStyle('right'),
-                             width: this.width, height: this.height };
-    }
-  },
-  
-  _restoreLocation: function() {
-    if (this.storedLocation != null) {
-      this.useLeft = this.storedLocation.useLeft;
-      this.useTop = this.storedLocation.useTop;
-      
-      if (this.useLeft && this.useTop && Window.hasEffectLib && Effect.ResizeWindow)
-        new Effect.ResizeWindow(this, this.storedLocation.top, this.storedLocation.left, this.storedLocation.width, this.storedLocation.height, {duration: Window.resizeEffectDuration});
-      else {
-        this.element.setStyle(this.useLeft ? {left: this.storedLocation.left} : {right: this.storedLocation.right});
-        this.element.setStyle(this.useTop ? {top: this.storedLocation.top} : {bottom: this.storedLocation.bottom});
-        this.setSize(this.storedLocation.width, this.storedLocation.height);
-      }
-      
-      Windows.resetOverflow();
-      this._removeStoreLocation();
-    }
-  },
-  
-  _removeStoreLocation: function() {
-    this.storedLocation = null;
-  },
-  
-  _saveCookie: function() {
-    if (this.cookie) {
-      var value = "";
-      if (this.useLeft)
-        value += "l:" +  (this.storedLocation ? this.storedLocation.left : this.element.getStyle('left'))
-      else
-        value += "r:" + (this.storedLocation ? this.storedLocation.right : this.element.getStyle('right'))
-      if (this.useTop)
-        value += ",t:" + (this.storedLocation ? this.storedLocation.top : this.element.getStyle('top'))
-      else
-        value += ",b:" + (this.storedLocation ? this.storedLocation.bottom :this.element.getStyle('bottom'))
-        
-      value += "," + (this.storedLocation ? this.storedLocation.width : this.width);
-      value += "," + (this.storedLocation ? this.storedLocation.height : this.height);
-      value += "," + this.isMinimized();
-      value += "," + this.isMaximized();
-      WindowUtilities.setCookie(value, this.cookie)
-    }
-  },
-  
-  _createWiredElement: function() {
-    if (! this.wiredElement) {
-      if (Prototype.Browser.IE)
-        this._getWindowBorderSize();
-      var div = document.createElement("div");
-      div.className = "wired_frame " + this.options.className + "_wired_frame";
-      
-      div.style.position = 'absolute';
-      this.options.parent.insertBefore(div, this.options.parent.firstChild);
-      this.wiredElement = $(div);
-    }
-    if (this.useLeft) 
-      this.wiredElement.setStyle({left: this.element.getStyle('left')});
-    else 
-      this.wiredElement.setStyle({right: this.element.getStyle('right')});
-      
-    if (this.useTop) 
-      this.wiredElement.setStyle({top: this.element.getStyle('top')});
-    else 
-      this.wiredElement.setStyle({bottom: this.element.getStyle('bottom')});
-
-    var dim = this.element.getDimensions();
-    this.wiredElement.setStyle({width: dim.width + "px", height: dim.height +"px"});
-
-    this.wiredElement.setStyle({zIndex: Windows.maxZIndex+30});
-    return this.wiredElement;
-  },
-  
-  _hideWiredElement: function() {
-    if (! this.wiredElement || ! this.currentDrag)
-      return;
-    if (this.currentDrag == this.element) 
-      this.currentDrag = null;
-    else {
-      if (this.useLeft) 
-        this.element.setStyle({left: this.currentDrag.getStyle('left')});
-      else 
-        this.element.setStyle({right: this.currentDrag.getStyle('right')});
-
-      if (this.useTop) 
-        this.element.setStyle({top: this.currentDrag.getStyle('top')});
-      else 
-        this.element.setStyle({bottom: this.currentDrag.getStyle('bottom')});
-
-      this.currentDrag.hide();
-      this.currentDrag = null;
-      if (this.doResize)
-        this.setSize(this.width, this.height);
-    } 
-  },
-  
-  _notify: function(eventName) {
-    if (this.options[eventName])
-      this.options[eventName](this);
-    else
-      Windows.notify(eventName, this);
-  }
-};
-
-// Windows containers, register all page windows
-var Windows = {
-  windows: [],
-  modalWindows: [],
-  observers: [],
-  focusedWindow: null,
-  maxZIndex: 0,
-  overlayShowEffectOptions: {duration: 0.5},
-  overlayHideEffectOptions: {duration: 0.5},
-
-  addObserver: function(observer) {
-    this.removeObserver(observer);
-    this.observers.push(observer);
-  },
-  
-  removeObserver: function(observer) {  
-    this.observers = this.observers.reject( function(o) { return o==observer });
-  },
-  
-  // onDestroy onStartResize onStartMove onResize onMove onEndResize onEndMove onFocus onBlur onBeforeShow onShow onHide onMinimize onMaximize onClose
-  notify: function(eventName, win) {  
-    this.observers.each( function(o) {if(o[eventName]) o[eventName](eventName, win);});
-  },
-
-  // Gets window from its id
-  getWindow: function(id) {
-    return this.windows.detect(function(d) { return d.getId() ==id });
-  },
-
-  // Gets the last focused window
-  getFocusedWindow: function() {
-    return this.focusedWindow;
-  },
-
-  updateFocusedWindow: function() {
-    this.focusedWindow = this.windows.length >=2 ? this.windows[this.windows.length-2] : null;    
-  },
-  
-  // Registers a new window (called by Windows constructor)
-  register: function(win) {
-    this.windows.push(win);
-  },
-    
-  // Add a modal window in the stack
-  addModalWindow: function(win) {
-    // Disable screen if first modal window
-    if (this.modalWindows.length == 0) {
-      WindowUtilities.disableScreen(win.options.className, 'overlay_modal', win.overlayOpacity, win.getId(), win.options.parent);
-    }
-    else {
-      // Move overlay over all windows
-      if (Window.keepMultiModalWindow) {
-        $('overlay_modal').style.zIndex = Windows.maxZIndex + 1;
-        Windows.maxZIndex += 1;
-        WindowUtilities._hideSelect(this.modalWindows.last().getId());
-      }
-      // Hide current modal window
-      else
-        this.modalWindows.last().element.hide();
-      // Fucking IE select issue
-      WindowUtilities._showSelect(win.getId());
-    }      
-    this.modalWindows.push(win);    
-  },
-  
-  removeModalWindow: function(win) {
-    this.modalWindows.pop();
-    
-    // No more modal windows
-    if (this.modalWindows.length == 0)
-      WindowUtilities.enableScreen();     
-    else {
-      if (Window.keepMultiModalWindow) {
-        this.modalWindows.last().toFront();
-        WindowUtilities._showSelect(this.modalWindows.last().getId());        
-      }
-      else
-        this.modalWindows.last().element.show();
-    }
-  },
-  
-  // Registers a new window (called by Windows constructor)
-  register: function(win) {
-    this.windows.push(win);
-  },
-  
-  // Unregisters a window (called by Windows destructor)
-  unregister: function(win) {
-    this.windows = this.windows.reject(function(d) { return d==win });
-  }, 
-  
-  // Closes all windows
-  closeAll: function() {  
-    this.windows.each( function(w) {Windows.close(w.getId())} );
-  },
-  
-  closeAllModalWindows: function() {
-    WindowUtilities.enableScreen();     
-    this.modalWindows.each( function(win) {if (win) win.close()});    
-  },
-
-  // Minimizes a window with its id
-  minimize: function(id, event) {
-    var win = this.getWindow(id)
-    if (win && win.visible)
-      win.minimize();
-    Event.stop(event);
-  },
-  
-  // Maximizes a window with its id
-  maximize: function(id, event) {
-    var win = this.getWindow(id)
-    if (win && win.visible)
-      win.maximize();
-    Event.stop(event);
-  },
-
-  // Closes a window with its id
-  close: function(id, event) {
-    var win = this.getWindow(id);
-    if (win) 
-      win.close();
-    if (event)
-      Event.stop(event);
-  },
-  
-  blur: function(id) {
-    var win = this.getWindow(id);  
-    if (!win)
-      return;
-    if (win.options.blurClassName)
-      win.changeClassName(win.options.blurClassName);
-    if (this.focusedWindow == win)  
-      this.focusedWindow = null;
-    win._notify("onBlur");  
-  },
-  
-  focus: function(id) {
-    var win = this.getWindow(id);  
-    if (!win)
-      return;       
-    if (this.focusedWindow)
-      this.blur(this.focusedWindow.getId())
-
-    if (win.options.focusClassName)
-      win.changeClassName(win.options.focusClassName);  
-    this.focusedWindow = win;
-    win._notify("onFocus");
-  },
-  
-  unsetOverflow: function(except) {    
-    this.windows.each(function(d) { d.oldOverflow = d.getContent().getStyle("overflow") || "auto" ; d.getContent().setStyle({overflow: "hidden"}) });
-    if (except && except.oldOverflow)
-      except.getContent().setStyle({overflow: except.oldOverflow});
-  },
-
-  resetOverflow: function() {
-    this.windows.each(function(d) { if (d.oldOverflow) d.getContent().setStyle({overflow: d.oldOverflow}) });
-  },
-
-  updateZindex: function(zindex, win) { 
-    if (zindex > this.maxZIndex) {   
-      this.maxZIndex = zindex;    
-      if (this.focusedWindow) 
-        this.blur(this.focusedWindow.getId())
-    }
-    this.focusedWindow = win;
-    if (this.focusedWindow) 
-      this.focus(this.focusedWindow.getId())
-  }
-};
-
-var Dialog = {
-  dialogId: null,
-  onCompleteFunc: null,
-  callFunc: null, 
-  parameters: null, 
-    
-  confirm: function(content, parameters) {
-    // Get Ajax return before
-    if (content && typeof content != "string") {
-      Dialog._runAjaxRequest(content, parameters, Dialog.confirm);
-      return 
-    }
-    content = content || "";
-    
-    parameters = parameters || {};
-    var okLabel = parameters.okLabel ? parameters.okLabel : "Ok";
-    var cancelLabel = parameters.cancelLabel ? parameters.cancelLabel : "Cancel";
-
-    // Backward compatibility
-    parameters = Object.extend(parameters, parameters.windowParameters || {});
-    parameters.windowParameters = parameters.windowParameters || {};
-
-    parameters.className = parameters.className || "alert";
-
-    var okButtonClass = "class ='" + (parameters.buttonClass ? parameters.buttonClass + " " : "") + " ok_button'" 
-    var cancelButtonClass = "class ='" + (parameters.buttonClass ? parameters.buttonClass + " " : "") + " cancel_button'" 
-    var content = "\
-      <div class='" + parameters.className + "_message'>" + content  + "</div>\
-        <div class='" + parameters.className + "_buttons'>\
-          <input type='button' value='" + okLabel + "' onclick='Dialog.okCallback()' " + okButtonClass + "/>\
-          <input type='button' value='" + cancelLabel + "' onclick='Dialog.cancelCallback()' " + cancelButtonClass + "/>\
-        </div>\
-    ";
-    return this._openDialog(content, parameters)
-  },
-  
-  alert: function(content, parameters) {
-    // Get Ajax return before
-    if (content && typeof content != "string") {
-      Dialog._runAjaxRequest(content, parameters, Dialog.alert);
-      return 
-    }
-    content = content || "";
-    
-    parameters = parameters || {};
-    var okLabel = parameters.okLabel ? parameters.okLabel : "Ok";
-
-    // Backward compatibility    
-    parameters = Object.extend(parameters, parameters.windowParameters || {});
-    parameters.windowParameters = parameters.windowParameters || {};
-    
-    parameters.className = parameters.className || "alert";
-    
-    var okButtonClass = "class ='" + (parameters.buttonClass ? parameters.buttonClass + " " : "") + " ok_button'" 
-    var content = "\
-      <div class='" + parameters.className + "_message'>" + content  + "</div>\
-        <div class='" + parameters.className + "_buttons'>\
-          <input type='button' value='" + okLabel + "' onclick='Dialog.okCallback()' " + okButtonClass + "/>\
-        </div>";                  
-    return this._openDialog(content, parameters)
-  },
-  
-  info: function(content, parameters) {   
-    // Get Ajax return before
-    if (content && typeof content != "string") {
-      Dialog._runAjaxRequest(content, parameters, Dialog.info);
-      return 
-    }
-    content = content || "";
-     
-    // Backward compatibility
-    parameters = parameters || {};
-    parameters = Object.extend(parameters, parameters.windowParameters || {});
-    parameters.windowParameters = parameters.windowParameters || {};
-    
-    parameters.className = parameters.className || "alert";
-    
-    var content = "<div id='modal_dialog_message' class='" + parameters.className + "_message'>" + content  + "</div>";
-    if (parameters.showProgress)
-      content += "<div id='modal_dialog_progress' class='" + parameters.className + "_progress'>  </div>";
-
-    parameters.ok = null;
-    parameters.cancel = null;
-    
-    return this._openDialog(content, parameters)
-  },
-  
-  setInfoMessage: function(message) {
-    $('modal_dialog_message').update(message);
-  },
-  
-  closeInfo: function() {
-    Windows.close(this.dialogId);
-  },
-  
-  _openDialog: function(content, parameters) {
-    var className = parameters.className;
-    
-    if (! parameters.height && ! parameters.width) {
-      parameters.width = WindowUtilities.getPageSize(parameters.options.parent || document.body).pageWidth / 2;
-    }
-    if (parameters.id)
-      this.dialogId = parameters.id;
-    else { 
-      var t = new Date();
-      this.dialogId = 'modal_dialog_' + t.getTime();
-      parameters.id = this.dialogId;
-    }
-
-    // compute height or width if need be
-    if (! parameters.height || ! parameters.width) {
-      var size = WindowUtilities._computeSize(content, this.dialogId, parameters.width, parameters.height, 5, className)
-      if (parameters.height)
-        parameters.width = size + 5
-      else
-        parameters.height = size + 5
-    }
-    parameters.effectOptions = parameters.effectOptions ;
-    parameters.resizable   = parameters.resizable || false;
-    parameters.minimizable = parameters.minimizable || false;
-    parameters.maximizable = parameters.maximizable ||  false;
-    parameters.draggable   = parameters.draggable || false;
-    parameters.closable    = parameters.closable || false;
-    
-    var win = new Window(parameters);
-    win.getContent().innerHTML = content;
-    
-    win.showCenter(true, parameters.top, parameters.left);  
-    win.setDestroyOnClose();
-    
-    win.cancelCallback = parameters.onCancel || parameters.cancel; 
-    win.okCallback = parameters.onOk || parameters.ok;
-    
-    return win;    
-  },
-  
-  _getAjaxContent: function(originalRequest)  {
-      Dialog.callFunc(originalRequest.responseText, Dialog.parameters)
-  },
-  
-  _runAjaxRequest: function(message, parameters, callFunc) {
-    if (message.options == null)
-      message.options = {}  
-    Dialog.onCompleteFunc = message.options.onComplete;
-    Dialog.parameters = parameters;
-    Dialog.callFunc = callFunc;
-    
-    message.options.onComplete = Dialog._getAjaxContent;
-    new Ajax.Request(message.url, message.options);
-  },
-  
-  okCallback: function() {
-    var win = Windows.focusedWindow;
-    if (!win.okCallback || win.okCallback(win)) {
-      // Remove onclick on button
-      $$("#" + win.getId()+" input").each(function(element) {element.onclick=null;})
-      win.close();
-    }
-  },
-
-  cancelCallback: function() {
-    var win = Windows.focusedWindow;
-    // Remove onclick on button
-    $$("#" + win.getId()+" input").each(function(element) {element.onclick=null})
-    win.close();
-    if (win.cancelCallback)
-      win.cancelCallback(win);
-  }
-}
-/*
-  Based on Lightbox JS: Fullsize Image Overlays 
-  by Lokesh Dhakar - http://www.huddletogether.com
-
-  For more information on this script, visit:
-  http://huddletogether.com/projects/lightbox/
-
-  Licensed under the Creative Commons Attribution 2.5 License - http://creativecommons.org/licenses/by/2.5/
-  (basically, do anything you want, just leave my name and link)
-*/
-
-if (Prototype.Browser.WebKit) {
-  var array = navigator.userAgent.match(new RegExp(/AppleWebKit\/([\d\.\+]*)/));
-  Prototype.Browser.WebKitVersion = parseFloat(array[1]);
-}
-
-var WindowUtilities = {  
-  // From dragdrop.js
-  getWindowScroll: function(parent) {
-    var T, L, W, H;
-    parent = parent || document.body;              
-    if (parent != document.body) {
-      T = parent.scrollTop;
-      L = parent.scrollLeft;
-      W = parent.scrollWidth;
-      H = parent.scrollHeight;
-    } 
-    else {
-      var w = window;
-      with (w.document) {
-        if (w.document.documentElement && documentElement.scrollTop) {
-          T = documentElement.scrollTop;
-          L = documentElement.scrollLeft;
-        } else if (w.document.body) {
-          T = body.scrollTop;
-          L = body.scrollLeft;
-        }
-        if (w.innerWidth) {
-          W = w.innerWidth;
-          H = w.innerHeight;
-        } else if (w.document.documentElement && documentElement.clientWidth) {
-          W = documentElement.clientWidth;
-          H = documentElement.clientHeight;
-        } else {
-          W = body.offsetWidth;
-          H = body.offsetHeight
-        }
-      }
-    }
-    return { top: T, left: L, width: W, height: H };
-  }, 
-  //
-  // getPageSize()
-  // Returns array with page width, height and window width, height
-  // Core code from - quirksmode.org
-  // Edit for Firefox by pHaez
-  //
-  getPageSize: function(parent){
-    parent = parent || document.body;              
-    var windowWidth, windowHeight;
-    var pageHeight, pageWidth;
-    if (parent != document.body) {
-      windowWidth = parent.getWidth();
-      windowHeight = parent.getHeight();                                
-      pageWidth = parent.scrollWidth;
-      pageHeight = parent.scrollHeight;                                
-    } 
-    else {
-      var xScroll, yScroll;
-
-      if (window.innerHeight && window.scrollMaxY) {  
-        xScroll = document.body.scrollWidth;
-        yScroll = window.innerHeight + window.scrollMaxY;
-      } else if (document.body.scrollHeight > document.body.offsetHeight){ // all but Explorer Mac
-        xScroll = document.body.scrollWidth;
-        yScroll = document.body.scrollHeight;
-      } else { // Explorer Mac...would also work in Explorer 6 Strict, Mozilla and Safari
-        xScroll = document.body.offsetWidth;
-        yScroll = document.body.offsetHeight;
-      }
-
-
-      if (self.innerHeight) {  // all except Explorer
-        windowWidth = self.innerWidth;
-        windowHeight = self.innerHeight;
-      } else if (document.documentElement && document.documentElement.clientHeight) { // Explorer 6 Strict Mode
-        windowWidth = document.documentElement.clientWidth;
-        windowHeight = document.documentElement.clientHeight;
-      } else if (document.body) { // other Explorers
-        windowWidth = document.body.clientWidth;
-        windowHeight = document.body.clientHeight;
-      }  
-
-      // for small pages with total height less then height of the viewport
-      if(yScroll < windowHeight){
-        pageHeight = windowHeight;
-      } else { 
-        pageHeight = yScroll;
-      }
-
-      // for small pages with total width less then width of the viewport
-      if(xScroll < windowWidth){  
-        pageWidth = windowWidth;
-      } else {
-        pageWidth = xScroll;
-      }
-    }             
-    return {pageWidth: pageWidth ,pageHeight: pageHeight , windowWidth: windowWidth, windowHeight: windowHeight};
-  },
-
-  disableScreen: function(className, overlayId, overlayOpacity, contentId, parent) {
-    WindowUtilities.initLightbox(overlayId, className, function() {this._disableScreen(className, overlayId, overlayOpacity, contentId)}.bind(this), parent || document.body);
-  },
-
-  _disableScreen: function(className, overlayId, overlayOpacity, contentId) {
-    // prep objects
-    var objOverlay = $(overlayId);
-
-    var pageSize = WindowUtilities.getPageSize(objOverlay.parentNode);
-
-    // Hide select boxes as they will 'peek' through the image in IE, store old value
-    if (contentId && Prototype.Browser.IE) {
-      WindowUtilities._hideSelect();
-      WindowUtilities._showSelect(contentId);
-    }  
-  
-    // set height of Overlay to take up whole page and show
-    objOverlay.style.height = (pageSize.pageHeight + 'px');
-    objOverlay.style.display = 'none'; 
-    if (overlayId == "overlay_modal" && Window.hasEffectLib && Windows.overlayShowEffectOptions) {
-      objOverlay.overlayOpacity = overlayOpacity;
-      new Effect.Appear(objOverlay, Object.extend({from: 0, to: overlayOpacity}, Windows.overlayShowEffectOptions));
-    }
-    else
-      objOverlay.style.display = "block";
-  },
-  
-  enableScreen: function(id) {
-    id = id || 'overlay_modal';
-    var objOverlay =  $(id);
-    if (objOverlay) {
-      // hide lightbox and overlay
-      if (id == "overlay_modal" && Window.hasEffectLib && Windows.overlayHideEffectOptions)
-        new Effect.Fade(objOverlay, Object.extend({from: objOverlay.overlayOpacity, to:0}, Windows.overlayHideEffectOptions));
-      else {
-        objOverlay.style.display = 'none';
-        objOverlay.parentNode.removeChild(objOverlay);
-      }
-      
-      // make select boxes visible using old value
-      if (id != "__invisible__") 
-        WindowUtilities._showSelect();
-    }
-  },
-
-  _hideSelect: function(id) {
-    if (Prototype.Browser.IE) {
-      id = id ==  null ? "" : "#" + id + " ";
-      $$(id + 'select').each(function(element) {
-        if (! WindowUtilities.isDefined(element.oldVisibility)) {
-          element.oldVisibility = element.style.visibility ? element.style.visibility : "visible";
-          element.style.visibility = "hidden";
-        }
-      });
-    }
-  },
-  
-  _showSelect: function(id) {
-    if (Prototype.Browser.IE) {
-      id = id ==  null ? "" : "#" + id + " ";
-      $$(id + 'select').each(function(element) {
-        if (WindowUtilities.isDefined(element.oldVisibility)) {
-          // Why?? Ask IE
-          try {
-            element.style.visibility = element.oldVisibility;
-          } catch(e) {
-            element.style.visibility = "visible";
-          }
-          element.oldVisibility = null;
-        }
-        else {
-          if (element.style.visibility)
-            element.style.visibility = "visible";
-        }
-      });
-    }
-  },
-
-  isDefined: function(object) {
-    return typeof(object) != "undefined" && object != null;
-  },
-  
-  // initLightbox()
-  // Function runs on window load, going through link tags looking for rel="lightbox".
-  // These links receive onclick events that enable the lightbox display for their targets.
-  // The function also inserts html markup at the top of the page which will be used as a
-  // container for the overlay pattern and the inline image.
-  initLightbox: function(id, className, doneHandler, parent) {
-    // Already done, just update zIndex
-    if ($(id)) {
-      Element.setStyle(id, {zIndex: Windows.maxZIndex + 1});
-      Windows.maxZIndex++;
-      doneHandler();
-    }
-    // create overlay div and hardcode some functional styles (aesthetic styles are in CSS file)
-    else {
-      var objOverlay = document.createElement("div");
-      objOverlay.setAttribute('id', id);
-      objOverlay.className = "overlay_" + className
-      objOverlay.style.display = 'none';
-      objOverlay.style.position = 'absolute';
-      objOverlay.style.top = '0';
-      objOverlay.style.left = '0';
-      objOverlay.style.zIndex = Windows.maxZIndex + 1;
-      Windows.maxZIndex++;
-      objOverlay.style.width = '100%';
-      parent.insertBefore(objOverlay, parent.firstChild);
-      if (Prototype.Browser.WebKit && id == "overlay_modal") {
-        setTimeout(function() {doneHandler()}, 10);
-      }
-      else
-        doneHandler();
-    }    
-  },
-  
-  setCookie: function(value, parameters) {
-    document.cookie= parameters[0] + "=" + escape(value) +
-      ((parameters[1]) ? "; expires=" + parameters[1].toGMTString() : "") +
-      ((parameters[2]) ? "; path=" + parameters[2] : "") +
-      ((parameters[3]) ? "; domain=" + parameters[3] : "") +
-      ((parameters[4]) ? "; secure" : "");
-  },
-
-  getCookie: function(name) {
-    var dc = document.cookie;
-    var prefix = name + "=";
-    var begin = dc.indexOf("; " + prefix);
-    if (begin == -1) {
-      begin = dc.indexOf(prefix);
-      if (begin != 0) return null;
-    } else {
-      begin += 2;
-    }
-    var end = document.cookie.indexOf(";", begin);
-    if (end == -1) {
-      end = dc.length;
-    }
-    return unescape(dc.substring(begin + prefix.length, end));
-  },
-    
-  _computeSize: function(content, id, width, height, margin, className) {
-    var objBody = document.body;
-    var tmpObj = document.createElement("div");
-    tmpObj.setAttribute('id', id);
-    tmpObj.className = className + "_content";
-
-    if (height)
-      tmpObj.style.height = height + "px"
-    else
-      tmpObj.style.width = width + "px"
-  
-    tmpObj.style.position = 'absolute';
-    tmpObj.style.top = '0';
-    tmpObj.style.left = '0';
-    tmpObj.style.display = 'none';
-
-    tmpObj.innerHTML = content;
-    objBody.insertBefore(tmpObj, objBody.firstChild);
-
-    var size;
-    if (height)
-      size = $(tmpObj).getDimensions().width + margin;
-    else
-      size = $(tmpObj).getDimensions().height + margin;
-    objBody.removeChild(tmpObj);
-    return size;
-  }  
-}
-
diff --git a/webinterface/src/web-data/lib/ptwindow/javascripts/window_effects.js b/webinterface/src/web-data/lib/ptwindow/javascripts/window_effects.js
deleted file mode 100644 (file)
index 6ad73cc..0000000
+++ /dev/null
@@ -1,157 +0,0 @@
-Effect.ResizeWindow = Class.create();
-Object.extend(Object.extend(Effect.ResizeWindow.prototype, Effect.Base.prototype), {
-  initialize: function(win, top, left, width, height) {
-    this.window = win;
-    this.window.resizing = true;
-    
-    var size = win.getSize();
-    this.initWidth    = parseFloat(size.width);
-    this.initHeight   = parseFloat(size.height);
-
-    var location = win.getLocation();
-    this.initTop    = parseFloat(location.top);
-    this.initLeft   = parseFloat(location.left);
-
-    this.width    = width != null  ? parseFloat(width)  : this.initWidth;
-    this.height   = height != null ? parseFloat(height) : this.initHeight;
-    this.top      = top != null    ? parseFloat(top)    : this.initTop;
-    this.left     = left != null   ? parseFloat(left)   : this.initLeft;
-
-    this.dx     = this.left   - this.initLeft;
-    this.dy     = this.top    - this.initTop;
-    this.dw     = this.width  - this.initWidth;
-    this.dh     = this.height - this.initHeight;
-    
-    this.r2      = $(this.window.getId() + "_row2");
-    this.content = $(this.window.getId() + "_content");
-        
-    this.contentOverflow = this.content.getStyle("overflow") || "auto";
-    this.content.setStyle({overflow: "hidden"});
-    
-    // Wired mode
-    if (this.window.options.wiredDrag) {
-      this.window.currentDrag = win._createWiredElement();
-      this.window.currentDrag.show();
-      this.window.element.hide();
-    }
-
-    this.start(arguments[5]);
-  },
-  
-  update: function(position) {
-    var width  = Math.floor(this.initWidth  + this.dw * position);
-    var height = Math.floor(this.initHeight + this.dh * position);
-    var top    = Math.floor(this.initTop    + this.dy * position);
-    var left   = Math.floor(this.initLeft   + this.dx * position);
-
-    if (window.ie) {
-      if (Math.floor(height) == 0)  
-        this.r2.hide();
-      else if (Math.floor(height) >1)  
-        this.r2.show();
-    }      
-    this.r2.setStyle({height: height});
-    this.window.setSize(width, height);
-    this.window.setLocation(top, left);
-  },
-  
-  finish: function(position) {
-    // Wired mode
-    if (this.window.options.wiredDrag) {
-      this.window._hideWiredElement();
-      this.window.element.show();
-    }
-
-    this.window.setSize(this.width, this.height);
-    this.window.setLocation(this.top, this.left);
-    this.r2.setStyle({height: null});
-    
-    this.content.setStyle({overflow: this.contentOverflow});
-      
-    this.window.resizing = false;
-  }
-});
-
-Effect.ModalSlideDown = function(element) {
-  var windowScroll = WindowUtilities.getWindowScroll();    
-  var height = element.getStyle("height");  
-  element.setStyle({top: - (parseFloat(height) - windowScroll.top) + "px"});
-  
-  element.show();
-  return new Effect.Move(element, Object.extend({ x: 0, y: parseFloat(height) }, arguments[1] || {}));
-};
-
-
-Effect.ModalSlideUp = function(element) {
-  var height = element.getStyle("height");
-  return new Effect.Move(element, Object.extend({ x: 0, y: -parseFloat(height) }, arguments[1] || {}));
-};
-
-PopupEffect = Class.create();
-PopupEffect.prototype = {    
-  initialize: function(htmlElement) {
-    this.html = $(htmlElement);      
-    this.options = Object.extend({className: "popup_effect", duration: 0.4}, arguments[1] || {});
-    
-  },
-  show: function(element, options) { 
-    var position = Position.cumulativeOffset(this.html);      
-    var size = this.html.getDimensions();
-    var bounds = element.win.getBounds();
-    this.window =  element.win;      
-    // Create a div
-    if (!this.div) {
-      this.div = document.createElement("div");
-      this.div.className = this.options.className;
-      this.div.style.height = size.height + "px";
-      this.div.style.width  = size.width  + "px";
-      this.div.style.top    = position[1] + "px";
-      this.div.style.left   = position[0] + "px";   
-      this.div.style.position = "absolute"
-      document.body.appendChild(this.div);
-    }                                                   
-    if (this.options.fromOpacity)
-      this.div.setStyle({opacity: this.options.fromOpacity})
-    this.div.show();          
-    var style = "top:" + bounds.top + ";left:" +bounds.left + ";width:" + bounds.width +";height:" + bounds.height;
-    if (this.options.toOpacity)
-      style += ";opacity:" + this.options.toOpacity;
-    
-    new Effect.Morph(this.div ,{style: style, duration: this.options.duration, afterFinish: this._showWindow.bind(this)});    
-  },
-
-  hide: function(element, options) {     
-    var position = Position.cumulativeOffset(this.html);      
-    var size = this.html.getDimensions();    
-    this.window.visible = true; 
-    var bounds = this.window.getBounds();
-    this.window.visible = false; 
-
-    this.window.element.hide();
-
-    this.div.style.height = bounds.height;
-    this.div.style.width  = bounds.width;
-    this.div.style.top    = bounds.top;
-    this.div.style.left   = bounds.left;
-    
-    if (this.options.toOpacity)
-      this.div.setStyle({opacity: this.options.toOpacity})
-
-    this.div.show();                                 
-    var style = "top:" + position[1] + "px;left:" + position[0] + "px;width:" + size.width +"px;height:" + size.height + "px";
-
-    if (this.options.fromOpacity)
-      style += ";opacity:" + this.options.fromOpacity;
-    new Effect.Morph(this.div ,{style: style, duration: this.options.duration, afterFinish: this._hideDiv.bind(this)});    
-  },
-  
-  _showWindow: function() {
-    this.div.hide();
-    this.window.element.show(); 
-  },
-  
-  _hideDiv: function() {
-    this.div.hide();
-  }
-}
-
diff --git a/webinterface/src/web-data/lib/ptwindow/javascripts/window_ext.js b/webinterface/src/web-data/lib/ptwindow/javascripts/window_ext.js
deleted file mode 100644 (file)
index 60efac6..0000000
+++ /dev/null
@@ -1,115 +0,0 @@
-// Copyright (c) 2006 Sébastien Gruhier (http://xilinus.com, http://itseb.com)
-// YOU MUST INCLUDE window.js BEFORE
-//
-// Object to store hide/show windows status in a cookie
-// Just add at the end of your HTML file this javascript line: WindowStore.init()
-WindowStore = {
-  doSetCookie: false,
-  cookieName:  "__window_store__",
-  expired:     null,
-  
-  // Init function with two optional parameters
-  // - cookieName (default = __window_store__)
-  // - expiration date (default 3 years from now)
-  init: function(cookieName, expired) {
-    WindowStore.cookieName = cookieName || WindowStore.cookieName
-
-    if (! expired) {
-      var today = new Date();
-      today.setYear(today.getYear()+1903);
-      WindowStore.expired = today;
-    }
-    else
-      WindowStore.expired = expired;
-
-    Windows.windows.each(function(win) {
-      win.setCookie(win.getId(), WindowStore.expired);
-    });
-
-    // Create observer on show/hide events
-    var myObserver = {
-       onShow: function(eventName, win) {
-         WindowStore._saveCookie();
-       },
-       
-       onClose: function(eventName, win) {
-         WindowStore._saveCookie();
-         },
-         
-       onHide: function(eventName, win) {
-         WindowStore._saveCookie();
-       }
-    }
-    Windows.addObserver(myObserver);
-
-    WindowStore._restoreWindows();
-    WindowStore._saveCookie();
-  },
-  
-  show: function(win) {
-    eval("var cookie = " + WindowUtilities.getCookie(WindowStore.cookieName));
-    if (cookie != null) {
-      if (cookie[win.getId()])
-        win.show();
-    }
-    else
-      win.show();
-  },
-
-  // Function to store windows show/hide status in a cookie 
-  _saveCookie: function() {
-    if (!doSetCookie)
-      return;
-    
-    var cookieValue = "{";
-    Windows.windows.each(function(win) {
-      if (cookieValue != "{")
-        cookieValue += ","
-      cookieValue += win.getId() + ": " + win.isVisible();
-    });
-    cookieValue += "}"
-  
-    WindowUtilities.setCookie(cookieValue, [WindowStore.cookieName, WindowStore.expired]);  
-  },
-
-  // Function to restore windows show/hide status from a cookie if exists
-  _restoreWindows: function() {
-    eval("var cookie = " + WindowUtilities.getCookie(WindowStore.cookieName));
-    if (cookie != null) {
-      doSetCookie = false;
-      Windows.windows.each(function(win) {
-        if (cookie[win.getId()])
-          win.show();
-      });
-    }
-    doSetCookie = true;
-  }
-}
-
-// Object to set a close key an all windows
-WindowCloseKey = {
-  keyCode: Event.KEY_ESC,
-  
-  init: function(keyCode) {
-    if (keyCode)
-      WindowCloseKey.keyCode = keyCode;      
-      
-    Event.observe(document, 'keydown', this._closeCurrentWindow.bindAsEventListener(this));   
-  },
-  
-  _closeCurrentWindow: function(event) {
-    var e = event || window.event
-       var characterCode = e.which || e.keyCode;
-       
-       // Check if there is a top window (it means it's an URL content)
-       var win = top.Windows.focusedWindow;
-    if (characterCode == WindowCloseKey.keyCode && win) {
-      if (win.cancelCallback) 
-        top.Dialog.cancelCallback();      
-      else if (win.okCallback) 
-        top.Dialog.okCallback();
-      else
-        top.Windows.close(top.Windows.focusedWindow.getId());
-    }
-  }
-}
\ No newline at end of file
diff --git a/webinterface/src/web-data/lib/ptwindow/themes/Makefile.am b/webinterface/src/web-data/lib/ptwindow/themes/Makefile.am
deleted file mode 100644 (file)
index 0bcfeb8..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-installdir = /usr/lib/enigma2/python/Plugins/Extensions/WebInterface/web-data/lib/ptwindow/themes/
-
-install_DATA = *.css behavior.htc
-
-SUBDIRS = alert alphacube default iefix
diff --git a/webinterface/src/web-data/lib/ptwindow/themes/alert.css b/webinterface/src/web-data/lib/ptwindow/themes/alert.css
deleted file mode 100644 (file)
index 432d14e..0000000
+++ /dev/null
@@ -1,119 +0,0 @@
-.overlay_alert {
-       background-color: #85BBEF;
-       filter:alpha(opacity=60);
-       -moz-opacity: 0.6;
-       opacity: 0.6;
-}
-
-.alert_nw {
-       width: 5px;
-       height: 5px;
-       background: transparent url(alert/top_left.gif) no-repeat bottom left;                  
-}
-
-.alert_n {
-       height: 5px;
-       background: transparent url(alert/top.gif) repeat-x bottom left;                        
-}
-
-.alert_ne {
-       width: 5px;
-       height: 5px;
-       background: transparent url(alert/top_right.gif) no-repeat bottom left                  
-}
-
-.alert_e {
-       width: 5px;
-       background: transparent url(alert/right.gif) repeat-y 0 0;                      
-}
-
-.alert_w {
-       width: 5px;
-       background: transparent url(alert/left.gif) repeat-y 0 0;                       
-}
-
-.alert_sw {
-       width: 5px;
-       height: 5px;
-       background: transparent url(alert/bottom_left.gif) no-repeat 0 0;                       
-}
-
-.alert_s {
-       height: 5px;
-       background: transparent url(alert/bottom.gif) repeat-x 0 0;                     
-}
-
-.alert_se, .alert_sizer {
-       width: 5px;
-       height: 5px;
-       background: transparent url(alert/bottom_right.gif) no-repeat 0 0;                      
-}
-
-.alert_close {
-       width:0px;
-       height:0px;
-       display:none;
-}
-
-.alert_minimize {
-       width:0px;
-       height:0px;
-       display:none;
-}
-
-.alert_maximize {
-       width:0px;
-       height:0px;
-       display:none;
-}
-
-.alert_title {
-       float:left;
-       height:1px;
-       width:100%;
-}
-
-.alert_content {
-       overflow:visible;
-       color: #000;
-       font-family: Tahoma, Arial, sans-serif;
-  font: 12px arial;
-       background: #FFF;
-}
-
-/* For alert/confirm dialog */
-.alert_window {
-       background: #FFF;
-       padding:20px;
-       margin-left:auto;
-       margin-right:auto;
-       width:400px;
-}
-
-.alert_message {
-  font: 12px arial;
-       width:100%;
-       color:#F00;
-       padding-bottom:10px;
-}
-
-.alert_buttons {
-       text-align:center;
-       width:100%;
-}
-
-.alert_buttons input {
-       width:20%;
-       margin:10px;
-}
-
-.alert_progress {
-       float:left;
-       margin:auto;
-       text-align:center;
-       width:100%;
-       height:16px;
-       background: #FFF url('alert/progress.gif') no-repeat center center
-}
-
-
diff --git a/webinterface/src/web-data/lib/ptwindow/themes/alert/Makefile.am b/webinterface/src/web-data/lib/ptwindow/themes/alert/Makefile.am
deleted file mode 100644 (file)
index 5c1ee6f..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-installdir = /usr/lib/enigma2/python/Plugins/Extensions/WebInterface/web-data/lib/ptwindow/themes/alert/
-
-install_DATA = *.gif *.png
-
diff --git a/webinterface/src/web-data/lib/ptwindow/themes/alert/bottom.gif b/webinterface/src/web-data/lib/ptwindow/themes/alert/bottom.gif
deleted file mode 100644 (file)
index 9870f52..0000000
Binary files a/webinterface/src/web-data/lib/ptwindow/themes/alert/bottom.gif and /dev/null differ
diff --git a/webinterface/src/web-data/lib/ptwindow/themes/alert/bottom_left.gif b/webinterface/src/web-data/lib/ptwindow/themes/alert/bottom_left.gif
deleted file mode 100644 (file)
index 583f113..0000000
Binary files a/webinterface/src/web-data/lib/ptwindow/themes/alert/bottom_left.gif and /dev/null differ
diff --git a/webinterface/src/web-data/lib/ptwindow/themes/alert/bottom_right.gif b/webinterface/src/web-data/lib/ptwindow/themes/alert/bottom_right.gif
deleted file mode 100644 (file)
index 230ba12..0000000
Binary files a/webinterface/src/web-data/lib/ptwindow/themes/alert/bottom_right.gif and /dev/null differ
diff --git a/webinterface/src/web-data/lib/ptwindow/themes/alert/left.gif b/webinterface/src/web-data/lib/ptwindow/themes/alert/left.gif
deleted file mode 100644 (file)
index 4a3fab5..0000000
Binary files a/webinterface/src/web-data/lib/ptwindow/themes/alert/left.gif and /dev/null differ
diff --git a/webinterface/src/web-data/lib/ptwindow/themes/alert/overlay.png b/webinterface/src/web-data/lib/ptwindow/themes/alert/overlay.png
deleted file mode 100644 (file)
index 2f3344e..0000000
Binary files a/webinterface/src/web-data/lib/ptwindow/themes/alert/overlay.png and /dev/null differ
diff --git a/webinterface/src/web-data/lib/ptwindow/themes/alert/progress.gif b/webinterface/src/web-data/lib/ptwindow/themes/alert/progress.gif
deleted file mode 100644 (file)
index 529e72f..0000000
Binary files a/webinterface/src/web-data/lib/ptwindow/themes/alert/progress.gif and /dev/null differ
diff --git a/webinterface/src/web-data/lib/ptwindow/themes/alert/right.gif b/webinterface/src/web-data/lib/ptwindow/themes/alert/right.gif
deleted file mode 100644 (file)
index 85ba9e2..0000000
Binary files a/webinterface/src/web-data/lib/ptwindow/themes/alert/right.gif and /dev/null differ
diff --git a/webinterface/src/web-data/lib/ptwindow/themes/alert/top.gif b/webinterface/src/web-data/lib/ptwindow/themes/alert/top.gif
deleted file mode 100644 (file)
index 8f61936..0000000
Binary files a/webinterface/src/web-data/lib/ptwindow/themes/alert/top.gif and /dev/null differ
diff --git a/webinterface/src/web-data/lib/ptwindow/themes/alert/top_left.gif b/webinterface/src/web-data/lib/ptwindow/themes/alert/top_left.gif
deleted file mode 100644 (file)
index fabb33a..0000000
Binary files a/webinterface/src/web-data/lib/ptwindow/themes/alert/top_left.gif and /dev/null differ
diff --git a/webinterface/src/web-data/lib/ptwindow/themes/alert/top_right.gif b/webinterface/src/web-data/lib/ptwindow/themes/alert/top_right.gif
deleted file mode 100644 (file)
index 9fec6fa..0000000
Binary files a/webinterface/src/web-data/lib/ptwindow/themes/alert/top_right.gif and /dev/null differ
diff --git a/webinterface/src/web-data/lib/ptwindow/themes/alert_lite.css b/webinterface/src/web-data/lib/ptwindow/themes/alert_lite.css
deleted file mode 100644 (file)
index c2ad538..0000000
+++ /dev/null
@@ -1,88 +0,0 @@
-.overlay_alert_lite {
-       background-color: #85BBEF;
-       filter:alpha(opacity=60);
-       -moz-opacity: 0.6;
-       opacity: 0.6;
-}
-
-.alert_lite_sizer {
-       width:0px;
-       height:0px;
-       display:none;
-}
-
-.alert_lite_close {
-       width:0px;
-       height:0px;
-       display:none;
-}
-
-.alert_lite_minimize {
-       width:0px;
-       height:0px;
-       display:none;
-}
-
-.alert_lite_maximize {
-       width:0px;
-       height:0px;
-       display:none;
-}
-
-.alert_lite_title {
-       width:0px;
-       height:0px;
-       display:none;
-}
-
-.alert_lite_content {
-       overflow:auto;
-       color: #000;
-       font-family: Tahoma, Arial, sans-serif;
-       font-size: 10px;
-       background: #FFF;
-}
-
-
-/* For alert/confirm dialog */
-.alert_lite_window {
-       border:1px solid #F00;  
-       background: #FFF;
-       padding:20px;
-       margin-left:auto;
-       margin-right:auto;
-       width:400px;
-}
-
-.alert_lite_message {
-       font-size:16px;
-       text-align:center;
-       width:100%;
-       color:#F00;
-       padding-bottom:10px;
-}
-
-.alert_lite_buttons {
-       text-align:center;
-       width:100%;
-}
-
-.alert_lite_buttons input {
-       width:20%;
-       margin:10px;
-}
-
-.alert_lite_progress {
-       float:left;
-       margin:auto;
-       text-align:center;
-       width:100%;
-       height:16px;
-       background: #FFF url('alert/progress.gif') no-repeat center center
-}
-
-table.alert_lite_header  {
-  border:1px solid #F00;
-  background:#FFF
-}
-
diff --git a/webinterface/src/web-data/lib/ptwindow/themes/alphacube.css b/webinterface/src/web-data/lib/ptwindow/themes/alphacube.css
deleted file mode 100644 (file)
index 7d2790e..0000000
+++ /dev/null
@@ -1,150 +0,0 @@
-.overlay_alphacube {
-       background-color: #85BBEF;
-       filter:alpha(opacity=60);
-       -moz-opacity: 0.6;
-       opacity: 0.6;
-}
-
-.alphacube_nw {
-       background: transparent url(alphacube/left-top.gif) no-repeat 0 0;                      
-  width:10px;
-  height:25px;
-}
-
-.alphacube_n {
-  background: transparent url(alphacube/top-middle.gif) repeat-x 0 0;                  
-  height:25px;
-}
-
-.alphacube_ne {
-  background: transparent url(alphacube/right-top.gif) no-repeat 0 0;                  
-  width:10px;    
-  height:25px;
-}
-
-.alphacube_w {
-  background: transparent url(alphacube/frame-left.gif) repeat-y top left;                     
-  width:7px;
-}
-
-.alphacube_e {
-  background: transparent url(alphacube/frame-right.gif) repeat-y top right;                   
-  width:7px;     
-}
-
-.alphacube_sw {
-  background: transparent url(alphacube/bottom-left-c.gif) no-repeat 0 0;                      
-  width:7px;
-  height:7px;
-}
-
-.alphacube_s {
-  background: transparent url(alphacube/bottom-middle.gif) repeat-x 0 0;                       
-  height:7px;
-}
-
-.alphacube_se, .alphacube_sizer  {
-  background: transparent url(alphacube/bottom-right-c.gif) no-repeat 0 0;                     
-  width:7px;
-  height:7px;
-}
-
-.alphacube_sizer {
-       cursor:se-resize;       
-}
-
-.alphacube_close {
-       width: 23px;
-       height: 23px;
-       background: transparent url(alphacube/button-close-focus.gif) no-repeat 0 0;                    
-       position:absolute;
-       top:0px;
-       right:11px;
-       cursor:pointer;
-       z-index:1000;
-}
-
-.alphacube_minimize {
-       width: 23px;
-       height: 23px;
-       background: transparent url(alphacube/button-min-focus.gif) no-repeat 0 0;                      
-       position:absolute;
-       top:0px;
-       right:55px;
-       cursor:pointer;
-       z-index:1000;
-}
-
-.alphacube_maximize {
-       width: 23px;
-       height: 23px;
-       background: transparent url(alphacube/button-max-focus.gif) no-repeat 0 0;                      
-       position:absolute;
-       top:0px;
-       right:33px;
-       cursor:pointer;
-       z-index:1000;
-}
-
-.alphacube_title {
-       float:left;
-       height:14px;
-       font-size:14px;
-       text-align:center;
-       margin-top:2px;
-       width:100%;
-       color:#123456;
-}
-
-.alphacube_content {
-       overflow:auto;
-       color: #000;
-       font-family: Tahoma, Arial, sans-serif;
-  font: 12px arial;
-       background:#FDFDFD;
-}
-
-/* For alert/confirm dialog */
-.alphacube_window {
-       border:1px solid #F00;  
-       background: #FFF;
-       padding:20px;
-       margin-left:auto;
-       margin-right:auto;
-       width:400px;
-}
-
-.alphacube_message {
-  font: 12px arial;
-       text-align:center;
-       width:100%;
-       padding-bottom:10px;
-}
-
-.alphacube_buttons {
-       text-align:center;
-       width:100%;
-}
-
-.alphacube_buttons input {
-       width:20%;
-       margin:10px;
-}
-
-.alphacube_progress {
-       float:left;
-       margin:auto;
-       text-align:center;
-       width:100%;
-       height:16px;
-       background: #FFF url('alert/progress.gif') no-repeat center center
-}
-
-.alphacube_wired_frame {
-       background: #FFF;
-       filter:alpha(opacity=60);
-       -moz-opacity: 0.6;
-       opacity: 0.6;   
-}
-
-
diff --git a/webinterface/src/web-data/lib/ptwindow/themes/alphacube/Makefile.am b/webinterface/src/web-data/lib/ptwindow/themes/alphacube/Makefile.am
deleted file mode 100644 (file)
index 9a278e2..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-installdir = /usr/lib/enigma2/python/Plugins/Extensions/WebInterface/web-data/lib/ptwindow/themes/alphacube/
-
-install_DATA = *.gif
diff --git a/webinterface/src/web-data/lib/ptwindow/themes/alphacube/bottom-left-c.gif b/webinterface/src/web-data/lib/ptwindow/themes/alphacube/bottom-left-c.gif
deleted file mode 100644 (file)
index 531acdc..0000000
Binary files a/webinterface/src/web-data/lib/ptwindow/themes/alphacube/bottom-left-c.gif and /dev/null differ
diff --git a/webinterface/src/web-data/lib/ptwindow/themes/alphacube/bottom-middle.gif b/webinterface/src/web-data/lib/ptwindow/themes/alphacube/bottom-middle.gif
deleted file mode 100644 (file)
index d4ce3be..0000000
Binary files a/webinterface/src/web-data/lib/ptwindow/themes/alphacube/bottom-middle.gif and /dev/null differ
diff --git a/webinterface/src/web-data/lib/ptwindow/themes/alphacube/bottom-right-c.gif b/webinterface/src/web-data/lib/ptwindow/themes/alphacube/bottom-right-c.gif
deleted file mode 100644 (file)
index 2164c22..0000000
Binary files a/webinterface/src/web-data/lib/ptwindow/themes/alphacube/bottom-right-c.gif and /dev/null differ
diff --git a/webinterface/src/web-data/lib/ptwindow/themes/alphacube/button-close-focus.gif b/webinterface/src/web-data/lib/ptwindow/themes/alphacube/button-close-focus.gif
deleted file mode 100644 (file)
index 99f635c..0000000
Binary files a/webinterface/src/web-data/lib/ptwindow/themes/alphacube/button-close-focus.gif and /dev/null differ
diff --git a/webinterface/src/web-data/lib/ptwindow/themes/alphacube/button-max-focus.gif b/webinterface/src/web-data/lib/ptwindow/themes/alphacube/button-max-focus.gif
deleted file mode 100644 (file)
index 1708a1e..0000000
Binary files a/webinterface/src/web-data/lib/ptwindow/themes/alphacube/button-max-focus.gif and /dev/null differ
diff --git a/webinterface/src/web-data/lib/ptwindow/themes/alphacube/button-min-focus.gif b/webinterface/src/web-data/lib/ptwindow/themes/alphacube/button-min-focus.gif
deleted file mode 100644 (file)
index ff69d1b..0000000
Binary files a/webinterface/src/web-data/lib/ptwindow/themes/alphacube/button-min-focus.gif and /dev/null differ
diff --git a/webinterface/src/web-data/lib/ptwindow/themes/alphacube/frame-left.gif b/webinterface/src/web-data/lib/ptwindow/themes/alphacube/frame-left.gif
deleted file mode 100644 (file)
index 543f13d..0000000
Binary files a/webinterface/src/web-data/lib/ptwindow/themes/alphacube/frame-left.gif and /dev/null differ
diff --git a/webinterface/src/web-data/lib/ptwindow/themes/alphacube/frame-right.gif b/webinterface/src/web-data/lib/ptwindow/themes/alphacube/frame-right.gif
deleted file mode 100644 (file)
index 5d7afef..0000000
Binary files a/webinterface/src/web-data/lib/ptwindow/themes/alphacube/frame-right.gif and /dev/null differ
diff --git a/webinterface/src/web-data/lib/ptwindow/themes/alphacube/left-top.gif b/webinterface/src/web-data/lib/ptwindow/themes/alphacube/left-top.gif
deleted file mode 100644 (file)
index 8373aaa..0000000
Binary files a/webinterface/src/web-data/lib/ptwindow/themes/alphacube/left-top.gif and /dev/null differ
diff --git a/webinterface/src/web-data/lib/ptwindow/themes/alphacube/right-top.gif b/webinterface/src/web-data/lib/ptwindow/themes/alphacube/right-top.gif
deleted file mode 100644 (file)
index 77cf65e..0000000
Binary files a/webinterface/src/web-data/lib/ptwindow/themes/alphacube/right-top.gif and /dev/null differ
diff --git a/webinterface/src/web-data/lib/ptwindow/themes/alphacube/top-middle.gif b/webinterface/src/web-data/lib/ptwindow/themes/alphacube/top-middle.gif
deleted file mode 100644 (file)
index 9cab17d..0000000
Binary files a/webinterface/src/web-data/lib/ptwindow/themes/alphacube/top-middle.gif and /dev/null differ
diff --git a/webinterface/src/web-data/lib/ptwindow/themes/behavior.htc b/webinterface/src/web-data/lib/ptwindow/themes/behavior.htc
deleted file mode 100644 (file)
index 437c5ec..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-<public:component>
-<public:attach event="onpropertychange" onevent="propertyChanged()" />
-<script>
-
-var supported = /MSIE (5\.5)|[6789]/.test(navigator.userAgent) && navigator.platform == "Win32";
-var realSrc;
-var blankSrc = "blank.gif";
-
-if (supported) fixImage();
-
-function propertyChanged() {
-   if (!supported) return;
-
-   var pName = event.propertyName;
-   if (pName != "src") return;
-   // if not set to blank
-   if ( ! new RegExp(blankSrc).test(src))
-      fixImage();
-};
-
-function fixImage() {
-   // get src
-   var src = element.src;
-
-   // check for real change
-   if (src == realSrc) {
-      element.src = blankSrc;
-      return;
-   }
-
-   if ( ! new RegExp(blankSrc).test(src)) {
-      // backup old src
-      realSrc = src;
-   }
-
-   // test for png
-   if ( /\.png$/.test( realSrc.toLowerCase() ) ) {
-      // set blank image
-      element.src = blankSrc;
-      // set filter
-      element.runtimeStyle.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" +
-                                     src + "',sizingMethod='scale')";
-   }
-   else {
-      // remove filter
-      element.runtimeStyle.filter = "";
-   }
-}
-
-</script>
-</public:component>
\ No newline at end of file
diff --git a/webinterface/src/web-data/lib/ptwindow/themes/debug.css b/webinterface/src/web-data/lib/ptwindow/themes/debug.css
deleted file mode 100644 (file)
index 69e3b7f..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-div.inspector div.inspectable {
- padding: 0.25em 0 0.25em 1em;
- background-color: Gray;
- color: white;
- border: outset 2px white;
- cursor: pointer;
-}
-div.inspector div.child {
- margin: 0 0 0 1em;
-}
-#debug_window_content { /*  DIV container for debug sizing*/
- width:250px;
- height:100px;
- background-color:#000;
-}
-#debug {         /*  DIV container for debug contents*/
- padding:3px;
- color:#0f0;
- font-family:monaco, Tahoma, Verdana, Arial, Helvetica, sans-serif;
- font-size:10px;
-}
diff --git a/webinterface/src/web-data/lib/ptwindow/themes/default.css b/webinterface/src/web-data/lib/ptwindow/themes/default.css
deleted file mode 100644 (file)
index 6ab1378..0000000
+++ /dev/null
@@ -1,155 +0,0 @@
-.overlay_dialog {
-       background-color: #666666;
-       filter:alpha(opacity=60);
-       -moz-opacity: 0.6;
-       opacity: 0.6;
-}
-
-.overlay___invisible__ {
-  background-color: #666666;
-       filter:alpha(opacity=0);
-       -moz-opacity: 0;
-       opacity: 0;
-}
-
-.dialog_nw {
-       width: 9px;
-       height: 23px;
-       background: transparent url(default/top_left.gif) no-repeat 0 0;                
-}
-
-.dialog_n {
-       background: transparent url(default/top_mid.gif) repeat-x 0 0;  
-       height: 23px;
-}
-
-.dialog_ne {
-       width: 9px;
-       height: 23px;
-       background: transparent url(default/top_right.gif) no-repeat 0 0;               
-}
-
-.dialog_e {
-       width: 2px;
-       background: transparent url(default/center_right.gif) repeat-y 0 0;     
-}
-
-.dialog_w {
-       width: 2px;
-       background: transparent url(default/center_left.gif) repeat-y 0 0;              
-}
-
-.dialog_sw {
-       width: 9px;
-       height: 19px;
-       background: transparent url(default/bottom_left.gif) no-repeat 0 0;                     
-}
-
-.dialog_s {
-       background: transparent url(default/bottom_mid.gif) repeat-x 0 0;               
-       height: 19px;
-}
-
-.dialog_se {
-       width: 9px;
-       height: 19px;
-       background: transparent url(default/bottom_right.gif) no-repeat 0 0;                    
-}
-
-.dialog_sizer {
-       width: 9px;
-       height: 19px;
-       background: transparent url(default/sizer.gif) no-repeat 0 0;   
-       cursor:se-resize;       
-}
-
-.dialog_close {
-       width: 14px;
-       height: 14px;
-       background: transparent url(default/close.gif) no-repeat 0 0;                   
-       position:absolute;
-       top:5px;
-       left:8px;
-       cursor:pointer;
-       z-index:2000;
-}
-
-.dialog_minimize {
-       width: 14px;
-       height: 15px;
-       background: transparent url(default/minimize.gif) no-repeat 0 0;                        
-       position:absolute;
-       top:5px;
-       left:28px;
-       cursor:pointer;
-       z-index:2000;
-}
-
-.dialog_maximize {
-       width: 14px;
-       height: 15px;
-       background: transparent url(default/maximize.gif) no-repeat 0 0;                        
-       position:absolute;
-       top:5px;
-       left:49px;
-       cursor:pointer;
-       z-index:2000;
-}
-
-.dialog_title {
-       float:left;
-       height:14px;
-       font-family: Tahoma, Arial, sans-serif;
-       font-size:12px;
-       text-align:center;
-       width:100%;
-       color:#000;
-}
-
-.dialog_content {
-       overflow:auto;
-       color: #DDD;
-       font-family: Tahoma, Arial, sans-serif;
-       font-size: 10px;
-       background-color:#123;
-}
-
-.top_draggable, .bottom_draggable {
-  cursor:move;
-}
-
-.status_bar {
-  font-size:12px;
-}
-.status_bar input{
-  font-size:12px;
-}
-
-.wired_frame {
-       display: block;
-  position: absolute;
-  border: 1px #000 dashed;
-}
-
-/* DO NOT CHANGE THESE VALUES*/
-.dialog {
-       display: block;
-       position: absolute;
-}
-
-.dialog table.table_window  { 
-  border-collapse: collapse; 
-  border-spacing: 0; 
-  width: 100%;
-       margin: 0px;
-       padding:0px;
-}
-
-.dialog table.table_window td , .dialog table.table_window th { 
-  padding: 0; 
-}
-
-.dialog .title_window {
-  -moz-user-select:none;
-}                                                    
-
diff --git a/webinterface/src/web-data/lib/ptwindow/themes/default/Makefile.am b/webinterface/src/web-data/lib/ptwindow/themes/default/Makefile.am
deleted file mode 100644 (file)
index be6b523..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-installdir = /usr/lib/enigma2/python/Plugins/Extensions/WebInterface/web-data/lib/ptwindow/themes/default/
-
-install_DATA = *.gif *.png
-
diff --git a/webinterface/src/web-data/lib/ptwindow/themes/default/bottom_left.gif b/webinterface/src/web-data/lib/ptwindow/themes/default/bottom_left.gif
deleted file mode 100644 (file)
index 4c73d35..0000000
Binary files a/webinterface/src/web-data/lib/ptwindow/themes/default/bottom_left.gif and /dev/null differ
diff --git a/webinterface/src/web-data/lib/ptwindow/themes/default/bottom_mid.gif b/webinterface/src/web-data/lib/ptwindow/themes/default/bottom_mid.gif
deleted file mode 100644 (file)
index 9205d30..0000000
Binary files a/webinterface/src/web-data/lib/ptwindow/themes/default/bottom_mid.gif and /dev/null differ
diff --git a/webinterface/src/web-data/lib/ptwindow/themes/default/bottom_right.gif b/webinterface/src/web-data/lib/ptwindow/themes/default/bottom_right.gif
deleted file mode 100644 (file)
index 8d002ee..0000000
Binary files a/webinterface/src/web-data/lib/ptwindow/themes/default/bottom_right.gif and /dev/null differ
diff --git a/webinterface/src/web-data/lib/ptwindow/themes/default/bottom_right_resize.gif b/webinterface/src/web-data/lib/ptwindow/themes/default/bottom_right_resize.gif
deleted file mode 100644 (file)
index 649b0d8..0000000
Binary files a/webinterface/src/web-data/lib/ptwindow/themes/default/bottom_right_resize.gif and /dev/null differ
diff --git a/webinterface/src/web-data/lib/ptwindow/themes/default/center_left.gif b/webinterface/src/web-data/lib/ptwindow/themes/default/center_left.gif
deleted file mode 100644 (file)
index 79e7a1c..0000000
Binary files a/webinterface/src/web-data/lib/ptwindow/themes/default/center_left.gif and /dev/null differ
diff --git a/webinterface/src/web-data/lib/ptwindow/themes/default/center_right.gif b/webinterface/src/web-data/lib/ptwindow/themes/default/center_right.gif
deleted file mode 100644 (file)
index 554c55c..0000000
Binary files a/webinterface/src/web-data/lib/ptwindow/themes/default/center_right.gif and /dev/null differ
diff --git a/webinterface/src/web-data/lib/ptwindow/themes/default/clear.gif b/webinterface/src/web-data/lib/ptwindow/themes/default/clear.gif
deleted file mode 100644 (file)
index c10b166..0000000
Binary files a/webinterface/src/web-data/lib/ptwindow/themes/default/clear.gif and /dev/null differ
diff --git a/webinterface/src/web-data/lib/ptwindow/themes/default/close.gif b/webinterface/src/web-data/lib/ptwindow/themes/default/close.gif
deleted file mode 100644 (file)
index 31ef5a3..0000000
Binary files a/webinterface/src/web-data/lib/ptwindow/themes/default/close.gif and /dev/null differ
diff --git a/webinterface/src/web-data/lib/ptwindow/themes/default/inspect.gif b/webinterface/src/web-data/lib/ptwindow/themes/default/inspect.gif
deleted file mode 100644 (file)
index ebeeb02..0000000
Binary files a/webinterface/src/web-data/lib/ptwindow/themes/default/inspect.gif and /dev/null differ
diff --git a/webinterface/src/web-data/lib/ptwindow/themes/default/maximize.gif b/webinterface/src/web-data/lib/ptwindow/themes/default/maximize.gif
deleted file mode 100644 (file)
index 892a0f0..0000000
Binary files a/webinterface/src/web-data/lib/ptwindow/themes/default/maximize.gif and /dev/null differ
diff --git a/webinterface/src/web-data/lib/ptwindow/themes/default/minimize.gif b/webinterface/src/web-data/lib/ptwindow/themes/default/minimize.gif
deleted file mode 100644 (file)
index a721416..0000000
Binary files a/webinterface/src/web-data/lib/ptwindow/themes/default/minimize.gif and /dev/null differ
diff --git a/webinterface/src/web-data/lib/ptwindow/themes/default/overlay.png b/webinterface/src/web-data/lib/ptwindow/themes/default/overlay.png
deleted file mode 100644 (file)
index 648e71e..0000000
Binary files a/webinterface/src/web-data/lib/ptwindow/themes/default/overlay.png and /dev/null differ
diff --git a/webinterface/src/web-data/lib/ptwindow/themes/default/resize.gif b/webinterface/src/web-data/lib/ptwindow/themes/default/resize.gif
deleted file mode 100644 (file)
index c440702..0000000
Binary files a/webinterface/src/web-data/lib/ptwindow/themes/default/resize.gif and /dev/null differ
diff --git a/webinterface/src/web-data/lib/ptwindow/themes/default/sizer.gif b/webinterface/src/web-data/lib/ptwindow/themes/default/sizer.gif
deleted file mode 100644 (file)
index 649b0d8..0000000
Binary files a/webinterface/src/web-data/lib/ptwindow/themes/default/sizer.gif and /dev/null differ
diff --git a/webinterface/src/web-data/lib/ptwindow/themes/default/top_left.gif b/webinterface/src/web-data/lib/ptwindow/themes/default/top_left.gif
deleted file mode 100644 (file)
index 774538a..0000000
Binary files a/webinterface/src/web-data/lib/ptwindow/themes/default/top_left.gif and /dev/null differ
diff --git a/webinterface/src/web-data/lib/ptwindow/themes/default/top_mid.gif b/webinterface/src/web-data/lib/ptwindow/themes/default/top_mid.gif
deleted file mode 100644 (file)
index 6124e78..0000000
Binary files a/webinterface/src/web-data/lib/ptwindow/themes/default/top_mid.gif and /dev/null differ
diff --git a/webinterface/src/web-data/lib/ptwindow/themes/default/top_right.gif b/webinterface/src/web-data/lib/ptwindow/themes/default/top_right.gif
deleted file mode 100644 (file)
index fbc94bf..0000000
Binary files a/webinterface/src/web-data/lib/ptwindow/themes/default/top_right.gif and /dev/null differ
diff --git a/webinterface/src/web-data/lib/ptwindow/themes/iefix/Makefile.am b/webinterface/src/web-data/lib/ptwindow/themes/iefix/Makefile.am
deleted file mode 100644 (file)
index f0a722a..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-installdir = /usr/lib/enigma2/python/Plugins/Extensions/WebInterface/web-data/lib/ptwindow/themes/iefix/
-
-install_DATA = iepngfix.css iepngfix.htc blank.gif
diff --git a/webinterface/src/web-data/lib/ptwindow/themes/iefix/blank.gif b/webinterface/src/web-data/lib/ptwindow/themes/iefix/blank.gif
deleted file mode 100644 (file)
index 75b945d..0000000
Binary files a/webinterface/src/web-data/lib/ptwindow/themes/iefix/blank.gif and /dev/null differ
diff --git a/webinterface/src/web-data/lib/ptwindow/themes/iefix/iepngfix.css b/webinterface/src/web-data/lib/ptwindow/themes/iefix/iepngfix.css
deleted file mode 100644 (file)
index 257a1b1..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-/* PNG fix for all themes that uses PNG images on IE */
-td, div { behavior: url(../themes/iefix/iepngfix.htc) }
-
diff --git a/webinterface/src/web-data/lib/ptwindow/themes/iefix/iepngfix.htc b/webinterface/src/web-data/lib/ptwindow/themes/iefix/iepngfix.htc
deleted file mode 100644 (file)
index a6c683b..0000000
+++ /dev/null
@@ -1,54 +0,0 @@
-<public:component>
-<public:attach event="onpropertychange" onevent="doFix()" />
-
-<script type="text/javascript">
-
-// IE5.5+ PNG Alpha Fix v1.0RC4
-// (c) 2004-2005 Angus Turnbull http://www.twinhelix.com
-
-// This is licensed under the CC-GNU LGPL, version 2.1 or later.
-// For details, see: http://creativecommons.org/licenses/LGPL/2.1/
-
-// Modified/Simplified on 04/23/2007 by Sebastien Gruhier (http://www.xilinus.com) 
-// To work only on background and to handle repeat bg  
-                     
-// This must be a path to a blank image. That's all the configuration you need.
-if (typeof blankImg == 'undefined') var blankImg = 'blank.gif';
-
-var f = 'DXImageTransform.Microsoft.AlphaImageLoader';
-
-function filt(s, m)
-{
- if (filters[f])
- {
-  filters[f].enabled = s ? true : false;
-  if (s) with (filters[f]) { src = s; sizingMethod = m }
- }
- else if (s) style.filter = 'progid:'+f+'(src="'+s+'",sizingMethod="'+m+'")';
-}
-
-function doFix()
-{         
- // Assume IE7 is OK.
- if (!/MSIE (5\.5|6\.)/.test(navigator.userAgent) ||
-  (event && !/(background|src)/.test(event.propertyName))) return;
-
- var bgImg = currentStyle.backgroundImage || style.backgroundImage;  
- var bgRepeat = currentStyle.backgroundRepeat || style.backgroundRepeat;        
- if (bgImg && bgImg != 'none')
- {
-  if (bgImg.match(/^url[("']+(.*\.png)[)"']+$/i))
-  {
-   var s = RegExp.$1;
-   if (currentStyle.width == 'auto' && currentStyle.height == 'auto')
-    style.width = offsetWidth + 'px';
-   style.backgroundImage = 'none';
-   filt(s, bgRepeat == "no-repeat" ? 'crop' : 'scale');
-  }
- }
-}
-
-doFix();
-
-</script>
-</public:component>
\ No newline at end of file
diff --git a/webinterface/src/web-data/lib/rico.js b/webinterface/src/web-data/lib/rico.js
deleted file mode 100644 (file)
index 65bcb48..0000000
+++ /dev/null
@@ -1,2818 +0,0 @@
-/**
-  *
-  *  Copyright 2005 Sabre Airline Solutions
-  *
-  *  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.
-  **/
-
-
-//-------------------- rico.js
-var Rico = {
-  Version: '1.1.2',
-  prototypeVersion: parseFloat(Prototype.Version.split(".")[0] + "." + Prototype.Version.split(".")[1])
-}
-
-if((typeof Prototype=='undefined') || Rico.prototypeVersion < 1.3)
-      throw("Rico requires the Prototype JavaScript framework >= 1.3");
-
-Rico.ArrayExtensions = new Array();
-
-if (Object.prototype.extend) {
-   Rico.ArrayExtensions[ Rico.ArrayExtensions.length ] = Object.prototype.extend;
-}else{
-  Object.prototype.extend = function(object) {
-    return Object.extend.apply(this, [this, object]);
-  }
-  Rico.ArrayExtensions[ Rico.ArrayExtensions.length ] = Object.prototype.extend;
-}
-
-if (Array.prototype.push) {
-   Rico.ArrayExtensions[ Rico.ArrayExtensions.length ] = Array.prototype.push;
-}
-
-if (!Array.prototype.remove) {
-   Array.prototype.remove = function(dx) {
-      if( isNaN(dx) || dx > this.length )
-         return false;
-      for( var i=0,n=0; i<this.length; i++ )
-         if( i != dx )
-            this[n++]=this[i];
-      this.length-=1;
-   };
-  Rico.ArrayExtensions[ Rico.ArrayExtensions.length ] = Array.prototype.remove;
-}
-
-if (!Array.prototype.removeItem) {
-   Array.prototype.removeItem = function(item) {
-      for ( var i = 0 ; i < this.length ; i++ )
-         if ( this[i] == item ) {
-            this.remove(i);
-            break;
-         }
-   };
-  Rico.ArrayExtensions[ Rico.ArrayExtensions.length ] = Array.prototype.removeItem;
-}
-
-if (!Array.prototype.indices) {
-   Array.prototype.indices = function() {
-      var indexArray = new Array();
-      for ( index in this ) {
-         var ignoreThis = false;
-         for ( var i = 0 ; i < Rico.ArrayExtensions.length ; i++ ) {
-            if ( this[index] == Rico.ArrayExtensions[i] ) {
-               ignoreThis = true;
-               break;
-            }
-         }
-         if ( !ignoreThis )
-            indexArray[ indexArray.length ] = index;
-      }
-      return indexArray;
-   }
-  Rico.ArrayExtensions[ Rico.ArrayExtensions.length ] = Array.prototype.indices;
-}
-
-// Create the loadXML method and xml getter for Mozilla
-if ( window.DOMParser &&
-         window.XMLSerializer &&
-         window.Node && Node.prototype && Node.prototype.__defineGetter__ ) {
-
-   if (!Document.prototype.loadXML) {
-      Document.prototype.loadXML = function (s) {
-         var doc2 = (new DOMParser()).parseFromString(s, "text/xml");
-         while (this.hasChildNodes())
-            this.removeChild(this.lastChild);
-
-         for (var i = 0; i < doc2.childNodes.length; i++) {
-            this.appendChild(this.importNode(doc2.childNodes[i], true));
-         }
-      };
-       }
-
-       Document.prototype.__defineGetter__( "xml",
-          function () {
-                  return (new XMLSerializer()).serializeToString(this);
-          }
-        );
-}
-
-document.getElementsByTagAndClassName = function(tagName, className) {
-  if ( tagName == null )
-     tagName = '*';
-
-  var children = document.getElementsByTagName(tagName) || document.all;
-  var elements = new Array();
-
-  if ( className == null )
-    return children;
-
-  for (var i = 0; i < children.length; i++) {
-    var child = children[i];
-    var classNames = child.className.split(' ');
-    for (var j = 0; j < classNames.length; j++) {
-      if (classNames[j] == className) {
-        elements.push(child);
-        break;
-      }
-    }
-  }
-
-  return elements;
-}
-
-
-//-------------------- ricoAccordion.js
-Rico.Accordion = Class.create();
-
-Rico.Accordion.prototype = {
-
-   initialize: function(container, options) {
-      this.container            = $(container);
-      this.lastExpandedTab      = null;
-      this.accordionTabs        = new Array();
-      this.setOptions(options);
-      this._attachBehaviors();
-      if(!container) return;
-
-      this.container.style.borderBottom = '1px solid ' + this.options.borderColor;
-      // validate onloadShowTab
-       if (this.options.onLoadShowTab >= this.accordionTabs.length)
-        this.options.onLoadShowTab = 0;
-
-      // set the initial visual state...
-      for ( var i=0 ; i < this.accordionTabs.length ; i++ )
-      {
-        if (i != this.options.onLoadShowTab){
-         this.accordionTabs[i].collapse();
-         this.accordionTabs[i].content.style.display = 'none';
-        }
-      }
-      this.lastExpandedTab = this.accordionTabs[this.options.onLoadShowTab];
-      if (this.options.panelHeight == 'auto'){
-          var tabToCheck = (this.options.onloadShowTab === 0)? 1 : 0;
-          var titleBarSize = parseInt(RicoUtil.getElementsComputedStyle(this.accordionTabs[tabToCheck].titleBar, 'height'));
-          if (isNaN(titleBarSize))
-            titleBarSize = this.accordionTabs[tabToCheck].titleBar.offsetHeight;
-          
-          var totalTitleBarSize = this.accordionTabs.length * titleBarSize;
-          var parentHeight = parseInt(RicoUtil.getElementsComputedStyle(this.container.parentNode, 'height'));
-          if (isNaN(parentHeight))
-            parentHeight = this.container.parentNode.offsetHeight;
-          
-          this.options.panelHeight = parentHeight - totalTitleBarSize-2;
-      }
-      
-      this.lastExpandedTab.content.style.height = this.options.panelHeight + "px";
-      this.lastExpandedTab.showExpanded();
-      this.lastExpandedTab.titleBar.style.fontWeight = this.options.expandedFontWeight;
-
-   },
-
-   setOptions: function(options) {
-      this.options = {
-         expandedBg          : '#63699c',
-         hoverBg             : '#63699c',
-         collapsedBg         : '#6b79a5',
-         expandedTextColor   : '#ffffff',
-         expandedFontWeight  : 'bold',
-         hoverTextColor      : '#ffffff',
-         collapsedTextColor  : '#ced7ef',
-         collapsedFontWeight : 'normal',
-         hoverTextColor      : '#ffffff',
-         borderColor         : '#1f669b',
-         panelHeight         : 200,
-         onHideTab           : null,
-         onShowTab           : null,
-         onLoadShowTab       : 0
-      }
-      Object.extend(this.options, options || {});
-   },
-
-   showTabByIndex: function( anIndex, animate ) {
-      var doAnimate = arguments.length == 1 ? true : animate;
-      this.showTab( this.accordionTabs[anIndex], doAnimate );
-   },
-
-   showTab: function( accordionTab, animate ) {
-     if ( this.lastExpandedTab == accordionTab )
-        return;
-
-      var doAnimate = arguments.length == 1 ? true : animate;
-
-      if ( this.options.onHideTab )
-         this.options.onHideTab(this.lastExpandedTab);
-
-      this.lastExpandedTab.showCollapsed(); 
-      var accordion = this;
-      var lastExpandedTab = this.lastExpandedTab;
-
-      this.lastExpandedTab.content.style.height = (this.options.panelHeight - 1) + 'px';
-      accordionTab.content.style.display = '';
-
-      accordionTab.titleBar.style.fontWeight = this.options.expandedFontWeight;
-
-      if ( doAnimate ) {
-         new Rico.Effect.AccordionSize( this.lastExpandedTab.content,
-                                   accordionTab.content,
-                                   1,
-                                   this.options.panelHeight,
-                                   100, 10,
-                                   { complete: function() {accordion.showTabDone(lastExpandedTab)} } );
-         this.lastExpandedTab = accordionTab;
-      }
-      else {
-         this.lastExpandedTab.content.style.height = "1px";
-         accordionTab.content.style.height = this.options.panelHeight + "px";
-         this.lastExpandedTab = accordionTab;
-         this.showTabDone(lastExpandedTab);
-      }
-   },
-
-   showTabDone: function(collapsedTab) {
-      collapsedTab.content.style.display = 'none';
-      this.lastExpandedTab.showExpanded();
-      if ( this.options.onShowTab )
-         this.options.onShowTab(this.lastExpandedTab);
-   },
-
-   _attachBehaviors: function() {
-      var panels = this._getDirectChildrenByTag(this.container, 'DIV');
-      for ( var i = 0 ; i < panels.length ; i++ ) {
-
-         var tabChildren = this._getDirectChildrenByTag(panels[i],'DIV');
-         if ( tabChildren.length != 2 )
-            continue; // unexpected
-
-         var tabTitleBar   = tabChildren[0];
-         var tabContentBox = tabChildren[1];
-         this.accordionTabs.push( new Rico.Accordion.Tab(this,tabTitleBar,tabContentBox) );
-      }
-   },
-
-   _getDirectChildrenByTag: function(e, tagName) {
-      var kids = new Array();
-      var allKids = e.childNodes;
-      for( var i = 0 ; i < allKids.length ; i++ )
-         if ( allKids[i] && allKids[i].tagName && allKids[i].tagName == tagName )
-            kids.push(allKids[i]);
-      return kids;
-   }
-
-};
-
-Rico.Accordion.Tab = Class.create();
-
-Rico.Accordion.Tab.prototype = {
-
-   initialize: function(accordion, titleBar, content) {
-      this.accordion = accordion;
-      this.titleBar  = titleBar;
-      this.content   = content;
-      this._attachBehaviors();
-   },
-
-   collapse: function() {
-      this.showCollapsed();
-      this.content.style.height = "1px";
-   },
-
-   showCollapsed: function() {
-      this.expanded = false;
-      this.titleBar.style.backgroundColor = this.accordion.options.collapsedBg;
-      this.titleBar.style.color           = this.accordion.options.collapsedTextColor;
-      this.titleBar.style.fontWeight      = this.accordion.options.collapsedFontWeight;
-      this.content.style.overflow = "hidden";
-   },
-
-   showExpanded: function() {
-      this.expanded = true;
-      this.titleBar.style.backgroundColor = this.accordion.options.expandedBg;
-      this.titleBar.style.color           = this.accordion.options.expandedTextColor;
-      this.content.style.overflow         = "auto";
-   },
-
-   titleBarClicked: function(e) {
-      if ( this.accordion.lastExpandedTab == this )
-         return;
-      this.accordion.showTab(this);
-   },
-
-   hover: function(e) {
-               this.titleBar.style.backgroundColor = this.accordion.options.hoverBg;
-               this.titleBar.style.color           = this.accordion.options.hoverTextColor;
-   },
-
-   unhover: function(e) {
-      if ( this.expanded ) {
-         this.titleBar.style.backgroundColor = this.accordion.options.expandedBg;
-         this.titleBar.style.color           = this.accordion.options.expandedTextColor;
-      }
-      else {
-         this.titleBar.style.backgroundColor = this.accordion.options.collapsedBg;
-         this.titleBar.style.color           = this.accordion.options.collapsedTextColor;
-      }
-   },
-
-   _attachBehaviors: function() {
-      this.content.style.border = "1px solid " + this.accordion.options.borderColor;
-      this.content.style.borderTopWidth    = "0px";
-      this.content.style.borderBottomWidth = "0px";
-      this.content.style.margin            = "0px";
-
-      this.titleBar.onclick     = this.titleBarClicked.bindAsEventListener(this);
-      this.titleBar.onmouseover = this.hover.bindAsEventListener(this);
-      this.titleBar.onmouseout  = this.unhover.bindAsEventListener(this);
-   }
-
-};
-
-
-//-------------------- ricoAjaxEngine.js
-Rico.AjaxEngine = Class.create();
-
-Rico.AjaxEngine.prototype = {
-
-   initialize: function() {
-      this.ajaxElements = new Array();
-      this.ajaxObjects  = new Array();
-      this.requestURLS  = new Array();
-      this.options = {};
-   },
-
-   registerAjaxElement: function( anId, anElement ) {
-      if ( !anElement )
-         anElement = $(anId);
-      this.ajaxElements[anId] = anElement;
-   },
-
-   registerAjaxObject: function( anId, anObject ) {
-      this.ajaxObjects[anId] = anObject;
-   },
-
-   registerRequest: function (requestLogicalName, requestURL) {
-      this.requestURLS[requestLogicalName] = requestURL;
-   },
-
-   sendRequest: function(requestName, options) {
-      // Allow for backwards Compatibility
-      if ( arguments.length >= 2 )
-       if (typeof arguments[1] == 'string')
-         options = {parameters: this._createQueryString(arguments, 1)};
-      this.sendRequestWithData(requestName, null, options);
-   },
-
-   sendRequestWithData: function(requestName, xmlDocument, options) {
-      var requestURL = this.requestURLS[requestName];
-      if ( requestURL == null )
-         return;
-
-      // Allow for backwards Compatibility
-      if ( arguments.length >= 3 )
-        if (typeof arguments[2] == 'string')
-          options.parameters = this._createQueryString(arguments, 2);
-
-      new Ajax.Request(requestURL, this._requestOptions(options,xmlDocument));
-   },
-
-   sendRequestAndUpdate: function(requestName,container,options) {
-      // Allow for backwards Compatibility
-      if ( arguments.length >= 3 )
-        if (typeof arguments[2] == 'string')
-          options.parameters = this._createQueryString(arguments, 2);
-
-      this.sendRequestWithDataAndUpdate(requestName, null, container, options);
-   },
-
-   sendRequestWithDataAndUpdate: function(requestName,xmlDocument,container,options) {
-      var requestURL = this.requestURLS[requestName];
-      if ( requestURL == null )
-         return;
-
-      // Allow for backwards Compatibility
-      if ( arguments.length >= 4 )
-        if (typeof arguments[3] == 'string')
-          options.parameters = this._createQueryString(arguments, 3);
-
-      var updaterOptions = this._requestOptions(options,xmlDocument);
-
-      new Ajax.Updater(container, requestURL, updaterOptions);
-   },
-
-   // Private -- not part of intended engine API --------------------------------------------------------------------
-
-   _requestOptions: function(options,xmlDoc) {
-      var requestHeaders = ['X-Rico-Version', Rico.Version ];
-      var sendMethod = 'post';
-      if ( xmlDoc == null )
-        if (Rico.prototypeVersion < 1.4)
-        requestHeaders.push( 'Content-type', 'text/xml' );
-      else
-          sendMethod = 'get';
-      (!options) ? options = {} : '';
-
-      if (!options._RicoOptionsProcessed){
-      // Check and keep any user onComplete functions
-        if (options.onComplete)
-             options.onRicoComplete = options.onComplete;
-        // Fix onComplete
-        if (options.overrideOnComplete)
-          options.onComplete = options.overrideOnComplete;
-        else
-          options.onComplete = this._onRequestComplete.bind(this);
-        options._RicoOptionsProcessed = true;
-      }
-
-     // Set the default options and extend with any user options
-     this.options = {
-                     requestHeaders: requestHeaders,
-                     parameters:     options.parameters,
-                     postBody:       xmlDoc,
-                     method:         sendMethod,
-                     onComplete:     options.onComplete
-                    };
-     // Set any user options:
-     Object.extend(this.options, options);
-     return this.options;
-   },
-
-   _createQueryString: function( theArgs, offset ) {
-      var queryString = ""
-      for ( var i = offset ; i < theArgs.length ; i++ ) {
-          if ( i != offset )
-            queryString += "&";
-
-          var anArg = theArgs[i];
-
-          if ( anArg.name != undefined && anArg.value != undefined ) {
-            queryString += anArg.name +  "=" + escape(anArg.value);
-          }
-          else {
-             var ePos  = anArg.indexOf('=');
-             var argName  = anArg.substring( 0, ePos );
-             var argValue = anArg.substring( ePos + 1 );
-             queryString += argName + "=" + escape(argValue);
-          }
-      }
-      return queryString;
-   },
-
-   _onRequestComplete : function(request) {
-      if(!request)
-          return;
-      // User can set an onFailure option - which will be called by prototype
-      if (request.status != 200)
-        return;
-
-      var response = request.responseXML.getElementsByTagName("ajax-response");
-      if (response == null || response.length != 1)
-         return;
-      this._processAjaxResponse( response[0].childNodes );
-      
-      // Check if user has set a onComplete function
-      var onRicoComplete = this.options.onRicoComplete;
-      if (onRicoComplete != null)
-          onRicoComplete();
-   },
-
-   _processAjaxResponse: function( xmlResponseElements ) {
-      for ( var i = 0 ; i < xmlResponseElements.length ; i++ ) {
-         var responseElement = xmlResponseElements[i];
-
-         // only process nodes of type element.....
-         if ( responseElement.nodeType != 1 )
-            continue;
-
-         var responseType = responseElement.getAttribute("type");
-         var responseId   = responseElement.getAttribute("id");
-
-         if ( responseType == "object" )
-            this._processAjaxObjectUpdate( this.ajaxObjects[ responseId ], responseElement );
-         else if ( responseType == "element" )
-            this._processAjaxElementUpdate( this.ajaxElements[ responseId ], responseElement );
-         else
-            alert('unrecognized AjaxResponse type : ' + responseType );
-      }
-   },
-
-   _processAjaxObjectUpdate: function( ajaxObject, responseElement ) {
-      ajaxObject.ajaxUpdate( responseElement );
-   },
-
-   _processAjaxElementUpdate: function( ajaxElement, responseElement ) {
-      ajaxElement.innerHTML = RicoUtil.getContentAsString(responseElement);
-   }
-
-}
-
-var ajaxEngine = new Rico.AjaxEngine();
-
-
-//-------------------- ricoColor.js
-Rico.Color = Class.create();
-
-Rico.Color.prototype = {
-
-   initialize: function(red, green, blue) {
-      this.rgb = { r: red, g : green, b : blue };
-   },
-
-   setRed: function(r) {
-      this.rgb.r = r;
-   },
-
-   setGreen: function(g) {
-      this.rgb.g = g;
-   },
-
-   setBlue: function(b) {
-      this.rgb.b = b;
-   },
-
-   setHue: function(h) {
-
-      // get an HSB model, and set the new hue...
-      var hsb = this.asHSB();
-      hsb.h = h;
-
-      // convert back to RGB...
-      this.rgb = Rico.Color.HSBtoRGB(hsb.h, hsb.s, hsb.b);
-   },
-
-   setSaturation: function(s) {
-      // get an HSB model, and set the new hue...
-      var hsb = this.asHSB();
-      hsb.s = s;
-
-      // convert back to RGB and set values...
-      this.rgb = Rico.Color.HSBtoRGB(hsb.h, hsb.s, hsb.b);
-   },
-
-   setBrightness: function(b) {
-      // get an HSB model, and set the new hue...
-      var hsb = this.asHSB();
-      hsb.b = b;
-
-      // convert back to RGB and set values...
-      this.rgb = Rico.Color.HSBtoRGB( hsb.h, hsb.s, hsb.b );
-   },
-
-   darken: function(percent) {
-      var hsb  = this.asHSB();
-      this.rgb = Rico.Color.HSBtoRGB(hsb.h, hsb.s, Math.max(hsb.b - percent,0));
-   },
-
-   brighten: function(percent) {
-      var hsb  = this.asHSB();
-      this.rgb = Rico.Color.HSBtoRGB(hsb.h, hsb.s, Math.min(hsb.b + percent,1));
-   },
-
-   blend: function(other) {
-      this.rgb.r = Math.floor((this.rgb.r + other.rgb.r)/2);
-      this.rgb.g = Math.floor((this.rgb.g + other.rgb.g)/2);
-      this.rgb.b = Math.floor((this.rgb.b + other.rgb.b)/2);
-   },
-
-   isBright: function() {
-      var hsb = this.asHSB();
-      return this.asHSB().b > 0.5;
-   },
-
-   isDark: function() {
-      return ! this.isBright();
-   },
-
-   asRGB: function() {
-      return "rgb(" + this.rgb.r + "," + this.rgb.g + "," + this.rgb.b + ")";
-   },
-
-   asHex: function() {
-      return "#" + this.rgb.r.toColorPart() + this.rgb.g.toColorPart() + this.rgb.b.toColorPart();
-   },
-
-   asHSB: function() {
-      return Rico.Color.RGBtoHSB(this.rgb.r, this.rgb.g, this.rgb.b);
-   },
-
-   toString: function() {
-      return this.asHex();
-   }
-
-};
-
-Rico.Color.createFromHex = function(hexCode) {
-  if(hexCode.length==4) {
-    var shortHexCode = hexCode; 
-    var hexCode = '#';
-    for(var i=1;i<4;i++) hexCode += (shortHexCode.charAt(i) + 
-shortHexCode.charAt(i));
-  }
-   if ( hexCode.indexOf('#') == 0 )
-      hexCode = hexCode.substring(1);
-   var red   = hexCode.substring(0,2);
-   var green = hexCode.substring(2,4);
-   var blue  = hexCode.substring(4,6);
-   return new Rico.Color( parseInt(red,16), parseInt(green,16), parseInt(blue,16) );
-}
-
-/**
- * Factory method for creating a color from the background of
- * an HTML element.
- */
-Rico.Color.createColorFromBackground = function(elem) {
-
-   var actualColor = RicoUtil.getElementsComputedStyle($(elem), "backgroundColor", "background-color");
-
-   if ( actualColor == "transparent" && elem.parentNode )
-      return Rico.Color.createColorFromBackground(elem.parentNode);
-
-   if ( actualColor == null )
-      return new Rico.Color(255,255,255);
-
-   if ( actualColor.indexOf("rgb(") == 0 ) {
-      var colors = actualColor.substring(4, actualColor.length - 1 );
-      var colorArray = colors.split(",");
-      return new Rico.Color( parseInt( colorArray[0] ),
-                            parseInt( colorArray[1] ),
-                            parseInt( colorArray[2] )  );
-
-   }
-   else if ( actualColor.indexOf("#") == 0 ) {
-      return Rico.Color.createFromHex(actualColor);
-   }
-   else
-      return new Rico.Color(255,255,255);
-}
-
-Rico.Color.HSBtoRGB = function(hue, saturation, brightness) {
-
-   var red   = 0;
-       var green = 0;
-       var blue  = 0;
-
-   if (saturation == 0) {
-      red = parseInt(brightness * 255.0 + 0.5);
-          green = red;
-          blue = red;
-       }
-       else {
-      var h = (hue - Math.floor(hue)) * 6.0;
-      var f = h - Math.floor(h);
-      var p = brightness * (1.0 - saturation);
-      var q = brightness * (1.0 - saturation * f);
-      var t = brightness * (1.0 - (saturation * (1.0 - f)));
-
-      switch (parseInt(h)) {
-         case 0:
-            red   = (brightness * 255.0 + 0.5);
-            green = (t * 255.0 + 0.5);
-            blue  = (p * 255.0 + 0.5);
-            break;
-         case 1:
-            red   = (q * 255.0 + 0.5);
-            green = (brightness * 255.0 + 0.5);
-            blue  = (p * 255.0 + 0.5);
-            break;
-         case 2:
-            red   = (p * 255.0 + 0.5);
-            green = (brightness * 255.0 + 0.5);
-            blue  = (t * 255.0 + 0.5);
-            break;
-         case 3:
-            red   = (p * 255.0 + 0.5);
-            green = (q * 255.0 + 0.5);
-            blue  = (brightness * 255.0 + 0.5);
-            break;
-         case 4:
-            red   = (t * 255.0 + 0.5);
-            green = (p * 255.0 + 0.5);
-            blue  = (brightness * 255.0 + 0.5);
-            break;
-          case 5:
-            red   = (brightness * 255.0 + 0.5);
-            green = (p * 255.0 + 0.5);
-            blue  = (q * 255.0 + 0.5);
-            break;
-           }
-       }
-
-   return { r : parseInt(red), g : parseInt(green) , b : parseInt(blue) };
-}
-
-Rico.Color.RGBtoHSB = function(r, g, b) {
-
-   var hue;
-   var saturation;
-   var brightness;
-
-   var cmax = (r > g) ? r : g;
-   if (b > cmax)
-      cmax = b;
-
-   var cmin = (r < g) ? r : g;
-   if (b < cmin)
-      cmin = b;
-
-   brightness = cmax / 255.0;
-   if (cmax != 0)
-      saturation = (cmax - cmin)/cmax;
-   else
-      saturation = 0;
-
-   if (saturation == 0)
-      hue = 0;
-   else {
-      var redc   = (cmax - r)/(cmax - cmin);
-       var greenc = (cmax - g)/(cmax - cmin);
-       var bluec  = (cmax - b)/(cmax - cmin);
-
-       if (r == cmax)
-          hue = bluec - greenc;
-       else if (g == cmax)
-          hue = 2.0 + redc - bluec;
-      else
-          hue = 4.0 + greenc - redc;
-
-       hue = hue / 6.0;
-       if (hue < 0)
-          hue = hue + 1.0;
-   }
-
-   return { h : hue, s : saturation, b : brightness };
-}
-
-
-//-------------------- ricoCorner.js
-Rico.Corner = {
-
-   round: function(e, options) {
-      var e = $(e);
-      this._setOptions(options);
-
-      var color = this.options.color;
-      if ( this.options.color == "fromElement" )
-         color = this._background(e);
-
-      var bgColor = this.options.bgColor;
-      if ( this.options.bgColor == "fromParent" )
-         bgColor = this._background(e.offsetParent);
-
-      this._roundCornersImpl(e, color, bgColor);
-   },
-
-   _roundCornersImpl: function(e, color, bgColor) {
-      if(this.options.border)
-         this._renderBorder(e,bgColor);
-      if(this._isTopRounded())
-         this._roundTopCorners(e,color,bgColor);
-      if(this._isBottomRounded())
-         this._roundBottomCorners(e,color,bgColor);
-   },
-
-   _renderBorder: function(el,bgColor) {
-      var borderValue = "1px solid " + this._borderColor(bgColor);
-      var borderL = "border-left: "  + borderValue;
-      var borderR = "border-right: " + borderValue;
-      var style   = "style='" + borderL + ";" + borderR +  "'";
-      el.innerHTML = "<div " + style + ">" + el.innerHTML + "</div>"
-   },
-
-   _roundTopCorners: function(el, color, bgColor) {
-      var corner = this._createCorner(bgColor);
-      for(var i=0 ; i < this.options.numSlices ; i++ )
-         corner.appendChild(this._createCornerSlice(color,bgColor,i,"top"));
-      el.style.paddingTop = 0;
-      el.insertBefore(corner,el.firstChild);
-   },
-
-   _roundBottomCorners: function(el, color, bgColor) {
-      var corner = this._createCorner(bgColor);
-      for(var i=(this.options.numSlices-1) ; i >= 0 ; i-- )
-         corner.appendChild(this._createCornerSlice(color,bgColor,i,"bottom"));
-      el.style.paddingBottom = 0;
-      el.appendChild(corner);
-   },
-
-   _createCorner: function(bgColor) {
-      var corner = document.createElement("div");
-      corner.style.backgroundColor = (this._isTransparent() ? "transparent" : bgColor);
-      return corner;
-   },
-
-   _createCornerSlice: function(color,bgColor, n, position) {
-      var slice = document.createElement("span");
-
-      var inStyle = slice.style;
-      inStyle.backgroundColor = color;
-      inStyle.display  = "block";
-      inStyle.height   = "1px";
-      inStyle.overflow = "hidden";
-      inStyle.fontSize = "1px";
-
-      var borderColor = this._borderColor(color,bgColor);
-      if ( this.options.border && n == 0 ) {
-         inStyle.borderTopStyle    = "solid";
-         inStyle.borderTopWidth    = "1px";
-         inStyle.borderLeftWidth   = "0px";
-         inStyle.borderRightWidth  = "0px";
-         inStyle.borderBottomWidth = "0px";
-         inStyle.height            = "0px"; // assumes css compliant box model
-         inStyle.borderColor       = borderColor;
-      }
-      else if(borderColor) {
-         inStyle.borderColor = borderColor;
-         inStyle.borderStyle = "solid";
-         inStyle.borderWidth = "0px 1px";
-      }
-
-      if ( !this.options.compact && (n == (this.options.numSlices-1)) )
-         inStyle.height = "2px";
-
-      this._setMargin(slice, n, position);
-      this._setBorder(slice, n, position);
-      return slice;
-   },
-
-   _setOptions: function(options) {
-      this.options = {
-         corners : "all",
-         color   : "fromElement",
-         bgColor : "fromParent",
-         blend   : true,
-         border  : false,
-         compact : false
-      }
-      Object.extend(this.options, options || {});
-
-      this.options.numSlices = this.options.compact ? 2 : 4;
-      if ( this._isTransparent() )
-         this.options.blend = false;
-   },
-
-   _whichSideTop: function() {
-      if ( this._hasString(this.options.corners, "all", "top") )
-         return "";
-
-      if ( this.options.corners.indexOf("tl") >= 0 && this.options.corners.indexOf("tr") >= 0 )
-         return "";
-
-      if (this.options.corners.indexOf("tl") >= 0)
-         return "left";
-      else if (this.options.corners.indexOf("tr") >= 0)
-          return "right";
-      return "";
-   },
-
-   _whichSideBottom: function() {
-      if ( this._hasString(this.options.corners, "all", "bottom") )
-         return "";
-
-      if ( this.options.corners.indexOf("bl")>=0 && this.options.corners.indexOf("br")>=0 )
-         return "";
-
-      if(this.options.corners.indexOf("bl") >=0)
-         return "left";
-      else if(this.options.corners.indexOf("br")>=0)
-         return "right";
-      return "";
-   },
-
-   _borderColor : function(color,bgColor) {
-      if ( color == "transparent" )
-         return bgColor;
-      else if ( this.options.border )
-         return this.options.border;
-      else if ( this.options.blend )
-         return this._blend( bgColor, color );
-      else
-         return "";
-   },
-
-
-   _setMargin: function(el, n, corners) {
-      var marginSize = this._marginSize(n);
-      var whichSide = corners == "top" ? this._whichSideTop() : this._whichSideBottom();
-
-      if ( whichSide == "left" ) {
-         el.style.marginLeft = marginSize + "px"; el.style.marginRight = "0px";
-      }
-      else if ( whichSide == "right" ) {
-         el.style.marginRight = marginSize + "px"; el.style.marginLeft  = "0px";
-      }
-      else {
-         el.style.marginLeft = marginSize + "px"; el.style.marginRight = marginSize + "px";
-      }
-   },
-
-   _setBorder: function(el,n,corners) {
-      var borderSize = this._borderSize(n);
-      var whichSide = corners == "top" ? this._whichSideTop() : this._whichSideBottom();
-      if ( whichSide == "left" ) {
-         el.style.borderLeftWidth = borderSize + "px"; el.style.borderRightWidth = "0px";
-      }
-      else if ( whichSide == "right" ) {
-         el.style.borderRightWidth = borderSize + "px"; el.style.borderLeftWidth  = "0px";
-      }
-      else {
-         el.style.borderLeftWidth = borderSize + "px"; el.style.borderRightWidth = borderSize + "px";
-      }
-      if (this.options.border != false)
-        el.style.borderLeftWidth = borderSize + "px"; el.style.borderRightWidth = borderSize + "px";
-   },
-
-   _marginSize: function(n) {
-      if ( this._isTransparent() )
-         return 0;
-
-      var marginSizes          = [ 5, 3, 2, 1 ];
-      var blendedMarginSizes   = [ 3, 2, 1, 0 ];
-      var compactMarginSizes   = [ 2, 1 ];
-      var smBlendedMarginSizes = [ 1, 0 ];
-
-      if ( this.options.compact && this.options.blend )
-         return smBlendedMarginSizes[n];
-      else if ( this.options.compact )
-         return compactMarginSizes[n];
-      else if ( this.options.blend )
-         return blendedMarginSizes[n];
-      else
-         return marginSizes[n];
-   },
-
-   _borderSize: function(n) {
-      var transparentBorderSizes = [ 5, 3, 2, 1 ];
-      var blendedBorderSizes     = [ 2, 1, 1, 1 ];
-      var compactBorderSizes     = [ 1, 0 ];
-      var actualBorderSizes      = [ 0, 2, 0, 0 ];
-
-      if ( this.options.compact && (this.options.blend || this._isTransparent()) )
-         return 1;
-      else if ( this.options.compact )
-         return compactBorderSizes[n];
-      else if ( this.options.blend )
-         return blendedBorderSizes[n];
-      else if ( this.options.border )
-         return actualBorderSizes[n];
-      else if ( this._isTransparent() )
-         return transparentBorderSizes[n];
-      return 0;
-   },
-
-   _hasString: function(str) { for(var i=1 ; i<arguments.length ; i++) if (str.indexOf(arguments[i]) >= 0) return true; return false; },
-   _blend: function(c1, c2) { var cc1 = Rico.Color.createFromHex(c1); cc1.blend(Rico.Color.createFromHex(c2)); return cc1; },
-   _background: function(el) { try { return Rico.Color.createColorFromBackground(el).asHex(); } catch(err) { return "#ffffff"; } },
-   _isTransparent: function() { return this.options.color == "transparent"; },
-   _isTopRounded: function() { return this._hasString(this.options.corners, "all", "top", "tl", "tr"); },
-   _isBottomRounded: function() { return this._hasString(this.options.corners, "all", "bottom", "bl", "br"); },
-   _hasSingleTextChild: function(el) { return el.childNodes.length == 1 && el.childNodes[0].nodeType == 3; }
-}
-
-
-//-------------------- ricoDragAndDrop.js
-Rico.DragAndDrop = Class.create();
-
-Rico.DragAndDrop.prototype = {
-
-   initialize: function() {
-      this.dropZones                = new Array();
-      this.draggables               = new Array();
-      this.currentDragObjects       = new Array();
-      this.dragElement              = null;
-      this.lastSelectedDraggable    = null;
-      this.currentDragObjectVisible = false;
-      this.interestedInMotionEvents = false;
-      this._mouseDown = this._mouseDownHandler.bindAsEventListener(this);
-      this._mouseMove = this._mouseMoveHandler.bindAsEventListener(this);
-      this._mouseUp = this._mouseUpHandler.bindAsEventListener(this);
-   },
-
-   registerDropZone: function(aDropZone) {
-      this.dropZones[ this.dropZones.length ] = aDropZone;
-   },
-
-   deregisterDropZone: function(aDropZone) {
-      var newDropZones = new Array();
-      var j = 0;
-      for ( var i = 0 ; i < this.dropZones.length ; i++ ) {
-         if ( this.dropZones[i] != aDropZone )
-            newDropZones[j++] = this.dropZones[i];
-      }
-
-      this.dropZones = newDropZones;
-   },
-
-   clearDropZones: function() {
-      this.dropZones = new Array();
-   },
-
-   registerDraggable: function( aDraggable ) {
-      this.draggables[ this.draggables.length ] = aDraggable;
-      this._addMouseDownHandler( aDraggable );
-   },
-
-   clearSelection: function() {
-      for ( var i = 0 ; i < this.currentDragObjects.length ; i++ )
-         this.currentDragObjects[i].deselect();
-      this.currentDragObjects = new Array();
-      this.lastSelectedDraggable = null;
-   },
-
-   hasSelection: function() {
-      return this.currentDragObjects.length > 0;
-   },
-
-   setStartDragFromElement: function( e, mouseDownElement ) {
-      this.origPos = RicoUtil.toDocumentPosition(mouseDownElement);
-      this.startx = e.screenX - this.origPos.x
-      this.starty = e.screenY - this.origPos.y
-      //this.startComponentX = e.layerX ? e.layerX : e.offsetX;
-      //this.startComponentY = e.layerY ? e.layerY : e.offsetY;
-      //this.adjustedForDraggableSize = false;
-
-      this.interestedInMotionEvents = this.hasSelection();
-      this._terminateEvent(e);
-   },
-
-   updateSelection: function( draggable, extendSelection ) {
-      if ( ! extendSelection )
-         this.clearSelection();
-
-      if ( draggable.isSelected() ) {
-         this.currentDragObjects.removeItem(draggable);
-         draggable.deselect();
-         if ( draggable == this.lastSelectedDraggable )
-            this.lastSelectedDraggable = null;
-      }
-      else {
-         this.currentDragObjects[ this.currentDragObjects.length ] = draggable;
-         draggable.select();
-         this.lastSelectedDraggable = draggable;
-      }
-   },
-
-   _mouseDownHandler: function(e) {
-      if ( arguments.length == 0 )
-         e = event;
-
-      // if not button 1 ignore it...
-      var nsEvent = e.which != undefined;
-      if ( (nsEvent && e.which != 1) || (!nsEvent && e.button != 1))
-         return;
-
-      var eventTarget      = e.target ? e.target : e.srcElement;
-      var draggableObject  = eventTarget.draggable;
-
-      var candidate = eventTarget;
-      while (draggableObject == null && candidate.parentNode) {
-         candidate = candidate.parentNode;
-         draggableObject = candidate.draggable;
-      }
-   
-      if ( draggableObject == null )
-         return;
-
-      this.updateSelection( draggableObject, e.ctrlKey );
-
-      // clear the drop zones postion cache...
-      if ( this.hasSelection() )
-         for ( var i = 0 ; i < this.dropZones.length ; i++ )
-            this.dropZones[i].clearPositionCache();
-
-      this.setStartDragFromElement( e, draggableObject.getMouseDownHTMLElement() );
-   },
-
-
-   _mouseMoveHandler: function(e) {
-      var nsEvent = e.which != undefined;
-      if ( !this.interestedInMotionEvents ) {
-         //this._terminateEvent(e);
-         return;
-      }
-
-      if ( ! this.hasSelection() )
-         return;
-
-      if ( ! this.currentDragObjectVisible )
-         this._startDrag(e);
-
-      if ( !this.activatedDropZones )
-         this._activateRegisteredDropZones();
-
-      //if ( !this.adjustedForDraggableSize )
-      //   this._adjustForDraggableSize(e);
-
-      this._updateDraggableLocation(e);
-      this._updateDropZonesHover(e);
-
-      this._terminateEvent(e);
-   },
-
-   _makeDraggableObjectVisible: function(e)
-   {
-      if ( !this.hasSelection() )
-         return;
-
-      var dragElement;
-      if ( this.currentDragObjects.length > 1 )
-         dragElement = this.currentDragObjects[0].getMultiObjectDragGUI(this.currentDragObjects);
-      else
-         dragElement = this.currentDragObjects[0].getSingleObjectDragGUI();
-
-      // go ahead and absolute position it...
-      if ( RicoUtil.getElementsComputedStyle(dragElement, "position")  != "absolute" )
-         dragElement.style.position = "absolute";
-
-      // need to parent him into the document...
-      if ( dragElement.parentNode == null || dragElement.parentNode.nodeType == 11 )
-         document.body.appendChild(dragElement);
-
-      this.dragElement = dragElement;
-      this._updateDraggableLocation(e);
-
-      this.currentDragObjectVisible = true;
-   },
-
-   /**
-   _adjustForDraggableSize: function(e) {
-      var dragElementWidth  = this.dragElement.offsetWidth;
-      var dragElementHeight = this.dragElement.offsetHeight;
-      if ( this.startComponentX > dragElementWidth )
-         this.startx -= this.startComponentX - dragElementWidth + 2;
-      if ( e.offsetY ) {
-         if ( this.startComponentY > dragElementHeight )
-            this.starty -= this.startComponentY - dragElementHeight + 2;
-      }
-      this.adjustedForDraggableSize = true;
-   },
-   **/
-
-   _leftOffset: function(e) {
-          return e.offsetX ? document.body.scrollLeft : 0
-       },
-
-   _topOffset: function(e) {
-          return e.offsetY ? document.body.scrollTop:0
-       },
-
-               
-   _updateDraggableLocation: function(e) {
-      var dragObjectStyle = this.dragElement.style;
-      dragObjectStyle.left = (e.screenX + this._leftOffset(e) - this.startx) + "px"
-      dragObjectStyle.top  = (e.screenY + this._topOffset(e) - this.starty) + "px";
-   },
-
-   _updateDropZonesHover: function(e) {
-      var n = this.dropZones.length;
-      for ( var i = 0 ; i < n ; i++ ) {
-         if ( ! this._mousePointInDropZone( e, this.dropZones[i] ) )
-            this.dropZones[i].hideHover();
-      }
-
-      for ( var i = 0 ; i < n ; i++ ) {
-         if ( this._mousePointInDropZone( e, this.dropZones[i] ) ) {
-            if ( this.dropZones[i].canAccept(this.currentDragObjects) )
-               this.dropZones[i].showHover();
-         }
-      }
-   },
-
-   _startDrag: function(e) {
-      for ( var i = 0 ; i < this.currentDragObjects.length ; i++ )
-         this.currentDragObjects[i].startDrag();
-
-      this._makeDraggableObjectVisible(e);
-   },
-
-   _mouseUpHandler: function(e) {
-      if ( ! this.hasSelection() )
-         return;
-
-      var nsEvent = e.which != undefined;
-      if ( (nsEvent && e.which != 1) || (!nsEvent && e.button != 1))
-         return;
-
-      this.interestedInMotionEvents = false;
-
-      if ( this.dragElement == null ) {
-         this._terminateEvent(e);
-         return;
-      }
-
-      if ( this._placeDraggableInDropZone(e) )
-         this._completeDropOperation(e);
-      else {
-         this._terminateEvent(e);
-         new Rico.Effect.Position( this.dragElement,
-                              this.origPos.x,
-                              this.origPos.y,
-                              200,
-                              20,
-                              { complete : this._doCancelDragProcessing.bind(this) } );
-      }
-
-     Event.stopObserving(document.body, "mousemove", this._mouseMove);
-     Event.stopObserving(document.body, "mouseup",  this._mouseUp);
-   },
-
-   _retTrue: function () {
-      return true;
-   },
-
-   _completeDropOperation: function(e) {
-      if ( this.dragElement != this.currentDragObjects[0].getMouseDownHTMLElement() ) {
-         if ( this.dragElement.parentNode != null )
-            this.dragElement.parentNode.removeChild(this.dragElement);
-      }
-
-      this._deactivateRegisteredDropZones();
-      this._endDrag();
-      this.clearSelection();
-      this.dragElement = null;
-      this.currentDragObjectVisible = false;
-      this._terminateEvent(e);
-   },
-
-   _doCancelDragProcessing: function() {
-      this._cancelDrag();
-
-        if ( this.dragElement != this.currentDragObjects[0].getMouseDownHTMLElement() && this.dragElement)
-           if ( this.dragElement.parentNode != null )
-              this.dragElement.parentNode.removeChild(this.dragElement);
-
-
-      this._deactivateRegisteredDropZones();
-      this.dragElement = null;
-      this.currentDragObjectVisible = false;
-   },
-
-   _placeDraggableInDropZone: function(e) {
-      var foundDropZone = false;
-      var n = this.dropZones.length;
-      for ( var i = 0 ; i < n ; i++ ) {
-         if ( this._mousePointInDropZone( e, this.dropZones[i] ) ) {
-            if ( this.dropZones[i].canAccept(this.currentDragObjects) ) {
-               this.dropZones[i].hideHover();
-               this.dropZones[i].accept(this.currentDragObjects);
-               foundDropZone = true;
-               break;
-            }
-         }
-      }
-
-      return foundDropZone;
-   },
-
-   _cancelDrag: function() {
-      for ( var i = 0 ; i < this.currentDragObjects.length ; i++ )
-         this.currentDragObjects[i].cancelDrag();
-   },
-
-   _endDrag: function() {
-      for ( var i = 0 ; i < this.currentDragObjects.length ; i++ )
-         this.currentDragObjects[i].endDrag();
-   },
-
-   _mousePointInDropZone: function( e, dropZone ) {
-
-      var absoluteRect = dropZone.getAbsoluteRect();
-
-      return e.clientX  > absoluteRect.left + this._leftOffset(e) &&
-             e.clientX  < absoluteRect.right + this._leftOffset(e) &&
-             e.clientY  > absoluteRect.top + this._topOffset(e)   &&
-             e.clientY  < absoluteRect.bottom + this._topOffset(e);
-   },
-
-   _addMouseDownHandler: function( aDraggable )
-   {
-       htmlElement  = aDraggable.getMouseDownHTMLElement();
-      if ( htmlElement  != null ) { 
-         htmlElement.draggable = aDraggable;
-         Event.observe(htmlElement , "mousedown", this._onmousedown.bindAsEventListener(this));
-         Event.observe(htmlElement, "mousedown", this._mouseDown);
-      }
-   },
-
-   _activateRegisteredDropZones: function() {
-      var n = this.dropZones.length;
-      for ( var i = 0 ; i < n ; i++ ) {
-         var dropZone = this.dropZones[i];
-         if ( dropZone.canAccept(this.currentDragObjects) )
-            dropZone.activate();
-      }
-
-      this.activatedDropZones = true;
-   },
-
-   _deactivateRegisteredDropZones: function() {
-      var n = this.dropZones.length;
-      for ( var i = 0 ; i < n ; i++ )
-         this.dropZones[i].deactivate();
-      this.activatedDropZones = false;
-   },
-
-   _onmousedown: function () {
-     Event.observe(document.body, "mousemove", this._mouseMove);
-     Event.observe(document.body, "mouseup",  this._mouseUp);
-   },
-
-   _terminateEvent: function(e) {
-      if ( e.stopPropagation != undefined )
-         e.stopPropagation();
-      else if ( e.cancelBubble != undefined )
-         e.cancelBubble = true;
-
-      if ( e.preventDefault != undefined )
-         e.preventDefault();
-      else
-         e.returnValue = false;
-   },
-
-
-          initializeEventHandlers: function() {
-             if ( typeof document.implementation != "undefined" &&
-                document.implementation.hasFeature("HTML",   "1.0") &&
-                document.implementation.hasFeature("Events", "2.0") &&
-                document.implementation.hasFeature("CSS",    "2.0") ) {
-                document.addEventListener("mouseup",   this._mouseUpHandler.bindAsEventListener(this),  false);
-                document.addEventListener("mousemove", this._mouseMoveHandler.bindAsEventListener(this), false);
-             }
-             else {
-                document.attachEvent( "onmouseup",   this._mouseUpHandler.bindAsEventListener(this) );
-                document.attachEvent( "onmousemove", this._mouseMoveHandler.bindAsEventListener(this) );
-             }
-          }
-       }
-
-       var dndMgr = new Rico.DragAndDrop();
-       dndMgr.initializeEventHandlers();
-
-
-//-------------------- ricoDraggable.js
-Rico.Draggable = Class.create();
-
-Rico.Draggable.prototype = {
-
-   initialize: function( type, htmlElement ) {
-      this.type          = type;
-      this.htmlElement   = $(htmlElement);
-      this.selected      = false;
-   },
-
-   /**
-    *   Returns the HTML element that should have a mouse down event
-    *   added to it in order to initiate a drag operation
-    *
-    **/
-   getMouseDownHTMLElement: function() {
-      return this.htmlElement;
-   },
-
-   select: function() {
-      this.selected = true;
-
-      if ( this.showingSelected )
-         return;
-
-      var htmlElement = this.getMouseDownHTMLElement();
-
-      var color = Rico.Color.createColorFromBackground(htmlElement);
-      color.isBright() ? color.darken(0.033) : color.brighten(0.033);
-
-      this.saveBackground = RicoUtil.getElementsComputedStyle(htmlElement, "backgroundColor", "background-color");
-      htmlElement.style.backgroundColor = color.asHex();
-      this.showingSelected = true;
-   },
-
-   deselect: function() {
-      this.selected = false;
-      if ( !this.showingSelected )
-         return;
-
-      var htmlElement = this.getMouseDownHTMLElement();
-
-      htmlElement.style.backgroundColor = this.saveBackground;
-      this.showingSelected = false;
-   },
-
-   isSelected: function() {
-      return this.selected;
-   },
-
-   startDrag: function() {
-   },
-
-   cancelDrag: function() {
-   },
-
-   endDrag: function() {
-   },
-
-   getSingleObjectDragGUI: function() {
-      return this.htmlElement;
-   },
-
-   getMultiObjectDragGUI: function( draggables ) {
-      return this.htmlElement;
-   },
-
-   getDroppedGUI: function() {
-      return this.htmlElement;
-   },
-
-   toString: function() {
-      return this.type + ":" + this.htmlElement + ":";
-   }
-
-}
-
-
-//-------------------- ricoDropzone.js
-Rico.Dropzone = Class.create();
-
-Rico.Dropzone.prototype = {
-
-   initialize: function( htmlElement ) {
-      this.htmlElement  = $(htmlElement);
-      this.absoluteRect = null;
-   },
-
-   getHTMLElement: function() {
-      return this.htmlElement;
-   },
-
-   clearPositionCache: function() {
-      this.absoluteRect = null;
-   },
-
-   getAbsoluteRect: function() {
-      if ( this.absoluteRect == null ) {
-         var htmlElement = this.getHTMLElement();
-         var pos = RicoUtil.toViewportPosition(htmlElement);
-
-         this.absoluteRect = {
-            top:    pos.y,
-            left:   pos.x,
-            bottom: pos.y + htmlElement.offsetHeight,
-            right:  pos.x + htmlElement.offsetWidth
-         };
-      }
-      return this.absoluteRect;
-   },
-
-   activate: function() {
-      var htmlElement = this.getHTMLElement();
-      if (htmlElement == null  || this.showingActive)
-         return;
-
-      this.showingActive = true;
-      this.saveBackgroundColor = htmlElement.style.backgroundColor;
-
-      var fallbackColor = "#ffea84";
-      var currentColor = Rico.Color.createColorFromBackground(htmlElement);
-      if ( currentColor == null )
-         htmlElement.style.backgroundColor = fallbackColor;
-      else {
-         currentColor.isBright() ? currentColor.darken(0.2) : currentColor.brighten(0.2);
-         htmlElement.style.backgroundColor = currentColor.asHex();
-      }
-   },
-
-   deactivate: function() {
-      var htmlElement = this.getHTMLElement();
-      if (htmlElement == null || !this.showingActive)
-         return;
-
-      htmlElement.style.backgroundColor = this.saveBackgroundColor;
-      this.showingActive = false;
-      this.saveBackgroundColor = null;
-   },
-
-   showHover: function() {
-      var htmlElement = this.getHTMLElement();
-      if ( htmlElement == null || this.showingHover )
-         return;
-
-      this.saveBorderWidth = htmlElement.style.borderWidth;
-      this.saveBorderStyle = htmlElement.style.borderStyle;
-      this.saveBorderColor = htmlElement.style.borderColor;
-
-      this.showingHover = true;
-      htmlElement.style.borderWidth = "1px";
-      htmlElement.style.borderStyle = "solid";
-      //htmlElement.style.borderColor = "#ff9900";
-      htmlElement.style.borderColor = "#ffff00";
-   },
-
-   hideHover: function() {
-      var htmlElement = this.getHTMLElement();
-      if ( htmlElement == null || !this.showingHover )
-         return;
-
-      htmlElement.style.borderWidth = this.saveBorderWidth;
-      htmlElement.style.borderStyle = this.saveBorderStyle;
-      htmlElement.style.borderColor = this.saveBorderColor;
-      this.showingHover = false;
-   },
-
-   canAccept: function(draggableObjects) {
-      return true;
-   },
-
-   accept: function(draggableObjects) {
-      var htmlElement = this.getHTMLElement();
-      if ( htmlElement == null )
-         return;
-
-      n = draggableObjects.length;
-      for ( var i = 0 ; i < n ; i++ )
-      {
-         var theGUI = draggableObjects[i].getDroppedGUI();
-         if ( RicoUtil.getElementsComputedStyle( theGUI, "position" ) == "absolute" )
-         {
-            theGUI.style.position = "static";
-            theGUI.style.top = "";
-            theGUI.style.top = "";
-         }
-         htmlElement.appendChild(theGUI);
-      }
-   }
-}
-
-
-//-------------------- ricoEffects.js
-
-Rico.Effect = {};
-
-Rico.Effect.SizeAndPosition = Class.create();
-Rico.Effect.SizeAndPosition.prototype = {
-
-   initialize: function(element, x, y, w, h, duration, steps, options) {
-      this.element = $(element);
-      this.x = x;
-      this.y = y;
-      this.w = w;
-      this.h = h;
-      this.duration = duration;
-      this.steps    = steps;
-      this.options  = arguments[7] || {};
-
-      this.sizeAndPosition();
-   },
-
-   sizeAndPosition: function() {
-      if (this.isFinished()) {
-         if(this.options.complete) this.options.complete(this);
-         return;
-      }
-
-      if (this.timer)
-         clearTimeout(this.timer);
-
-      var stepDuration = Math.round(this.duration/this.steps) ;
-
-      // Get original values: x,y = top left corner;  w,h = width height
-      var currentX = this.element.offsetLeft;
-      var currentY = this.element.offsetTop;
-      var currentW = this.element.offsetWidth;
-      var currentH = this.element.offsetHeight;
-
-      // If values not set, or zero, we do not modify them, and take original as final as well
-      this.x = (this.x) ? this.x : currentX;
-      this.y = (this.y) ? this.y : currentY;
-      this.w = (this.w) ? this.w : currentW;
-      this.h = (this.h) ? this.h : currentH;
-
-      // how much do we need to modify our values for each step?
-      var difX = this.steps >  0 ? (this.x - currentX)/this.steps : 0;
-      var difY = this.steps >  0 ? (this.y - currentY)/this.steps : 0;
-      var difW = this.steps >  0 ? (this.w - currentW)/this.steps : 0;
-      var difH = this.steps >  0 ? (this.h - currentH)/this.steps : 0;
-
-      this.moveBy(difX, difY);
-      this.resizeBy(difW, difH);
-
-      this.duration -= stepDuration;
-      this.steps--;
-
-      this.timer = setTimeout(this.sizeAndPosition.bind(this), stepDuration);
-   },
-
-   isFinished: function() {
-      return this.steps <= 0;
-   },
-
-   moveBy: function( difX, difY ) {
-      var currentLeft = this.element.offsetLeft;
-      var currentTop  = this.element.offsetTop;
-      var intDifX     = parseInt(difX);
-      var intDifY     = parseInt(difY);
-
-      var style = this.element.style;
-      if ( intDifX != 0 )
-         style.left = (currentLeft + intDifX) + "px";
-      if ( intDifY != 0 )
-         style.top  = (currentTop + intDifY) + "px";
-   },
-
-   resizeBy: function( difW, difH ) {
-      var currentWidth  = this.element.offsetWidth;
-      var currentHeight = this.element.offsetHeight;
-      var intDifW       = parseInt(difW);
-      var intDifH       = parseInt(difH);
-
-      var style = this.element.style;
-      if ( intDifW != 0 )
-         style.width   = (currentWidth  + intDifW) + "px";
-      if ( intDifH != 0 )
-         style.height  = (currentHeight + intDifH) + "px";
-   }
-}
-
-Rico.Effect.Size = Class.create();
-Rico.Effect.Size.prototype = {
-
-   initialize: function(element, w, h, duration, steps, options) {
-      new Rico.Effect.SizeAndPosition(element, null, null, w, h, duration, steps, options);
-  }
-}
-
-Rico.Effect.Position = Class.create();
-Rico.Effect.Position.prototype = {
-
-   initialize: function(element, x, y, duration, steps, options) {
-      new Rico.Effect.SizeAndPosition(element, x, y, null, null, duration, steps, options);
-  }
-}
-
-Rico.Effect.Round = Class.create();
-Rico.Effect.Round.prototype = {
-
-   initialize: function(tagName, className, options) {
-      var elements = document.getElementsByTagAndClassName(tagName,className);
-      for ( var i = 0 ; i < elements.length ; i++ )
-         Rico.Corner.round( elements[i], options );
-   }
-};
-
-Rico.Effect.FadeTo = Class.create();
-Rico.Effect.FadeTo.prototype = {
-
-   initialize: function( element, opacity, duration, steps, options) {
-      this.element  = $(element);
-      this.opacity  = opacity;
-      this.duration = duration;
-      this.steps    = steps;
-      this.options  = arguments[4] || {};
-      this.fadeTo();
-   },
-
-   fadeTo: function() {
-      if (this.isFinished()) {
-         if(this.options.complete) this.options.complete(this);
-         return;
-      }
-
-      if (this.timer)
-         clearTimeout(this.timer);
-
-      var stepDuration = Math.round(this.duration/this.steps) ;
-      var currentOpacity = this.getElementOpacity();
-      var delta = this.steps > 0 ? (this.opacity - currentOpacity)/this.steps : 0;
-
-      this.changeOpacityBy(delta);
-      this.duration -= stepDuration;
-      this.steps--;
-
-      this.timer = setTimeout(this.fadeTo.bind(this), stepDuration);
-   },
-
-   changeOpacityBy: function(v) {
-      var currentOpacity = this.getElementOpacity();
-      var newOpacity = Math.max(0, Math.min(currentOpacity+v, 1));
-      this.element.ricoOpacity = newOpacity;
-
-      this.element.style.filter = "alpha(opacity:"+Math.round(newOpacity*100)+")";
-      this.element.style.opacity = newOpacity; /*//*/;
-   },
-
-   isFinished: function() {
-      return this.steps <= 0;
-   },
-
-   getElementOpacity: function() {
-      if ( this.element.ricoOpacity == undefined ) {
-         var opacity = RicoUtil.getElementsComputedStyle(this.element, 'opacity');
-         this.element.ricoOpacity = opacity != undefined ? opacity : 1.0;
-      }
-      return parseFloat(this.element.ricoOpacity);
-   }
-}
-
-Rico.Effect.AccordionSize = Class.create();
-
-Rico.Effect.AccordionSize.prototype = {
-
-   initialize: function(e1, e2, start, end, duration, steps, options) {
-      this.e1       = $(e1);
-      this.e2       = $(e2);
-      this.start    = start;
-      this.end      = end;
-      this.duration = duration;
-      this.steps    = steps;
-      this.options  = arguments[6] || {};
-
-      this.accordionSize();
-   },
-
-   accordionSize: function() {
-
-      if (this.isFinished()) {
-         // just in case there are round errors or such...
-         this.e1.style.height = this.start + "px";
-         this.e2.style.height = this.end + "px";
-
-         if(this.options.complete)
-            this.options.complete(this);
-         return;
-      }
-
-      if (this.timer)
-         clearTimeout(this.timer);
-
-      var stepDuration = Math.round(this.duration/this.steps) ;
-
-      var diff = this.steps > 0 ? (parseInt(this.e1.offsetHeight) - this.start)/this.steps : 0;
-      this.resizeBy(diff);
-
-      this.duration -= stepDuration;
-      this.steps--;
-
-      this.timer = setTimeout(this.accordionSize.bind(this), stepDuration);
-   },
-
-   isFinished: function() {
-      return this.steps <= 0;
-   },
-
-   resizeBy: function(diff) {
-      var h1Height = this.e1.offsetHeight;
-      var h2Height = this.e2.offsetHeight;
-      var intDiff = parseInt(diff);
-      if ( diff != 0 ) {
-         this.e1.style.height = (h1Height - intDiff) + "px";
-         this.e2.style.height = (h2Height + intDiff) + "px";
-      }
-   }
-
-};
-
-
-//-------------------- ricoLiveGrid.js
-// Rico.LiveGridMetaData -----------------------------------------------------
-
-Rico.LiveGridMetaData = Class.create();
-
-Rico.LiveGridMetaData.prototype = {
-
-   initialize: function( pageSize, totalRows, columnCount, options ) {
-      this.pageSize  = pageSize;
-      this.totalRows = totalRows;
-      this.setOptions(options);
-      this.ArrowHeight = 16;
-      this.columnCount = columnCount;
-   },
-
-   setOptions: function(options) {
-      this.options = {
-         largeBufferSize    : 7.0,   // 7 pages
-         nearLimitFactor    : 0.2    // 20% of buffer
-      };
-      Object.extend(this.options, options || {});
-   },
-
-   getPageSize: function() {
-      return this.pageSize;
-   },
-
-   getTotalRows: function() {
-      return this.totalRows;
-   },
-
-   setTotalRows: function(n) {
-      this.totalRows = n;
-   },
-
-   getLargeBufferSize: function() {
-      return parseInt(this.options.largeBufferSize * this.pageSize);
-   },
-
-   getLimitTolerance: function() {
-      return parseInt(this.getLargeBufferSize() * this.options.nearLimitFactor);
-   }
-};
-
-// Rico.LiveGridScroller -----------------------------------------------------
-
-Rico.LiveGridScroller = Class.create();
-
-Rico.LiveGridScroller.prototype = {
-
-   initialize: function(liveGrid, viewPort) {
-      this.isIE = navigator.userAgent.toLowerCase().indexOf("msie") >= 0;
-      this.liveGrid = liveGrid;
-      this.metaData = liveGrid.metaData;
-      this.createScrollBar();
-      this.scrollTimeout = null;
-      this.lastScrollPos = 0;
-      this.viewPort = viewPort;
-      this.rows = new Array();
-   },
-
-   isUnPlugged: function() {
-      return this.scrollerDiv.onscroll == null;
-   },
-
-   plugin: function() {
-      this.scrollerDiv.onscroll = this.handleScroll.bindAsEventListener(this);
-   },
-
-   unplug: function() {
-      this.scrollerDiv.onscroll = null;
-   },
-
-   sizeIEHeaderHack: function() {
-      if ( !this.isIE ) return;
-      var headerTable = $(this.liveGrid.tableId + "_header");
-      if ( headerTable )
-         headerTable.rows[0].cells[0].style.width =
-            (headerTable.rows[0].cells[0].offsetWidth + 1) + "px";
-   },
-
-   createScrollBar: function() {
-      var visibleHeight = this.liveGrid.viewPort.visibleHeight();
-      // create the outer div...
-      this.scrollerDiv  = document.createElement("div");
-      var scrollerStyle = this.scrollerDiv.style;
-      scrollerStyle.borderRight = this.liveGrid.options.scrollerBorderRight;
-      scrollerStyle.position    = "relative";
-      scrollerStyle.left        = this.isIE ? "-6px" : "-3px";
-      scrollerStyle.width       = "19px";
-      scrollerStyle.height      = visibleHeight + "px";
-      scrollerStyle.overflow    = "auto";
-
-      // create the inner div...
-      this.heightDiv = document.createElement("div");
-      this.heightDiv.style.width  = "1px";
-
-      this.heightDiv.style.height = parseInt(visibleHeight *
-                        this.metaData.getTotalRows()/this.metaData.getPageSize()) + "px" ;
-      this.scrollerDiv.appendChild(this.heightDiv);
-      this.scrollerDiv.onscroll = this.handleScroll.bindAsEventListener(this);
-
-     var table = this.liveGrid.table;
-     table.parentNode.parentNode.insertBefore( this.scrollerDiv, table.parentNode.nextSibling );
-         var eventName = this.isIE ? "mousewheel" : "DOMMouseScroll";
-         Event.observe(table, eventName, 
-                       function(evt) {
-                          if (evt.wheelDelta>=0 || evt.detail < 0) //wheel-up
-                             this.scrollerDiv.scrollTop -= (2*this.viewPort.rowHeight);
-                          else
-                             this.scrollerDiv.scrollTop += (2*this.viewPort.rowHeight);
-                          this.handleScroll(false);
-                       }.bindAsEventListener(this), 
-                       false);
-     },
-
-   updateSize: function() {
-      var table = this.liveGrid.table;
-      var visibleHeight = this.viewPort.visibleHeight();
-      this.heightDiv.style.height = parseInt(visibleHeight *
-                                  this.metaData.getTotalRows()/this.metaData.getPageSize()) + "px";
-   },
-
-   rowToPixel: function(rowOffset) {
-      return (rowOffset / this.metaData.getTotalRows()) * this.heightDiv.offsetHeight
-   },
-   
-   moveScroll: function(rowOffset) {
-      this.scrollerDiv.scrollTop = this.rowToPixel(rowOffset);
-      if ( this.metaData.options.onscroll )
-         this.metaData.options.onscroll( this.liveGrid, rowOffset );
-   },
-
-   handleScroll: function() {
-     if ( this.scrollTimeout )
-         clearTimeout( this.scrollTimeout );
-
-    var scrollDiff = this.lastScrollPos-this.scrollerDiv.scrollTop;
-    if (scrollDiff != 0.00) {
-       var r = this.scrollerDiv.scrollTop % this.viewPort.rowHeight;
-       if (r != 0) {
-          this.unplug();
-          if ( scrollDiff < 0 ) {
-             this.scrollerDiv.scrollTop += (this.viewPort.rowHeight-r);
-          } else {
-             this.scrollerDiv.scrollTop -= r;
-          }
-          this.plugin();
-       }
-    }
-    var contentOffset = parseInt(this.scrollerDiv.scrollTop / this.viewPort.rowHeight);
-    this.liveGrid.requestContentRefresh(contentOffset);
-    this.viewPort.scrollTo(this.scrollerDiv.scrollTop);
-
-    if ( this.metaData.options.onscroll )
-       this.metaData.options.onscroll( this.liveGrid, contentOffset );
-
-    this.scrollTimeout = setTimeout(this.scrollIdle.bind(this), 1200 );
-    this.lastScrollPos = this.scrollerDiv.scrollTop;
-
-   },
-
-   scrollIdle: function() {
-      if ( this.metaData.options.onscrollidle )
-         this.metaData.options.onscrollidle();
-   }
-};
-
-// Rico.LiveGridBuffer -----------------------------------------------------
-
-Rico.LiveGridBuffer = Class.create();
-
-Rico.LiveGridBuffer.prototype = {
-
-   initialize: function(metaData, viewPort) {
-      this.startPos = 0;
-      this.size     = 0;
-      this.metaData = metaData;
-      this.rows     = new Array();
-      this.updateInProgress = false;
-      this.viewPort = viewPort;
-      this.maxBufferSize = metaData.getLargeBufferSize() * 2;
-      this.maxFetchSize = metaData.getLargeBufferSize();
-      this.lastOffset = 0;
-   },
-
-   getBlankRow: function() {
-      if (!this.blankRow ) {
-         this.blankRow = new Array();
-         for ( var i=0; i < this.metaData.columnCount ; i++ ) 
-            this.blankRow[i] = "&nbsp;";
-     }
-     return this.blankRow;
-   },
-
-   loadRows: function(ajaxResponse) {
-      var rowsElement = ajaxResponse.getElementsByTagName('rows')[0];
-      this.updateUI = rowsElement.getAttribute("update_ui") == "true"
-      var newRows = new Array()
-      var trs = rowsElement.getElementsByTagName("tr");
-      for ( var i=0 ; i < trs.length; i++ ) {
-         var row = newRows[i] = new Array(); 
-         var cells = trs[i].getElementsByTagName("td");
-         for ( var j=0; j < cells.length ; j++ ) {
-            var cell = cells[j];
-            var convertSpaces = cell.getAttribute("convert_spaces") == "true";
-            var cellContent = RicoUtil.getContentAsString(cell);
-            row[j] = convertSpaces ? this.convertSpaces(cellContent) : cellContent;
-            if (!row[j]) 
-               row[j] = '&nbsp;';
-         }
-      }
-      return newRows;
-   },
-      
-   update: function(ajaxResponse, start) {
-     var newRows = this.loadRows(ajaxResponse);
-      if (this.rows.length == 0) { // initial load
-         this.rows = newRows;
-         this.size = this.rows.length;
-         this.startPos = start;
-         return;
-      }
-      if (start > this.startPos) { //appending
-         if (this.startPos + this.rows.length < start) {
-            this.rows =  newRows;
-            this.startPos = start;//
-         } else {
-              this.rows = this.rows.concat( newRows.slice(0, newRows.length));
-            if (this.rows.length > this.maxBufferSize) {
-               var fullSize = this.rows.length;
-               this.rows = this.rows.slice(this.rows.length - this.maxBufferSize, this.rows.length)
-               this.startPos = this.startPos +  (fullSize - this.rows.length);
-            }
-         }
-      } else { //prepending
-         if (start + newRows.length < this.startPos) {
-            this.rows =  newRows;
-         } else {
-            this.rows = newRows.slice(0, this.startPos).concat(this.rows);
-            if (this.rows.length > this.maxBufferSize) 
-               this.rows = this.rows.slice(0, this.maxBufferSize)
-         }
-         this.startPos =  start;
-      }
-      this.size = this.rows.length;
-   },
-   
-   clear: function() {
-      this.rows = new Array();
-      this.startPos = 0;
-      this.size = 0;
-   },
-
-   isOverlapping: function(start, size) {
-      return ((start < this.endPos()) && (this.startPos < start + size)) || (this.endPos() == 0)
-   },
-
-   isInRange: function(position) {
-      return (position >= this.startPos) && (position + this.metaData.getPageSize() <= this.endPos()); 
-             //&& this.size()  != 0;
-   },
-
-   isNearingTopLimit: function(position) {
-      return position - this.startPos < this.metaData.getLimitTolerance();
-   },
-
-   endPos: function() {
-      return this.startPos + this.rows.length;
-   },
-   
-   isNearingBottomLimit: function(position) {
-      return this.endPos() - (position + this.metaData.getPageSize()) < this.metaData.getLimitTolerance();
-   },
-
-   isAtTop: function() {
-      return this.startPos == 0;
-   },
-
-   isAtBottom: function() {
-      return this.endPos() == this.metaData.getTotalRows();
-   },
-
-   isNearingLimit: function(position) {
-      return ( !this.isAtTop()    && this.isNearingTopLimit(position)) ||
-             ( !this.isAtBottom() && this.isNearingBottomLimit(position) )
-   },
-
-   getFetchSize: function(offset) {
-      var adjustedOffset = this.getFetchOffset(offset);
-      var adjustedSize = 0;
-      if (adjustedOffset >= this.startPos) { //apending
-         var endFetchOffset = this.maxFetchSize  + adjustedOffset;
-         if (endFetchOffset > this.metaData.totalRows)
-            endFetchOffset = this.metaData.totalRows;
-         adjustedSize = endFetchOffset - adjustedOffset;  
-                       if(adjustedOffset == 0 && adjustedSize < this.maxFetchSize){
-                          adjustedSize = this.maxFetchSize;
-                       }
-      } else {//prepending
-         var adjustedSize = this.startPos - adjustedOffset;
-         if (adjustedSize > this.maxFetchSize)
-            adjustedSize = this.maxFetchSize;
-      }
-      return adjustedSize;
-   }, 
-
-   getFetchOffset: function(offset) {
-      var adjustedOffset = offset;
-      if (offset > this.startPos)  //apending
-         adjustedOffset = (offset > this.endPos()) ? offset :  this.endPos(); 
-      else { //prepending
-         if (offset + this.maxFetchSize >= this.startPos) {
-            var adjustedOffset = this.startPos - this.maxFetchSize;
-            if (adjustedOffset < 0)
-               adjustedOffset = 0;
-         }
-      }
-      this.lastOffset = adjustedOffset;
-      return adjustedOffset;
-   },
-
-   getRows: function(start, count) {
-      var begPos = start - this.startPos
-      var endPos = begPos + count
-
-      // er? need more data...
-      if ( endPos > this.size )
-         endPos = this.size
-
-      var results = new Array()
-      var index = 0;
-      for ( var i=begPos ; i < endPos; i++ ) {
-         results[index++] = this.rows[i]
-      }
-      return results
-   },
-
-   convertSpaces: function(s) {
-      return s.split(" ").join("&nbsp;");
-   }
-
-};
-
-
-//Rico.GridViewPort --------------------------------------------------
-Rico.GridViewPort = Class.create();
-
-Rico.GridViewPort.prototype = {
-
-   initialize: function(table, rowHeight, visibleRows, buffer, liveGrid) {
-      this.lastDisplayedStartPos = 0;
-      this.div = table.parentNode;
-      this.table = table
-      this.rowHeight = rowHeight;
-      this.div.style.height = (this.rowHeight * visibleRows) + "px";
-      this.div.style.overflow = "hidden";
-      this.buffer = buffer;
-      this.liveGrid = liveGrid;
-      this.visibleRows = visibleRows + 1;
-      this.lastPixelOffset = 0;
-      this.startPos = 0;
-   },
-
-   populateRow: function(htmlRow, row) {
-      for (var j=0; j < row.length; j++) {
-         htmlRow.cells[j].innerHTML = row[j]
-      }
-   },
-   
-   bufferChanged: function() {
-      this.refreshContents( parseInt(this.lastPixelOffset / this.rowHeight));
-   },
-   
-   clearRows: function() {
-      if (!this.isBlank) {
-         this.liveGrid.table.className = this.liveGrid.options.loadingClass;
-         for (var i=0; i < this.visibleRows; i++)
-            this.populateRow(this.table.rows[i], this.buffer.getBlankRow());
-         this.isBlank = true;
-      }
-   },
-   
-   clearContents: function() {   
-      this.clearRows();
-      this.scrollTo(0);
-      this.startPos = 0;
-      this.lastStartPos = -1;   
-   },
-   
-   refreshContents: function(startPos) {
-      if (startPos == this.lastRowPos && !this.isPartialBlank && !this.isBlank) {
-         return;
-      }
-      if ((startPos + this.visibleRows < this.buffer.startPos)  
-          || (this.buffer.startPos + this.buffer.size < startPos) 
-          || (this.buffer.size == 0)) {
-         this.clearRows();
-         return;
-      }
-      this.isBlank = false;
-      var viewPrecedesBuffer = this.buffer.startPos > startPos
-      var contentStartPos = viewPrecedesBuffer ? this.buffer.startPos: startPos; 
-      var contentEndPos = (this.buffer.startPos + this.buffer.size < startPos + this.visibleRows) 
-                                 ? this.buffer.startPos + this.buffer.size
-                                 : startPos + this.visibleRows;
-      var rowSize = contentEndPos - contentStartPos;
-      var rows = this.buffer.getRows(contentStartPos, rowSize ); 
-      var blankSize = this.visibleRows - rowSize;
-      var blankOffset = viewPrecedesBuffer ? 0: rowSize;
-      var contentOffset = viewPrecedesBuffer ? blankSize: 0;
-
-      for (var i=0; i < rows.length; i++) {//initialize what we have
-        this.populateRow(this.table.rows[i + contentOffset], rows[i]);
-      }
-      for (var i=0; i < blankSize; i++) {// blank out the rest 
-        this.populateRow(this.table.rows[i + blankOffset], this.buffer.getBlankRow());
-      }
-      this.isPartialBlank = blankSize > 0;
-      this.lastRowPos = startPos;
-
-       this.liveGrid.table.className = this.liveGrid.options.tableClass;
-       // Check if user has set a onRefreshComplete function
-       var onRefreshComplete = this.liveGrid.options.onRefreshComplete;
-       if (onRefreshComplete != null)
-           onRefreshComplete();
-   },
-
-   scrollTo: function(pixelOffset) {      
-      if (this.lastPixelOffset == pixelOffset)
-         return;
-
-      this.refreshContents(parseInt(pixelOffset / this.rowHeight))
-      this.div.scrollTop = pixelOffset % this.rowHeight        
-      
-      this.lastPixelOffset = pixelOffset;
-   },
-   
-   visibleHeight: function() {
-      return parseInt(RicoUtil.getElementsComputedStyle(this.div, 'height'));
-   }
-
-};
-
-
-Rico.LiveGridRequest = Class.create();
-Rico.LiveGridRequest.prototype = {
-   initialize: function( requestOffset, options ) {
-      this.requestOffset = requestOffset;
-   }
-};
-
-// Rico.LiveGrid -----------------------------------------------------
-
-Rico.LiveGrid = Class.create();
-
-Rico.LiveGrid.prototype = {
-
-   initialize: function( tableId, visibleRows, totalRows, url, options, ajaxOptions ) {
-
-     this.options = {
-                tableClass:           $(tableId).className,
-                loadingClass:         $(tableId).className,
-                scrollerBorderRight: '1px solid #ababab',
-                bufferTimeout:        20000,
-                sortAscendImg:        'images/sort_asc.gif',
-                sortDescendImg:       'images/sort_desc.gif',
-                sortImageWidth:       9,
-                sortImageHeight:      5,
-                ajaxSortURLParms:     [],
-                onRefreshComplete:    null,
-                requestParameters:    null,
-                inlineStyles:         true
-                };
-      Object.extend(this.options, options || {});
-
-      this.ajaxOptions = {parameters: null};
-      Object.extend(this.ajaxOptions, ajaxOptions || {});
-
-      this.tableId     = tableId; 
-      this.table       = $(tableId);
-
-      this.addLiveGridHtml();
-
-      var columnCount  = this.table.rows[0].cells.length;
-      this.metaData    = new Rico.LiveGridMetaData(visibleRows, totalRows, columnCount, options);
-      this.buffer      = new Rico.LiveGridBuffer(this.metaData);
-
-      var rowCount = this.table.rows.length;
-      this.viewPort =  new Rico.GridViewPort(this.table, 
-                                            this.table.offsetHeight/rowCount,
-                                            visibleRows,
-                                            this.buffer, this);
-      this.scroller    = new Rico.LiveGridScroller(this,this.viewPort);
-      this.options.sortHandler = this.sortHandler.bind(this);
-
-      if ( $(tableId + '_header') )
-         this.sort = new Rico.LiveGridSort(tableId + '_header', this.options)
-
-      this.processingRequest = null;
-      this.unprocessedRequest = null;
-
-      this.initAjax(url);
-      if ( this.options.prefetchBuffer || this.options.prefetchOffset > 0) {
-         var offset = 0;
-         if (this.options.offset ) {
-            offset = this.options.offset;            
-            this.scroller.moveScroll(offset);
-            this.viewPort.scrollTo(this.scroller.rowToPixel(offset));            
-         }
-         if (this.options.sortCol) {
-             this.sortCol = options.sortCol;
-             this.sortDir = options.sortDir;
-         }
-         this.requestContentRefresh(offset);
-      }
-   },
-
-   addLiveGridHtml: function() {
-     // Check to see if need to create a header table.
-     if (this.table.getElementsByTagName("thead").length > 0){
-       // Create Table this.tableId+'_header'
-       var tableHeader = this.table.cloneNode(true);
-       tableHeader.setAttribute('id', this.tableId+'_header');
-       tableHeader.setAttribute('class', this.table.className+'_header');
-
-       // Clean up and insert
-       for( var i = 0; i < tableHeader.tBodies.length; i++ ) 
-       tableHeader.removeChild(tableHeader.tBodies[i]);
-       this.table.deleteTHead();
-       this.table.parentNode.insertBefore(tableHeader,this.table);
-     }
-
-    new Insertion.Before(this.table, "<div id='"+this.tableId+"_container'></div>");
-    this.table.previousSibling.appendChild(this.table);
-    new Insertion.Before(this.table,"<div id='"+this.tableId+"_viewport' style='float:left;'></div>");
-    this.table.previousSibling.appendChild(this.table);
-   },
-
-
-   resetContents: function() {
-      this.scroller.moveScroll(0);
-      this.buffer.clear();
-      this.viewPort.clearContents();
-   },
-   
-   sortHandler: function(column) {
-          if(!column) return ;
-      this.sortCol = column.name;
-      this.sortDir = column.currentSort;
-
-      this.resetContents();
-      this.requestContentRefresh(0) 
-   },
-
-   adjustRowSize: function() {
-         
-       },
-       
-   setTotalRows: function( newTotalRows ) {
-      this.resetContents();
-      this.metaData.setTotalRows(newTotalRows);
-      this.scroller.updateSize();
-   },
-
-   initAjax: function(url) {
-      ajaxEngine.registerRequest( this.tableId + '_request', url );
-      ajaxEngine.registerAjaxObject( this.tableId + '_updater', this );
-   },
-
-   invokeAjax: function() {
-   },
-
-   handleTimedOut: function() {
-      //server did not respond in 4 seconds... assume that there could have been
-      //an error or something, and allow requests to be processed again...
-      this.processingRequest = null;
-      this.processQueuedRequest();
-   },
-
-   fetchBuffer: function(offset) {
-      if ( this.buffer.isInRange(offset) &&
-         !this.buffer.isNearingLimit(offset)) {
-         return;
-         }
-      if (this.processingRequest) {
-          this.unprocessedRequest = new Rico.LiveGridRequest(offset);
-         return;
-      }
-      var bufferStartPos = this.buffer.getFetchOffset(offset);
-      this.processingRequest = new Rico.LiveGridRequest(offset);
-      this.processingRequest.bufferOffset = bufferStartPos;   
-      var fetchSize = this.buffer.getFetchSize(offset);
-      var partialLoaded = false;
-      
-      var queryString
-      if (this.options.requestParameters)
-         queryString = this._createQueryString(this.options.requestParameters, 0);
-
-        queryString = (queryString == null) ? '' : queryString+'&';
-        queryString  = queryString+'id='+this.tableId+'&page_size='+fetchSize+'&offset='+bufferStartPos;
-        if (this.sortCol)
-            queryString = queryString+'&sort_col='+escape(this.sortCol)+'&sort_dir='+this.sortDir;
-
-        this.ajaxOptions.parameters = queryString;
-
-       ajaxEngine.sendRequest( this.tableId + '_request', this.ajaxOptions );
-
-       this.timeoutHandler = setTimeout( this.handleTimedOut.bind(this), this.options.bufferTimeout);
-
-   },
-
-   setRequestParams: function() {
-      this.options.requestParameters = [];
-      for ( var i=0 ; i < arguments.length ; i++ )
-         this.options.requestParameters[i] = arguments[i];
-   },
-
-   requestContentRefresh: function(contentOffset) {
-      this.fetchBuffer(contentOffset);
-   },
-
-   ajaxUpdate: function(ajaxResponse) {
-      try {
-         clearTimeout( this.timeoutHandler );
-         this.buffer.update(ajaxResponse,this.processingRequest.bufferOffset);
-         this.viewPort.bufferChanged();
-      }
-      catch(err) {}
-      finally {this.processingRequest = null; }
-      this.processQueuedRequest();
-   },
-
-   _createQueryString: function( theArgs, offset ) {
-      var queryString = ""
-      if (!theArgs)
-          return queryString;
-
-      for ( var i = offset ; i < theArgs.length ; i++ ) {
-          if ( i != offset )
-            queryString += "&";
-
-          var anArg = theArgs[i];
-
-          if ( anArg.name != undefined && anArg.value != undefined ) {
-            queryString += anArg.name +  "=" + escape(anArg.value);
-          }
-          else {
-             var ePos  = anArg.indexOf('=');
-             var argName  = anArg.substring( 0, ePos );
-             var argValue = anArg.substring( ePos + 1 );
-             queryString += argName + "=" + escape(argValue);
-          }
-      }
-      return queryString;
-   },
-
-   processQueuedRequest: function() {
-      if (this.unprocessedRequest != null) {
-         this.requestContentRefresh(this.unprocessedRequest.requestOffset);
-         this.unprocessedRequest = null
-      }
-   }
-};
-
-
-//-------------------- ricoLiveGridSort.js
-Rico.LiveGridSort = Class.create();
-
-Rico.LiveGridSort.prototype = {
-
-   initialize: function(headerTableId, options) {
-      this.headerTableId = headerTableId;
-      this.headerTable   = $(headerTableId);
-      this.options = options;
-      this.setOptions();
-      this.applySortBehavior();
-
-      if ( this.options.sortCol ) {
-         this.setSortUI( this.options.sortCol, this.options.sortDir );
-      }
-   },
-
-   setSortUI: function( columnName, sortDirection ) {
-      var cols = this.options.columns;
-      for ( var i = 0 ; i < cols.length ; i++ ) {
-         if ( cols[i].name == columnName ) {
-            this.setColumnSort(i, sortDirection);
-            break;
-         }
-      }
-   },
-
-   setOptions: function() {
-      // preload the images...
-      new Image().src = this.options.sortAscendImg;
-      new Image().src = this.options.sortDescendImg;
-
-      this.sort = this.options.sortHandler;
-      if ( !this.options.columns )
-         this.options.columns = this.introspectForColumnInfo();
-      else {
-         // allow client to pass { columns: [ ["a", true], ["b", false] ] }
-         // and convert to an array of Rico.TableColumn objs...
-         this.options.columns = this.convertToTableColumns(this.options.columns);
-      }
-   },
-
-   applySortBehavior: function() {
-      var headerRow   = this.headerTable.rows[0];
-      var headerCells = headerRow.cells;
-      for ( var i = 0 ; i < headerCells.length ; i++ ) {
-         this.addSortBehaviorToColumn( i, headerCells[i] );
-      }
-   },
-
-   addSortBehaviorToColumn: function( n, cell ) {
-      if ( this.options.columns[n].isSortable() ) {
-         cell.id            = this.headerTableId + '_' + n;
-         cell.style.cursor  = 'pointer';
-         cell.onclick       = this.headerCellClicked.bindAsEventListener(this);
-         cell.innerHTML     = cell.innerHTML + '<span id="' + this.headerTableId + '_img_' + n + '">'
-                           + '&nbsp;&nbsp;&nbsp;</span>';
-      }
-   },
-
-   // event handler....
-   headerCellClicked: function(evt) {
-      var eventTarget = evt.target ? evt.target : evt.srcElement;
-      var cellId = eventTarget.id;
-      var columnNumber = parseInt(cellId.substring( cellId.lastIndexOf('_') + 1 ));
-      var sortedColumnIndex = this.getSortedColumnIndex();
-      if ( sortedColumnIndex != -1 ) {
-         if ( sortedColumnIndex != columnNumber ) {
-            this.removeColumnSort(sortedColumnIndex);
-            this.setColumnSort(columnNumber, Rico.TableColumn.SORT_ASC);
-         }
-         else
-            this.toggleColumnSort(sortedColumnIndex);
-      }
-      else
-         this.setColumnSort(columnNumber, Rico.TableColumn.SORT_ASC);
-
-      if (this.options.sortHandler) {
-         this.options.sortHandler(this.options.columns[columnNumber]);
-      }
-   },
-
-   removeColumnSort: function(n) {
-      this.options.columns[n].setUnsorted();
-      this.setSortImage(n);
-   },
-
-   setColumnSort: function(n, direction) {
-       if(isNaN(n)) return ;
-      this.options.columns[n].setSorted(direction);
-      this.setSortImage(n);
-   },
-
-   toggleColumnSort: function(n) {
-      this.options.columns[n].toggleSort();
-      this.setSortImage(n);
-   },
-
-   setSortImage: function(n) {
-      var sortDirection = this.options.columns[n].getSortDirection();
-
-      var sortImageSpan = $( this.headerTableId + '_img_' + n );
-      if ( sortDirection == Rico.TableColumn.UNSORTED )
-         sortImageSpan.innerHTML = '&nbsp;&nbsp;';
-      else if ( sortDirection == Rico.TableColumn.SORT_ASC )
-         sortImageSpan.innerHTML = '&nbsp;&nbsp;<img width="'  + this.options.sortImageWidth    + '" ' +
-                                                     'height="'+ this.options.sortImageHeight   + '" ' +
-                                                     'src="'   + this.options.sortAscendImg + '"/>';
-      else if ( sortDirection == Rico.TableColumn.SORT_DESC )
-         sortImageSpan.innerHTML = '&nbsp;&nbsp;<img width="'  + this.options.sortImageWidth    + '" ' +
-                                                     'height="'+ this.options.sortImageHeight   + '" ' +
-                                                     'src="'   + this.options.sortDescendImg + '"/>';
-   },
-
-   getSortedColumnIndex: function() {
-      var cols = this.options.columns;
-      for ( var i = 0 ; i < cols.length ; i++ ) {
-         if ( cols[i].isSorted() )
-            return i;
-      }
-
-      return -1;
-   },
-
-   introspectForColumnInfo: function() {
-      var columns = new Array();
-      var headerRow   = this.headerTable.rows[0];
-      var headerCells = headerRow.cells;
-      for ( var i = 0 ; i < headerCells.length ; i++ )
-         columns.push( new Rico.TableColumn( this.deriveColumnNameFromCell(headerCells[i],i), true ) );
-      return columns;
-   },
-
-   convertToTableColumns: function(cols) {
-      var columns = new Array();
-      for ( var i = 0 ; i < cols.length ; i++ )
-         columns.push( new Rico.TableColumn( cols[i][0], cols[i][1] ) );
-      return columns;
-   },
-
-   deriveColumnNameFromCell: function(cell,columnNumber) {
-      var cellContent = cell.innerText != undefined ? cell.innerText : cell.textContent;
-      return cellContent ? cellContent.toLowerCase().split(' ').join('_') : "col_" + columnNumber;
-   }
-};
-
-Rico.TableColumn = Class.create();
-
-Rico.TableColumn.UNSORTED  = 0;
-Rico.TableColumn.SORT_ASC  = "ASC";
-Rico.TableColumn.SORT_DESC = "DESC";
-
-Rico.TableColumn.prototype = {
-   initialize: function(name, sortable) {
-      this.name        = name;
-      this.sortable    = sortable;
-      this.currentSort = Rico.TableColumn.UNSORTED;
-   },
-
-   isSortable: function() {
-      return this.sortable;
-   },
-
-   isSorted: function() {
-      return this.currentSort != Rico.TableColumn.UNSORTED;
-   },
-
-   getSortDirection: function() {
-      return this.currentSort;
-   },
-
-   toggleSort: function() {
-      if ( this.currentSort == Rico.TableColumn.UNSORTED || this.currentSort == Rico.TableColumn.SORT_DESC )
-         this.currentSort = Rico.TableColumn.SORT_ASC;
-      else if ( this.currentSort == Rico.TableColumn.SORT_ASC )
-         this.currentSort = Rico.TableColumn.SORT_DESC;
-   },
-
-   setUnsorted: function(direction) {
-      this.setSorted(Rico.TableColumn.UNSORTED);
-   },
-
-   setSorted: function(direction) {
-      // direction must by one of Rico.TableColumn.UNSORTED, .SORT_ASC, or .SORT_DESC...
-      this.currentSort = direction;
-   }
-
-};
-
-
-//-------------------- ricoUtil.js
-var RicoUtil = {
-
-   getElementsComputedStyle: function ( htmlElement, cssProperty, mozillaEquivalentCSS) {
-      if ( arguments.length == 2 )
-         mozillaEquivalentCSS = cssProperty;
-
-      var el = $(htmlElement);
-      if ( el.currentStyle )
-         return el.currentStyle[cssProperty];
-      else
-         return document.defaultView.getComputedStyle(el, null).getPropertyValue(mozillaEquivalentCSS);
-   },
-
-   createXmlDocument : function() {
-      if (document.implementation && document.implementation.createDocument) {
-         var doc = document.implementation.createDocument("", "", null);
-
-         if (doc.readyState == null) {
-            doc.readyState = 1;
-            doc.addEventListener("load", function () {
-               doc.readyState = 4;
-               if (typeof doc.onreadystatechange == "function")
-                  doc.onreadystatechange();
-            }, false);
-         }
-
-         return doc;
-      }
-
-      if (window.ActiveXObject)
-          return Try.these(
-            function() { return new ActiveXObject('MSXML2.DomDocument')   },
-            function() { return new ActiveXObject('Microsoft.DomDocument')},
-            function() { return new ActiveXObject('MSXML.DomDocument')    },
-            function() { return new ActiveXObject('MSXML3.DomDocument')   }
-          ) || false;
-
-      return null;
-   },
-
-   getContentAsString: function( parentNode ) {
-      return parentNode.xml != undefined ? 
-         this._getContentAsStringIE(parentNode) :
-         this._getContentAsStringMozilla(parentNode);
-   },
-
-  _getContentAsStringIE: function(parentNode) {
-     var contentStr = "";
-     for ( var i = 0 ; i < parentNode.childNodes.length ; i++ ) {
-         var n = parentNode.childNodes[i];
-         if (n.nodeType == 4) {
-             contentStr += n.nodeValue;
-         }
-         else {
-           contentStr += n.xml;
-       }
-     }
-     return contentStr;
-  },
-
-  _getContentAsStringMozilla: function(parentNode) {
-     var xmlSerializer = new XMLSerializer();
-     var contentStr = "";
-     for ( var i = 0 ; i < parentNode.childNodes.length ; i++ ) {
-          var n = parentNode.childNodes[i];
-          if (n.nodeType == 4) { // CDATA node
-              contentStr += n.nodeValue;
-          }
-          else {
-            contentStr += xmlSerializer.serializeToString(n);
-        }
-     }
-     return contentStr;
-  },
-
-   toViewportPosition: function(element) {
-      return this._toAbsolute(element,true);
-   },
-
-   toDocumentPosition: function(element) {
-      return this._toAbsolute(element,false);
-   },
-
-   /**
-    *  Compute the elements position in terms of the window viewport
-    *  so that it can be compared to the position of the mouse (dnd)
-    *  This is additions of all the offsetTop,offsetLeft values up the
-    *  offsetParent hierarchy, ...taking into account any scrollTop,
-    *  scrollLeft values along the way...
-    *
-    * IE has a bug reporting a correct offsetLeft of elements within a
-    * a relatively positioned parent!!!
-    **/
-   _toAbsolute: function(element,accountForDocScroll) {
-
-      if ( navigator.userAgent.toLowerCase().indexOf("msie") == -1 )
-         return this._toAbsoluteMozilla(element,accountForDocScroll);
-
-      var x = 0;
-      var y = 0;
-      var parent = element;
-      while ( parent ) {
-
-         var borderXOffset = 0;
-         var borderYOffset = 0;
-         if ( parent != element ) {
-            var borderXOffset = parseInt(this.getElementsComputedStyle(parent, "borderLeftWidth" ));
-            var borderYOffset = parseInt(this.getElementsComputedStyle(parent, "borderTopWidth" ));
-            borderXOffset = isNaN(borderXOffset) ? 0 : borderXOffset;
-            borderYOffset = isNaN(borderYOffset) ? 0 : borderYOffset;
-         }
-
-         x += parent.offsetLeft - parent.scrollLeft + borderXOffset;
-         y += parent.offsetTop - parent.scrollTop + borderYOffset;
-         parent = parent.offsetParent;
-      }
-
-      if ( accountForDocScroll ) {
-         x -= this.docScrollLeft();
-         y -= this.docScrollTop();
-      }
-
-      return { x:x, y:y };
-   },
-
-   /**
-    *  Mozilla did not report all of the parents up the hierarchy via the
-    *  offsetParent property that IE did.  So for the calculation of the
-    *  offsets we use the offsetParent property, but for the calculation of
-    *  the scrollTop/scrollLeft adjustments we navigate up via the parentNode
-    *  property instead so as to get the scroll offsets...
-    *
-    **/
-   _toAbsoluteMozilla: function(element,accountForDocScroll) {
-      var x = 0;
-      var y = 0;
-      var parent = element;
-      while ( parent ) {
-         x += parent.offsetLeft;
-         y += parent.offsetTop;
-         parent = parent.offsetParent;
-      }
-
-      parent = element;
-      while ( parent &&
-              parent != document.body &&
-              parent != document.documentElement ) {
-         if ( parent.scrollLeft  )
-            x -= parent.scrollLeft;
-         if ( parent.scrollTop )
-            y -= parent.scrollTop;
-         parent = parent.parentNode;
-      }
-
-      if ( accountForDocScroll ) {
-         x -= this.docScrollLeft();
-         y -= this.docScrollTop();
-      }
-
-      return { x:x, y:y };
-   },
-
-   docScrollLeft: function() {
-      if ( window.pageXOffset )
-         return window.pageXOffset;
-      else if ( document.documentElement && document.documentElement.scrollLeft )
-         return document.documentElement.scrollLeft;
-      else if ( document.body )
-         return document.body.scrollLeft;
-      else
-         return 0;
-   },
-
-   docScrollTop: function() {
-      if ( window.pageYOffset )
-         return window.pageYOffset;
-      else if ( document.documentElement && document.documentElement.scrollTop )
-         return document.documentElement.scrollTop;
-      else if ( document.body )
-         return document.body.scrollTop;
-      else
-         return 0;
-   }
-
-};
diff --git a/webinterface/src/web-data/lib/shadedborder.js b/webinterface/src/web-data/lib/shadedborder.js
new file mode 100644 (file)
index 0000000..abe9a5c
--- /dev/null
@@ -0,0 +1,267 @@
+/**
+ * RUZEE.ShadedBorder 0.6.1
+ * (c) 2006 Steffen Rusitschka
+ *
+ * RUZEE.ShadedBorder is freely distributable under the terms of an MIT-style license.
+ * For details, see http://www.ruzee.com/
+ */
+
+var RUZEE = window.RUZEE || {};
+
+RUZEE.ShadedBorder = {
+
+create: function(opts) {
+  var isie = /msie/i.test(navigator.userAgent) && !window.opera;
+  var isie6 = isie && !window.XMLHttpRequest;
+  function sty(el, h) {
+    for(k in h) {
+      if (/ie_/.test(k)) {
+        if (isie) el.style[k.substr(3)]=h[k];
+      } else el.style[k]=h[k];
+    }
+  }
+  function crdiv(h) {
+    var el=document.createElement("div");
+    el.className = "sb-gen";
+    sty(el, h);
+    return el;
+  }
+  function op(v) {
+    v = v<0 ? 0 : v;
+    if (v>0.99999) return "";
+    return isie ? " filter:alpha(opacity=" + (v*100) + ");" : " opacity:" + v + ';';
+  }
+
+  var sr = opts.shadow || 0;
+  var r = opts.corner || 0;
+  var bor = 0;
+  var bow = opts.border || 0;
+  var boo = opts.borderOpacity || 1;
+  var shadow = sr != 0;
+  var lw = r > sr ? r : sr;
+  var rw = lw;
+  var th = lw;
+  var bh = lw;
+  if (bow > 0) {
+    bor = r;
+    r = r - bow;
+  }
+  var cx = r != 0 && shadow ? Math.round(lw/3) : 0;
+  var cy = cx;
+  var cs = Math.round(cx/2);
+  var iclass = r > 0 ? "sb-inner" : "sb-shadow";
+  var sclass = "sb-shadow";
+  var bclass = "sb-border";
+  var edges = opts.edges || "trlb";
+  if (!/t/i.test(edges)) th=0;
+  if (!/b/i.test(edges)) bh=0;
+  if (!/l/i.test(edges)) lw=0;
+  if (!/r/i.test(edges)) rw=0;
+
+  var p = { position:"absolute", left:"0", top:"0", width:lw + "px", height:th + "px", 
+            ie_fontSize:"1px", overflow:"hidden", margin:"0", padding:"0" }; var tl = crdiv(p);
+  delete p.left; p.right="0"; p.width=rw + "px"; var tr = crdiv(p);
+  delete p.top; p.bottom="0"; p.height=bh + "px"; var br = crdiv(p);
+  delete p.right; p.left="0"; p.width=lw + "px"; var bl = crdiv(p);
+
+  var tw = crdiv({ position:"absolute", width:"100%", height:th + "px", ie_fontSize:"1px",
+                   top:"0", left:"0", overflow:"hidden", margin:"0", padding:"0" });
+  var t = crdiv({ position:"relative", height:th + "px", ie_fontSize:"1px",
+                  margin:"0 "+ rw + "px 0 " + lw + "px", overflow:"hidden", padding:"0" });
+  tw.appendChild(t);
+
+  var bw = crdiv({ position:"absolute", left:"0", bottom:"0", width:"100%", height:bh + "px", 
+                   ie_fontSize:"1px", overflow:"hidden", margin:"0", padding:"0" });
+                   
+  var b = crdiv({ position:"relative", height:bh + "px", ie_fontSize:"1px",
+                  margin:"0 "+ rw + "px 0 " + lw + "px", overflow:"hidden", padding:"0" });
+                  
+  bw.appendChild(b);
+
+  var mw = crdiv({ position:"absolute", top:(-bh)+"px", left:"0", width:"100%", height:"100%",
+                   overflow:"hidden", ie_fontSize:"1px", padding:"0", margin:"0" });
+
+  function corner(el,t,l) {
+    var w = l ? lw : rw;
+    var h = t ? th : bh;
+    var s = t ? cs : -cs;
+    var dsb = []; var dsi = []; var dss = [];
+    
+    var xp=0; var xd=1; if (l) { xp=w-1; xd=-1; }
+    for (var x=0; x<w; ++x) {
+      var yp=h-1; var yd=-1; if (t) { yp=0; yd=1; }
+      var finished=false;
+      for (var y=h-1; y>=0 && !finished; --y) {
+        var div = '<div style="position:absolute; top:' + yp + 'px; left:' + xp + 'px; ' +
+                  'width:1px; height:1px; overflow:hidden; margin:0; padding:0;';
+
+        var xc = x - cx; var yc = y - cy - s;
+        var d = Math.sqrt(xc*xc+yc*yc);
+        var doShadow = false;
+
+        if (r > 0) {
+          // draw border
+          if (xc < 0 && yc < bor && yc >= r || yc < 0 && xc < bor && xc >= r) {
+            dsb.push(div + op(boo) + '" class="' + bclass + '"></div>');
+          } else
+          if (d<bor && d>=r-1 && xc>=0 && yc>=0) {
+            var dd = div;
+            if (d>=bor-1) {
+              dd += op((bor-d)*boo);
+              doShadow = true;
+            } else dd += op(boo);
+            dsb.push(dd + '" class="' + bclass + '"></div>');
+          }
+          
+          // draw inner
+          var dd = div + ' z-index:2;' + (t ? 'background-position:0 -' + (r-yc-1) + 'px;' : 'background-image:none;');
+          var finish = function() {
+            if (!t) dd = dd.replace(/top\:\d+px/, "top:0px");
+            dd = dd.replace(/height\:1px/, "height:" + (y+1) + "px");
+            dsi.push(dd + '" class="' + iclass + '"></div>');
+            finished = true;
+          };
+          if (xc < 0 && yc < r || yc < 0 && xc < r) {
+            finish();
+          } else
+          if (d<r && xc>=0 && yc>=0) {
+            if (d>=r-1) {
+              dd += op(r-d);
+              doShadow = true;
+              dsi.push(dd + '" class="' + iclass + '"></div>');
+            } else {
+              finish();
+            }
+          } else doShadow = true;
+        } else doShadow = true;
+        
+        // draw shadow
+        if (sr > 0 && doShadow) {
+          d = Math.sqrt(x*x+y*y);
+          if (d<sr) {
+            dss.push(div + ' z-index:0; ' + op(1-(d/sr)) + '" class="' + sclass + '"></div>');
+          }
+        }
+        yp += yd;
+      }
+      xp += xd;
+    }
+    el.innerHTML = dss.concat(dsb.concat(dsi)).join('');
+  }
+  
+  function mid(mw) {
+    var ds = [];
+
+    ds.push('<div style="position:relative; top:' + (th+bh) + 'px; height:2048px; ' +
+            ' margin:0 ' + (rw-r-cx) + 'px 0 ' + (lw-r-cx) + 'px; ' +
+            ' padding:0; overflow:hidden;' +
+            ' background-position:0 ' + (th > 0 ? -(r+cy+cs) : '0') + 'px;"' +
+            ' class="' + iclass + '"></div>');
+
+    var dd = '<div style="position:absolute; width:1px;' +
+        ' top:' + (th+bh) + 'px; height:2048px; padding:0; margin:0;';
+    if (sr>0) {
+      for (var x=0; x<lw-r-cx; ++x) {
+        ds.push(dd + ' left:' + x + 'px;' + op((x+1.0)/lw) + 
+            '" class="' + sclass + '"></div>');
+      }
+
+      for (var x=0; x<rw-r-cx; ++x) {
+        ds.push(dd + ' right:' + x + 'px;' + op((x+1.0)/rw) + 
+            '" class="' + sclass + '"></div>');
+      }
+    }
+
+    if (bow > 0) {
+      var su = ' width:' + bow + 'px;' + op(boo) + '" class="' + bclass + '"></div>';
+      ds.push(dd + ' left:' + (lw-bor-cx) + 'px;' + su);
+      ds.push(dd + ' right:' + (rw-bor-cx) + 'px;' + su);
+    }
+
+    mw.innerHTML = ds.join('');
+  }
+
+  function tb(el, t) {
+    var ds = [];
+    var h = t ? th : bh;
+    var dd = '<div style="height:1px; overflow:hidden; position:absolute; margin:0; padding:0;' +
+        ' width:100%; left:0px; ';
+    var s = t ? cs : -cs;
+    for (var y=0; y<h-s-cy-r; ++y) {
+      if (sr>0) ds.push(dd + (t ? 'top:' : 'bottom:') + y + 'px;' + op((y+1)*1.0/h) + 
+          '" class="' + sclass + '"></div>');
+    }
+    if (y >= bow) {
+      ds.push(dd + (t ? 'top:' : 'bottom:') + (y - bow) + 'px;' + op(boo) +
+          ' height:' + bow + 'px;" class="' + bclass + '"></div>');
+    }
+
+    ds.push(dd + (t ? 'background-position-y:0; top:' : 
+                      'background-image:none; bottom:') + y + 'px;' +
+        ' height:' + (r+cy+s) + 'px;" class="' + iclass + '"></div>');
+
+    el.innerHTML = ds.join('');
+  }
+
+  corner(tl, true, true); corner(tr, true, false);
+  corner(bl, false, true); corner(br, false, false);
+  mid(mw); tb(t, true); tb(b, false);
+
+  return {
+    render: function(el) {
+      if (typeof el == 'string') el = document.getElementById(el);
+      if (el.length != undefined) {
+        for (var i=0; i<el.length; ++i) this.render(el[i]);
+        return;
+      }
+      el.className += " sb";
+      sty(el, { position:"relative", background:"transparent" });
+
+      // remove generated children
+      var node = el.firstChild;
+      while (node) {
+        var nextNode = node.nextSibling;
+        if (node.nodeType == 1 && node.className == 'sb-gen')
+          el.removeChild(node);
+        node = nextNode;
+      }
+
+      var iel = el.firstChild;
+
+      var twc = tw.cloneNode(true);
+      var mwc = mw.cloneNode(true);
+      var bwc = bw.cloneNode(true);
+      
+      el.insertBefore(tl.cloneNode(true), iel); el.insertBefore(tr.cloneNode(true), iel);
+      el.insertBefore(bl.cloneNode(true), iel); el.insertBefore(br.cloneNode(true), iel);
+      el.insertBefore(twc, iel); el.insertBefore(mwc, iel);
+      el.insertBefore(bwc, iel);
+
+      if (isie6) {
+        el.onmouseover=function() { this.className+=" hover"; }
+        el.onmouseout=function() { this.className=this.className.replace(/ hover/,""); }
+      }
+      if (isie) {
+        function resize() {
+          twc.style.width = bwc.style.width = mwc.style.width = el.offsetWidth + "px";
+          mwc.firstChild.style.height = el.offsetHeight + "px";
+        }
+        el.onresize=resize;
+        resize();
+      }
+    }
+  };
+}
+}
+
+// add our styles to the document
+document.write('\
+  <style type="text/css">\
+  .sb, .sbi, .sb *, .sbi * { position:relative; z-index:1; }\
+  * html .sb, * html .sbi { height:1%; }\
+  .sbi { display:inline-block; }\
+  .sb-inner { background:#ddd; }\
+  .sb-shadow { background:#000; }\
+  .sb-border { background:#bbb; }\
+  </style>\
+');
diff --git a/webinterface/src/web-data/lib/trimpath-template-1.0.38.js b/webinterface/src/web-data/lib/trimpath-template-1.0.38.js
new file mode 100644 (file)
index 0000000..976151d
--- /dev/null
@@ -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 4767bd4..23ff91f 100644 (file)
@@ -7,34 +7,34 @@ function EPGList(xml){
        //debug('init EPGList'+xml);
        try{
                this.xmlitems = xml.getElementsByTagName("e2eventlist").item(0).getElementsByTagName("e2event");
-       } catch (e) { debug("EPGList parsing Error");}
+       } catch (e) { debug("[EPGList] parsing Error");}
        
        this.getArray = function(sortbytime){
-               debug("sort EPGList by time "+sortbytime);
-               if (sortbytime == true){
-                       var sort1 = new Array();
+               debug("[EPGList] Sort by time "+sortbytime);
+               if (sortbytime === true){
+                       var sort1 = [];
                        for(var i=0;i<this.xmlitems.length;i++){
                                var xv = new EPGEvent(this.xmlitems.item(i));
-                               sort1.push(new Array(xv.startTime,xv));
+                               sort1.push( [xv.startTime, xv] );
                        }
                        sort1.sort(this.sortFunction);
-                       var sort2 = new Array();
-                       for(var i=0;i<sort1.length;i++){
+                       var sort2 = [];
+                       for(i=0;i<sort1.length;i++){
                                sort2.push(sort1[i][1]);
                        }
                        return sort2;
                }else{
-                       var listxy = new Array();
-                       for (var i=0;i<this.xmlitems.length;i++){
-                               var xv = new EPGEvent(this.xmlitems.item(i));
+                       var listxy = [];
+                       for (i=0;i<this.xmlitems.length;i++){
+                               xv = new EPGEvent(this.xmlitems.item(i));
                                listxy.push(xv);                        
                        }
                        return listxy;
                }
-       }
+       };
        this.sortFunction = function(a,b){
          return a[0] - b[0];
-       }
+       };
 }
 //END class EPGList
 
@@ -50,7 +50,6 @@ function EPGEvent(xml){
                this.serviceName = xml.getElementsByTagName('e2eventservicename').item(0).firstChild.data;
                this.fileName = xml.getElementsByTagName('e2filename').item(0).firstChild.data;
        } catch (e) {
-               //debug("EPGEvent parsing Error");
        }       
        try{
                this.description = xml.getElementsByTagName('e2eventdescription').item(0).firstChild.data;
@@ -60,80 +59,67 @@ function EPGEvent(xml){
                this.descriptionE = xml.getElementsByTagName('e2eventdescriptionextended').item(0).firstChild.data;
        } catch (e) {   this.descriptionE = 'N/A';      }
 
-       this.getFilename = function ()
-       {
+       this.getFilename = function (){
                return this.fileName;
-       }
-       this.getEventId = function ()
-       {
+       };
+       this.getEventId = function (){
                return this.eventID;
-       }
-       this.getTimeStart = function ()
-       {
-               var date = new Date(parseInt(this.startTime)*1000);
+       };
+       this.getTimeStart = function (){
+               var date = new Date(parseInt(this.startTime, 10)*1000);
                return date;
-       }
-       this.getTimeStartString = function ()
-       {
+       };
+       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 = new Array("So", "Mo", "Di", "Mi", "Do", "Fr", "Sa");
+       };
+       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.getTimeBegin = function(){
-               return this.getTimeStart().getTime()/1000
-       }
-       this.getTimeEnd = function ()
-       {
-               var date = new Date((parseInt(this.startTime)+parseInt(this.duration))*1000);
-               return date.getTime()/1000
-       }
-       this.getTimeEndString = function ()
-       {
-               var date = new Date((parseInt(this.startTime)+parseInt(this.duration))*1000);
+               return this.getTimeStart().getTime()/1000;
+       };
+       this.getTimeEnd = function (){
+               var date = new Date((parseInt(this.startTime, 10)+parseInt(this.duration, 10))*1000);
+               return date.getTime()/1000;
+       };
+       this.getTimeEndString = function (){
+               var date = new Date((parseInt(this.startTime, 10)+parseInt(this.duration, 10))*1000);
                var h = date.getHours();
                var m = date.getMinutes();
                if (m < 10){
                        m="0"+m;
                }
                return h+":"+m;
-       }
-       this.getDuration = function ()
-       {
-               return  new Date(parseInt(this.duration)*1000);
-       }
-       this.getTitle = function ()
-       {
+       };
+       this.getDuration = function (){
+               return  new Date(parseInt(this.duration, 10)*1000);
+       };
+       this.getTitle = function (){
                return this.title;
-       }
-       this.getDescription = function ()
-       {
+       };
+       this.getDescription = function (){
                return this.description;
-       }
-       this.getDescriptionExtended = function ()
-       {
+       };
+       this.getDescriptionExtended = function (){
                return this.descriptionE;
-       }
-       this.getServiceReference = function ()
-       {
+       };
+       this.getServiceReference = function (){
                return encodeURIComponent(this.serviceRef);
-       }
-       this.getServiceName = function ()
-       {
+       };
+       this.getServiceName = function (){
                return this.serviceName.replace(" ","&nbsp;");
-       }
+       };
 }
 //END class EPGEvent
 
@@ -150,21 +136,23 @@ function ServiceReference(xml){
        
        this.getServiceReference = function(){
                return encodeURIComponent(this.servicereference);
-       }
+       };
+       
        this.getClearServiceReference = function(){
                return this.servicereference;
-       }
+       };
                
        this.getServiceName = function(){
                return this.servicename.replace('&quot;', '"');
-       }
+       };
+       
        this.setServiceReference = function(toInsert){
                this.servicereference = toInsert;
-       }
+       };
                
        this.setServiceName = function(toInsert){
                this.servicename = toInsert.replace('&quot;', '"');
-       }
+       };
 }      
 //END class Service
 
@@ -178,7 +166,7 @@ function ServiceList(xml){
                //debug("Service parsing Error");
        }
        this.getArray = function(){
-               var listxy = new Array();
+               var listxy = [];
                try{
                        for (var i=0;i<this.xmlitems.length;i++){
                                var xv = new ServiceReference(this.xmlitems.item(i));
@@ -187,33 +175,33 @@ function ServiceList(xml){
                }catch (e){}
                
                return listxy;
-       }
+       };
 }
 //END class ServiceList
 
 //START class MovieList
 function MovieList(xml){
        // parsing values from xml-element
-       debug('init MovieList'+xml);
+       debug('[MovieList] init: ' + xml);
        try{
                this.xmlitems = xml.getElementsByTagName("e2movielist").item(0).getElementsByTagName("e2movie");
        } catch (e) {
-               debug("MovieList parsing Error");
+               debug("[MovieList] parsing Error");
        }
        this.getArray = function(){
-               var listxy = new Array();
+               var listxy = [];
                for(var i=0;i<this.xmlitems.length;i++){
                        //debug("parsing movie "+i+" of "+this.xmlitems.length);
                        var xv = new Movie(this.xmlitems.item(i));
                        listxy.push(xv);                        
                }
                return listxy;
-       }
+       };
 }
 //END class MovieList
 
 //START class Movie
-function Movie(xml){
+function Movie(xml){   
        // parsing values from xml-element
        //debug('init Movie');
        try{
@@ -270,61 +258,64 @@ function Movie(xml){
                
        
 
-       this.getLength = function ()
-       {
+       this.getLength = function (){
                return this.length;
-       }
-       this.getTimeStart = function ()
-       {
-               var date = new Date(parseInt(this.startTime)*1000);
+       };
+       
+       this.getTimeStart = function (){
+               var date = new Date(parseInt(this.startTime, 10)*1000);
                return date;
-       }
-       this.getTimeStartString = function ()
-       {
+       };
+       
+       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 = new Array("So", "Mo", "Di", "Mi", "Do", "Fr", "Sa");
+       };
+       
+       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);
-               
-       }       
+               return encodeURIComponent(this.filename);               
+       };
+       
        this.getFilesizeMB = function(){                
-               return Math.round((parseInt(this.filesize)/1024)/1024)+"MB";
-               
-       }       
+               return Math.round((parseInt(this.filesize, 10)/1024)/1024)+"MB";
+       };      
 }      
 //END class Movie
 
@@ -334,17 +325,17 @@ function TimerList(xml){
        try{
                this.xmlitems = xml.getElementsByTagName("e2timerlist").item(0).getElementsByTagName("e2timer");
        } catch (e) {
-               debug("TimerList parsing Error");
+               debug("[TimerList] parsing Error");
        }
        this.getArray = function(){
-               var listxy = new Array();
+               var listxy = [];
                for(var i=0;i<this.xmlitems.length;i++){
                        //debug("parsing timer "+i+" of "+this.xmlitems.length);
                        var xv = new Timer(this.xmlitems.item(i));
                        listxy.push(xv);                        
                }
                return listxy;
-       }
+       };
 }
 //END class TimerList
 
@@ -480,100 +471,128 @@ function Timer(xml){
 
        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);
-       }       
+               return parseInt(this.duration, 10);
+       };
+       
        this.getStartPrepare = function(){
                return this.startprepare;
-       }       
+       };
+       
        this.getJustplay = function(){
                return this.justplay;
-       }       
+       };
+       
        this.getAfterevent = function(){
                return this.afterevent;
-       }       
+       };
+       
        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;
-       }       
+       };      
 }
 // START SimpleXMLResult ehemals TimerAddResult
 function SimpleXMLResult(xml){
        // parsing values from xml-element
-       debug('init SimpleXMLResult'+xml);
+       debug('[SimpleXMLResult] init: '+xml);
        try{
                this.xmlitems = xml.getElementsByTagName("e2simplexmlresult").item(0);
-               debug(xml.getElementsByTagName("e2simplexmlresult").length);
+               debug("[SimpleXMLResult] count: " + xml.getElementsByTagName("e2simplexmlresult").length);
        } catch (e) {
-               debug("SimpleXMLResult parsing e2simplexmlresult"+e);
+               debug("[SimpleXMLResult] parsing e2simplexmlresult"+e);
        }
        try{
                this.state = this.xmlitems.getElementsByTagName("e2state").item(0).firstChild.data;
        } catch (e) {
-               debug("SimpleXMLResult parsing e2state"+e);
+               debug("[SimpleXMLResult] parsing e2state"+e);
        }
        try{
                this.statetext = this.xmlitems.getElementsByTagName("e2statetext").item(0).firstChild.data;
        } catch (e) {
-               debug("SimpleXMLResult parsing e2statetext"+e);
+               debug("[SimpleXMLResult] parsing e2statetext"+e);
        }
        
        this.getState = function(){
@@ -582,10 +601,10 @@ function SimpleXMLResult(xml){
                }else{
                        return false;
                }
-       }
+       };
        this.getStateText = function(){
                        return this.statetext;
-       }
+       };
 }
 // END SimpleXMLResult
 
@@ -595,18 +614,18 @@ function Settings(xml){
        //debug('init ServiceList'+xml);
        try{
                this.xmlitems = xml.getElementsByTagName("e2settings").item(0).getElementsByTagName("e2setting");
-               debug(this.xmlitems);
+               debug("[Settings] Number of items: " + this.xmlitems);
        } catch (e) {
                //debug("Service parsing Error");
        }
        this.getArray = function(){
-               var listxy = new Array();
+               var listxy = [];
                for (var i=0;i<this.xmlitems.length;i++){
                        var xv = new Setting(this.xmlitems.item(i));
                        listxy.push(xv);                        
                }
                return listxy;
-       }
+       };
 }
 //END class Settings
 
@@ -624,31 +643,31 @@ function Setting(xml){
        
        this.getSettingValue = function(){
                return this.settingvalue;
-       }
+       };
                
        this.getSettingName = function(){
                return this.settingname;
-       }
+       };
        
 }
 //START class FileList
 function FileList(xml){
        // parsing values from xml-element
-       debug('init FileList'+xml);
+       debug('[FileList] init: ' + xml);
        try{
                this.xmlitems = xml.getElementsByTagName("e2filelist").item(0).getElementsByTagName("e2file");
        } catch (e) {
-               debug("FileList parsing Error");
+               debug("[FileList] parsing Error");
        }
        this.getArray = function(){
-               var listxy = new Array();
+               var listxy = [];
                for(var i=0;i<this.xmlitems.length;i++){
                        //debug("parsing File "+i+" of "+this.xmlitems.length);
                        var xv = new File(this.xmlitems.item(i));
                        listxy.push(xv);                        
                }
                return listxy;
-       }
+       };
 }
 //END class FileList
 
@@ -663,30 +682,35 @@ function File(xml){
        }
        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"), '');
                }
-       }
+       };
+       
        try{
                this.isdirectory = xml.getElementsByTagName('e2isdirectory').item(0).firstChild.data;
        } catch (e) {
                this.isdirectory = "N/A";
        }
+       
        this.getIsDirectory = function(){
                return this.isdirectory;
-       }
+       };
+       
        try{
                this.root = xml.getElementsByTagName('e2root').item(0).firstChild.data;
        } catch (e) {
                this.root = "N/A";
        }
+       
        this.getRoot = function(){
                return this.root;
-       }
+       };
 }      
 //END class File
 
@@ -698,16 +722,16 @@ function NoteList(xml){
        try{
                this.xmlitems = xml.getElementsByTagName("e2noteslist").item(0).getElementsByTagName("e2note");
        } catch (e) {
-               debug("NoteList parsing Error");
+               debug("[NoteList] parsing Error");
        }
        this.getArray = function(){
-               var listxy = new Array();
+               var listxy = [];
                for(var i=0;i<this.xmlitems.length;i++){
                        var xv = new Note(this.xmlitems.item(i));
                        listxy.push(xv);                        
                }
                return listxy;
-       }
+       };
 }
 //END class NoteList
 
@@ -739,281 +763,32 @@ function Note(xml){
                this.size = "N/A";
        }
        try{
-               this.mtime = new Date(parseInt(xml.getElementsByTagName('e2notemtime').item(0).firstChild.data)*1000);
+               this.mtime = new Date(parseInt(xml.getElementsByTagName('e2notemtime').item(0).firstChild.data, 10)*1000);
        } catch (e) {
                this.mtime = "N/A";
        }
        try{
-               this.ctime = new Date(parseInt(xml.getElementsByTagName('e2notectime').item(0).firstChild.data)*1000);
+               this.ctime = new Date(parseInt(xml.getElementsByTagName('e2notectime').item(0).firstChild.data, 10)*1000);
        } catch (e) {
                this.ctime = "N/A";
        }
 
-       this.getMTime = function()
-       {
-               var Wochentag = new Array("So", "Mo", "Di", "Mi", "Do", "Fr", "Sa");
+       this.getMTime = function(){
+               var Wochentag = ["So", "Mo", "Di", "Mi", "Do", "Fr", "Sa"];
                var wday = Wochentag[this.mtime.getDay()];
                var day = this.mtime.getDate();
                var month = this.mtime.getMonth()+1;
                var year = this.mtime.getFullYear();
                return wday+".&nbsp;"+day+"."+month+"."+year+" "+this.mtime.getHours()+":"+this.mtime.getMinutes();
-       }
-       this.getCTime = function()
-       {
-               var Wochentag = new Array("So", "Mo", "Di", "Mi", "Do", "Fr", "Sa");
+       };
+       
+       this.getCTime = function(){
+               var Wochentag = ["So", "Mo", "Di", "Mi", "Do", "Fr", "Sa"];
                var wday = Wochentag[this.ctime.getDay()];
                var day = this.ctime.getDate();
                var month = this.ctime.getMonth()+1;
                var year = this.ctime.getFullYear();
                return wday+".&nbsp;"+day+"."+month+"."+year+" "+this.ctime.getHours()+":"+this.ctime.getMinutes();
-       }
+       };
 }
 //END class NoteList
-
-//START class AutoTimerList
-function AutoTimerList(xml){
-       // parsing values from xml-element
-       debug('init AutoTimerList'+xml);
-       try{
-               this.xmlitems = xml.getElementsByTagName("e2autotmerlist").item(0).getElementsByTagName("e2autotimer");
-       } catch (e) {
-               debug("AutoTimerList parsing Error");
-       }
-       this.getArray = function(){
-               var listxy = new Array();
-               for(var i=0;i<this.xmlitems.length;i++){
-                       //debug("parsing movie "+i+" of "+this.xmlitems.length);
-                       var xv = new AutoTimer(this.xmlitems.item(i));
-                       listxy.push(xv);                        
-               }
-               return listxy;
-       }
-}
-//END class AutoTimerList
-//START class AutoTimer
-function AutoTimer(xml){
-       // parsing values from xml-element
-       //debug('init Movie');
-       try{
-               this.name = xml.getElementsByTagName('e2name').item(0).firstChild.data;
-       } catch (e) {
-               this.name = "N/A";
-       }
-       try{
-               this.match = xml.getElementsByTagName('e2match').item(0).firstChild.data;
-       } catch (e) {
-               this.match = "N/A";
-       }
-       try{
-               this.enabled = xml.getElementsByTagName('e2enabled').item(0).firstChild.data;
-       } catch (e) {
-               this.enabled = "N/A";
-       }
-       try{
-               this.excludetitle = xml.getElementsByTagName('e2excludetitle').item(0).firstChild.data;
-       } catch (e) {
-               this.excludetitle = "N/A";
-       }
-       try{
-               this.excludeshort = xml.getElementsByTagName('e2excludeshort').item(0).firstChild.data;
-       } catch (e) {
-               this.excludeshort = "N/A";
-       }
-       try{
-               this.excludedescription = xml.getElementsByTagName('e2excludedescription').item(0).firstChild.data;
-       } catch (e) {
-               this.excludedescription = "N/A";
-       }
-       try{
-               this.excludedays = xml.getElementsByTagName('e2excludedays').item(0).firstChild.data;
-       } catch (e) {
-               this.excludedays = "n/a";
-       }
-       try{
-               this.includetitle = xml.getElementsByTagName('e2includetitle').item(0).firstChild.data;
-       } catch (e) {
-               this.includetitle = "N/A";
-       }
-       try{
-               this.includeshort = xml.getElementsByTagName('e2includeshort').item(0).firstChild.data;
-       } catch (e) {
-               this.includeshort = "N/A";
-       }
-       try{
-               this.includedescription = xml.getElementsByTagName('e2includedescription').item(0).firstChild.data;
-       } catch (e) {
-               this.includedescription = "N/A";
-       }
-       try{
-               this.includedays = xml.getElementsByTagName('e2includedays').item(0).firstChild.data;
-       } catch (e) {
-               this.includedays = "N/A";
-       }
-       try{
-               this.services = xml.getElementsByTagName('e2services').item(0).firstChild.data;
-       } catch (e) {
-               this.services = "N/A";
-       }
-       try{
-               this.bouquets = xml.getElementsByTagName('e2bouquets').item(0).firstChild.data;
-       } catch (e) {
-               this.bouquets = "N/A";
-       }
-       try{
-               this.timespanbegin = xml.getElementsByTagName('e2timespanbegin').item(0).firstChild.data;
-       } catch (e) {
-               this.timespanbegin = "0";
-       }
-       try{
-               this.timespanend = xml.getElementsByTagName('e2timespanend').item(0).firstChild.data;
-       } catch (e) {
-               this.timespanend = "0";
-       }
-       try{
-               this.duration = xml.getElementsByTagName('e2duration').item(0).firstChild.data;
-       } catch (e) {
-               this.duration = "0";
-       }
-       try{
-               this.counter = xml.getElementsByTagName('e2counter').item(0).firstChild.data;
-       } catch (e) {
-               this.counter = "0";
-       }
-       try{
-               this.counterleft = xml.getElementsByTagName('e2counterleft').item(0).firstChild.data;
-       } catch (e) {
-               this.counterleft = "0";
-       }
-       try{
-               this.counterlimit = xml.getElementsByTagName('e2counterlimit').item(0).firstChild.data;
-       } catch (e) {
-               this.counterlimit = "0";
-       }
-       try{
-               this.counterformatstring = xml.getElementsByTagName('e2counterformatstring').item(0).firstChild.data;
-       } catch (e) {
-               this.counterformatstring = "0";
-       }
-       try{
-               this.destination = xml.getElementsByTagName('e2destination').item(0).firstChild.data;
-       } catch (e) {
-               this.destination = "N/A";
-       }
-       try{
-               this.lastbegin = xml.getElementsByTagName('e2lastbegin').item(0).firstChild.data;
-       } catch (e) {
-               this.lastbegin = "0";
-       }
-       try{
-               this.justplay = xml.getElementsByTagName('e2justplay').item(0).firstChild.data;
-       } catch (e) {
-               this.justplay = "N/A";
-       }
-       try{
-               this.avoidduplicatedescription = xml.getElementsByTagName('e2avoidduplicatedescription').item(0).firstChild.data;
-       } catch (e) {
-               this.avoidduplicatedescription = "N/A";
-       }
-       try{
-               this.afterevent = xml.getElementsByTagName('e2afterevent').item(0).firstChild.data;
-               if(this.afterevent == "None") {
-                       this.afterevent = 0;
-               }
-               this.afterevent = Number(this.afterevent);
-       } catch (e) {
-               this.afterevent = 0;
-       }
-       try{
-               this.toggledisabledimg = xml.getElementsByTagName('e2toggledisableimg').item(0).firstChild.data;
-       } catch (e) {
-               this.toggledisabledimg = "N/A";
-       }
-       try{
-               this.tags = xml.getElementsByTagName('e2tags').item(0).firstChild.data;
-       } catch (e) {
-               this.tags = "no&nbsp;tags"; // no whitespaces... tags will be splittet later
-       }
-       
-       this.getName = function(){
-        return this.name;
-    }
-    this.getMatch = function(){
-        return this.match;
-    }
-    this.getEnabled = function(){
-        return this.enabled;
-    }
-    this.getExcludetitle = function(){
-        return this.excludetitle;
-    }
-    this.getExcludeshort = function(){
-        return this.excludeshort;
-    }
-    this.getExcludedescription = function(){
-        return this.excludedescription;
-    }
-    this.getExcludedays = function(){
-        return this.excludedays;
-    }
-    this.getIncludetitle = function(){
-        return this.includetitle;
-    }
-    this.getIncludeshort = function(){
-        return this.includeshort;
-    }
-    this.getIncludedescription = function(){
-        return this.includedescription;
-    }
-    this.getIncludedays = function(){
-        return this.includedays;
-    }
-    this.getServices = function(){
-        return this.services;
-    }
-    this.getBouquets = function(){
-        return this.bouquets;
-    }
-    this.getTimespanbegin = function(){
-        return this.timespanbegin;
-    }
-    this.getTimespanend = function(){
-        return this.timespanend;
-    }
-    this.getDuration = function(){
-        return this.duration;
-    }
-    this.getCounter = function(){
-        return this.counter;
-    }
-    this.getCounterleft = function(){
-        return this.counterleft;
-    }
-    this.getCounterlimit = function(){
-        return this.counterlimit;
-    }
-    this.getCounterformatstring = function(){
-        return this.counterformatstring;
-    }
-    this.getDestination = function(){
-        return this.destination;
-    }
-    this.getLastbegin = function(){
-        return this.lastbegin;
-    }
-    this.getJustplay = function(){
-        return this.justplay;
-    }
-    this.getAvoidduplicatedescription = function(){
-        return this.avoidduplicatedescription;
-    }
-    this.getTags = function(){
-        return this.tags;
-    }
-    this.getAfterevent = function(){
-        return this.afterevent;
-    }
-    this.getToggleDisabledIMG = function(){
-               return this.toggledisabledimg;
-       }
-}      
-//END class AutoTimer
\ No newline at end of file
index d4923cf..a3949dd 100644 (file)
-button, span { 
-       behavior: url(webdata/IEFixes.htc);
-}
-
-body {         
-       text-align:left;
-       vertical-align: top;
-       margin:0px; 
-       font-family:Arial,sans-serif;
-       font-size: 12px;
-       background-color:#EEE;
-       color:#444;
-}
-
-a:link { color:#444; }
-a:visited { color:#444; }
-a:active { color:#444; }
-
-hr{ border: 1px solid #BBB; 
-       margin-left: 3px;
-       margin-right: 3px;
-}
-
-form{
-       margin: 0px;
-       padding: 0px;
-}
-
-button {
-       background-image: url('gfx/button.png');
-       height: 20px;
-       width: 140px;
-       border: 1px solid #AAA;
-}
-
-button:hover, button.hover {
-       border: 1px solid #000;
-}
-
-#currentServiceName { 
-       font-family:Arial,sans-serif;
-       font-size:14px;
-       font-weight:bold;
-       
-       float:right;
-
-       color: #FFFFFF;
-       text-align:left;
-
-       width:30%;
-       height:20px;
-}
-.currentServiceEPGStarttime { 
-       font-family:Arial,sans-serif;
-       font-size:14px;
-       font-weight:bold;
-       
-       float:left;
-
-       color: #FFFFFF;
-       text-align:left;
-
-       width:40px;
-       height:20px;
-}
-.currentServiceEPGTitle { 
-       font-family:Arial,sans-serif;
-       font-size:14px;
-       font-weight:bold;
-       
-       float:left;
-
-       color: #FFFFFF;
-       text-align:left;
-
-       width:240px;
-       height:20px;
-}
-.currentServiceEPGDuration { 
-       font-family:Arial,sans-serif;
-       font-size:14px;
-       font-weight:bold;
-       
-       float:left;
-       color: #FFFFFF;
-       text-align:right;
-
-       width:70px;
-       height:20px;
-}
-
-#searchText{
-       border: 1px solid #000;
-       margin: 0 0 0 0;
-}
-#filterMovietag{
-       border: 1px solid #000;
-       margin: 0 0 0 0;
-}
-
-/**************************************************************
-Make the ServiceList Table scrollable**************************
-***************************************************************/
-
-/* define height and width of scrollable area. Add 16px to width for scrollbar          */
-div.BodyContent {
-       border: 1px solid #000;
-       height: 455px;
-       overflow: auto;
-       margin: 0px 9px 0px;
-       font-size: 12px;
-}
-
-div.BodyContentChannellist {
-       clear: both;
-       max-height: 455px;
-       overflow: auto;
-/*     width: 780px; */
-}
-
-.BodyContentChannellist{
-       font-size: 12px;
-}
-
-/* Reset overflow value to hidden for all non-IE browsers. */
-html>body div.BodyContentChannellist {
-       overflow: hidden;
-       width: 780px;
-}
-
-/* define width of table. IE browsers only                 */
-div.BodyContentChannellist table {
-       float: left;
-       width: 760px;
-       max-height: 455px;
-}
-
-/* define width of table. Add 16px to width for scrollbar.           */
-/* All other non-IE browsers.                                        */
-html>body div.BodyContentChannellist table {
-       width: 780px;
-}
-
-/* set table header to a fixed position. WinIE 6.x only                                       */
-/* In WinIE 6.x, any element with a position property set to relative and is a child of       */
-/* an element that has an overflow property set, the relative value translates into fixed.    */
-/* Ex: parent element DIV with a class of tableContainer has an overflow property set to auto */
-thead.fixedHeader tr {
-       position: relative;
-       height: 30px;
-       background: url(gfx/banner_30.png);     
-}
-
-/* set THEAD element to have block level attributes. All other non-IE browsers            */
-/* this enables overflow to work on TBODY element. All other non-IE, non-Mozilla browsers */
-html>body thead.fixedHeader tr {
-       display: block
-}
-
-/* make the TH elements pretty */
-thead.fixedHeader th {
-       border: 0px;
-       font-weight: normal;
-       padding: 4px 3px;
-       text-align: left
-}
-
-/* make the A elements pretty. makes for nice clickable headers                */
-thead.fixedHeader a, thead.fixedHeader a:link, thead.fixedHeader a:visited {
-       color: #FFF;
-       display: block;
-       text-decoration: none;
-       width: 100%
-}
-
-/* make the A elements pretty. makes for nice clickable headers                */
-/* WARNING: swapping the background on hover may cause problems in WinIE 6.x   */
-thead.fixedHeader a:hover {
-       color: #FFF;
-       display: block;
-       text-decoration: underline;
-       width: 100%
-}
-
-/* define the table content to be scrollable                                              */
-/* set TBODY element to have block level attributes. All other non-IE browsers            */
-/* this enables overflow to work on TBODY element. All other non-IE, non-Mozilla browsers */
-/* induced side effect is that child TDs no longer accept width: auto                     */
-html>body tbody.scrollContent {
-       display: block;
-       height: 422px;
-       /* This is realy bad for resolution below 1280x1024 */
-       overflow: auto;
-       width: 100%;
-}
-
-/* make TD elements pretty. Provide alternating classes for striping the table */
-/* http://www.alistapart.com/articles/zebratables/                             */
-
-
-tbody.scrollContent td, tbody.scrollContent tr.normalRow td {
-       background: #FFF;
-       border-bottom: none;
-       border-left: none;
-       border-right: 1px solid #CCC;
-       border-top: 1px solid #DDD;
-       padding: 2px 3px 3px 4px;
-}
-
-/* define width of TH elements: 1st, 2nd, and 3rd respectively.          */
-/* Add 16px to last TH for scrollbar padding. All other non-IE browsers. */
-/* http://www.w3.org/TR/REC-CSS2/selector.html#adjacent-selectors        */
-html>body thead.fixedHeader th {
-       width: 780px; 
-}
-
-/* define width of TD elements: 1st, 2nd, and 3rd respectively.          */
-/* All other non-IE browsers.                                            */
-/* http://www.w3.org/TR/REC-CSS2/selector.html#adjacent-selectors        */
-html>body tbody.scrollContent td {
-width: 764px; 
-}
-
-/****************************************
-normal stylesheet-stuff******************
-*****************************************/
-
-#Main{
-       width:960px;
-       background-color: #AAA;
-       text-align: left;
-       margin: 0; 
-       padding: 0;
-       overflow: auto;
-       vertical-align: top;
-       cursor: default;
-       border: 1px solid #000; 
-}
-
-#Content{
-       vertical-align: middle;  
-       float: left;
-       background-color: #FFF;
-       width: 800px;
-       padding-bottom: 10px;
-       border-right: 1px solid #000;
-       border-left: 1px solid #000;
-}
-
-#CurrentService { 
-       font-family: Arial,sans-serif;
-       font-size: 14px;
-       font-weight: bold;
-       float: left;
-       color: #FFFFFF;
-       
-       width: 55%;
-       height: 20px;
-}
-
-#CurrentEvent { 
-       font-family: Arial,sans-serif;
-       font-size: 14px;
-       font-weight: bold;
-       float: left;
-       color: #FFFFFF;
-       text-align: right;
-       width: 45%;
-       height: 20px;
-}
-
-#VolumePanel { 
-       font-family:Arial,sans-serif;
-       font-size:14px;
-       font-weight:bold;
-       
-       float:left;
-       color: #FFFFFF;
-       
-       width:25%;
-       height:20px;
-}
-
-#CurrentTime { 
-       font-family:Arial,sans-serif;
-       font-size:14px;
-       font-weight:bold;
-       
-       float:left;
-       text-align:right;
-       color: #FFFFFF;
-       
-       width: 11%;
-       height: 20px;
-}
-
-#SignalPanel { 
-       font-family:Arial,sans-serif;
-       font-size:14px;
-       font-weight:bold;
-       
-       float:left;
-
-       color: #FFFFFF;
-       text-align:right;
-
-       width:20px;
-       height:20px;
-}
-#StreaminterfaceButton { 
-       font-family:Arial,sans-serif;
-       font-size:14px;
-       font-weight:bold;
-       
-       float:left;
-
-       color: #FFFFFF;
-       text-align:right;
-
-       width:20px;
-       height:20px;
-}
-
-
-#RecordButton { 
-       float:left;
-       width:20px;
-       height:20px;
-}
-
-#ServiceInfo{
-       width:800px;
-       height: 20px;
-       border-bottom: 1px solid #000;
-       float:none;
-       clear:both;
-       padding: 0 0 0;
-       margin: 0 0 0;
-       vertical-align: middle;
-       background: url(gfx/banner.png);
-       color: #FFFFFF;
-}
-
-#nav{
-       float: left;
-       width: 117px;
-       background-color: #AAA;
-}
-
-#navTable{
-       background-color: #EEE;
-       vertical-align: middle;
-       font-size: 14px;
-       font-weight: bold;
-       width: 100%;
-       margin:0 0 0 0;
-       padding:0 0 0 0;
-}
-
-#NavHd{
-       background: url(gfx/banner.png);
-       color: #FFFFFF;
-       font-size:10px;
-       font-weight: bold;
-       height: 20px;
-       vertical-align: middle;
-}
-#RequestIndicator{
-       display: inline;
-       vertical-align: middle;
-       font-size:14px;
-       font-weight: bold;
-       height:20px;
-}
-
-#EventNowNext{
-}
-
-#updates{
-       visibility: hidden;
-}
-
-.navMenuPanel{
-       background-color: #BBB;
-}
-.navMenuHeader{
-       font-size: 14px;
-       border-top: 1px solid #000;
-       height: 20px;
-}
-
-.navMenuContent{
-       font-size: 12px;
-       font-weight: normal;
-       background-color: #EEE;
-       border: 0px;
-}
-.navMenuItem{
-       font-size: 12px;
-}
-
-.divblock{
-       width:100%;
-       float:none;
-       clear:both;
-}
-
-.event{
-       font-size:12px;
-       width:100%;
-       font-weight:bold;
-       background-color: #DDEEFF;
-       margin-bottom: 1px;
-       cursor:help;
-}
-.eventRA{
-       font-size:12px;
-       width:100%;
-       font-weight:bold;
-       text-align:right;
-       background-color: #DDEEFF;
-       margin-bottom: 1px;
-       cursor:help;
-}
-
-.eventExtDesc{
-       color: #777;
-       background-color: #FFF;
-       font-size:12px;
-       margin-bottom: 1px;
-       width:100%;
-}
-
-.bgMain{
-       background-color: #FFF;
-       width: 100%;
-}
-.sListHeader{
-       font-size: 14px;
-       font-weight: bold;
-       color: #FFF;
-       float:left;
-       width:50%;
-}
-.sListSearch{
-       font-size: 14px;
-       float:left;
-       width:50%;
-       text-align: right;
-       margin: 0 0 0 0;
-}
-
-.sListTh{
-       height: 30px;
-       background: url(gfx/banner_30.png);     
-       vertical-align: middle;
-}
-
-form.sListSearch{
-       text-align: right;
-}
-.sListSName{
-       font-size: 14px;
-       font-weight: bold;
-       float:left;
-       width:661px;
-}
-
-span.sListSLink{
-       display: block;
-       width: 656px;
-       height: 100%;
-       text-decoration: none;
-}
-
-span.sListSLink:hover, span.sListSLink.hover{
-       background-color: #DDD;
-}
-
-.sListExt{
-       border-left: 1px solid #CCC;
-       float:left;
-       width:90px;
-       text-align: right;
-}
-.sListEPGTime{
-       float:left;
-       width:60px;
-       text-align: left;
-}
-.sListEPGTitle{
-       border-left: 1px solid #CCC;
-       border-right: 1px solid #CCC;
-       float: left;
-       width:600px; 
-       text-align: left;
-}
-.sListEPGDuration{
-       float:left;
-       width:75px;
-       text-align: right;
-}
-.tListSName{
-       width: 180px;
-       text-align: left;
-}
-.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;
-}
-#TimerColor0 {
-       color: #000000;
-}
-#TimerColor1 {
-       color: #00BCBC;
-       background-color: #DDD;
-}
-#TimerColor2 {
-       color: #9F1919;
-       background-color: #DDD;
-}
-#TimerColor3 {
-       color: #00BCBC;
-       background-color: #DDD;
-}
-
-.pageHeader {
-       width:100%;
-       height: 30px;
-       background: url(gfx/banner_30.png);
-       color: #FFF;
-       font-weight:bold;
-}
-
-.aboutHeader {
-       width:100%;
-       color:#444444;
-       font-weight:bold;
-       background-color:#DDEEFF;
-}
-
-.about {
-       border: 1px solid #AAA;
-       width: 100%;
-       font-size: 12px;
-}
-
-.fullwidth {
-       width: 100%;
-}
-
-.aboutSection{
-       width:100%;
-       margin: 0 0 0 0;
-}
-
-.aboutSectionLeft{
-       width:50%;
-       vertical-align: top;
-}
-
-.aboutSectionRight{
-       width:50%;
-       vertical-align: top;
-}
-
-.aboutElement{
-       float: none;
-}
-
-.aboutElementLeft{
-       font-weight:bold;
-       width: 50%;
-       text-align: left;
-}
-
-.aboutElementRight{
-       width: 50%;
-}
-
-/* movielist */
-.movieListName{
-       font-size: 14px;
-       font-weight: bold;
-       float:left;
-       width:661px;
-       cursor:help;
-}
-.movieListExt{
-       border-left: 1px solid #CCC;
-       float:left;
-       width:90px;
-       text-align: right;
-}
-
-.movieDetails {
-       border: 1px solid #AAA;
-       width: 100%;
-       font-size: 12px;
-}
-
-.movieElementRight{
-       width: 1%;
-}
-
-.movieElementLeft{
-       font-weight:bold;
-       width: 99%;
-       text-align: left;
-}
+       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: #FFF;
+               text-decoration: none;
+       }
+
+/***********************
+ GENERAL
+ ***********************/
+
+       .odd{
+               background-color: #FFF;
+       }
+       
+       .even{
+               background-color: #DDD;
+       }
+       
+       .fullwidth {
+               width: 100%;
+       }
+       
+       .center {
+               text-align: center;
+       }
+
+
+/***********************
+ BANNER with MainMenu
+ ***********************/
+
+       #banner{
+               width: 1000px;
+               height: 70px;
+               background: #000;
+               padding-left: 5px;
+               margin-bottom: 8px;
+       }
+
+       #banner, #banner .sb-inner { background:#000 }
+       #banner .sb-border { background: #FFF }
+       #bannerText{
+               margin-bottom: 10px;
+               padding-left: 2px;
+               padding-top: 6px;
+       }
+
+       #bannerLeft{
+               width: 800px;
+               float: left;
+       }
+       
+       #bannerRight{
+               width: 190px;
+               text-align: right;
+               height: 60px;
+               float: left;
+       }
+       
+       #bannerRight img{
+               padding-top: 5px;
+       }
+       
+       
+       #current{
+               width: 999px;
+               background: #000;
+               padding-left: 3px;
+               padding-right: 3px;
+               padding-bottom: 1px;
+               margin-bottom: 8px;
+       }
+
+       #current, #current .sb-inner { background:#000 }
+       #current .sb-border { background: #FFF }
+       #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: 850px;
+       }
+
+       #mainMenu li{
+               list-style: none;
+               float: left;
+               width: 130px;
+               height: 21px;
+               margin-left: 2px;
+       }
+       #mainMenu li .sb-border { background:#485052; }
+       #mainMenu li, #mainMenu li .sb-inner { background-color: #485052; }
+
+       #mainMenu a{ display:block; padding: 1px; }
+
+       #mainMenu li:hover, #mainMenu li:hover .sb-inner { background: #AAA; }
+       #mainMenu li.hover, #mainMenu li.hover .sb-inner { background: #AAA; }
+
+/***************
+ Upper Left Nav
+ ***************/
+
+       #navContainer{
+               float:left;
+               width: 160px;
+       }
+        
+       #nav{
+               width: 100%;
+               height: 250px;
+               background: #000;
+               padding-left: 5px;
+       }
+
+       #nav, #nav .sb-inner { 
+               background:#FFF; 
+               padding-left: 2px;
+               padding-right: 2px;
+       }
+       #nav .sb-border { background:#000; }
+
+       #navHd, #navHd .sb-inner{
+               background: #000;
+               text-align: center;
+       }
+       
+       #navContent{
+               color: #485052;
+               padding-left: 5px;
+       }
+
+       #navSearch{
+               width: 100%;
+               height: 61px;
+               background: #000;
+               padding-left: 5px;
+       }
+
+       #navSearch, #navSearch .sb-inner { 
+               background:#FFF; 
+               padding-left: 2px;
+               padding-right: 2px;
+       }
+       #navSearch .sb-border { background:#000; }
+
+       #searchHd, #searchHd .sb-inner{
+               background: #000;
+               text-align: center;
+       }
+       
+       
+       #navVolume{
+               width: 100%;
+               height: 75px;
+               background: #000;
+               padding-left: 0px;
+       }
+
+       #navVolume, #navVolume .sb-inner { 
+               background:#FFF; 
+               padding-left: 2px;
+               padding-right: 2px;
+       }
+       #navVolume .sb-border { background:#000; }
+
+       #volHd, #volHd .sb-inner{
+               background: #000;
+               text-align: center;
+       }
+       
+       
+
+/**************
+ Content
+ **************/
+       #content{
+               float: left;
+               color: #485052;
+               background: #000;
+               width: 833px;
+               min-height: 308px;
+               margin-left: 8px;
+       }
+
+       #content, #content .sb-inner { background:#FFF; padding: 2px}
+       #content .sb-border { background:#000; }
+
+       #contentHd, #contentHd .sb-inner{
+               background: #000;
+               color: #fff;
+       }
+
+       #epgSearch{ width: 120px; }
+       
+       .boxContent{
+               padding: 3px;   
+       }
+       
+/*****************
+* Subnavigation
+******************/    
+       .navTable{
+               width: 100%;
+       }
+       
+       .navTable a, .navTable a:visited, .navTable a:active{
+               color: #485052;
+               text-decoration: none;
+               display: block;
+       }
+       
+       .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;
+       }
+       
+       #contentTable div{
+               width: auto;
+               overflow: auto;
+       }
+
+       #contentMain{
+               padding: 8px;
+               margin-bottom: 5px;
+       }
+
+       #contentMain {
+               clear: both;
+               /*overflow-x: hidden;*/
+               overflow-y: auto;
+               width: 815px;
+       }
+
+       /*
+       html>body #contentMain div{
+               overflow: hidden;
+               width: 785px;
+       }
+*/
+       #contentMain div table {
+               float: left;
+               width: 799px;
+       }
+       
+       .sListItem{
+               /*border-bottom: 2px solid #CCC;*/
+               width: 780px;
+       }
+
+/*****************
+* ServiceList EPG
+******************/            
+       .epgStart{
+               width: 50px;            
+       }
+       
+       .epgTitle{
+               width: 680px;
+       }
+       
+       .epgLength{
+               width: 50px;
+               text-align: right;
+       }
+       
+       
+/*****************
+* MovieList EPG
+******************/    
+       .mListDetail{
+               font-size: 12px;
+       }
+       
+       .mStart{
+               width: 160px;           
+       }
+       
+       .mTitle{
+               width: 650px;
+       }
+       
+       .mLength{
+               width: 90px;
+               text-align: right;
+       }
+       
+/*****************
+* About
+******************/    
+       
+       .aboutHeader {
+               width:100%;
+               color:#FFF;
+               font-weight:bold;
+               background-color:#000;
+       }
+
+       .about {
+               border: 1px solid #CCC;
+               width: 100%;
+               margin: 0px;
+               padding: 0px;
+       }
+
+       .aboutSection{
+               width:100%;
+               margin: 0 0 0 0;
+       }
+
+       .aboutSectionLeft{
+               width:50%;
+               vertical-align: top;
+       }
+
+       .aboutSectionRight{
+               width:50%;
+               vertical-align: top;
+       }
+
+       .aboutElement{
+               float: none;
+       }
+
+       .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: #00BCBC;
+       }
+       
+       .timerState2 {
+               color: #990000;
+       }
+       
+       .timerState3 {
+               color: #000099;         
+       }
+       
+/*****************
+* EPG List
+******************/                    
+       .epgListItem{
+               font-size:12px;
+       }
\ No newline at end of file
index a23def1..2f349f9 100644 (file)
 Version = '$Header$';
 // EPG Templates
 var tplUpdateStreamReaderIE = '<iframe id="UpdateStreamReaderIEFixIFrame" src="%(url_updates)" height="0" width="0" scrolling="none" frameborder="0">no iframe support!</iframe>';
-var tplEPGListHeader = '<table width="100%" border="0" cellspacing="1" cellpadding="0">';
 
-var tplEPGListItem  = '<tr style="background-color: #DDDDDD;">';
-       tplEPGListItem += '<td width="10%">%(date)</td>';
-       tplEPGListItem += '<td width="30%">%(servicename)</td>';
-       tplEPGListItem += '<td>%(title)</td>';
-       tplEPGListItem += '</tr>';
-
-       tplEPGListItem += '<tr style="background-color: #DDDDDD;">';
-       tplEPGListItem += '<td>%(starttime)</td>';
-       tplEPGListItem += '<td>%(duration) min.</td>';
-       tplEPGListItem += '<td>%(description)</td>';
-       tplEPGListItem += '</tr>';
-
-       tplEPGListItem += '<tr style="background-color: #DDDDDD;">';
-       tplEPGListItem += '<td valign="top">%(endtime)</td>';
-       tplEPGListItem += '<td colspan="2"rowspan="2" id="extdescription%(number)">%(extdescriptionSmall)</td>';
-       tplEPGListItem += '</tr>';
-
-       tplEPGListItem +='<tr style="background-color: #DDDDDD;"><td>';
-       tplEPGListItem +='<a target="_blank" ><img src="/webdata/gfx/timer.png" title="add to Timers" border="0" onclick=" if( parentPin( \'%(servicereference)\' ) ) { addTimerByID(\'%(servicereference)\',\'%(eventid)\',\'0\'); }"></a>&nbsp;&nbsp;';
-       tplEPGListItem +='<a target="_blank" ><img src="/webdata/gfx/zap.png" title="add zap to Timers" border="0" onclick="if ( parentPin( \'%(servicereference)\' ) ) { addTimerByID(\'%(servicereference)\',\'%(eventid)\',\'1\'); }"></a>&nbsp;&nbsp;';
-       tplEPGListItem +='<a target="_blank" ><img src="/webdata/gfx/edit.gif" title="edit and add timer" border="0" onclick="loadTimerFormSeconds(0,\'%(start)\',\'%(end)\',0,\'%(servicereference)\',\'%(servicename)\',\'%(title)\',\'%(description)\',\'0\',0,\'%(eventid)\');"></a><br/>';
-       tplEPGListItem +='<a target="_blank" href="/web/epgsearch.rss?search=%(title)" ><img src="/webdata/gfx/feed.png" title="RSS-Feed for this Title" border="0"></a><br/>';
-       tplEPGListItem +='<a target="_blank" href="http://www.imdb.com/find?s=all&amp;q=%(titleESC)" ><img src="/webdata/gfx/world.png" title="search IMDb" border="0"></a><br/>';
-       tplEPGListItem +='</td></tr>';
-       tplEPGListItem += '<tr style="background-color: #AAAAAA;">';
-       tplEPGListItem += '<td colspan="3">&nbsp;</td>';
-       tplEPGListItem += '</tr>';
 
 var tplEPGListItemExtend  = '%(shortTxt) ...<a nohref onclick="setComplete(\'extdescription%(number)\',\'%(txt)\');">more</a>';
 
-var tplEPGListFooter = "</table>";
-
-// ServiceList Templates
-var tplServiceListHeader  = '<div class="BodyContentChannellist">\n';
-       tplServiceListHeader += '<table border="0" cellpadding="0" cellspacing="0" class="BodyContentChannellist">\n';
-       tplServiceListHeader += '<thead class="fixedHeader">\n';
-       tplServiceListHeader += '<tr>\n';
-       tplServiceListHeader += '<th><div class="sListHeader">ServiceList</div>\n';
-       tplServiceListHeader += '<div class="sListSearch">';
-       tplServiceListHeader += '<form onSubmit="loadEPGBySearchString(document.getElementById(\'searchText\').value); return false;">';
-       tplServiceListHeader += '<input type="text" id="searchText" onfocus="this.value=\'\'" value="Search EPG"/>';
-       tplServiceListHeader += '<input style="vertical-align:middle" type="image" src="/webdata/gfx/search.png" alt="search...">';
-       tplServiceListHeader += '</form></div></th>';
-       tplServiceListHeader += '</tr>\n';
-       tplServiceListHeader += '</thead>\n';
-       tplServiceListHeader += '<tbody class="scrollContent">\n';
-       tplServiceListHeader += '<input type="hidden" id="mainServiceRef" name="mainServiceRef" value="%(mainServiceRef)">\n';
-
-var tplServiceListItem  = '<tr>\n';
-       tplServiceListItem += '<td style="border-top: 2px solid #AAA;" ><div class="sListSName"><span id="%(servicereference)" onclick="if ( parentPin( \'%(servicereference)\' ) ) { zap(this.id); }" class="sListSLink">%(servicename)</span></div>';
-       tplServiceListItem += '<div class="sListExt"><a onclick="if ( parentPin( \'%(servicereference)\' ) ) { loadEPGByServiceReference(this.id); }" id="%(servicereference)"><img src="/webdata/gfx/epg.png" border="0"/></a>\n';
-       tplServiceListItem += '<a target="_blank" onclick="return parentPin( \'%(servicereference)\' );" href="/web/stream.m3u?ref=%(servicereference)"><img src="/webdata/gfx/screen.png" title="stream Service" border="0"></a></div>\n';
-       tplServiceListItem += '</td></tr>\n';
-       tplServiceListItem += '<tr><td id="%(servicereference)sub"></td></tr>';
-    tplServiceListItem += '<tr>\n';
-       tplServiceListItem += '<td colspan="2"><div id="%(servicereference)EPGNOW"></div></td>\n';
-       tplServiceListItem += '</tr>\n';
-
-var tplServiceListFooter = "</tbody>\n</table>\n</div>\n";
-
-//Subservice Templates
-var    tplServiceListEPGItem  = '<div class="sListEPGTime">%(starttime)</div>\n';
-       tplServiceListEPGItem += '<div class="sListEPGTitle">%(title)</div>\n';
-       tplServiceListEPGItem += '<div class="sListEPGDuration">%(length) min.</div>\n';
-
-var    tplSubServiceListItem  = '<div class="sListSName"><span id="%(servicereference)" onclick="if ( parentPin( \'%(servicereference)\' ) ) { zap(this.id); }" class="sListSLink">%(servicename)</span></div>\n';
-       tplSubServiceListItem += '<div class="sListExt"><a onclick="loadEPGByServiceReference(this.id)" id="%(servicereference)"><img src="/webdata/gfx/epg.png" border="0"/></a>\n';
-       tplSubServiceListItem += '<a target="_blank" href="/web/stream.m3u?ref=%(servicereference)"><img src="/webdata/gfx/screen.png" title="stream Service" border="0"></a></div>\n';
-
-// MovieList Templates
-var tplMovieListHeader  = '<div class="BodyContentChannellist">\n';
-       tplMovieListHeader += '<table border="0" cellpadding="0" cellspacing="0" class="BodyContentChannellist">\n';
-       tplMovieListHeader += '<thead class="fixedHeader">\n';
-       tplMovieListHeader += '<tr>\n';
-       tplMovieListHeader += '<th colspan="2"><div class="sListHeader">MovieList</div>\n';
-       tplMovieListHeader += '<div class="sListSearch">';
-       tplMovieListHeader += '<form onSubmit="loadMovieList(document.getElementById(\'filterMovietag\').value); return false;">';
-       tplMovieListHeader += '<input type="text" id="filterMovietag" onfocus="this.value=\'\'" value="filter by Tag"/>';
-       tplMovieListHeader += '<input style="vertical-align:middle" type="image" src="/webdata/gfx/search.png" alt="search...">';
-       tplMovieListHeader += '</form></div></th>';
-       tplMovieListHeader += '</tr>\n';
-       tplMovieListHeader += '</thead>\n';
-       tplMovieListHeader += '<tbody class="scrollContent">\n';
-
-var tplMovieListItem  = '<tr>\n';
-       tplMovieListItem += '<td><div class="movieListName" title="%(description), %(descriptionextended)" onClick="$(\'moviedetails_%(servicereference)\').toggle();">%(title) (%(servicename))</div>';
-       tplMovieListItem += '<div class="movieListExt">\n';
-       tplMovieListItem += '<a target="_blank" href="/web/ts.m3u?file=%(filelink)"><img src="/webdata/gfx/screen.png" title="play file" border="0"></a>\n';
-       tplMovieListItem += '&nbsp;<a target="_blank" href="/file/?file=%(filelink)&root=/hdd/movie/"><img src="/webdata/gfx/save.png" title="download Movie" border="0"></a>\n';
-       tplMovieListItem += '&nbsp;<a target="_blank" ><img src="/webdata/gfx/trash.gif" title="delete files" border="0" onclick="delMovieFile(\'%(filename)\',\'%(servicename)\',\'%(title)\',\'%(description)\');"></a>\n';
-       tplMovieListItem += '</div>\n';
-       tplMovieListItem += '<div id="moviedetails_%(servicereference)"  style="display:none;">\n';
-       tplMovieListItem += '<table class="movieDetails">\n';
-               tplMovieListItem += '<tr>\n';
-               tplMovieListItem += '<td class="movieElementLeft">Details:</td>\n';
-               tplMovieListItem += '<td class="movieElementRight">%(description)&nbsp;</td>\n';
-               tplMovieListItem += '</tr>\n';
-               tplMovieListItem += '<tr>\n';
-               tplMovieListItem += '<td class="movieElementLeft">Extended:</td>\n';
-               tplMovieListItem += '<td class="movieElementRight">%(descriptionextended)&nbsp;</td>\n';
-               tplMovieListItem += '</tr>\n';
-               tplMovieListItem += '<tr>\n';
-               tplMovieListItem += '<td class="movieElementLeft">Date/Time:</td>\n';
-               tplMovieListItem += '<td class="movieElementRight">%(time)&nbsp;</td>\n';
-               tplMovieListItem += '</tr>\n';
-               tplMovieListItem += '<tr>\n';
-               tplMovieListItem += '<td class="movieElementLeft">Length:</td>\n';
-               tplMovieListItem += '<td class="movieElementRight">%(length)&nbsp;</td>\n';
-               tplMovieListItem += '</tr>\n';
-               tplMovieListItem += '<tr>\n';
-               tplMovieListItem += '<td class="movieElementLeft">Tags:</td>\n';
-               tplMovieListItem += '<td class="movieElementRight">%(tags)&nbsp;</td>\n';
-               tplMovieListItem += '</tr>\n';
-               tplMovieListItem += '<tr>\n';
-               tplMovieListItem += '<td class="movieElementLeft">Size:</td>\n';
-               tplMovieListItem += '<td class="movieElementRight">%(filesize)&nbsp;</td>\n';
-               tplMovieListItem += '</tr>\n';
-               tplMovieListItem += '</table>\n';
-       tplMovieListItem += '</div>\n';
-       tplMovieListItem += '</tr>\n';
-
-var tplMovieListFooter = "</tbody></table>\n</div>\n";
-
-// TimerList Templates
-var tplTimerListHeader  = '<div class="BodyContentChannellist">\n';
-       tplTimerListHeader += '<table border="0" cellpadding="0" cellspacing="0" class="BodyContentChannellist">\n';
-       tplTimerListHeader += '<thead class="fixedHeader">\n';
-       tplTimerListHeader += '<tr>\n';
-       tplTimerListHeader += '<th colspan="7"><div class="sListHeader">%(page_title)</div>\n';
-       tplTimerListHeader += '<div class="sListSearch">';
-       tplTimerListHeader += '<form onSubmit="loadEPGBySearchString(document.getElementById(\'searchText\').value); return false;">';
-       tplTimerListHeader += '<input type="text" id="searchText" onfocus="this.value=\'\'" value="Search EPG"/>';
-       tplTimerListHeader += '<input style="vertical-align:middle" type="image" src="/webdata/gfx/search.png" alt="search...">';
-       tplTimerListHeader += '</form></div></th>';
-       tplTimerListHeader += '</tr>\n';
-       tplTimerListHeader += '</thead>\n';
-       tplTimerListHeader += '<tbody class="scrollContent" height="100%">\n';
-       tplTimerListHeader += '<tr>';
-       tplTimerListHeader += '<td><div style="color: #00BCBC;" class="tListSName"><b>%(name1)</b><br/>%(name2)</div></td>';
-       tplTimerListHeader += '<td><div style="color: #00BCBC;" class="tListRepeat"><b>%(repeated)</b></div></td>';
-       tplTimerListHeader += '<td><div style="color: #00BCBC;" class="tListDuration"><b>%(duration)</b></div></td>';
-       tplTimerListHeader += '<td><div style="color: #00BCBC;" class="tListBegin"><b>%(start)</b></div></td>';
-       tplTimerListHeader += '<td><div style="color: #00BCBC;" class="tListEnd"><b>%(end)</b></div></td>';
-       tplTimerListHeader += '<td><div style="color: #00BCBC;" class="tListAfter"><b>%(event)</b><br/>%(after_event)</div></td>';
-       tplTimerListHeader += '<td><div style="color: #00BCBC;" class="tListOption"><b>%(options)</b></div></td></tr>\n';
-
-var tplTimerListItem  = '<tr width="99%">\n';
-       tplTimerListItem += '<td><div style="color: #%(color);" class="tListSName" title="%(description), %(descriptionextended)"><b>%(servicename)</b> <br/><br/> %(title)</div></td>\n';
-       tplTimerListItem += '<td><div style="color: #%(color);" class="tListRepeat">%(repeatedReadable)</div></td>\n';
-       tplTimerListItem += '<td><div style="color: #%(color);" class="tListDuration">%(duration)&nbsp;Min</div></td>\n';
-       tplTimerListItem += '<td><div style="color: #%(color);" class="tListBegin">%(beginDate)</div></td>\n';
-       tplTimerListItem += '<td><div style="color: #%(color);" class="tListEnd">%(endDate)</div></td>\n';
-       tplTimerListItem += '<td><div style="color: #%(color);" class="tListAfter"><b>%(justplayReadable)</b> <br/><br/> %(aftereventReadable)</div></td>\n';
-/*     tplTimerListItem += '<td><div style="color: #%(color);" class="tListOption"><a target="_blank" ><img src="/webdata/gfx/trash.gif" title="delete timer entry" border="0" onclick="delTimer(\'%(servicereference)\',\'%(begin)\',\'%(end)\',\'%(servicename)\',\'%(title)\',\'%(description)\',incomingTimerDelResult);"></a>\n';
-       tplTimerListItem += '<a target="_blank" ><img src="/webdata/gfx/%(onOff).png" title="toggle On/Off" border="0" onclick="sendToggleTimerDisable(\'%(justplay)\',\'%(begin)\',\'%(end)\',\'%(repeated)\',\'%(servicereference)\',\'%(title)\',\'%(description)\',\'%(afterevent)\',\'%(disabled)\' );"></a>\n';
-       tplTimerListItem += '<a target="_blank" ><img src="/webdata/gfx/edit.gif" title="edit timer entry" border="0" onclick="loadTimerFormSeconds(\'%(justplay)\',\'%(begin)\',\'%(end)\',\'%(repeated)\',\'%(servicereference)\',\'%(servicename)\',\'%(title)\',\'%(description)\',\'%(afterevent)\',1);"></a></div></td>\n';*/
-       tplTimerListItem += '<td><div style="color: #%(color);" class="tListOption"><a target="_blank" ><img src="/webdata/gfx/trash.gif" title="delete timer entry" border="0" onclick="%(delTimer_FUNCTION);"></a>\n';
-       tplTimerListItem += '<a target="_blank" ><img src="/webdata/gfx/%(onOff).png" title="toggle On/Off" border="0" onclick="%(sendToggleTimerDisable_FUNCTION);"></a>\n';
-       tplTimerListItem += '<a target="_blank" ><img src="/webdata/gfx/edit.gif" title="edit timer entry" border="0" onclick="%(loadTimerFormSeconds_FUNCTION);"></a></div></td>\n';
-       
-       tplTimerListItem += '</tr>\n';
-
-var tplTimerListFooter  = '<tr><td colspan="7"><button onclick="writeTimerListNow()">Write To Memory</button></td></tr>\n';
-       tplTimerListFooter += '<tr><td colspan="7"><button onclick="cleanTimerListNow()">Cleanup</button></td></tr>\n';
-    tplTimerListFooter += '</tbody></table>\n</div>\n';
-
 var tplRecordingFooter   = '<hr><br><table style="text-align: left; width: 100%; height: 178px;" border="0" cellpadding="2" cellspacing="2"><tbody>';
     tplRecordingFooter  += '<tr><td style="vertical-align: top;">';
     tplRecordingFooter  += '<input type="radio" id="recordNowNothing" name="recordNow" value="nothing" checked>';
@@ -192,30 +28,6 @@ var tplRecordingFooter   = '<hr><br><table style="text-align: left; width: 100%;
     tplRecordingFooter  += '</td></tr>';
     tplRecordingFooter  += '</tbody></table>';
 
-// Bouquetlist Template
-var tplBouquetListHeader = '<table id="BouquetList" width="100%" border="0" cellspacing="1" cellpadding="0" border="0">';
-
-var tplBouquetListItem  = '<tr>\n';
-       tplBouquetListItem += '<td><div class="navMenuItem" id="%(servicereference)" onclick="loadBouquet(this.id);">%(bouquetname)</div></td>';
-       tplBouquetListItem += '</tr>\n';
-
-var tplBouquetListFooter = "</table>";
-
-//Volume Template
-var tplVolumePanel  = "<img onclick='volumeUp()' src='/webdata/gfx/arrow_up.png'>";
-       tplVolumePanel += "<img onclick='volumeDown()' src='/webdata/gfx/arrow_down.png'>";
-       tplVolumePanel += "<img id='volume1' onclick='volumeSet(10)' src='/webdata/gfx/led_off.png'>";
-       tplVolumePanel += "<img id='volume2' onclick='volumeSet(20)' src='/webdata/gfx/led_off.png'>";
-       tplVolumePanel += "<img id='volume3' onclick='volumeSet(30)' src='/webdata/gfx/led_off.png'>";
-       tplVolumePanel += "<img id='volume4' onclick='volumeSet(40)' src='/webdata/gfx/led_off.png'>";
-       tplVolumePanel += "<img id='volume5' onclick='volumeSet(50)' src='/webdata/gfx/led_off.png'>";
-       tplVolumePanel += "<img id='volume6' onclick='volumeSet(60)' src='/webdata/gfx/led_off.png'>";
-       tplVolumePanel += "<img id='volume7' onclick='volumeSet(70)' src='/webdata/gfx/led_off.png'>";
-       tplVolumePanel += "<img id='volume8' onclick='volumeSet(80)' src='/webdata/gfx/led_off.png'>";
-       tplVolumePanel += "<img id='volume9' onclick='volumeSet(90)' src='/webdata/gfx/led_off.png'>";
-       tplVolumePanel += "<img id='volume10' onclick='volumeSet(100)' src='/webdata/gfx/led_off.png'>";
-       tplVolumePanel += "<img id='speaker' onclick='volumeMute()' src='/webdata/gfx/speak_on.png'>";
-
 //Signal Template
 var tplSignalPanel  = '<table width="100%" id="SignalPanelTable">';
        tplSignalPanel += '<tr><td style="background-color: #DDDDDD;">dB</td><td style="background-color: #DDDDDD;"><div id="SNRdB">N/A</div></td></tr>';
@@ -225,299 +37,6 @@ var tplSignalPanel  = '<table width="100%" id="SignalPanelTable">';
        tplSignalPanel += '</table>';
 
 
-// Message send
-var tplMessageSendForm  = '<table cellspacing="0" cellpadding="0" class="aboutSection">\n';
-       tplMessageSendForm += '<tr>\n';
-       tplMessageSendForm += '<th class="pageHeader">Send Message</th>\n';
-       tplMessageSendForm += '</tr>\n';
-       tplMessageSendForm += '<tr><td>\n';
-       tplMessageSendForm += '<table style="width: 100%;">\n';
-       tplMessageSendForm += '<tr><td>Text</td><td><input type="text" id="MessageSendFormText" value=""></td></tr>\n';
-       tplMessageSendForm += '<tr><td>Timeout</td><td><input type="text" id="MessageSendFormTimeout" value=""></td></tr>\n';
-       tplMessageSendForm += '<tr><td>Typ</td><td><select id="MessageSendFormType">';
-       tplMessageSendForm += '<option value="1">Info</option>';
-       tplMessageSendForm += '<option value="0">YesNo</option>';
-       tplMessageSendForm += '<option value="2">Warning</option>';
-       tplMessageSendForm += '<option value="3">Error</option>';
-       tplMessageSendForm += '</select></td></tr>\n';
-       tplMessageSendForm += '<tr><td colspan="2"><button onclick="sendMessage()">Send Message</button></td></tr>\n';
-       tplMessageSendForm += "</tr></td></table></form>\n";
-
-var tplPowerStateSendForm  = '<table cellspacing="0" cellpadding="0" class="aboutSection">\n';
-       tplPowerStateSendForm += '<tr>\n';
-       tplPowerStateSendForm += '<th class="pageHeader">Powercontrol</th>\n';
-       tplPowerStateSendForm += '</tr>\n';
-       tplPowerStateSendForm += '<tr><td>\n';
-       tplPowerStateSendForm += '<table style="width: 100%; text-align: center">\n';
-       tplPowerStateSendForm += '<tr><td><center><button onclick="sendRemoteControlRequest(116)">Toggle Standby</button></center></td></tr>\n';
-//     tplPowerStateSendForm += '<tr><td><center><button onclick="sendPowerState(0)">Standby</button></center></td></tr>\n';
-    tplPowerStateSendForm += '<tr><td><center><button onclick="sendPowerState(1)">Deepstandby</button></center></td></tr>\n';
-    tplPowerStateSendForm += '<tr><td><center><button onclick="sendPowerState(2)">Reboot</button></center></td></tr>\n';
-       tplPowerStateSendForm += '<tr><td><center><button onclick="sendPowerState(3)">Restart Enigma2</button></center></td></tr>\n';
-       tplPowerStateSendForm += '</tr></td></table>\n</table>\n';
-
-// Template for the RemoteControl Window
-var tplRemoteControlForm = '<center><input type="checkbox" id="getScreen" name="getScreen" checked>&nbsp;get Screen</center><br>';
-       tplRemoteControlForm += '<map name="remotecontrol">';
-       tplRemoteControlForm += '<area shape="circle" coords="129, 54, 10" nohref onclick="sendRemoteControlRequest(116)" alt="Power">';
-//     tplRemoteControlForm += '<area shape="circle" coords="72, 95, 15" nohref alt="Dream message">';
-       tplRemoteControlForm += '<area shape="circle" coords="130, 95, 15" nohref onclick="openGrabPicture()" alt="TV Screenshot">';
-       tplRemoteControlForm += '<area shape="circle" coords="63, 123, 10" nohref onclick="sendRemoteControlRequest(2)" alt="1">';
-       tplRemoteControlForm += '<area shape="circle" coords="109, 123, 10" nohref onclick="sendRemoteControlRequest(3)" alt="2">';
-       tplRemoteControlForm += '<area shape="circle" coords="153, 123, 10" nohref onclick="sendRemoteControlRequest(4)" alt="3">';
-       tplRemoteControlForm += '<area shape="circle" coords="63, 148, 10" nohref onclick="sendRemoteControlRequest(5)" alt="4">';
-       tplRemoteControlForm += '<area shape="circle" coords="109, 148, 10" nohref onclick="sendRemoteControlRequest(6)" alt="5">';
-       tplRemoteControlForm += '<area shape="circle" coords="153, 148, 10" nohref onclick="sendRemoteControlRequest(7)" alt="6">';
-       tplRemoteControlForm += '<area shape="circle" coords="63, 173, 10" nohref onclick="sendRemoteControlRequest(8)" alt="7">';
-       tplRemoteControlForm += '<area shape="circle" coords="109, 173, 10" nohref onclick="sendRemoteControlRequest(9)" alt="8">';
-       tplRemoteControlForm += '<area shape="circle" coords="153, 173, 10" nohref onclick="sendRemoteControlRequest(10)" alt="9">';
-       tplRemoteControlForm += '<area shape="circle" coords="63, 197, 10" nohref onclick="sendRemoteControlRequest(412)" alt="previous">';
-       tplRemoteControlForm += '<area shape="circle" coords="109, 197, 10" nohref onclick="sendRemoteControlRequest(11)" alt="0">';
-       tplRemoteControlForm += '<area shape="circle" coords="153, 197, 10" nohref onclick="sendRemoteControlRequest(407)" alt="next">';
-       tplRemoteControlForm += '<area shape="circle" coords="54, 243, 15" nohref onclick="sendRemoteControlRequest(115)" alt="volume up">';
-       tplRemoteControlForm += '<area shape="circle" coords="107, 233, 10" nohref onclick="sendRemoteControlRequest(113)" alt="mute">';
-       tplRemoteControlForm += '<area shape="circle" coords="159, 243, 15" nohref onclick="sendRemoteControlRequest(402)" alt="bouquet up">';
-       tplRemoteControlForm += '<area shape="circle" coords="66, 274, 15" nohref onclick="sendRemoteControlRequest(114)" alt="volume down">';
-       tplRemoteControlForm += '<area shape="circle" coords="107, 258, 10" nohref onclick="sendRemoteControlRequest(174)" alt="lame">';
-       tplRemoteControlForm += '<area shape="circle" coords="147, 274, 15" nohref onclick="sendRemoteControlRequest(403)" alt="bouquet down">';
-       tplRemoteControlForm += '<area shape="circle" coords="48, 306, 10" nohref onclick="sendRemoteControlRequest(358)" alt="info">';
-       tplRemoteControlForm += '<area shape="circle" coords="106, 310, 15" nohref onclick="sendRemoteControlRequest(103)" alt="up">';
-       tplRemoteControlForm += '<area shape="circle" coords="167, 306, 10" nohref onclick="sendRemoteControlRequest(139)" alt="menu">';
-       tplRemoteControlForm += '<area shape="circle" coords="70, 343, 15" nohref onclick="sendRemoteControlRequest(105)" alt="left">';
-    tplRemoteControlForm += '<area shape="circle" coords="108, 340, 15" nohref onclick="sendRemoteControlRequest(352)" alt="OK">';
-       tplRemoteControlForm += '<area shape="circle" coords="146, 343, 15" nohref onclick="sendRemoteControlRequest(106)" alt="right">';
-       tplRemoteControlForm += '<area shape="circle" coords="53, 381, 10" nohref onclick="sendRemoteControlRequest(392)" alt="audio">';
-       tplRemoteControlForm += '<area shape="circle" coords="106, 374, 15" nohref onclick="sendRemoteControlRequest(108)" alt="down">';
-       tplRemoteControlForm += '<area shape="circle" coords="162, 381, 10" nohref onclick="sendRemoteControlRequest(393)" alt="video">';
-       tplRemoteControlForm += '<area shape="circle" coords="56, 421, 10" nohref onclick="sendRemoteControlRequest(398)" alt="red">';
-       tplRemoteControlForm += '<area shape="circle" coords="90, 422, 10" nohref onclick="sendRemoteControlRequest(399)" alt="green">';
-       tplRemoteControlForm += '<area shape="circle" coords="123, 422, 10" nohref onclick="sendRemoteControlRequest(400)" alt="yellow">';
-       tplRemoteControlForm += '<area shape="circle" coords="158, 421, 10" nohref onclick="sendRemoteControlRequest(401)" alt="blue">';
-       tplRemoteControlForm += '<area shape="circle" coords="61, 460, 10" nohref onclick="sendRemoteControlRequest(377)" alt="tv">';
-       tplRemoteControlForm += '<area shape="circle" coords="90, 461, 10" nohref onclick="sendRemoteControlRequest(385)" alt="radio">';
-       tplRemoteControlForm += '<area shape="circle" coords="123, 461, 10" nohref onclick="sendRemoteControlRequest(388)" alt="text">';
-       tplRemoteControlForm += '<area shape="circle" coords="153, 460, 10" nohref onclick="sendRemoteControlRequest(138)" alt="help">';
-    tplRemoteControlForm += '</map>';
-       tplRemoteControlForm += '<img src="/webdata/gfx/remotecontrol.jpg" height="607" width="220" border="0)" alt="Remote Control" usemap="#remotecontrol">';
-
-var tplAddTimerForm  = '<table border=0 cellpadding=0 cellspacing=10>';
-       tplAddTimerForm += '<tr><td colspan="3">Action:</td>';
-       tplAddTimerForm += '<td colspan="3">';
-       tplAddTimerForm += '<select name="justplay" id="justplay" size="1">';
-       tplAddTimerForm += '%(justplay)';
-       tplAddTimerForm += '</select></td></tr>';
-       tplAddTimerForm += '<tr><td colspan="3">&nbsp;</td>';
-       tplAddTimerForm += '<td colspan="3">Note: For recurring events start/end day/month are not required.</td></tr>';
-       tplAddTimerForm += '<tr><td colspan="3">Start:</td>';
-       tplAddTimerForm += '<td colspan="3"><select name="syear" size="1" id="syear" onchange="javascript:addTimerFormChangeTime(\'syear\');">%(syear)</select>.';
-       tplAddTimerForm += '<select name="smonth" id="smonth" size="1" onchange="javascript:addTimerFormChangeTime(\'smonth\');">%(smonth)</select>.';
-       tplAddTimerForm += '<select name="sday" id="sday" size="1" onchange="javascript:addTimerFormChangeTime(\'sday\');">%(sday)</select>';
-       tplAddTimerForm += '&nbsp;-&nbsp;<select name="shour" id="shour" size="1" onchange="javascript:addTimerFormChangeTime(\'shour\');">%(shour)</select>';
-       tplAddTimerForm += ':<select name="smin" id="smin" size="1" onchange="javascript:addTimerFormChangeTime(\'smin\');">%(smin)</select></td></tr>';
-       tplAddTimerForm += '<tr><td colspan="3">End:</td>';
-       tplAddTimerForm += '<td colspan="3"><select name="eyear" id="eyear" size="1" onchange="javascript:addTimerFormChangeTime(\'eyear\');">%(eyear)</select>.';
-       tplAddTimerForm += '<select name="emonth" id="emonth" size="1" onchange="javascript:addTimerFormChangeTime(\'emonth\');">%(emonth)</select>.';
-       tplAddTimerForm += '<select name="eday" id="eday" size="1" onchange="javascript:addTimerFormChangeTime(\'eday\');">%(eday)</select>';
-       tplAddTimerForm += '&nbsp;-&nbsp;<select name="ehour" id="ehour" size="1" onchange="javascript:addTimerFormChangeTime(\'ehour\');">%(ehour)</select>';
-       tplAddTimerForm += ':<select name="emin" id="emin" size="1" onchange="javascript:addTimerFormChangeTime(\'emin\');">%(emin)</select></td></tr>';
-       tplAddTimerForm += '<tr><td colspan="3">&nbsp;</td><td colspan="3">Note: For one-time events the "days" field doesn\'t have to be specified.</td></tr>';
-       tplAddTimerForm += '<tr><td colspan="3">Days:</td><td colspan="3">%(repeated)';
-       tplAddTimerForm += '<tr><td colspan="3">Channel:</td><td>';
-       tplAddTimerForm += '<p><input type="radio" id="tvradio" name="tvradio" value="tv" checked onchange="javascript:addTimerFormChangeType();"">TV</p>';
-       tplAddTimerForm += '<p><input type="radio" name="tvradio" value="radio" onchange="javascript:addTimerFormChangeType();">Radio</p><td>';
-       tplAddTimerForm += '<p>Channel:</p>';
-       tplAddTimerForm += '<select name="channel" id="channel" size="1" onchange="timerFormExtendChannellist($(\'channel\').options[$(\'channel\').selectedIndex].value)">%(channel)</select></td></tr>';
-       tplAddTimerForm += '<tr><td colspan="3">Name:</td>';
-       tplAddTimerForm += '<td colspan="3"><input name="name" id="name" type="text" size="100" maxlength="100" style="color: #000000;" value="%(name)"></td></tr>';
-       tplAddTimerForm += '<tr><td colspan="3">Description:</td>';
-       tplAddTimerForm += '<td colspan="3"><input name="descr" id="descr" type="text" size="100" maxlength="100" style="color: #000000;" value="%(description)"></td></tr>';
-       tplAddTimerForm += '<tr><td colspan="3">After event do:</td>';
-       tplAddTimerForm += '<td colspan="3"><select id="after_event" name="after_event" size="1">%(afterEvent)</select></td></tr>';
-       tplAddTimerForm += '<tr>&nbsp;&nbsp;</tr>';
-       tplAddTimerForm += '<tr><td colspan="3">&nbsp;</td><td colspan="3">';
-       tplAddTimerForm += '<input name="deleteOldOnSave" id="deleteOldOnSave" type="hidden" value="%(deleteOldOnSave)">';
-       tplAddTimerForm += '<input name="channelOld" id="channelOld" type="hidden" value="%(channelOld)">';
-       tplAddTimerForm += '<input name="beginOld" id="beginOld" type="hidden" value="%(beginOld)">';
-       tplAddTimerForm += '<input name="endOld" id="endOld" type="hidden" value="%(endOld)">';
-       tplAddTimerForm += '<input name="eventID" id="eventID" type="hidden" value="%(eventID)">';
-       tplAddTimerForm +=      '<button onclick="sendAddTimer();">Add/Save</button></td></tr></table>';
-
-var tplAddTimerFormOptions = '<option value="%(value)" %(selected)>%(txt)</option>';
-
-var tplAddTimerFormCheckbox = '<input type="checkbox" id="%(id)" name="%(name)" value="%(value)" %(checked)>&nbsp;%(txt)&nbsp;&nbsp;';
-
-var tplAbout  = '<table cellspacing="0" cellpadding="0" class="aboutSection">\n';
-       tplAbout += '<tr>\n';
-       tplAbout += '<th colspan="2" class="pageHeader">About</th>\n';
-       tplAbout += '</tr>\n';
-       tplAbout += '<tr>\n';
-       tplAbout += '<td class="aboutSectionLeft">\n';
-       tplAbout += '<table class="fullwidth">\n';
-       tplAbout += '<tr>\n';
-       tplAbout += '<td class="fullwidth">\n';
-       tplAbout += '<table cellspacing="0" class="about">\n';
-       tplAbout += '<tr>\n';
-       tplAbout += '<th colspan="2" class="aboutHeader">Software</th>\n';
-       tplAbout += '</tr>\n';
-       tplAbout += '<tr>\n';
-       tplAbout += '<td class="aboutElementLeft">Dreambox:</td>\n';
-       tplAbout += '<td class="aboutElementRight">%(dreamboxmodel)</td>\n';
-       tplAbout += '</tr>\n';
-       tplAbout += '<tr>\n';
-       tplAbout += '<td class="aboutElementLeft">Enigma Version:</td>\n';
-       tplAbout += '<td class="aboutElementRight">%(enigmaVersion)</td>\n';
-       tplAbout += '</tr>\n';
-       tplAbout += '<tr>\n';
-       tplAbout += '<td class="aboutElementLeft">Frontprozessor Version:</td>\n';
-       tplAbout += '<td class="aboutElementRight">%(fpVersion)</td>\n';
-       tplAbout += '</tr>\n';
-       tplAbout += '<tr>\n';
-       tplAbout += '<td class="aboutElementLeft">Webinterface Version:</td>\n';
-       tplAbout += '<td class="aboutElementRight">%(webifversion)</td>\n';
-       tplAbout += '</tr>\n';
-       tplAbout += '</table>\n';
-       tplAbout += '</td>\n';
-       tplAbout += '</tr>\n';
-       tplAbout += '<tr>\n';
-       tplAbout += '<td class="fullwidth">\n';
-       tplAbout += '<table cellspacing="0" class="about">\n';
-       tplAbout += '<tr>\n';
-       tplAbout += '<th colspan="2" class="aboutHeader">Detected Tuners</th>\n';
-       tplAbout += '</tr>\n';
-       tplAbout += '%(tunerInfo)';
-       tplAbout += '</table>\n';
-       tplAbout += '</td>\n';
-       tplAbout += '</tr>\n';
-       tplAbout += '<tr>\n';
-       tplAbout += '<td class="fullwidth">\n';
-       tplAbout += '<table cellspacing="0" class="about">\n';
-       tplAbout += '<tr>\n';
-       tplAbout += '<th colspan="2" class="aboutHeader">Harddisk</th>\n';
-       tplAbout += '</tr>\n';
-       tplAbout += '<tr>\n';
-       tplAbout += '<td class="aboutElementLeft">Model:</td>\n';
-       tplAbout += '<td class="aboutElementRight">%(hddmodel)</td>\n';
-       tplAbout += '</tr>\n';
-       tplAbout += '<tr>\n';
-       tplAbout += '<td class="aboutElementLeft">Capacity:</td>\n';
-       tplAbout += '<td class="aboutElementRight">%(hddcapacity)</td>\n';
-       tplAbout += '</tr>\n';
-       tplAbout += '<tr>\n';
-       tplAbout += '<td class="aboutElementLeft">Free:</td>\n';
-       tplAbout += '<td class="aboutElementRight">%(hddfree)</td>\n';
-       tplAbout += '</tr>\n';
-       tplAbout += '</table>\n';
-       tplAbout += '</td>\n';
-       tplAbout += '</tr>\n';
-       tplAbout += '<tr>\n';
-       tplAbout += '<td class="fullwidth">\n';
-       tplAbout += '<table cellspacing="0" class="about">\n';
-       tplAbout += '<tr>\n';
-       tplAbout += '<th colspan="2" class="aboutHeader">Network</th>\n';
-       tplAbout += '</tr>\n';
-       tplAbout += '<tr>\n';
-       tplAbout += '<td class="aboutElementLeft">DHCP enabled:</td>\n';
-       tplAbout += '<td class="aboutElementRight">%(lanDHCP)</td>\n';
-       tplAbout += '</tr>\n';
-       tplAbout += '<tr>\n';
-       tplAbout += '<td class="aboutElementLeft">IP:</td>\n';
-       tplAbout += '<td class="aboutElementRight">%(lanIP)</td>\n';
-       tplAbout += '</tr>\n';
-       tplAbout += '<tr>\n';
-       tplAbout += '<td class="aboutElementLeft">Netmask:</td>\n';
-       tplAbout += '<td class="aboutElementRight">%(lanNetmask)</td>\n';
-       tplAbout += '</tr>\n';
-       tplAbout += '<tr>\n';
-       tplAbout += '<td class="aboutElementLeft">Gateway:</td>\n';
-       tplAbout += '<td class="aboutElementRight">%(lanGateway)</td>\n';
-       tplAbout += '</tr>\n';
-       tplAbout += '</table>\n';
-       tplAbout += '</td>\n';
-       tplAbout += '</tr>\n';
-       tplAbout += '</table>\n';
-       tplAbout += '</td>\n';
-       tplAbout += '<td class="aboutSectionRight">\n';
-       tplAbout += '<table class="fullwidth">\n';
-       tplAbout += '<tr>\n';
-       tplAbout += '<td class="fullwidth">\n';
-       tplAbout += '<table cellspacing="0" class="about">\n';
-       tplAbout += '<tr>\n';
-       tplAbout += '<th colspan="2" class="aboutHeader">Serviceinfo</th>\n';
-       tplAbout += '</tr>\n';
-       tplAbout += '<tr>\n';
-       tplAbout += '<td class="aboutElementLeft">Name:</td>\n';
-       tplAbout += '<td class="aboutElementRight">%(serviceName)</td>\n';
-       tplAbout += '</tr>\n';
-       tplAbout += '<tr>\n';
-       tplAbout += '<td class="aboutElementLeft">Provider:</td>\n';
-       tplAbout += '<td class="aboutElementRight">%(serviceProvider)</td>\n';
-       tplAbout += '</tr>\n';
-       tplAbout += '<tr>\n';
-       tplAbout += '<td class="aboutElementLeft">Videoformat:</td>\n';
-       tplAbout += '<td class="aboutElementRight">%(serviceAspect)</td>\n';
-       tplAbout += '</tr>\n';
-       tplAbout += '<tr>\n';
-       tplAbout += '<td class="aboutElementLeft">Videosize:</td>\n';
-       tplAbout += '<td class="aboutElementRight">%(serviceVideosize)</td>\n';
-       tplAbout += '</tr>\n';
-       tplAbout += '<tr>\n';
-       tplAbout += '<td class="aboutElementLeft">Namespace:</td>\n';
-       tplAbout += '<td class="aboutElementRight">%(serviceNamespace)</td>\n';
-       tplAbout += '</tr>\n';
-       tplAbout += '</table>\n';
-       tplAbout += '</td>\n';
-       tplAbout += '</tr>\n';
-       tplAbout += '<tr>\n';
-       tplAbout += '<td class="fullwidth">\n';
-       tplAbout += '<table cellspacing="0" class="about">\n';
-       tplAbout += '<tr>\n';
-       tplAbout += '<th colspan="2" class="aboutHeader">PIDs</th>\n';
-       tplAbout += '</tr>\n';
-       tplAbout += '<tr>\n';
-       tplAbout += '<td class="aboutElementLeft">VideoPID:</td>\n';
-       tplAbout += '<td class="aboutElementRight">%(vPIDh) (%(vPID)d)</td>\n';
-       tplAbout += '</tr>\n';
-       tplAbout += '<tr>\n';
-       tplAbout += '<td class="aboutElementLeft">AudioPID:</td>\n';
-       tplAbout += '<td class="aboutElementRight">%(aPIDh) (%(aPID)d)</td>\n';
-       tplAbout += '</tr>\n';
-       tplAbout += '<tr>\n';
-       tplAbout += '<td class="aboutElementLeft">PCRPID:</td>\n';
-       tplAbout += '<td class="aboutElementRight">%(pcrPIDh) (%(pcrPID)d)</td>\n';
-       tplAbout += '</tr>\n';
-       tplAbout += '<tr>\n';
-       tplAbout += '<td class="aboutElementLeft">PMTPID:</td>\n';
-       tplAbout += '<td class="aboutElementRight">%(pmtPIDh) (%(pmtPID)d)</td>\n';
-       tplAbout += '</tr>\n';
-       tplAbout += '<tr>\n';
-       tplAbout += '<td class="aboutElementLeft">TXTPID:</td>\n';
-       tplAbout += '<td class="aboutElementRight">%(txtPIDh) (%(txtPID)d)</td>\n';
-       tplAbout += '</tr>\n';
-       tplAbout += '<tr>\n';
-       tplAbout += '<td class="aboutElementLeft">TSID:</td>\n';
-       tplAbout += '<td class="aboutElementRight">%(tsIDh) (%(tsID)d)</td>\n';
-       tplAbout += '</tr>\n';
-       tplAbout += '<tr>\n';
-       tplAbout += '<td class="aboutElementLeft">ONID:</td>\n';
-       tplAbout += '<td class="aboutElementRight">%(onIDh) (%(onID)d)</td>\n';
-       tplAbout += '</tr>\n';
-       tplAbout += '<tr>\n';
-       tplAbout += '<td class="aboutElementLeft">SID:</td>\n';
-       tplAbout += '<td class="aboutElementRight">%(sidh) (%(sid)d)</td>\n';
-       tplAbout += '</tr>\n';
-       tplAbout += '</table>\n';
-       tplAbout += '</td>\n';
-       tplAbout += '</tr>\n';
-       tplAbout += '</table>\n';
-       tplAbout += '</td>\n';
-       tplAbout += '</tr>\n';
-       tplAbout += '</table>\n';
-
-var tplAboutTuner  = '<tr>\n';
-       tplAboutTuner += '<td class="aboutElementLeft">%(name):</td>\n';
-       tplAboutTuner += '<td class="aboutElementRight">%(type)</td>\n';
-       tplAboutTuner += '</tr>\n';
-
 var tplExtraHiddenFunctions  = '<ul style="list-style-type:disc">';
        tplExtraHiddenFunctions += '<li><div onclick="restartTwisted()">Restart Twisted</div></li>';
        tplExtraHiddenFunctions += '<li><div onclick="clearInterval(UpdateStreamReaderPollTimer);">Stop Time/Signal/Current-Channel -Updates</div></li>';
@@ -525,8 +44,6 @@ var tplExtraHiddenFunctions  = '<ul style="list-style-type:disc">';
        tplExtraHiddenFunctions += '<li><div onclick="startDebugWindow();">Start Debug-Window</div></li>';
        tplExtraHiddenFunctions += '</ul>'
 
-var tplRCGrab  = '<IMG id="grabPageIMG" src=""/ height="400" alt="loading image">';
-
 var tplMediaPlayerHeader  = '<div class="BodyContentChannellist">\n<table border="0" cellpadding="0" cellspacing="0" class="BodyContentChannellist">\n';
        tplMediaPlayerHeader += '<thead class="fixedHeader">\n';
        tplMediaPlayerHeader += '<tr>\n';
@@ -559,44 +76,6 @@ var tplMediaPlayerFooterPlaylist  = '<tr><td colspan="7"><button onclick="writeP
 var tplMediaPlayerFooter = "</tbody></table>\n";
 
 
-//Note Template
-var tplNotesListHeader  = '<table cellspacing="0" cellpadding="0" class="aboutSection">\n';
-       tplNotesListHeader += '<tr>\n';
-       tplNotesListHeader += '<th class="pageHeader">Notes</th>\n';
-       tplNotesListHeader += '<tbody class="scrollContent">\n';
-       tplNotesListHeader += '<button onclick="createNote()">create new Note</button>\n';
-
-var    tplNotesListFooter  = '</tbody></table>\n';
-
-var tplNotesListItem  = '<tr><td onclick="showNote(\'%(name)\');">%(name)</td><td>%(ctime)</td><td>%(size)</td></tr>';
-
-var tplNote  = '<form id="note_%(name)"><input type="hidden" id="note_%(name)_name" value="%(name)">';
-       tplNote += '<table width="100%">';
-       tplNote += '<tr style="background-color: #DDDDDD;">';
-       tplNote += '<td>Name:</td>';
-       tplNote += '<td><input type="text" value="%(name)" id="note_%(name)_namenew" size="30"></td>';
-       tplNote += '</tr>';
-       tplNote += '<tr style="background-color: #DDDDDD;">';
-       tplNote += '<td>Creationdate:</td>';
-       tplNote += '<td id="note_%(name)_ctime">%(ctime)</td>';
-       tplNote += '</tr>';
-       tplNote += '<tr style="background-color: #DDDDDD;">';
-       tplNote += '<td>Modified</td>';
-       tplNote += '<td id="note_%(name)_mtime">%(mtime)</td>';
-       tplNote += '</tr>';
-       tplNote += '<tr style="background-color: #DDDDDD;">';
-       tplNote += '<td>Size:</td>';
-       tplNote += '<td>%(size)</td>';
-       tplNote += '</tr>';
-       tplNote += '<tr style="background-color: #DDDDDD;">';
-       tplNote += '<td colspan="2"><textarea cols="50" rows="10"  id="note_%(name)_content">%(content)</textarea></td>';
-       tplNote += '</tr>';
-       tplNote += '<tr style="background-color: #DDDDDD;">';
-       tplNote += '<td colspan="2"><input type="button"  onclick="saveNote(\'note_%(name)\');" value="save"><input type="button"  onclick="$(\'note_%(name)\').reset();" value="reset"></td>';
-       tplNote += '</tr>';
-       tplNote += '</table></form>';
-
-
 var tplFileBrowserHeader  = '<div class="BodyContentChannellist">\n<table border="0" cellpadding="0" cellspacing="0" class="BodyContentChannellist">\n';
     tplFileBrowserHeader += '<thead class="fixedHeader">\n';
     tplFileBrowserHeader += '<tr>\n';
@@ -625,41 +104,3 @@ var tplFileBrowserFooter  = '</tbody></table>\n';
        tplFileBrowserFooter += '<input type="hidden" id="path" value="%(root)" name="path">';
        tplFileBrowserFooter += '<input name="file" type="file">';
        tplFileBrowserFooter += '<input type="image" style="vertical-align:middle" src="/webdata/gfx/save.png" alt="upload">';
-
-var tplAddAutoTimerForm  = '<table border=0 cellpadding=0 cellspacing=10>';
-       tplAddAutoTimerForm += '<tr><td colspan="3">Action:</td>';
-       tplAddAutoTimerForm += '<td colspan="3">';
-       tplAddAutoTimerForm += '<select name="justplay" id="justplay" size="1">';
-       tplAddAutoTimerForm += '%(justplay)';
-       tplAddAutoTimerForm += '</select></td></tr>';
-       tplAddAutoTimerForm += '<tr><td colspan="3">Start:</td>';
-       tplAddAutoTimerForm += '<td colspan="3"><select name="shour" id="shour" size="1" onchange="javascript:addTimerFormChangeTime(\'shour\');">%(shour)</select>';
-       tplAddAutoTimerForm += ':<select name="smin" id="smin" size="1" onchange="javascript:addTimerFormChangeTime(\'smin\');">%(smin)</select></td></tr>';
-       tplAddAutoTimerForm += '<tr><td colspan="3">End:</td>';
-       tplAddAutoTimerForm += '<td colspan="3"><select name="ehour" id="ehour" size="1" onchange="javascript:addTimerFormChangeTime(\'ehour\');">%(ehour)</select>';
-       tplAddAutoTimerForm += ':<select name="emin" id="emin" size="1" onchange="javascript:addTimerFormChangeTime(\'emin\');">%(emin)</select></td></tr>';
-       tplAddAutoTimerForm += '<tr><td colspan="3">Repeat times:</td><td colspan="3"><select name="repeated" id="repeated" size="1">%(repeated)</select>';
-       tplAddAutoTimerForm += '<tr><td colspan="3">Name:</td>';
-       tplAddAutoTimerForm += '<td colspan="3"><input name="name" id="name" type="text" size="100" maxlength="100" style="color: #000000;" value="%(name)"></td></tr>';
-       tplAddAutoTimerForm += '<tr><td colspan="3">Description:</td>';
-       tplAddAutoTimerForm += '<td colspan="3"><input name="descr" id="descr" type="text" size="100" maxlength="100" style="color: #000000;" value="%(description)"></td></tr>';
-
-       tplAddAutoTimerForm += '<tr><td colspan="3">Services:</td>';
-       tplAddAutoTimerForm += '<td colspan="3"><input name="services" id="services" type="text" size="95" style="color: #000000;" value="%(services)">';
-       tplAddAutoTimerForm += '&nbsp;<img src="/webdata/gfx/edit.gif" title="edit allowed services" border="0" onclick="editAutoTimerServices(%(timers_element));"></td></tr>';
-
-       tplAddAutoTimerForm += '<tr><td colspan="3">Excludes:</td>';
-       tplAddAutoTimerForm += '<td colspan="3"><input name="excludes" id="excludes" type="text" size="95" style="color: #000000;" value="%(excludes)">';
-       tplAddAutoTimerForm += '&nbsp;<img src="/webdata/gfx/edit.gif" title="edit excludes" border="0" onclick="editAutoTimerExcludes(%(timers_element));"></td></tr>';
-       
-       tplAddAutoTimerForm += '<tr><td colspan="3">Includes:</td>';
-       tplAddAutoTimerForm += '<td colspan="3"><input name="includes" id="includes" type="text" size="95" style="color: #000000;" value="%(includes)">';
-       tplAddAutoTimerForm += '&nbsp;<img src="/webdata/gfx/edit.gif" title="edit includes" border="0" onclick="editAutoTimerIncludes(%(timers_element));"></td></tr>';
-
-       tplAddAutoTimerForm += '<tr><td colspan="3">After event do:</td>';
-       tplAddAutoTimerForm += '<td colspan="3"><select id="after_event" name="after_event" size="1">%(afterEvent)</select></td></tr>';
-       tplAddAutoTimerForm += '<tr>&nbsp;&nbsp;</tr>';
-       tplAddAutoTimerForm += '<tr><td colspan="3">&nbsp;</td><td colspan="3">';
-       tplAddAutoTimerForm += '<input name="deleteOldOnSave" id="deleteOldOnSave" type="hidden" value="%(deleteOldOnSave)">';
-       tplAddAutoTimerForm += '<input name="timers_element" id="timers_element" type="hidden" value="%(timers_element)">';
-       tplAddAutoTimerForm +=  '<button onclick="sendAddAutoTimer();">Add/Save</button></td></tr></table>';
index 98f78a6..6269e34 100644 (file)
@@ -1,36 +1,30 @@
 // $Header$
 
 // TimerEdit variables:
-var addTimerEditFormObject = new Object();
-addTimerEditFormObject["TVListFilled"] = 0;
-addTimerEditFormObject["RadioListFilled"] = 0;
-addTimerEditFormObject["deleteOldOnSave"] = 0;
-addTimerEditFormObject["eventID"] = 0;
-days = [];
-days[0] = 'mo';
-days[1] = 'tu';
-days[2] = 'we';
-days[3] = 'th';
-days[4] = 'fr';
-days[5] = 'sa';
-days[6] = 'su';
+var addTimerEditFormArray = [];
+addTimerEditFormArray.TVListFilled = 0;
+addTimerEditFormArray.RadioListFilled = 0;
+addTimerEditFormArray.deleteOldOnSave = 0;
+addTimerEditFormArray.eventID = 0;
+
+days = ['mo', 'tu', 'we', 'th', 'fr', 'sa', 'su'];
 
 // Timer
 function addTimerByID(sRef,eventID,justplay){
        if(parentPin(sRef)) {
-               debug("addTimerByID\neventID: "+eventID);
+               debug("[addTimerByID] eventID: "+eventID);
                doRequest(url_timeraddbyeventid+"?sRef="+sRef+"&eventid="+eventID+"&justplay="+justplay, incomingTimerAddResult, false);        
        }
 }
 function incomingTimerAddResult(request){
-       debug("onTimerAdded");
+       debug("[incomingTimerAddResult] called");
        if(request.readyState == 4){
                var addresult = new SimpleXMLResult(getXML(request));
                if(addresult.getState()){
                        //timer was add
                        loadTimerList();
                }else{
-                       messageBox("Timer Error","your Timer could not be added!\nReason: "+addresult.getStateText());
+                       messageBox("Timer Error","Your Timer could not be added!\nReason: "+addresult.getStateText());
                }
        }               
 }
@@ -41,36 +35,33 @@ function loadTimerList(){
 function incomingTimerList(request){
        if(request.readyState == 4){
                var timers = new TimerList(getXML(request)).getArray();
-               debug("have "+timers.length+" timer");
-               var ns_tplTimerListHeader = {
-                       'page_title': 'Timerlist',
-                       'name1': 'Channel',
-                       'name2': 'Name',
-                       'repeated': 'Repeated',
-                       'duration': 'Time running',
-                       'start': 'Start time',
-                       'end': 'End time',
-                       'event': 'Event',
-                       'after_event': 'After event',
-                       'options': 'Options'                    
-               };
-               listerHtml = RND(tplTimerListHeader, ns_tplTimerListHeader);
-               var aftereventReadable = new Array ('Nothing', 'Standby', 'Deepstandby/Shutdown');
-               var justplayReadable = new Array('record', 'zap');
-               for ( var i = 0; i <timers.length; i++){
+               debug("[incomingTimerList] Got " + timers.length + " timers");
+
+               var aftereventReadable = ['Nothing', 'Standby', 'Deepstandby/Shutdown'];
+               var justplayReadable = ['record', 'zap'];
+               
+               var namespace = [];
+               var cssclass = "even";
+               
+               for ( var i = 0; i < timers.length; i++){
                        var timer = timers[i];
                        var beginDate = new Date(Number(timer.getTimeBegin())*1000);
                        var endDate = new Date(Number(timer.getTimeEnd())*1000);
-                       var namespace = {       
+                       
+                       var enDis = timer.getToggleDisabledIMG() == "on" ? "Disable Timer" : "Enable Timer";
+                       
+                       cssclass = cssclass == 'even' ? 'odd' : 'even';
+                       
+                       namespace[i] = {        
                                'servicereference': timer.getServiceReference(),
                                'servicename': quotes2html(timer.getServiceName()),
                                'title': quotes2html(timer.getName()),
                                'description': quotes2html(timer.getDescription()),
                                'descriptionextended': quotes2html(timer.getDescriptionExtended()),
                                'begin': timer.getTimeBegin(),
-                               'beginDate': beginDate.toLocaleString(),
+                               'beginDate': dateToString(beginDate),
                                'end': timer.getTimeEnd(),
-                               'endDate': endDate.toLocaleString(),
+                               'endDate': dateToString(endDate),
                                'state': timer.getState(),
                                'duration': Math.ceil((timer.getDuration()/60)),
                                'repeated': timer.getRepeated(),
@@ -81,37 +72,22 @@ function incomingTimerList(request){
                                'aftereventReadable': aftereventReadable[Number(timer.getAfterevent())],
                                'disabled': timer.getDisabled(),
                                'onOff': timer.getToggleDisabledIMG(),
-                               'color': timer.getColor(),
-                               'delTimer_FUNCTION': "delTimer(\'"+timer.getServiceReference()+"\',\'"+timer.getTimeBegin()
-                                       +"\',\'"+timer.getTimeEnd()+"\',\'"+quotes2html(timer.getServiceName())
-                                       +"\',\'"+quotes2html(timer.getName())+"\',\'"+quotes2html(timer.getDescription())
-                                       +"\',incomingTimerDelResult)",
-                               'sendToggleTimerDisable_FUNCTION': "sendToggleTimerDisable(\'"+timer.getJustplay()+"\',\'"
-                                       +timer.getTimeBegin()+"\',\'"+timer.getTimeEnd()+"\',\'"+timer.getRepeated()
-                                       +"\',\'"+timer.getServiceReference()+"\',\'"+quotes2html(timer.getName())
-                                       +"\',\'"+quotes2html(timer.getDescription())+"\',\'"+timer.getAfterevent()
-                                       +"\',\'"+timer.getDisabled()+"\')",
-                               'loadTimerFormSeconds_FUNCTION': "loadTimerFormSeconds(\'"+timer.getJustplay()+"\',\'"
-                                       +timer.getTimeBegin()+"\',\'"+timer.getTimeEnd()+"\',\'"+timer.getRepeated()
-                                       +"\',\'"+timer.getServiceReference()+"\',\'"+quotes2html(timer.getServiceName())
-                                       +"\',\'"+quotes2html(timer.getName())
-                                       +"\',\'"+quotes2html(timer.getDescription())+"\',\'"+timer.getAfterevent()+"\',1)"
-                       };
-                       listerHtml += RND(tplTimerListItem, namespace);
+                               'enDis': timer.getToggleDisabledText(),
+                               'cssclass': cssclass
+                       };                      
                }
-               listerHtml += tplTimerListFooter;
-               $('BodyContent').innerHTML = listerHtml;
-               setBodyMainContent('BodyContent');
+               data = { timer : namespace };
+               processTpl('tplTimerList', data, 'contentMain');
        }
 }
 function repeatedReadable(num) {
        num = Number(num);
-       if(num == 0) {
+       if(num === 0) {
                return "One Time";
        }
        
        var html = "";
-       var Repeated = new Object();
+       var Repeated = [];
        Repeated["Mo-Su"] =127;
        Repeated["Su"] =    64;
        Repeated["Sa"] =    32;
@@ -123,14 +99,14 @@ function repeatedReadable(num) {
        Repeated["Mo"] =     1;
        
        for(rep in Repeated) {
-               if(rep.toString() != "extend") {
+               if(rep.toString() != 'extend') {
                        var check = Number(Repeated[rep]);
                        if(check <= num) {
                                num -= check;
-                               if(html == "") {
+                               if(html === '') {
                                        html += rep.toString();
                                } else {
-                                       html = rep.toString()+","+html;
+                                       html = rep.toString()+','+html;
                                }
                        }
                }
@@ -139,7 +115,7 @@ function repeatedReadable(num) {
 }
 
 function colorTimerListEntry (state) {
-       if (state == 0) {
+       if (state === 0) {
                return "000000";
        } else if(state == 1) {
                return "00BCBC";
@@ -150,130 +126,128 @@ function colorTimerListEntry (state) {
        }
 }
 function delTimer(sRef,begin,end,servicename,title,description,readyFunction){
-       debug("delTimer: sRef("+sRef+"),begin("+begin+"),end("+end+"),servicename("+servicename+"),title("+title+"),description("+description+")");
-       Dialog.confirm(
-               "Selected timer:<br>"
-               +"Channel: "+servicename+"<br>"
-               +"Title: "+title+"<br>"
-               +"Description: "+description+"<br>"
-               +"Are you sure that you want to delete the Timer?",
-                {windowParameters: {width:300, className: windowStyle},
-                       okLabel: "delete",
-                       buttonClass: "myButtonClass",
-                       cancel: function(win) {debug("delTimer cancel confirm panel")},
-                       ok: function(win) { 
-                                                           debug("delTimer ok confirm panel"); 
-                                                           doRequest(url_timerdelete+"?sRef="+sRef+"&begin="+begin+"&end="+end, readyFunction, false);
-                                                           return true;
-                                                         }
-                       }
-       );
+       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("onTimerDeleted");
+       debug("[incomingTimerDelResult] called");
        if(request.readyState == 4){
                var delresult = new SimpleXMLResult(getXML(request));
-               debug("Lade liste");
+               debug("[incomingTimerDelResult] Loading List");
                loadTimerList();
        }               
 }
 function loadTimerFormNow() {
        var now = new Date();
-       addTimerEditFormObject["syear"] = now.getFullYear();
-       addTimerEditFormObject["smonth"] = now.getMonth() + 1;
-       addTimerEditFormObject["sday"] = now.getDate();
-       addTimerEditFormObject["shour"] = now.getHours();
-       addTimerEditFormObject["smin"] = now.getMinutes();
+       addTimerEditFormArray.syear = now.getFullYear();
+       addTimerEditFormArray.smonth = now.getMonth() + 1;
+       addTimerEditFormArray.sday = now.getDate();
+       addTimerEditFormArray.shour = now.getHours();
+       addTimerEditFormArray.smin = now.getMinutes();
 
        var     plusTwoHours = new Date(now.getTime() + ((120 *60)*1000) );
-       addTimerEditFormObject["eyear"] = plusTwoHours.getFullYear();
-       addTimerEditFormObject["emonth"] = plusTwoHours.getMonth() + 1;
-       addTimerEditFormObject["eday"] = plusTwoHours.getDate();
-       addTimerEditFormObject["ehour"] = plusTwoHours.getHours();
-       addTimerEditFormObject["emin"] = plusTwoHours.getMinutes();
+       addTimerEditFormArray.eyear = plusTwoHours.getFullYear();
+       addTimerEditFormArray.emonth = plusTwoHours.getMonth() + 1;
+       addTimerEditFormArray.eday = plusTwoHours.getDate();
+       addTimerEditFormArray.ehour = plusTwoHours.getHours();
+       addTimerEditFormArray.emin = plusTwoHours.getMinutes();
                
-       addTimerEditFormObject["justplay"] = "record";
-       addTimerEditFormObject["channel"] = "";
-       addTimerEditFormObject["channelName"] = "";
-       addTimerEditFormObject["channelSort"] = "tv";
-       addTimerEditFormObject["name"] = "";
-       addTimerEditFormObject["description"] = "";
-       addTimerEditFormObject["repeated"] = 0;
-       addTimerEditFormObject["afterEvent"] = "0";
-       addTimerEditFormObject["deleteOldOnSave"] = 0;
+       addTimerEditFormArray.justplay = "record";
+       addTimerEditFormArray.channel = "";
+       addTimerEditFormArray.channelName = "";
+       addTimerEditFormArray.channelSort = "tv";
+       addTimerEditFormArray.name = "";
+       addTimerEditFormArray.description = "";
+       addTimerEditFormArray.repeated = 0;
+       addTimerEditFormArray.afterEvent = "0";
+       addTimerEditFormArray.deleteOldOnSave = 0;
        
-       addTimerEditFormObject["beginOld"] = 0;
-       addTimerEditFormObject["endOld"] = 0;
+       addTimerEditFormArray.beginOld = 0;
+       addTimerEditFormArray.endOld = 0;
        
        
-       debug("loadTimerFormNow 2");
+       debug("[loadTimerFormNow] done");
        loadTimerFormChannels();
 }
 
-function loadTimerFormSeconds(justplay,begin,end,repeated,channel,channelName,name,description,afterEvent,deleteOldOnSave,eit) {
-       debug('justplay:'+justplay+' begin:'+begin+' end:'+end+' repeated:'+repeated+' channel:'+channel+' name:'+name+' description:'+description+' afterEvent:'+afterEvent+' deleteOldOnSave:'+deleteOldOnSave);
+function loadTimerFormSeconds(justplay, begin, end, repeated, channel, channelName, name, description, afterEvent, deleteOldOnSave, eit) {
+       debug('[loadTimerFormSeconds] justplay: ' + justplay + ',begin: ' + begin + ',end: ' + end + ',repeated: ' + repeated + ',channel: ' + channel + ',name: ' + name +',description: ' + description + ',afterEvent: ' + afterEvent + ',deleteOldOnSave: ' + deleteOldOnSave);
        var start = new Date(Number(begin)*1000);
-       addTimerEditFormObject["syear"] = start.getFullYear();
-       addTimerEditFormObject["smonth"] = start.getMonth() + 1;
-       addTimerEditFormObject["sday"] = start.getDate();
-       addTimerEditFormObject["shour"] = start.getHours();
-       addTimerEditFormObject["smin"] = start.getMinutes();
+       addTimerEditFormArray.syear = start.getFullYear();
+       addTimerEditFormArray.smonth = start.getMonth() + 1;
+       addTimerEditFormArray.sday = start.getDate();
+       addTimerEditFormArray.shour = start.getHours();
+       addTimerEditFormArray.smin = start.getMinutes();
        
        var     stopp = new Date(Number(end)*1000);
-       addTimerEditFormObject["eyear"] = stopp.getFullYear();
-       addTimerEditFormObject["emonth"] = stopp.getMonth() + 1;
-       addTimerEditFormObject["eday"] = stopp.getDate();
-       addTimerEditFormObject["ehour"] = stopp.getHours();
-       addTimerEditFormObject["emin"] = stopp.getMinutes();
+       addTimerEditFormArray.eyear = stopp.getFullYear();
+       addTimerEditFormArray.emonth = stopp.getMonth() + 1;
+       addTimerEditFormArray.eday = stopp.getDate();
+       addTimerEditFormArray.ehour = stopp.getHours();
+       addTimerEditFormArray.emin = stopp.getMinutes();
        
-       addTimerEditFormObject["justplay"] = String(justplay);
-       addTimerEditFormObject["channel"] = decodeURIComponent(String(channel));
-       addTimerEditFormObject["channelName"] = String(channelName);
-       addTimerEditFormObject["channelSort"] = "";
-       addTimerEditFormObject["name"] = String(name);
-       addTimerEditFormObject["description"] = String(description);
-       addTimerEditFormObject["repeated"] = Number(repeated);
-       addTimerEditFormObject["afterEvent"] = Number(afterEvent);
+       addTimerEditFormArray.justplay = String(justplay);
+       addTimerEditFormArray.channel = decodeURIComponent(String(channel));
+       addTimerEditFormArray.channelName = String(channelName);
+       addTimerEditFormArray.channelSort = "";
+       addTimerEditFormArray.name = String(name);
+       addTimerEditFormArray.description = String(description);
+       addTimerEditFormArray.repeated = Number(repeated);
+       addTimerEditFormArray.afterEvent = Number(afterEvent);
        
-       debug(justplay+"|"+begin+"|"+end+"|"+repeated+"|"+channel+"|"+name+"|"+description+"|"+afterEvent);
+       debug("[loadTimerFormSeconds]" + justplay + "|" + begin + "|" + end + "|" + repeated + "|"+channel+"|"+name+"|"+description+"|"+afterEvent);
 
-       addTimerEditFormObject["deleteOldOnSave"] = Number(deleteOldOnSave);
-       addTimerEditFormObject["beginOld"] = Number(begin);
-       addTimerEditFormObject["endOld"] = Number(end);
+       addTimerEditFormArray.deleteOldOnSave = Number(deleteOldOnSave);
+       addTimerEditFormArray.beginOld = Number(begin);
+       addTimerEditFormArray.endOld = Number(end);
        
-       addTimerEditFormObject["eventID"] = Number(eit);
+       addTimerEditFormArray.eventID = Number(eit);
        
        loadTimerFormChannels();
 }
 
 // startin to load for TV
 function loadTimerFormChannels() {
-       if(addTimerEditFormObject["TVListFilled"] == 1 && addTimerEditFormObject["RadioListFilled"] == 1) {
+       if(addTimerEditFormArray.TVListFilled === 1 && addTimerEditFormArray.RadioListFilled === 1) {
                loadTimerForm();
-       } else if(addTimerEditFormObject["TVListFilled"] == 1 && addTimerEditFormObject["RadioListFilled"] == 0) {
+       } else if(addTimerEditFormArray.TVListFilled === 1 && addTimerEditFormArray.RadioListFilled === 0) {
                addTimerListFormatTV();
        } else {
-               var favorites = '1%3A7%3A1%3A0%3A0%3A0%3A0%3A0%3A0%3A0%3AFROM%20BOUQUET%20%22userbouquet.favourites.tv%22%20ORDER%20BY%20bouquet'
+               var favorites = '1%3A7%3A1%3A0%3A0%3A0%3A0%3A0%3A0%3A0%3AFROM%20BOUQUET%20%22userbouquet.favourites.tv%22%20ORDER%20BY%20bouquet';
                doRequest(url_getServices+favorites, addTimerListFormatTV, false);
        }
 }
 
 function addTimerListFormatTV(request) {
-       if(addTimerEditFormObject["RadioListFilled"] == 0) {
+       if(addTimerEditFormArray.RadioListFilled === 0) {
                if(request.readyState == 4){
                        var services = new ServiceList(getXML(request)).getArray();
-                       var tv = new Object();
+                       var tv = {};
                        for ( var i = 0; i < services.length ; i++){
                                var reference = services[i];
                                tv[reference.servicereference] = reference.servicename;
                        }
-                       addTimerEditFormObject["TVListFilled"] = 1;
-                       addTimerEditFormObject["TVList"] = tv;
+                       addTimerEditFormArray.TVListFilled = 1;
+                       addTimerEditFormArray.TVList = tv;
                }
        }
-       if(addTimerEditFormObject["RadioListFilled"] == 1) {
-               loadTimerForm()
+       if(addTimerEditFormArray.RadioListFilled == 1) {
+               loadTimerForm();
        } else {
                var favorites = '1%3A7%3A1%3A0%3A0%3A0%3A0%3A0%3A0%3A0%3AFROM%20BOUQUET%20%22userbouquet.favourites.radio%22%20ORDER%20BY%20bouquet';
                doRequest(url_getServices+favorites, addTimerListFormatRadio, false);
@@ -282,24 +256,24 @@ function addTimerListFormatTV(request) {
 function addTimerListFormatRadio(request) {
        if(request.readyState == 4){
                var services = new ServiceList(getXML(request)).getArray();
-               var radio = new Object();
+               var radio = {};
                for ( var i = 0; i < services.length ; i++){
                        var reference = services[i];
                        radio[reference.servicereference] = reference.servicename;
                }
-               addTimerEditFormObject["RadioListFilled"] = 1;
-               addTimerEditFormObject["RadioList"] = radio;
+               addTimerEditFormArray.RadioListFilled = 1;
+               addTimerEditFormArray.RadioList = radio;
        }
        loadTimerForm();
 }
 
 function loadTimerForm(){
 
-       var Action = new Object();
+       var Action = {};
        Action["0"] = "Record";
        Action["1"] = "Zap";
        
-       var Repeated = new Object();
+       var Repeated = [];
        Repeated["1"] =  "mo";
        Repeated["2"] = "tu";
        Repeated["4"] =  "we";
@@ -308,182 +282,188 @@ function loadTimerForm(){
        Repeated["32"] = "sa";
        Repeated["64"] = "su";
        Repeated["31"] = "mf";
-       Repeated["127"] ="ms";
+       Repeated["127"] = "ms";
        
-       var AfterEvent = new Object();
+       var AfterEvent = {};
        AfterEvent["0"] = "Nothing";
        AfterEvent["1"] = "Standby";
        AfterEvent["2"] = "Deepstandby/Shutdown";
        
-       addTimerEditFormObject["name"] = (typeof(addTimerEditFormObject["name"]) != "undefined") ? addTimerEditFormObject["name"] : "";
-       addTimerEditFormObject["name"] = (addTimerEditFormObject["name"] == "") ? " " : addTimerEditFormObject["name"];
+       addTimerEditFormArray.name = (typeof(addTimerEditFormArray.name) != 'undefined') ? addTimerEditFormArray.name : '';
+       addTimerEditFormArray.name = (addTimerEditFormArray.name === '') ? ' ' : addTimerEditFormArray.name;
 
-       addTimerEditFormObject["description"] = (typeof(addTimerEditFormObject["description"]) != "undefined") ? addTimerEditFormObject["description"] : "";
-       addTimerEditFormObject["description"] = (addTimerEditFormObject["description"] == "") ? " " : addTimerEditFormObject["description"];
+       addTimerEditFormArray.description = (typeof(addTimerEditFormArray.description) != 'undefined') ? addTimerEditFormArray.description : '';
+       addTimerEditFormArray.description = (addTimerEditFormArray.description === '') ? ' ' : addTimerEditFormArray.description;
 
-       var channelObject = addTimerEditFormObject["TVList"];
-       if(     addTimerEditFormObject["channelSort"] == "tv") {
+       var channelObject = addTimerEditFormArray.TVList;
+       if(     addTimerEditFormArray.channelSort === 'tv') {
                // already set
-       } else if( addTimerEditFormObject["channelSort"] == "radio") {
-               channelObject = addTimerEditFormObject["RadioList"];
+       } else if( addTimerEditFormArray.channelSort === 'radio') {
+               channelObject = addTimerEditFormArray.RadioList;
        } else {
                var found = 0;
-               for( element in addTimerEditFormObject["TVList"]) {
-                       if( element == addTimerEditFormObject["channel"]) {
+               for( element in addTimerEditFormArray.TVList) {
+                       if( element == addTimerEditFormArray.channel) {
                                found = 1;
                                break;
                        }
                }
-               if(found == 0) {
-                       for( element in addTimerEditFormObject["RadioList"]) {
-                               if( element == addTimerEditFormObject["channel"]) {
-                                       channelObject = addTimerEditFormObject["RadioList"];
+               if(found === 0) {
+                       for( element in addTimerEditFormArray.RadioList) {
+                               if( element == addTimerEditFormArray.channel) {
+                                       channelObject = addTimerEditFormArray.RadioList;
                                        found = 1;
                                        break;
                                }
                        }
                }
-               if(found == 0) {
-                       addTimerEditFormObject["TVList"][addTimerEditFormObject["channel"]] = addTimerEditFormObject["channelName"];
+               if(found === 0) {
+                       addTimerEditFormArray.TVList[addTimerEditFormArray.channel] = addTimerEditFormArray.channelName;
                }
        }
+       
        var dashString = "------";
+       
        channelObject[dashString] = "- Bouquets -";
-       var listeNeu = new ServiceList(getXML(doRequestMemory[url_getServices+encodeURIComponent(bouqet_tv)])).getArray();
-       if(addTimerEditFormObject["channelSort"] == "radio") {
-               debug("weiter");
-               listeNeu = new ServiceList(getXML(doRequestMemory[url_getServices+encodeURIComponent(bouqet_radio)])).getArray();
+       
+       var listeNeu = new ServiceList(getXML(doRequestMemory[url_getServices+encodeURIComponent(bouquetsTv)])).getArray();
+       if(addTimerEditFormArray.channelSort == "radio") {
+               listeNeu = new ServiceList(getXML(doRequestMemory[url_getServices+encodeURIComponent(bouquetsRadio)])).getArray();
        }
+       
        for (i = 1; i < listeNeu.length; i++) {
-               var element = listeNeu[i];
+               element = listeNeu[i];
                channelObject[String(dashString+i)] = "---";
                channelObject[element.getServiceReference()] = element.getServiceName();
        }
-       var namespace = {       
-                               'justplay': addTimerFormCreateOptionList(Action, addTimerEditFormObject["justplay"]),
-                               'syear': addTimerFormCreateOptions(2008,2010,addTimerEditFormObject["syear"]),
-                               'smonth': addTimerFormCreateOptions(1,12,addTimerEditFormObject["smonth"]),
-                               'sday': addTimerFormCreateOptions(1,31,addTimerEditFormObject["sday"]),
-                               'shour': addTimerFormCreateOptions(0,23,addTimerEditFormObject["shour"]),
-                               'smin': addTimerFormCreateOptions(0,59,addTimerEditFormObject["smin"]),
-                               'eyear': addTimerFormCreateOptions(2008,2010,addTimerEditFormObject["eyear"]),
-                               'emonth': addTimerFormCreateOptions(1,12,addTimerEditFormObject["emonth"]),
-                               'eday': addTimerFormCreateOptions(1,31,addTimerEditFormObject["eday"]),
-                               'ehour': addTimerFormCreateOptions(0,23,addTimerEditFormObject["ehour"]),
-                               'emin': addTimerFormCreateOptions(0,59,addTimerEditFormObject["emin"]),
-                               'channel': addTimerFormCreateOptionList(channelObject, addTimerEditFormObject["channel"]),
-                               'name': addTimerEditFormObject["name"],
-                               'description': addTimerEditFormObject["description"],
-                               'repeated': addTimerFormCreateOptionListRepeated(Repeated, addTimerEditFormObject["repeated"]),
-                               'deleteOldOnSave': addTimerEditFormObject["deleteOldOnSave"],
-                               'channelOld': addTimerEditFormObject["channel"],
-                               'beginOld': addTimerEditFormObject["beginOld"],
-                               'endOld': addTimerEditFormObject["endOld"],
-                               'afterEvent': addTimerFormCreateOptionList(AfterEvent, addTimerEditFormObject["afterEvent"]),
-                               'eventID': addTimerEditFormObject["eventID"]
+
+       var namespace = {                                       
+                               syear: createOptions(2008,2015,addTimerEditFormArray.syear),
+                               smonth: createOptions(1,12,addTimerEditFormArray.smonth),
+                               sday: createOptions(1,31,addTimerEditFormArray.sday),
+                               shour: createOptions(0,23,addTimerEditFormArray.shour),
+                               smin: createOptions(0,59,addTimerEditFormArray.smin),
+                               eyear: createOptions(2008,2015,addTimerEditFormArray.eyear),
+                               emonth: createOptions(1,12,addTimerEditFormArray.emonth),
+                               eday: createOptions(1,31,addTimerEditFormArray.eday),
+                               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),
+
+                               timer: {
+                                       name: addTimerEditFormArray.name,
+                                       description: addTimerEditFormArray.description,
+                                       deleteOldOnSave: addTimerEditFormArray.deleteOldOnSave,
+                                       channelOld: addTimerEditFormArray.channel,
+                                       beginOld: addTimerEditFormArray.beginOld,
+                                       endOld: addTimerEditFormArray.endOld,                                   
+                                       eventID: addTimerEditFormArray.eventID
+                               }
                };
+       data = namespace;
+       processTpl('tplTimerEdit', data, 'contentMain');
+       /*
        var listerHtml = RND(tplAddTimerForm, namespace);
        $('BodyContent').innerHTML = listerHtml;
-
+       */
+       
        // Empty some stuff, but keep others to have the performance
-       var tmp1 = addTimerEditFormObject["RadioList"];
-       var tmp2 = addTimerEditFormObject["TVList"];
-       addTimerEditFormObject = new Object();
-       addTimerEditFormObject["deleteOldOnSave"] = 0;
-       addTimerEditFormObject["RadioList"] = tmp1;
-       addTimerEditFormObject["TVList"] = tmp2;
-       addTimerEditFormObject["TVListFilled"] = 1;
-       addTimerEditFormObject["RadioListFilled"] = 1;
-}
-
-function addTimerFormCreateOptions(start,end,number) {
-       var html = '';
+       var tmp1 = addTimerEditFormArray.RadioList;
+       var tmp2 = addTimerEditFormArray.TVList;
+       addTimerEditFormArray = [];
+       addTimerEditFormArray.deleteOldOnSave = 0;
+       addTimerEditFormArray.RadioList = tmp1;
+       addTimerEditFormArray.TVList = tmp2;
+       addTimerEditFormArray.TVListFilled = 1;
+       addTimerEditFormArray.RadioListFilled = 1;
+}
+
+function createOptions(start, end, number) {
+       var namespace =[];
+       
        for(i = start; i <= end; i++) {
                var txt = (String(i).length == 1) ? "0" + String(i) : String(i);
                var selected =  (i == Number(number)) ? "selected" : " ";
-               var namespace = {
+               namespace[i] = {
                        'value': i,
                        'txt': txt,
                        'selected': selected };
-               html += RND(tplAddTimerFormOptions, namespace);
        }
-       return html;
+       return namespace;
 }
-function addTimerFormCreateOptionList(object,selected) {
-       html = '';
-       var found = 0;
+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) {
-                       found = 1;
                        sel = "selected";
                }
-               var namespace = {
-                       'value': element,
-                       'txt': txt,
-                       'selected': sel };
+               
                if(element != "extend") {
-                       html += RND(tplAddTimerFormOptions, namespace);
+                       namespace[i] = {
+                               'value': element,
+                               'txt': txt,
+                               'selected': sel };
+                       i++;
                }
        }
-       if(found == 0) {
-               var namespace = {
-                       'value': element,
-                       'txt': txt,
-                       'selected': sel };
-       }
-       return html;
+
+       return namespace;
 }
 
-function timerFormExtendChannellist(bouqet) {
-       var listeTV = new ServiceList(getXML(doRequestMemory[url_getServices+encodeURIComponent(bouqet_tv)])).getArray();
-       var listeRadio = new ServiceList(getXML(doRequestMemory[url_getServices+encodeURIComponent(bouqet_radio)])).getArray();
+function timerFormExtendChannellist(bouquet) {
+       var listeTV = new ServiceList(getXML(doRequestMemory[url_getServices+encodeURIComponent(bouquetsTv)])).getArray();
+       var listeRadio = new ServiceList(getXML(doRequestMemory[url_getServices+encodeURIComponent(bouquetsRadio)])).getArray();
        found = 0;
        for(i = 0; i < listeTV.length; i++) {
-               var element = listeTV[i];
-               if(String(element.getServiceReference()) == bouqet) {
+               element = listeTV[i];
+               if(String(element.getServiceReference()) == bouquet) {
                        found = 1;
                        break;
                }
        }
-       if(found == 0) {
+       if(found === 0) {
                for(i = 0; i < listeRadio.length; i++) {
-                       var element = listeTV[i];
-                       if(String(element.getServiceReference()) == bouqet) {
+                       element = listeTV[i];
+                       if(String(element.getServiceReference()) == bouquet) {
                                found = 1;
                                break;
                        }
                }
        }
        if(found == 1) {
-               servicereftoloadepgnow = bouqet;
-               if( getElementOfChannelList(String(servicereftoloadepgnow)) ) { 
-                       incomingTimerFormExtendChannellist();
-               } else {
+               servicereftoloadepgnow = bouquet;
+               if(typeof(loadedChannellist[servicereftoloadepgnow]) == "undefined") {  
                        doRequest(url_getServices+servicereftoloadepgnow, incomingTimerFormExtendChannellist, true);
+               } else {
+                       incomingTimerFormExtendChannellist();
                }
        }
 }
 function incomingTimerFormExtendChannellist(request) {
        var services = null;
-       if( getElementOfChannelList(String(servicereftoloadepgnow)) ) {
-               services = getElementOfChannelList(String(servicereftoloadepgnow));
+       if(typeof(loadedChannellist[servicereftoloadepgnow]) != "undefined"){
+               services = loadedChannellist[servicereftoloadepgnow];
        } else if(request.readyState == 4) {
                services = new ServiceList(getXML(request)).getArray();
-               setElementOfChannelList(String(servicereftoloadepgnow), services);
-               debug("got "+services.length+" Services");
+               loadedChannellist[servicereftoloadepgnow] = services;   
        }
-       var attachLater = new Object();
-       if(services != null) {
-               debug("incomingTimerFormExtendChannellist " + services.length);
-               var selected = $('channel').selectedIndex;
+       attachLater = {};
+       if(services !== null) {
+               debug("[incomingTimerFormExtendChannellist] Got "+services.length+" Services");
+               selected = $('channel').selectedIndex;
                for(j = selected; j < $('channel').options.length; j++) {
                        if($('channel').options[j].value == servicereftoloadepgnow) {
                                j++;
                                for(var i = 0; i < services.length ; i++) {
-                                       var reference = services[i];
-                                       var newEntry = new Option(reference.getServiceName(), reference.getServiceReference(), false, true);
+                                       reference = services[i];
+                                       newEntry = new Option(reference.getServiceName(), reference.getServiceReference(), false, true);
                                        if(typeof($('channel').options[j]) != "undefined") {
                                                attachLater[String($('channel').options[j].value)] = $('channel').options[j].text;
                                        }
@@ -494,7 +474,7 @@ function incomingTimerFormExtendChannellist(request) {
                        break;
                }
                for(x in attachLater) {
-                       var newEntry = new Option(attachLater[x], x, false, true);
+                       newEntry = new Option(attachLater[x], x, false, true);
                        if(x != "extend") {
                                $('channel').options[$('channel').options.length] = newEntry;
                        }
@@ -513,7 +493,7 @@ function addTimerFormChangeTime(which) {
                opponent = (which.substr(0,1) == 's') ? 'e' +  which.substr(1, which.length -1) : 's' +  which.substr(1, which.length -1) ;
                $(opponent).value = $(which).value;
        }
-       var all = new Array('year','month','day','hour','min');
+       var all = ['year','month','day','hour','min'];
        for(i=0; i < all.length; i++) {
                if(which.substr(1, which.length -1) == all[i]) {
                        addTimerFormChangeTime(which.substr(0,1) + all[i+1] );
@@ -522,11 +502,13 @@ function addTimerFormChangeTime(which) {
        }
 }
 function addTimerFormChangeType() {
-       var selected = ($('tvradio').checked == true) ? addTimerEditFormObject["TVList"]: addTimerEditFormObject["RadioList"];
-       for (i = $('channel').options.length; i != 0; i--) {
+       selected = ($('tvradio').checked === true) ? addTimerEditFormArray.TVList: addTimerEditFormArray.RadioList;
+       
+       for (i = $('channel').options.length; i !== 0; i--) {
                $('channel').options[i - 1] = null;
        }
-       var i = -1;
+       
+       i = -1;
        for(element in selected) {
                if(element != "extend") {
                        i++;
@@ -535,13 +517,14 @@ function addTimerFormChangeType() {
                }
        }
 }
-function addTimerFormCreateOptionListRepeated(Repeated,repeated) {
-       var num = Number(repeated);
-       var html = "";
-       var html2 = "";
-       var list = new Array(127, 64, 32, 31, 16, 8, 4, 2, 1);
-       for(i = 0; i < list.length; i++) {
-               var txt = String(Repeated[String(list[i])]);
+function createOptionListRepeated(Repeated,repeated) {
+       num = Number(repeated);
+       
+       list = [127, 64, 32, 31, 16, 8, 4, 2, 1];
+       namespace = [];
+       
+       for(var i = 0; i < list.length; i++) {
+               txt = String(Repeated[String(list[i])]);
                if( String(Repeated[String(list[i])]) == "mf") {
                        txt = "Mo-Fr";
                } else if( String(Repeated[String(list[i])]) == "ms") {
@@ -549,36 +532,32 @@ function addTimerFormCreateOptionListRepeated(Repeated,repeated) {
                } else {
                        txt = txt.substr(0,1).toUpperCase() + txt.substr(1,1);
                }
-               var checked = " ";
-               if(num >=  list[i]) {
+               checked = " ";
+               if(num >= list[i]) {
                        num -= list[i];
                        checked = "checked";
                }
-               var namespace = {
-                       'id': Repeated[String(list[i])],
+               
+               namespace[i] = { 'id': Repeated[String(list[i])],
                        'name': Repeated[String(list[i])],
                        'value': list[i],
                        'txt': txt,
-                       'checked': checked };
-               if(String(Repeated[String(list[i])]) == "mf" || String(Repeated[String(list[i])]) == "ms") {
-                       html2 = RND(tplAddTimerFormCheckbox, namespace) + html2;
-               } else {
-                       html = RND(tplAddTimerFormCheckbox, namespace) + html;
-               }
+                       'checked': checked 
+               };
        }
-       return html + html2;
+       return namespace;
 }
 function sendAddTimer() {
-       debug("sendAddTimer" + "parentChannel:" +$('channel').value);
+       debug("[sendAddTimer]" + "parentChannel:" +$('channel').value);
        
        if(parentPin($('channel').value)) {
-               var beginD = new Date(ownLazyNumber($('syear').value), (ownLazyNumber($('smonth').value) - 1), ownLazyNumber($('sday').value), ownLazyNumber($('shour').value), ownLazyNumber($('smin').value));
-               var begin = beginD.getTime()/1000;
+               beginD = new Date(ownLazyNumber($('syear').value), (ownLazyNumber($('smonth').value) - 1), ownLazyNumber($('sday').value), ownLazyNumber($('shour').value), ownLazyNumber($('smin').value));
+               begin = beginD.getTime()/1000;
                
-               var endD = new Date(ownLazyNumber($('eyear').value), (ownLazyNumber($('emonth').value) - 1), ownLazyNumber($('eday').value), ownLazyNumber($('ehour').value), ownLazyNumber($('emin').value));
-               var end = endD.getTime()/1000;
+               endD = new Date(ownLazyNumber($('eyear').value), (ownLazyNumber($('emonth').value) - 1), ownLazyNumber($('eday').value), ownLazyNumber($('ehour').value), ownLazyNumber($('emin').value));
+               end = endD.getTime()/1000;
 
-               var repeated = 0;
+               repeated = 0;
                if( $('ms').checked ) {
                        repeated = 127;
                } else if($('mf').checked) {
@@ -590,7 +569,7 @@ function sendAddTimer() {
                                repeated += ownLazyNumber($('su').value);
                        }
                } else {
-                       var check = new Array('mo', 'tu', 'we', 'th', 'fr');
+                       check = ['mo', 'tu', 'we', 'th', 'fr'];
                        for(i = 0; i < check.length; i++) {
                                if($(check[i]).checked) {
                                        repeated += Number($(check[i]).value);
@@ -598,17 +577,17 @@ function sendAddTimer() {
                        }
                }
        
-               var descriptionClean = ($('descr').value == " " || $('descr').value == "N/A") ? "" : $('descr').value;
-               var nameClean = ($('name').value == " " || $('name').value == "N/A") ? "" : $('name').value;
+               descriptionClean = ($('descr').value == " " || $('descr').value == "N/A") ? "" : $('descr').value;
+               nameClean = ($('name').value == " " || $('name').value == "N/A") ? "" : $('name').value;
                
-               var neverString = "[0-9a-zA-Z\-_\.\!\(\)&=\+$,;\?/:\\\ ]*";
+               neverString = "[0-9a-zA-Z\\-_\\.\\!\\(\\)&=\\+$,;\\?/:\\\\ ]*";
                if(descriptionClean != descriptionClean.match(neverString) ||
                        nameClean != nameClean.match(neverString)) {
                        alert("Please only use "+neverString+" in the name and the description field");
                        return;
                }
 
-               var repeated = 0;
+               repeated = 0;
                if($('ms').checked) {
                        repeated = ownLazyNumber($('ms').value);
                } else if($('mf').checked) {
@@ -627,258 +606,56 @@ function sendAddTimer() {
                        }
                }
                //addTimerByID(\'%(servicereference)\',\'%(eventid)\',\'False\');
-               doRequest(url_timerchange+"?"+"sRef="+($('channel').value).replace("&quot;", '"')+"&begin="+begin
-                 +"&end="+end+"&name="+escape(nameClean)+"&description="+escape(descriptionClean)
-                 +"&afterevent="+$('after_event').value+"&eit=0&disabled=0"
-                 +"&justplay="+ownLazyNumber($('justplay').value)+"&repeated="+repeated
-                 +"&channelOld="+$('channelOld').value
-                 +"&beginOld="+$('beginOld').value+"&endOld="+$('endOld').value
-                 +"&eventID"+$('eventID').value
-                 +"&deleteOldOnSave="+ownLazyNumber($('deleteOldOnSave').value), incomingTimerAddResult, false);
+               doRequest(url_timerchange+"?"+"sRef="+($('channel').value).replace("&quot;", '"')+"&begin="+ begin +
+                 "&end="+end+"&name="+escape(nameClean)+"&description="+escape(descriptionClean) +
+                 "&afterevent="+$('after_event').value+"&eit=0&disabled=0" +
+                 "&justplay="+ownLazyNumber($('justplay').value)+"&repeated="+repeated +
+                 "&channelOld="+$('channelOld').value +
+                 "&beginOld="+$('beginOld').value+"&endOld="+$('endOld').value +
+                 "&eventID"+$('eventID').value +
+                 "&deleteOldOnSave="+ownLazyNumber($('deleteOldOnSave').value), incomingTimerAddResult, false);
        }
 }
 
+
 function cleanTimerListNow(){
-       debug("cleanTimerListNow pushed");
+       debug("[cleanTimerListNow] called");
        doRequest(url_timerlist, incomingCleanTimerListNow, false);     
 }
+
+
 function incomingCleanTimerListNow(request) {
        if(request.readyState == 4){
                var timers = new TimerList(getXML(request)).getArray();
-               debug("have "+timers.length+" timer");
+               debug("[cleanTimerListNow] Got "+timers.length+" timer");
                for ( var i = 0; i <timers.length; i++){
                        var timer = timers[i];
-                       debug(timer.getState() + " " + quotes2html(timer.getName()));
-                       if(timer.getState() != 0 && timer.getState() != 2) {
-                               delTimer(timer.getServiceReference(),timer.getTimeBegin(),timer.getTimeEnd()
-                                       ,quotes2html(timer.getServiceName()),quotes2html(timer.getName()),quotes2html(timer.getDescription()),incomingJustDoNothing);
+                       debug("[cleanTimerListNow]" + timer.getState() + " " + quotes2html(timer.getName()));
+                       if(timer.getState() !== 0 && timer.getState() !== 2) {
+                               delTimer(timer.getServiceReference(),timer.getTimeBegin(),timer.getTimeEnd(),
+                                       quotes2html(timer.getServiceName()),quotes2html(timer.getName()),quotes2html(timer.getDescription()),incomingJustDoNothing);
                        }
                }
        }
 }
-function incomingJustDoNothing(request){
-       debug("just do nothing");
-}
-function sendToggleTimerDisable(justplay,begin,end,repeated,channel,name,description,afterEvent,disabled){
-       disabled = (ownLazyNumber(disabled) == 0) ? 1 : 0;
-       
-       var descriptionClean = (description == " " || description == "N/A") ? "" : description;
-       var nameClean = (name == " " || name == "N/A") ? "" : name;
-
-       doRequest(url_timerchange+"?"+"sRef="+channel.replace("&quot;", '"')+"&begin="+begin
-        +"&end="+end+"&name="+escape(nameClean)+"&description="+escape(descriptionClean)
-        +"&afterevent="+afterEvent+"&eit=0&disabled="+disabled
-        +"&justplay="+justplay+"&repeated="+repeated
-        +"&channelOld="+channel
-        +"&beginOld="+begin+"&endOld="+end
-        +"&deleteOldOnSave=1", incomingTimerAddResult, false);
-}
 
 
-// AUTOTIMER
-function loadAutoTimerList(){
-       debug("loading AutoTimer");
-       doRequest(url_autotimerlist, incomingAutoTimerList, false);
-}
-
-var autotimers = null;
-function incomingAutoTimerList(request){
-       if(request.readyState == 4){
-               autotimers = new AutoTimerList(getXML(request)).getArray();
-               debug("have "+autotimers.length+" timer");
-               var ns_tplTimerListHeader = {
-                       'page_title': 'Auto timerlist',
-                       'name1': 'Name',
-                       'name2': 'Match',
-                       'repeated': 'Repeated',
-                       'duration': 'Time running',
-                       'start': 'Start time',
-                       'end': 'End time',
-                       'event': 'Event',
-                       'after_event': 'After event',
-                       'options': 'Options'                    
-               };
-               listerHtml = RND(tplTimerListHeader, ns_tplTimerListHeader);
-               var aftereventReadable = new Array ('Nothing', 'Standby', 'Deepstandby/Shutdown');
-               var justplayReadable = new Array('record', 'zap');
-               for ( var i = 0; i <autotimers.length; i++){
-                       var timer = autotimers[i];
-//                     var beginDate = new Date(Number(timer.getTimeBegin())*1000);
-//                     var endDate = new Date(Number(timer.getTimeEnd())*1000);
-                       var namespace = {       
-                                'servicereference': timer.getServices()
-                               ,'servicename': quotes2html(timer.getName())
-                               ,'title': quotes2html(timer.getMatch())
-                               ,'description': quotes2html(timer.getMatch())
-                               ,'justplay': timer.getJustplay()
-                               ,'justplayReadable': timer.getJustplay()
-                               ,'repeated': timer.getCounter()
-                               ,'repeatedReadable': timer.getCounter()
-                               ,'afterevent': timer.getAfterevent()
-                               ,'onOff': timer.getToggleDisabledIMG()
-                               ,'begin': timer.getTimespanbegin()
-                               ,'beginDate': timer.getTimespanbegin()
-                               ,'end': timer.getTimespanend()
-                               ,'endDate': timer.getTimespanend()
-                               ,'duration': timer.getDuration()
-                               
-                               ,'aftereventReadable': aftereventReadable[timer.getAfterevent()]
-                               ,'sendToggleTimerDisable_FUNCTION': "sendToggleAutoTimerDisable("+i+")"
-                               ,'delTimer_FUNCTION': "delAutoTimer("+i+")"
-                               ,'loadTimerFormSeconds_FUNCTION': "loadAutoTimer("+i+")"
-                               ,'color': '000000'
-/*                             'descriptionextended': quotes2html(timer.getDescriptionExtended()),
-                               'state': timer.getState(),
-                               'duration': Math.ceil((timer.getDuration()/60)),
-                               
-                               'aftereventReadable': aftereventReadable[Number(timer.getAfterevent())],
-                               'disabled': timer.getDisabled(),
-                               'onOff': timer.getToggleDisabledIMG(),
-                               'color': timer.getColor()*/
-                       };
-                       listerHtml += RND(tplTimerListItem, namespace);
-               }
-               listerHtml += tplTimerListFooter;
-               $('BodyContent').innerHTML = listerHtml;
-               setBodyMainContent('BodyContent');
-       }
-}
-
-function sendToggleAutoTimerDisable(element) {
-       timers = autotimers[Number(element)];
-       debug("sendToggleAutoTimerDisable["+element+"]: "+timers.getName());
-       
-       doRequest(url_autotimertoggledisable+"?name="+timer.getName()+"&match="+timer.getMatch()
-               , loadAutoTimerList, false);
+function incomingJustDoNothing(request){
+       debug("[incomingJustDoNothing] called");
 }
 
-function delAutoTimer(element) {
-       timers = autotimers[Number(element)];
-       debug("delAutoTimer["+element+"]: "+timers.getName());
-       Dialog.confirm(
-               "Selected timer:<br>"
-               +"Name: "+quotes2html(timer.getName())+"<br>"
-               +"Match: "+quotes2html(timer.getMatch())+"<br>"
-               +"Are you sure that you want to delete the AutoTimer?",
-                {windowParameters: {width:300, className: windowStyle},
-                       okLabel: "delete",
-                       buttonClass: "myButtonClass",
-                       cancel: function(win) {debug("delAutoTimer cancel confirm panel")},
-                       ok: function(win) { 
-                                                           debug("delAutoTimer ok confirm panel"); 
-                                                           doRequest(url_autotimerdelete+"?name="+timer.getName()+"&match="+timer.getMatch(), loadAutoTimerList, false);
-                                                           return true;
-                                                         }
-                       }
-       );
-}
 
-function loadAutoTimer(element) {
-       timer = autotimers[Number(element)];
-       debug("loadAutoTimer["+element+"]: "+timer.getName());
-       
-       var Action = new Object();
-       Action["0"] = "Record";
-       Action["1"] = "Zap";
-       
-       var Repeated = new Object();
-       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 = new Object();
-       AfterEvent["0"] = "Nothing";
-       AfterEvent["1"] = "Standby";
-       AfterEvent["2"] = "Deepstandby/Shutdown";
-       
-       var beginDate = timer.getTimespanbegin().split(":");
-       var endDate =   timer.getTimespanend().split(":");
-       
-       debug("loadedChannellist: "+loadedChannellist.length);
+function sendToggleTimerDisable(justplay,begin,end,repeated,channel,name,description,afterEvent,disabled){
+       disabled = (ownLazyNumber(disabled) === 0) ? 1 : 0;
        
-       var services = splitPythonArray(timer.getServices());
-       var servicesNames = "";
-       for ( var i = 0; i <services.length; i++){
-               if(i > 0) {servicesNames += ", ";} 
-               servicesNames += getServiceName(escape(services[i]));
-       }
-
-       var namespace = {       
-                                'justplay': addTimerFormCreateOptionList(Action, timer.getJustplay)
-                               ,'shour': addTimerFormCreateOptions(0,23,beginDate[0])
-                               ,'smin': addTimerFormCreateOptions(0,59,beginDate[1])
-                               ,'ehour': addTimerFormCreateOptions(0,23,endDate[0])
-                               ,'emin': addTimerFormCreateOptions(0,59,endDate[1])
-                               ,'name': timer.getName()
-                               ,'description': timer.getMatch()
-                               ,'repeated': addTimerFormCreateOptions(0,99,timer.getCounter())
-                               ,'deleteOldOnSave': addTimerEditFormObject["deleteOldOnSave"]
-                               ,'afterEvent': addTimerFormCreateOptionList(AfterEvent, timer.getAfterevent())
-                               ,'timers_element': ""+element
-                               ,'services': servicesNames
-               };
-       var listerHtml = RND(tplAddAutoTimerForm, namespace);
-       $('BodyContent').innerHTML = listerHtml;
-       $('services').disabled = true;
-       $('excludes').disabled = true;
-       $('includes').disabled = true;
-}
-
-function sendAddAutoTimer() {
-       debug("sendAddAutoTimer");
-}
-
-function editAutoTimerServices(element) {
-       debug("editAutoTimerServices " + element);
-       timer = autotimers[Number(element)];
+       var descriptionClean = (description == " " || description == "N/A") ? "" : description;
+       var nameClean = (name == " " || name == "N/A") ? "" : name;
 
-       services = splitPythonArray(timer.getServices());
-       debug("there are "+services.length+" services "+ services);
-       
-       var channels = "";
-       for ( var i = 0; i <services.length; i++){
-               debug("service "+services[i]);
-               channels += "<input type=checkbox name=\""+services[i]+"\">"+getServiceName(escape(services[i]))+"<br/>";
-       }
-       debug(channels);
-       var channelObject
-       var dashString = "------";
-       channelObject[dashString] = "- Bouquets -";
-       var listeNeu = new ServiceList(getXML(doRequestMemory[url_getServices+encodeURIComponent(bouqet_tv)])).getArray();
-       /*if(addTimerEditFormObject["channelSort"] == "radio") {
-               debug("weiter");
-               listeNeu = new ServiceList(getXML(doRequestMemory[url_getServices+encodeURIComponent(bouqet_radio)])).getArray();
-       }*/
-       for (i = 1; i < listeNeu.length; i++) {
-               var element = listeNeu[i];
-               channelObject[String(dashString+i)] = "---";
-               channelObject[element.getServiceReference()] = element.getServiceName();
-       }
-       Dialog.confirm(
-               "Selected channels:<br>"
-               +"Channel: "+channels+"<br>"
-               +"Select: "+addTimerFormCreateOptionList(channelObject, "")+"<br/>"
-               ,{windowParameters: {width:300, className: windowStyle},
-                       okLabel: "delete",
-                       buttonClass: "myButtonClass",
-                       cancel: function(win) {debug("editAutoTimerServices cancel confirm panel")},
-                       ok: function(win) { 
-                                                           debug("editAutoTimerServices ok confirm panel"); 
-                                                           //doRequest(url_timerdelete+"?sRef="+sRef+"&begin="+begin+"&end="+end, readyFunction, false);
-                                                           return true;
-                                                         }
-                       }
-       );
-}
-function splitPythonArray(str) {
-       //debug("splitPythonArray "+str);
-       str = str.replace(/\[[u]*\'(.*)\'\]/, "$1");
-       str = str.replace(/, u/, ", ");
-       return str.split("\', \'");
+       doRequest(url_timerchange+"?"+"sRef="+channel.replace("&quot;", '"')+"&begin="+begin +
+        "&end="+end+"&name="+escape(nameClean)+"&description="+escape(descriptionClean) +
+        "&afterevent="+afterEvent+"&eit=0&disabled="+disabled +
+        "&justplay="+justplay+"&repeated="+repeated +
+        "&channelOld="+channel +
+        "&beginOld="+begin+"&endOld="+end +
+        "&deleteOldOnSave=1", incomingTimerAddResult, false);
 }
\ No newline at end of file
index 20bee0d..c631c40 100644 (file)
 // $Header$
 
-var doRequestMemory = new Object();
-var doRequestMemorySave = new Object();
+var doRequestMemory = {};
+var doRequestMemorySave = {};
+
+var templates = {};
 
 var mediaPlayerStarted = false;
 
-// Get Settings
+// Settings
 var settings = null;
 var parentControlList = null;
 
-// UpdateStreamReader
-var UpdateStreamReaderNextReadPos = 0;
-var UpdateStreamReaderPollTimer = null;
-var UpdateStreamReaderPollTimerCounter = 0;
-var UpdateStreamReaderRetryCounter = 0;
-var UpdateStreamReaderRetryLimit = 10
-var UpdateStreamReaderRequest = null;
+// Globals
+var popUpBlockerHinted = false;
+var requestcounter = 0;
 
-//var UpdateStreamReaderPollTimerCounterTwisted = 0;
+var debugWin = '';
+var signalWin = '';
+var webRemoteWin = '';
+var signalPanelUpdatePoller = '';
+var EPGListWindow = '';
+var MessageAnswerPolling = '';
 
-function UpdateStreamReaderStart(){
-       var ua = navigator.userAgent;
-       
-       if(navigator.userAgent.indexOf("MSIE") >=0) {
-               debug("UpdateStreamReader IE Fix");
+var currentBouquet = bouquetsTv;
 
-               var namespace = {       
-                                       'url_updates': url_updates
-               };
-               $('UpdateStreamReaderIEFixPanel').innerHTML = RND(tplUpdateStreamReaderIE, namespace);
-               
-       }else {
-               UpdateStreamReaderNextReadPos = 0;
-               allMessages = "";
-               UpdateStreamReaderRequest = new XMLHttpRequest();
-               UpdateStreamReaderRequest.onerror = UpdateStreamReaderOnError;
-               UpdateStreamReaderRequest.open("GET", url_updates, true);
-               UpdateStreamReaderRequest.send(null);
-               UpdateStreamReaderPollTimer = setInterval(UpdateStreamReaderLatestResponse, 1000);
-       }
-}
-  
-function UpdateStreamReaderLatestResponse() {
-       UpdateStreamReaderPollTimerCounter++;
-       
-       if(UpdateStreamReaderPollTimerCounter > 30) {
-               clearInterval(UpdateStreamReaderPollTimer);
-               UpdateStreamReaderRequest.abort();
-               UpdateStreamReaderRequest = null;
-               UpdateStreamReaderPollTimerCounter = 0;
-               UpdateStreamReaderStart();
-               
-//             UpdateStreamReaderPollTimerCounterTwisted++;
-               return;
-       }
-       var allMessages = UpdateStreamReaderRequest.responseText;
-       do {
-               var unprocessed = allMessages.substring(UpdateStreamReaderNextReadPos);
-               var messageXMLEndIndex = unprocessed.indexOf("\n");
-               
-               if (messageXMLEndIndex!=-1) {
-                       //reset RetryCounter, if it was a reconnect, it succeeded!
-                       UpdateStreamReaderRetryCounter = 0;
-                       
-                       var endOfFirstMessageIndex = messageXMLEndIndex + "\n".length;
-                       var anUpdate = unprocessed.substring(0, endOfFirstMessageIndex);
-       
-                       var re = new RegExp("<script>parent\.(.*)</script>");
-                       anUpdate = re.exec(anUpdate);
+var signalPanelData = {};
+var epgListData = {};
+var bouquetsMemory = {};
+var loadedChannellist = {};
 
-                       if(anUpdate != null){
-                               if (anUpdate.length == 2){
-                                       eval(anUpdate[1]);
-                               }
-                       }
-                       
-                       UpdateStreamReaderNextReadPos += endOfFirstMessageIndex;
-               }
-               if(UpdateStreamReaderNextReadPos > 65000){
-                       UpdateStreamReaderRequest.abort();
-                       UpdateStreamReaderRequest = null;
-                       UpdateStreamReaderPollTimerCounter = 0;
-                       UpdateStreamReaderStart();
-                       messageXMLEndIndex = -1;
-               }
-       } while (messageXMLEndIndex != -1);
-}
 
-function UpdateStreamReaderOnError(){
-       window.clearInterval(UpdateStreamReaderPollTimer);
-       UpdateStreamReaderRetryCounter += 1;
-       
-       debug("UpdateStreamReaderOnError: ErrorCount "+UpdateStreamReaderRetryCounter);
-       
-       if(UpdateStreamReaderRetryCounter >= UpdateStreamReaderRetryLimit){
-               debug("UpdateStreamReaderOnError: RetryLimit reached!");
-               
-               UpdateStreamReaderRetryCounter = 0;
-               
-               Dialog.confirm(
-                       "Live Update Stream has an Error!<br><br>You will not receive any Updates from Enigma2.<br>Should I try to reconnect?",
-                       {       
-                               windowParameters: {width:300, className: windowStyle},
-                               okLabel: "reconnect",
-                               buttonClass: "myButtonClass",
-                               cancel: function(win) {debug("cancel confirm panel")},
-                               ok: function(win) {UpdateStreamReaderStart(); return true;}
-                       }
-               );
+//General Helpers
+function ownLazyNumber(num) {
+       if(isNaN(num)){
+               return 0;
        } else {
-               setTimeout("UpdateStreamReaderStart()", 5000);
+               return Number(num);
        }
 }
-//end UpdateStreamReader
-
-function openWindow(title, inner, width, height, x, y, id){
-                       if(id == null) id = new Date().toUTCString();
-                       if(x == null) x = 460;
-                       if(y == null) y = 400;
-                       var win = new Window(id, {className: windowStyle, title: title, width: width, height: height,wiredDrag: true});
-                       win.getContent().innerHTML = inner;
-                       win.setDestroyOnClose();
-                       win.showCenter();
-                       win.setLocation(y,x);//y=top,x=left
-                       debug("opening Window: "+title);
-                       return win;
-}
-function messageBox(t, m){
-       Dialog.alert(m, {windowParameters: {title: t, className: windowStyle, width:200}, okLabel: "Close"});
-}
-
-//RND Template Function (http://www.amix.dk)
-function RND(tmpl, ns) {
-       var fn = function(w, g) {
-               g = g.split("|");
-               var cnt = ns[g[0]];
-               //Support for filter functions
-               for(var i=1; i < g.length; i++) {
-                       cnt = eval(g[i])(cnt);
-               }
-               return cnt || w;
-       };
-       return tmpl.replace(/%\(([A-Za-z0-9_|.]*)\)/g, fn);
-}
+
 
 function d2h(nr, len){
 
-               hex = parseInt(nr).toString(16).toUpperCase();
-               if(len > 0){
-                       try{
-                               while(hex.length < len){
-                                       hex = "0"+hex;
-                               }
-                       } 
-                       catch(e){}
+       var hex = parseInt(nr, 10).toString(16).toUpperCase();
+       if(len > 0){
+               try{
+                       while(hex.length < len){
+                               hex = "0"+hex;
+                       }
                } 
-               return hex;
+               catch(e){}
+       } 
+       return hex;
 }
 
-function debug(text){
-       if(DBG){
-               try{
-                       debugWin.getContent().innerHTML += "DEBUG: "+text+"<br>";
-               } catch (windowNotPresent) {}
+
+function quotes2html(txt) {
+       return txt.replace(/'/g, "\\'").replace(/"/g, '&quot;');
+}
+
+
+function dateToString(date){
+
+       var dateString = "";
+       
+       dateString += date.getFullYear();
+       dateString += "-" + date.getMonth();
+       dateString += "-" + date.getDate();
+       
+       var hours = date.getHours();
+       if(hours < 10){
+               hours = '0' + hours;
+       }
+       dateString += " " + hours;
+       
+       var minutes = date.getMinutes();
+       if(minutes < 10){
+               minutes = '0' + minutes;
        }
+       dateString += ":" + minutes;
+       
+       return dateString;
 }
+
+
 function showhide(id){
-       o = $(id).style;
+       var o = $(id).style;
        o.display = (o.display!="none")? "none":"";
 }
+
+
+function show(id){
+       try{
+               $(id).style.display = "";
+       } catch(e) {}
+}
+
+
+function hide(id){
+       try{
+               $(id).style.display = "none";
+       } catch(e) {}
+}
+
+
 function set(element, value){
        if(element == "CurrentService") {
                if(value.search(/^MP3 File:/) != -1) {
@@ -184,7 +119,7 @@ function set(element, value){
        }
        if(navigator.userAgent.indexOf("MSIE") >=0) {
                try{
-                       elementscript= $('UpdateStreamReaderIEFixIFrame').$('scriptzone');
+                       var elementscript = $('UpdateStreamReaderIEFixIFrame').$('scriptzone');
                        if(elementscript){
                                elementscript.innerHTML = ""; // deleting set() from page, to keep the page short and to save memory                    
                        }
@@ -192,47 +127,198 @@ function set(element, value){
                catch(e){}
        }
 }
+
+
 function setComplete(element, value){
        //debug(element+"-"+value);
        element = parent.$(element);
        if (element){
                element.innerHTML = value;
        }
-       if(navigator.userAgent.indexOf("MSIE") >=0) {
+       if(navigator.userAgent.indexOf("MSIE") >= 0) {
                elementscript= $('UpdateStreamReaderIEFixIFrame').$('scriptzone');
                if(elementscript){
                        elementscript.innerHTML = ""; // deleting set() from page, to keep the page short and to save memory                    
                }
        }
 }
-// requestindikator
-var requestcounter = 0;
+
+
+/*
+ * Sets the Loading Notification to the given HTML Element
+ * @param targetElement - The element the Ajax-Loader should be set in
+ */
+function setAjaxLoad(targetElement){
+       $(targetElement).innerHTML = getAjaxLoad();
+}
+
+
+//Ajax Request Helpers
+//requestindikator
+
 function requestIndicatorUpdate(){
-       //debug(requestcounter+" open requests");
+       /*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;
+       requestcounter -= 1;
        requestIndicatorUpdate();
 }
+
+//Popup And Messagebox Helpers
+function messageBox(m){
+       alert(m);
+}
+
+
+function popUpBlockerHint(){
+       if(!popUpBlockerHinted){
+               messageBox("Please disable your Popup-Blocker for enigma2 WebControl to work flawlessly!");
+               popUpBlockerHinted = true;
+       }
+}
+
+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 null;
+       }
+}
+
+//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).innerHTML = result;
+       }catch(ex){
+               debug("[renderTpl] exception: " + ex);
+       }
+}
+
+
+function fetchTpl(tplName, callback){
+       if(typeof(templates.tplName) == 'undefined') {
+               var url = "/webdata/tpl/"+tplName+".htm";
+               var options = {
+                               asynchronous: true,
+                               method: 'GET',
+                               requestHeaders: ['Pragma', 'no-cache', 'Cache-Control', 'must-revalidate', 'If-Modified-Since', 'Sat, 1 Jan 2000 00:00:00 GMT'],
+                               onException: function(o, e){ 
+                                                               debug("[fetchTpl] exception "+ e); 
+                                                               throw(e); 
+                                                       },                              
+                               onSuccess: function(transport){
+                                                               saveTpl(transport, tplName);
+                                                               if(typeof(callback) == 'function'){
+                                                                       callback();
+                                                               }
+                                                       },
+                               onComplete: requestFinished 
+                       };
+                       
+               var request = new Ajax.Request(url, options);
+       } else {
+               if(typeof(callback) != 'undefined'){
+                       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 = "/webdata/tpl/"+tplName+".htm";
+               var request = new Ajax.Request(url,
+                       {
+                               asynchronous: true,
+                               method: 'GET',
+                               requestHeaders: ['Pragma', 'no-cache', 'Cache-Control', 'must-revalidate', 'If-Modified-Since', 'Sat, 1 Jan 2000 00:00:00 GMT'],
+                               onException: function(o, e){ 
+                                                               debug("[processTpl] exception " + e);
+                                                               debug("[processTpl] exception " + typeof(o));
+                                                               throw(e); 
+                                                       },                              
+                               onSuccess: function(transport){
+                                                               incomingProcessTpl(transport, data, domElement, callback);
+                                                       },
+                               onComplete: requestFinished 
+                       });
+}
+
+//Debugging Window
+
+
+function openDebug(){
+       debugWin = openPopup("Debug", templates.tplDebug, 500, 300);
+}
+
+
+function loadAndOpenDebug(){
+       fetchTpl('tplDebug', openDebug);
+}
+
+
+function debug(text){
+       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;
+                       }
+               } catch (Exception) {
+                       popUpBlockerHint();
+               }
+                       
+       }
+}
+
+
+
 // end requestindikator
 function doRequest(url, readyFunction, save){
        requestStarted();
        doRequestMemorySave[url] = save;
-       debug("doRequest: Requesting: "+url);
+//     debug("[doRequest] Requesting: "+url);
+/*     
        if(save == true && typeof(doRequestMemory[url]) != "undefined") {
                readyFunction(doRequestMemory[url]);
        } else {
-               debug("doRequest: loading");
-               new Ajax.Request(url,
+*/
+       try{
+               var request = new Ajax.Request(url,
                        {
                                asynchronous: true,
                                method: 'GET',
@@ -241,7 +327,7 @@ function doRequest(url, readyFunction, save){
                                onSuccess: function (transport, json) {
                                                        if(typeof(doRequestMemorySave[url]) != "undefined") {
                                                                if(doRequestMemorySave[url]) {
-                                                                       debug("doRequest: saving request"); 
+//                                                                     debug("[doRequest] saving request"); 
                                                                        doRequestMemory[url] = transport;
                                                                }
                                                        }
@@ -249,12 +335,13 @@ function doRequest(url, readyFunction, save){
                                                },
                                onComplete: requestFinished 
                        });
-       }
+       } catch(e) {}
+//     }
 }
 
 function getXML(request){
        if (document.implementation && document.implementation.createDocument){
-               var xmlDoc = request.responseXML
+               var xmlDoc = request.responseXML;
        }
        else if (window.ActiveXObject){
                var xmlInsert = document.createElement('xml');
@@ -265,30 +352,57 @@ function getXML(request){
                xmlDoc = $('_MakeAUniqueID');
                document.body.removeChild($('_MakeAUniqueID'));
        } else {
-               debug("Your Browser Sucks!");
+               debug("[getXML] Your Browser Sucks!");
        }
        return xmlDoc;
 }
+
+
+//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 "";
+}
+
+
 function parentPin(servicereference) {
     debug ("parentPin: parentControlList");
        servicereference = decodeURIComponent(servicereference);
-       if(parentControlList == null || String(getSettingByName("config.ParentalControl.configured")) != "true") {
+       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 leaving here 1");
+                       debug("[parentPin] Channel in whitelist");
                        return true;
                }
        } else {
-               debug("parentPin leaving here 2");
+               debug("[parentPin] sRef differs ");
                return true;
        }
-       debug("going to ask for PIN");
+       debug("[parentPin] Asking for PIN");
 
-       var userInput = prompt('ParentControll was switch on.<br> Please enter PIN','PIN');
-       if (userInput != '' && userInput != null) {
+       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 {
@@ -299,350 +413,446 @@ function parentPin(servicereference) {
        }
 }
 
+
+//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 incomingGetDreamboxSettings(request){
+       if(request.readyState == 4){
+               var settings = new Settings(getXML(request)).getArray();
+       }
+       debug ("starte getParentControl " + 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];
+
+                       var last = false;
+                       var namespace = [];
+                       
+                       //we already have the main service in our servicelist so we'll start with the second element
+                       for ( var i = 1; i < services.length ; i++){
+                               var reference = services[i];
+                               namespace[i] = {        
+                                       'servicereference': reference.getServiceReference(),
+                                       'servicename': reference.getServiceName()
+                               };
+                       }
+                       var data = { subservices : namespace };
+                       
+                       
+                       var id = 'SUB'+first.getServiceReference();
+                       show('tr' + id);
+                       processTpl('tplSubServices', data, id);
+               }
+       }
+}
+
+
+function getSubServices() {
+       doRequest(url_subservices, incomingSubServiceRequest, false);
+}
+
+
+function delayedGetSubservices(){
+       setTimeout(getSubServices, 5000);
+}
+
+//zap zap
 function zap(servicereference){
-       new Ajax.Request( "/web/zap?sRef=" + servicereference, 
+       var request = new Ajax.Request( "/web/zap?sRef=" + servicereference, 
                                                {
                                                        asynchronous: true,
                                                        method: 'get'
                                                }
                                        );
-       setTimeout("getSubServices()", 5000);
+       delayedGetSubservices();
+}
+
+//SignalPanel
+
+function updateSignalPanel(){  
+       var html = templates.tplSignalPanel.process(signalPanelData);
+       
+       if (!signalWin.closed && signalWin.location) {
+               setWindowContent(signalWin, html);
+       } else {
+               clearInterval(signalPanelUpdatePoller);
+               signalPanelUpdatePoller = '';
+       }
 }
 
-//++++       SignalPanel                           ++++
-function openSignalDialog(){
-       openWindow("Signal Info",tplSignalPanel, 215, 100,620,40);
+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);
+}
 
-//++++ EPG functions                               ++++
-function loadEPGBySearchString(string){
-               doRequest(url_epgsearch+escape(string),incomingEPGrequest, false);
+function openSignalPanel(){
+       if (!(!signalWin.closed && signalWin.location)){
+               signalWin = openPopup('SignalPanel', '', 220, 120);
+               if(signalPanelUpdatePoller === ''){
+                       signalPanelUpdatePoller = setInterval(reloadSignalPanel, 5000);
+               }
+       }
+       reloadSignalPanel();
 }
-function loadEPGByServiceReference(servicereference){
-               doRequest(url_epgservice+servicereference,incomingEPGrequest, false);
+
+//EPG functions
+
+
+function showEpgList(){
+       var html = templates.tplEpgList.process(epgListData);
+       
+       if (!EPGListWindow.closed && EPGListWindow.location) {
+               setWindowContent(EPGListWindow, html);
+       } else {
+               EPGListWindow = openPopup("EPG", html, 900, 500);
+       }
 }
+
 function incomingEPGrequest(request){
-       debug("incoming request" +request.readyState);          
+       debug("[incomingEPGrequest] readyState" +request.readyState);           
        if (request.readyState == 4){
                var EPGItems = new EPGList(getXML(request)).getArray(true);
-               debug("have "+EPGItems.length+" e2events");
+               debug("[incomingEPGrequest] got "+EPGItems.length+" e2events");
                if(EPGItems.length > 0){                        
-                       var html = tplEPGListHeader;
+                       var namespace = [];
                        for (var i=0; i < EPGItems.length; i++){
                                try{
                                        var item = EPGItems[i];                         
-                                       var namespace = {       
-                                                       'date': item.getTimeDay(),
-                                                       'eventid': item.getEventId(),
-                                                       'servicereference': item.getServiceReference(),
-                                                       'servicename': quotes2html(item.getServiceName()),
-                                                       'title': quotes2html(item.getTitle()),
-                                                       'titleESC': escape(item.getTitle()),
-                                                       'starttime': item.getTimeStartString(), 
-                                                       'duration': Math.ceil(item.getDuration()/60000), 
-                                                       'description': quotes2html(item.getDescription()),
-                                                       'endtime': item.getTimeEndString(), 
-                                                       'extdescription': quotes2html(item.getDescriptionExtended()),
-                                                       'number': String(i),
-                                                       'extdescriptionSmall': extdescriptionSmall(item.getDescriptionExtended(),String(i)),
-                                                       'start': item.getTimeBegin(),
-                                                       'end': item.getTimeEnd()
-                                               };
-                                       //Fill template with data and add id to our result
-                                       html += RND(tplEPGListItem, namespace);
-                               } catch (blubb) { debug("Error rendering: "+blubb);     }
+                                       namespace[i] = {        
+                                               'date': item.getTimeDay(),
+                                               'eventid': item.getEventId(),
+                                               'servicereference': item.getServiceReference(),
+                                               'servicename': quotes2html(item.getServiceName()),
+                                               'title': quotes2html(item.getTitle()),
+                                               'titleESC': escape(item.getTitle()),
+                                               'starttime': item.getTimeStartString(), 
+                                               'duration': Math.ceil(item.getDuration()/60000), 
+                                               'description': quotes2html(item.getDescription()),
+                                               'endtime': item.getTimeEndString(), 
+                                               'extdescription': quotes2html(item.getDescriptionExtended()),
+                                               'number': String(i),
+                                               'start': item.getTimeBegin(),
+                                               'end': item.getTimeEnd()
+                                       };
+                                       
+                               } catch (Exception) { 
+                                       debug("[incomingEPGrequest] Error rendering: " + Exception);    
+                               }
                        }
-                       html += tplEPGListFooter;
-                       openWindow("Electronic Program Guide", html, 900, 500,50,60);
+                       
+                       epgListData = {epg : namespace};
+                       fetchTpl('tplEpgList', showEpgList);
                } else {
-                       messageBox('No Items found!', 'Sorry but i could not find any EPG Content containing your search value');
+                       messageBox('No Items found!', 'Sorry but I could not find any EPG Content containing your search value');
                }
        }
 }
-function extdescriptionSmall(txt,num) {
-       if(txt.length > 410) {
-               var shortTxt = txt.substr(0,410);
-               txt = txt.replace(/\'\'/g, '&quot;');
-               txt = txt.replace(/\\/g, '\\\\');
-               txt = txt.replace(/\'/g, '\\\'');
-               txt = txt.replace(/\"/g, '&quot;');
-               var smallNamespace = { 'txt':txt,'number':num, 'shortTxt':shortTxt};
-               return RND(tplEPGListItemExtend, smallNamespace);
-       } else {
-               return txt;
-       }
-}      
 
-/////////////////////////
+function loadEPGBySearchString(string){
+       doRequest(url_epgsearch+escape(string),incomingEPGrequest, false);
+}
 
-function loadServiceEPGNowNext(servicereference){
-       var url = url_epgnow+servicereference;
-       doRequest(url, incomingServiceEPGNowNext, false);
+function loadEPGByServiceReference(servicereference){
+       doRequest(url_epgservice+servicereference,incomingEPGrequest, false);
+}
+
+//function extdescriptionSmall(txt,num) {
+//     if(txt.length > 410) {
+//             var shortTxt = txt.substr(0,410);
+//             txt = txt.replace(/\'\'/g, '&quot;');
+//             txt = txt.replace(/\\/g, '\\\\');
+//             txt = txt.replace(/\'/g, '\\\'');
+//             txt = txt.replace(/\"/g, '&quot;');
+//             var smallNamespace = { 'txt':txt,'number':num, 'shortTxt':shortTxt};
+//             return RND(tplEPGListItemExtend, smallNamespace);
+//     } else {
+//             return txt;
+//     }
+//}    
+
+function buildServiceListEPGItem(epgevent, type){
+       var namespace = {       
+               'starttime': epgevent.getTimeStartString(), 
+               'title': epgevent.getTitle(), 
+               'length': Math.ceil(epgevent.duration/60) 
+       };
+       var data = {epg : namespace};
+       //e.innerHTML = RND(tplServiceListEPGItem, namespace);
+       
+       var id = type + epgevent.getServiceReference();
+       
+       show('tr' + id);
+       
+               if(typeof(templates.tplServiceListEPGItem) == "string"){
+                       renderTpl(templates.tplServiceListEPGItem, data, id, true);
+               } else {
+                       debug("[buildServiceListEPGItem] tplServiceListEPGItem N/A");
+               }
 }
 
-function incomingServiceEPGNowNext(request){
+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++){
-                       var eventnow = new EPGEvent(epgevents.item(c));
+               for (var c = 0; c < epgevents.length; c++){
+                       try{
+                               var epgEvt = new EPGEvent(epgevents.item(c));
+                       } catch (e){
+                               debug("[incomingServiceEPGNowNext]" + e);
+                       }
                        
-                       if (eventnow.getEventId() != 'None'){
-                               buildServiceListEPGItem(eventnow,"NOW");
+                       if (epgEvt.getEventId() != 'None'){
+                               buildServiceListEPGItem(epgEvt, type);
                        }
                }
        }
 }
-function buildServiceListEPGItem(epgevent,nownext){
-       var e = $(epgevent.getServiceReference()+'EPG'+nownext);
-               try{
-                       var namespace = {       
-                               'starttime': epgevent.getTimeStartString(), 
-                               'title': epgevent.getTitle(), 
-                               'length': Math.ceil(epgevent.duration/60) 
-                       };
-                       e.innerHTML = RND(tplServiceListEPGItem, namespace);
-               } catch (blubb) {
-                       debug("Error rendering: "+blubb);
-               }       
-}
-///////////////////
-
 
-//+++++++++++++++++++++++++++++++++++++++++++++++++++++
-//+++++++++++++++++++++++++++++++++++++++++++++++++++++
-//++++ GUI functions                               ++++
-//+++++++++++++++++++++++++++++++++++++++++++++++++++++
-//+++++++++++++++++++++++++++++++++++++++++++++++++++++
+function incomingServiceEPGNow(request){
+       incomingServiceEPGNowNext(request, 'NOW');
+}
 
-var currentBodyMainElement = null
+function incomingServiceEPGNext(request){
+       incomingServiceEPGNowNext(request, 'NEXT');
+}
 
-function setBodyMainContent(newelementname){
-/*     debug("mediaPlayerStarted 1: " + mediaPlayerStarted);
-       if(mediaPlayerStarted) {
-               mediaPlayerStarted = false;
-               sendMediaPlayer(5);
-       }
-       debug("mediaPlayerStarted 2: " + mediaPlayerStarted);*/
-       newelement =$(newelementname);
-       if(currentBodyMainElement != null){
-               currentBodyMainElement.style.display = "none";
-               
+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);
        }
-       newelement.style.display = "";
-       currentBodyMainElement = newelement;
 }
 
+
+function getBouquetEpg(){
+       loadServiceEPGNowNext(currentBouquet);
+       loadServiceEPGNowNext(currentBouquet, true);
+}
 //+++++++++++++++++++++++++++++++++++++++++++++++++++++
 //+++++++++++++++++++++++++++++++++++++++++++++++++++++
 //++++ volume functions                            ++++
 //+++++++++++++++++++++++++++++++++++++++++++++++++++++
 //+++++++++++++++++++++++++++++++++++++++++++++++++++++
-
-function initVolumePanel(){
-       $('VolumePanel').innerHTML = tplVolumePanel;
-       getVolume(); 
-}
-function getVolume(){
-       doRequest(url_getvolume,handleVolumeRequest, false);
-}
-function volumeSet(newvalue){
-       doRequest(url_setvolume+newvalue,handleVolumeRequest, false);
-}
-function volumeUp(){
-       doRequest(url_volumeup,handleVolumeRequest, false);
-}
-function volumeDown(){
-       doRequest(url_volumedown,handleVolumeRequest, false);
-}
-function volumeMute(){
-       doRequest(url_volumemute,handleVolumeRequest, false);
-}
 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("volume"+newvalue+";"+mute);
+               debug("[handleVolumeRequest] Volume " + newvalue + " | Mute: " + mute);
                
                for (var i = 1; i <= 10; i++)           {
                        if ( (newvalue/10)>=i){
-                               $("volume"+i).src = "/webdata/gfx/led_on.png";
+                               $("volume"+i).src = "/webdata/img/led_on.png";
                        }else{
-                               $("volume"+i).src = "/webdata/gfx/led_off.png";
+                               $("volume"+i).src = "/webdata/img/led_off.png";
                        }
                }
                if (mute == "False"){
-                       $("speaker").src = "/webdata/gfx/speak_on.png";
+                       $("speaker").src = "/webdata/img/speak_on.png";
                }else{
-                       $("speaker").src = "/webdata/gfx/speak_off.png";
+                       $("speaker").src = "/webdata/img/speak_off.png";
                }
        }       
 }
 
-var bouqetsMemory = new Object();
 
-function initChannelList(){
-       //debug("init ChannelList");    
-       var url = url_getServices+encodeURIComponent(bouqet_tv);
-       doRequest(url, incomingTVBouquetList, true);
+function getVolume(){
+       doRequest(url_getvolume, handleVolumeRequest, false);
+}
 
-       var url = url_getServices+encodeURIComponent(bouqet_radio);
-       doRequest(url, incomingRadioBouquetList, true);
+function volumeSet(val){
+       doRequest(url_setvolume+val, handleVolumeRequest, false);
+}
 
-       var url = url_getServices+encodeURIComponent(bouqet_provider_tv);
-       doRequest(url, incomingProviderTVBouquetList, true);
+function volumeUp(){
+       doRequest(url_volumeup, handleVolumeRequest, false);
+}
 
-       var url = url_getServices+encodeURIComponent(bouqet_provider_radio);
-       doRequest(url, incomingProviderRadioBouquetList, true);
+function volumeDown(){
+       doRequest(url_volumedown, handleVolumeRequest, false);
 }
 
-var servicereftoloadepgnow = "";
-var loadedChannellist = new Array();
-function getElementOfChannelList(element) {
-       debug("getElementOfChannelList: "+element);
-       for ( var i = 0; i <loadedChannellist.length; i++){
-               if(loadedChannellist[i] == String(element)) {
-                       debug("getElementOfChannelList returning: " +loadedChannellist[i+1]);
-                       return loadedChannellist[i+1];
-               }
-               i++;
-       }
+function volumeMute(){
+       doRequest(url_volumemute, handleVolumeRequest, false);
 }
-function setElementOfChannelList(element, object) {
-       var num = loadedChannellist.length;
 
-       debug("setElementOfChannelList1:"+num);
-       
-       loadedChannellist[num] = String(element);
-       num++;
-       loadedChannellist[num] = object;
-       debug("setElementOfChannelList2:"+num);
-}
-function hasElementOfChannelList(element) {
-       for ( var i = 0; i <loadedChannellist.length; i++){
-               if(loadedChannellist[i] == String(element)) {
-                       return true;
-               }
-               i++;
+function initVolumePanel(){
+       getVolume(); 
+}
+
+//Channels and Bouquets
+
+
+function incomingChannellist(request){
+       var services = null;
+       if(request.readyState == 4) {
+               services = new ServiceList(getXML(request)).getArray();
+               debug("[incomingChannellist] got "+services.length+" Services");
        }
-       return false;
-}
-function getServiceName(ref) {
-       debug("getSericesName:"+ref);
-       ref = String(ref);
-       for ( var i = 1; i <loadedChannellist.length; i++){
-               services = loadedChannellist[i];
-               for ( var j = 0; j < services.length ; j++){
-                       var reference = services[j];
-                       debug(reference.getServiceReference() + " " +ref);
-                       if(String(reference.getServiceReference()) == ref) {
-                               return reference.getServiceName()
-                       }
+       if(services !== null) {
+               var namespace = {};
+               var cssclass = "even";
+               
+               for ( var i = 0; i < services.length ; i++){
+                       
+                       cssclass = cssclass == 'even' ? 'odd' : 'even';
+                       
+                       var service = services[i];
+                       namespace[i] = {        
+                               'servicereference' : service.getServiceReference(),
+                               'servicename' : service.getServiceName(),
+                               'cssclass' : cssclass
+                       };
                }
-               i++;
+               var data = { 
+                       services : namespace 
+               };
+               
+               processTpl('tplServiceList', data, 'contentMain', getBouquetEpg);
+               delayedGetSubservices();
+       } else {
+               debug("[incomingChannellist] services is null");
        }
-       return ref;
 }
-function loadBouquet(servicereference){ 
-       debug("loading bouquet with "+servicereference);
-       servicereftoloadepgnow = servicereference;
+
+
+function loadBouquet(servicereference, name){ 
+       debug("[loadBouquet] Loading "+servicereference);
+
+       currentBouquet = servicereference;
+               
+       setContentHd(name);
+       setAjaxLoad('contentMain');
        
-       if(hasElementOfChannelList(String(servicereftoloadepgnow))) {
-               incomingChannellist();
-       } else {
+       debug("[loadBouquet] " + typeof(loadedChannellist[servicereference]));
+       if(typeof(loadedChannellist[servicereference]) == "undefined") {
                doRequest(url_getServices+servicereference, incomingChannellist, true);
+       } else {
+               incomingChannellist();
        }
 }
 
-function incomingTVBouquetList(request){
+
+function incomingBouquetListInitial(request){
        if (request.readyState == 4) {
-               var list0 = new ServiceList(getXML(request)).getArray();
-               debug("have "+list0.length+" TV Bouquet ");     
-               $('accordionMenueBouquetContentTV').innerHTML = renderBouquetTable(list0,tplBouquetListHeader,tplBouquetListItem,tplBouquetListFooter);
+               var bouquetList = new ServiceList(getXML(request)).getArray();
+               debug("[loadBouquet] Got " + bouquetList.length + " TV Bouquets!");     
+
                //loading first entry of TV Favorites as default for ServiceList
-               loadBouquet(list0[0].getServiceReference());
-               bouqetsMemory["bouqet_tv"] = list0;
+               loadBouquet(bouquetList[0].getServiceReference(), bouquetList[0].getServiceName());
+
+               bouquetsMemory.bouquetsTv = bouquetList;
        }
 }
-function incomingRadioBouquetList(request){
-       if (request.readyState == 4) {
-               var list1 = new ServiceList(getXML(request)).getArray();
-               debug("have "+list1.length+" Radio Bouquet ");  
-               $('accordionMenueBouquetContentRadio').innerHTML = renderBouquetTable(list1,tplBouquetListHeader,tplBouquetListItem,tplBouquetListFooter);
-       }       
-}
-function incomingProviderTVBouquetList(request){
-       if (request.readyState == 4) {
-               var list2 = new ServiceList(getXML(request)).getArray();
-               debug("have "+list2.length+" TV Provider Bouquet ");    
-               $('accordionMenueBouquetContentProviderTV').innerHTML = renderBouquetTable(list2,tplBouquetListHeader,tplBouquetListItem,tplBouquetListFooter);
-       }       
-}
-function incomingProviderRadioBouquetList(request){
-       if (request.readyState == 4) {
-               var list2 = new ServiceList(getXML(request)).getArray();
-               debug("have "+list2.length+" Radio Provider Bouquet "); 
-               $('accordionMenueBouquetContentProviderRadio').innerHTML = renderBouquetTable(list2,tplBouquetListHeader,tplBouquetListItem,tplBouquetListFooter);
-       }       
-}
 
-function renderBouquetTable(bouquet,templateHeader,templateItem,templateFooter){
-       debug("renderBouquetTable with "+bouquet.length+" Bouqet");     
-       var html = templateHeader;
-       for (var i=0; i < bouquet.length; i++){
+
+function renderBouquetTable(list, target){
+       debug("[renderBouquetTable] Rendering " + list.length + " Bouquets");   
+       
+       var namespace = [];
+       if (list.length < 1){
+               alert("NO BOUQUETS!");
+       }
+       for (var i=0; i < list.length; i++){
                try{
-                       var namespace = {
-                               'servicereference': bouquet[i].getServiceReference(), 
-                               'bouquetname': bouquet[i].getServiceName()
+                       var bouquet = list[i];
+                       namespace[i] = {
+                               'servicereference': bouquet.getServiceReference(), 
+                               'bouquetname': bouquet.getServiceName()
                        };
-                       html += RND(templateItem, namespace);
-               } catch (blubb) {}
+               } catch (e) { 
+                       //TODO error handling 
+               }
        }
-       html += templateFooter;
-       return html;
+       var data = { 
+               services : namespace 
+       };
+       
+       processTpl('tplBouquetList', data, 'contentMain');
 }      
 
-function incomingChannellist(request){
-       var services = null;
-       if(hasElementOfChannelList(String(servicereftoloadepgnow))){
-               services = getElementOfChannelList(String(servicereftoloadepgnow));
-       } else if(request.readyState == 4) {
-               services = new ServiceList(getXML(request)).getArray();
-               setElementOfChannelList(String(servicereftoloadepgnow), services);
-       }
-       if(services != null) {
-               var smallNamespace = {'mainServiceRef': servicereftoloadepgnow };
-               listerHtml = RND(tplServiceListHeader, smallNamespace);
-               for ( var i = 0; i < services.length ; i++){
-                       var reference = services[i];
-                       var namespace = {       
-                               'servicereference': reference.getServiceReference(),
-                               'servicename': reference.getServiceName()
-                       };
-                       listerHtml += RND(tplServiceListItem, namespace);
-               }               
-               listerHtml += tplServiceListFooter;
-               $('BodyContent').innerHTML = listerHtml;
-               setBodyMainContent('BodyContent');
-               setTimeout("getSubServices()", 5000);
-               loadServiceEPGNowNext(servicereftoloadepgnow);
+
+
+function incomingBouquetList(request){
+       if (request.readyState == 4) {
+               var bouquetList = new ServiceList(getXML(request)).getArray();
+               debug("[incomingBouquetList] got " + bouquetList.length + " TV Bouquets!");     
+               renderBouquetTable(bouquetList, 'contentMain');         
        }
 }
-// Movies
-function loadMovieList(tag){
-       debug("loading movies by tag '"+tag+"'");
-       doRequest(url_movielist+tag, incomingMovieList, false);
+
+
+function initChannelList(){
+       //debug("init ChannelList");    
+       var url = url_getServices+encodeURIComponent(bouquetsTv);
+       currentBouquet = bouquetsTv;
+       doRequest(url, incomingBouquetListInitial, true);
 }
 
+
+
+// Movies
 function incomingMovieList(request){
        if(request.readyState == 4){
+               
                var movies = new MovieList(getXML(request)).getArray();
-               debug("have "+movies.length+" movies");
-               listerHtml      = tplMovieListHeader;           
-               for ( var i = 0; i <movies.length; i++){
+               debug("[incomingMovieList] Got "+movies.length+" movies");
+               namespace = []; 
+               
+               var cssclass = "even";
+               
+               for ( var i = 0; i < movies.length; i++){
+                       cssclass = cssclass == 'even' ? 'odd' : 'even';
+                       
                        var movie = movies[i];
-                       var namespace = {       
+                       namespace[i] = {        
                                'servicereference': movie.getServiceReference(),
                                'servicename': movie.getServiceName() ,
                                'title': movie.getTitle(), 
@@ -653,35 +863,27 @@ function incomingMovieList(request){
                                'filesize': movie.getFilesizeMB(),
                                'tags': movie.getTags().join(', ') ,
                                'length': movie.getLength() ,
-                               'time': movie.getTimeDay()+"&nbsp;"+ movie.getTimeStartString()
+                               'time': movie.getTimeDay()+"&nbsp;"+ movie.getTimeStartString(),
+                               'cssclass' : cssclass
                        };
-                       listerHtml += RND(tplMovieListItem, namespace);
                }
-               listerHtml += tplMovieListFooter;
-               $('BodyContent').innerHTML = listerHtml;
-               setBodyMainContent('BodyContent');
-               
+               var data = { movies : namespace };
+               processTpl('tplMovieList', data, 'contentMain');
        }               
 }
-function delMovieFile(file,servicename,title,description) {
-       debug("delMovieFile: file("+file+"),servicename("+servicename+"),title("+title+"),description("+description+")");
-       Dialog.confirm(
-               "Selected timer:<br>"
-               +"Servicename: "+servicename+"<br>"
-               +"Title: "+title+"<br>"
-               +"Description: "+description+"<br>"
-               +"Are you sure that you want to delete the Timer?",
-                {windowParameters: {width:300, className: windowStyle},
-                       okLabel: "delete",
-                       buttonClass: "myButtonClass",
-                       cancel: function(win) {debug("delMovieFile cancel confirm panel")},
-                       ok: function(win) { debug("delMovieFile ok confirm panel"); doRequest(url_moviefiledelete+"?filename="+file, incomingDelMovieFileResult, false); return true; }
-                       }
-       );
-       
+
+
+function loadMovieList(tag){
+       if(typeof(tag) == 'undefined'){
+               tag = '';
+       }
+       debug("[loadMovieList] Loading movies with tag '"+tag+"'");
+       doRequest(url_movielist+tag, incomingMovieList, false);
 }
+
+
 function incomingDelMovieFileResult(request) {
-       debug("incomingDelMovieFileResult");
+       debug("[incomingDelMovieFileResult] called");
        if(request.readyState == 4){
                var delresult = new SimpleXMLResult(getXML(request));
                if(delresult.getState()){
@@ -693,11 +895,46 @@ function incomingDelMovieFileResult(request) {
 }
 
 
-// send Messages
-function showMessageSendForm(){
-               $('BodyContent').innerHTML = tplMessageSendForm;
+function delMovieFile(file ,servicename, title, description) {
+       debug("[delMovieFile] File(" + file + "), servicename(" + servicename + ")," +
+                       "title(" + title + "), description(" + description + ")");
+       
+       result = confirm( "Are you sure want to delete the Movie?\n" +
+               "Servicename: "+servicename+"\n" +
+               "Title: "+title+"\n" + 
+               "Description: "+description+"\n");
+
+       if(result){
+               debug("[delMovieFile] ok confirm panel"); 
+               doRequest(url_moviefiledelete+"?filename="+file, incomingDelMovieFileResult, false); 
+               return true;
+       }
+       else{
+               debug("[delMovieFile] cancel confirm panel");
+               return false;
+       }
 }
-var MessageAnswerPolling;
+
+//Send Messages and Receive the Answer
+
+
+function incomingMessageResult(request){
+       if(request.readyState== 4){
+               var result = getXML(request).getElementsByTagName("e2message").item(0).getElementsByTagName('e2result').item(0).firstChild.data;
+               
+               if (result=="True"){
+                       messageBox('Message sent successfully!');
+                       return;
+               }
+       }       
+       messageBox('Message NOT sent!');
+}
+
+function getMessageAnswer() {
+       doRequest(url_messageanswer, incomingMessageResult, false);
+       clearInterval(MessageAnswerPolling);
+}
+
 function sendMessage(messagetext,messagetype,messagetimeout){
        if(!messagetext){
                messagetext = $('MessageSendFormText').value;
@@ -709,196 +946,149 @@ function sendMessage(messagetext,messagetype,messagetimeout){
                var index = $('MessageSendFormType').selectedIndex;
                messagetype = $('MessageSendFormType').options[index].value;
        }       
-       if(ownLazyNumber(messagetype) == 0){
-               new Ajax.Request(url_message+'?text='+messagetext+'&type='+messagetype+'&timeout='+messagetimeout, { asynchronous: true, method: 'get' });
+       if(ownLazyNumber(messagetype) === 0){
+               var request = new Ajax.Request(url_message+'?text='+messagetext+'&type='+messagetype+'&timeout='+messagetimeout, { asynchronous: true, method: 'get' });
+               
                MessageAnswerPolling = setInterval(getMessageAnswer, ownLazyNumber(messagetimeout)*1000);
        } else {
                doRequest(url_message+'?text='+messagetext+'&type='+messagetype+'&timeout='+messagetimeout, incomingMessageResult, false);
        }
 }
-function incomingMessageResult(request){
 
-       if(request.readyState== 4){
-               var b = getXML(request).getElementsByTagName("e2message");
-               var result = b.item(0).getElementsByTagName('e2result').item(0).firstChild.data;
-               var resulttext = b.item(0).getElementsByTagName('e2resulttext').item(0).firstChild.data;
-               if (result=="True"){
-                       messageBox('message send',resulttext);//'message send successfully! it appears on TV-Screen');
-               }else{
-                       messageBox('message send failed',resulttext);
-               }
-       }               
-}
-function getMessageAnswer() {
-       doRequest(url_messageanswer, incomingMessageResult, false);
-       clearInterval(MessageAnswerPolling);
-}
-// RemoteControl Code
-function showRemoteControllSendForm(){
-       if(! $('rcWindow')){
-               openWindow("Remote", tplRemoteControlForm, 220, 642, 920,0, "rcWindow");
-       }
-}
-function sendRemoteControlRequest(command){
-       doRequest(url_remotecontrol+'?command='+command, incomingRemoteControlResult, false);
-       if($('getScreen').checked) {
-               openGrabPicture();
-       }
-}
-function openGrabPicture() {
-       if($('BodyContent').innerHTML != tplRCGrab) {
-               $('BodyContent').innerHTML = tplRCGrab;
-       }
-       debug("openGrabPicture");
+
+//Screenshots
+function getScreenShot(what) {
+       debug("[getScreenShot] called");
+       
+       setAjaxLoad('contentMain');
+       setContentHd('Screenshot');
+       
        var buffer = new Image();
        var downloadStart;
+       var data = {};
+       
+       buffer.onload = function () { 
+               debug("[getScreenShot] image assigned");
+               
+               data = { img : { src : buffer.src } };
 
-       buffer.onload = function () { debug("image zugewiesen"); $('grabPageIMG').src = buffer.src; return true;};
-       buffer.onerror = function (meldung) { debug("reload grab image failed"); return true;};
+               
+               
+               processTpl('tplGrab', data, 'contentMain');
 
+               return true;
+       };
+       
+       buffer.onerror = function (meldung) { 
+               debug("[getScreenShot] Loading image failed"); 
+               return true;
+       };
+       switch(what){
+               case "o":
+                       what = "&o";
+                       break;
+               case "v":
+                       what = "&v";
+                       break;
+               default:
+                       what = "";
+                       break;
+       }
+       
        downloadStart = new Date().getTime();
-       buffer.src = '/grab?' + downloadStart;
-       $('grabPageIMG').height(400);
-       tplRCGrab = $('BodyContent').innerHTML;
+       buffer.src = '/grab?format=jpg&n=&r=720&' + what + '&' + downloadStart;
 }
+
+
+// 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;
-       } else {
-               $('rcWindow').innerHTML = "<h1>some unknown error</h1>" + tplRemoteControlForm;
-       }
+       } //else {
+               //TODO Some Error Handling
+//     }
 }
 
-function getDreamboxSettings(){
-       doRequest(url_settings, incomingGetDreamboxSettings, false);
-}
-function incomingGetDreamboxSettings(request){
-       if(request.readyState == 4){
-               settings = new Settings(getXML(request)).getArray();
-       }
-       debug ("starte getParentControl " + getSettingByName("config.ParentalControl.configured"));
-       if(String(getSettingByName("config.ParentalControl.configured")) == "true") {
-               getParentControl();
-       }
-}
-function getSettingByName(txt) {
-       debug("getSettingByName ("+txt+")");
-       for(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 getParentControl() {
-       doRequest(url_parentcontrol, incomingParentControl, false);
-}
-function incomingParentControl(request) {
-       if(request.readyState == 4){
-               parentControlList = new ServiceList(getXML(request)).getArray();
-               debug("parentControlList got "+parentControlList.length + " services");
-       }
-}
-function getParentControlByRef(txt) {
-       debug("getParentControlByRef ("+txt+")");
-       for(i = 0; i < parentControlList.length; i++) {
-               debug("("+parentControlList[i].getClearServiceReference()+")");
-               if(String(parentControlList[i].getClearServiceReference()) == String(txt)) {
-                       return parentControlList[i].getClearServiceReference();
-               } 
-       }
-       return "";
-}
-function ownLazyNumber(num) {
-       if(isNaN(num)){
-               return 0;
+function openWebRemote(){
+       
+       if (!webRemoteWin.closed && webRemoteWin.location) {
+               setWindowContent(webRemoteWin, templates.tplWebRemote);
        } else {
-               return Number(num);
+               webRemoteWin = openPopup('WebRemote', templates.tplWebRemote, 250, 670);
        }
+       
 }
 
-function getSubServices() {
-       doRequest(url_subservices,incomingSubServiceRequest, false);
+
+function loadAndOpenWebRemote(){
+       fetchTpl('tplWebRemote', openWebRemote);
 }
 
-//var SubServicePoller = setInterval(getSubServices, 15000);
-var subServicesInsertedList = new Object();
 
-function incomingSubServiceRequest(request){
-       if(request.readyState == 4){
-               var services = new ServiceList(getXML(request)).getArray();
-               listerHtml      = '';           
-               debug("got "+services.length+" SubServices");
-               if(services.length > 1) {
-                       
-                       first = services[0];
-                       var mainChannellist = getElementOfChannelList(String($('mainServiceRef').value));
-
-                       last = false
-                       for ( var i = 0; i < services.length ; i++){
-                               var reference = services[i];
-                               var namespace = {       
-                                       'servicereference': reference.getServiceReference(),
-                                       'servicename': reference.getServiceName()
-                               };
-                               
-                               if(i != 0){
-                                       listerHtml += RND(tplSubServiceListItem, namespace);
-                               }
-                               
-                               if(last == false){
-                                       last = reference.getServiceReference();
-                               }
-                               
-                               last = reference.getServiceReference();
-
-                       }
-                       //listerHtml += tplSubServiceListFooter;
-                       $(first.getServiceReference()+'sub').innerHTML = listerHtml;
-                       
-                       subServicesInsertedList[String(first.getServiceReference())] = services;
-                       setElementOfChannelList(String($('mainServiceRef').value), mainChannellist);
+function sendRemoteControlRequest(command){
+       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 );
- }
-}
+       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 i = 0, e = arguments, d = this.copy(), f = a, l = this.length;
-  if( !c ) { c = l - a; }
-  for( i; i < e.length - 2; i++ ) { this[a + i] = e[i + 2]; }
-  for( a; a < l - c; a++ ) { this[a + e.length - 2] = d[a - c]; }
-  this.length -= c - e.length + 2;
-  return d.slice( f, f + c );
- };
+       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 writeTimerListNow() {
-       new Ajax.Request( url_timerlistwrite, { asynchronous: true, method: 'get' });
-}
-function recordingPushed() {
-       doRequest(url_timerlist, incomingRecordingPushed, false);
+       var request = new Ajax.Request( url_timerlistwrite, { asynchronous: true, method: 'get' });
 }
+
+//Recording
 function incomingRecordingPushed(request) {
        if(request.readyState == 4){
                var timers = new TimerList(getXML(request)).getArray();
-               debug("have "+timers.length+" timer");
+               debug("[incomingRecordingPushed] Got " + timers.length + " timers");
                
-               var aftereventReadable = new Array ('Nothing', 'Standby', 'Deepstandby/Shutdown');
-               var justplayReadable = new Array('record', 'zap');
-               var OnOff = new Array('on', 'off');
+               var aftereventReadable = ['Nothing', 'Standby', 'Deepstandby/Shutdown'];
+               var justplayReadable = ['record', 'zap'];
+               var OnOff = ['on', 'off'];
                
-               listerHtml = '';
+               var namespace = [];
                
                for ( var i = 0; i <timers.length; i++){
                        var timer = timers[i];
@@ -906,7 +1096,7 @@ function incomingRecordingPushed(request) {
                        if(ownLazyNumber(timer.getDontSave()) == 1) {
                                var beginDate = new Date(Number(timer.getTimeBegin())*1000);
                                var endDate = new Date(Number(timer.getTimeEnd())*1000);
-                               var namespace = {
+                               namespace[i] = {
                                'servicereference': timer.getServiceReference(),
                                'servicename': timer.getServiceName() ,
                                'title': timer.getName(), 
@@ -925,51 +1115,26 @@ function incomingRecordingPushed(request) {
                                'afterevent': timer.getAfterevent(),
                                'aftereventReadable': aftereventReadable[Number(timer.getAfterevent())],
                                'disabled': timer.getDisabled(),
-                               'onOff': OnOff[Number(timer.getDisabled())],
-                               'color': colorTimerListEntry( timer.getState() )
+                               'onOff': OnOff[Number(timer.getDisabled())]
                                };
-                               listerHtml += RND(tplTimerListItem, namespace);
                        }
                }
-               openWindow("Record Now", listerHtml+tplRecordingFooter, 900, 500, "Record now window");
+               var data = { recordings : namespace };
+               openPopup("Record Now", 'tplTimerListItem', data, 900, 500, "Record now window");
        }
 }
-function inserteSizes() {
-/*     var screenW = 640, screenH = 480;
-       if (parseInt(navigator.appVersion)>3) { 
-               screenW = screen.width;
-               screenH = screen.height;
-       } else if (navigator.appName == "Netscape"
-          && parseInt(navigator.appVersion)==3
-          && navigator.javaEnabled() ) {
-               var jToolkit = java.awt.Toolkit.getDefaultToolkit();
-               var jScreenSize = jToolkit.getScreenSize();
-               screenW = jScreenSize.width;
-               screenH = jScreenSize.height;
-       }
-       debug("screenW:"+screenW+" screenH:"+screenH);
-       /* 640x480
-        * 800x600
-        * 1024x768
-        * 1280x1024
-        * 1600x1280
-       if(screenH == 800) {
-               debug("size 1");
-               $("BodyContent").style.height = '20%';
-       } else if(screenH == 1024) {
-               debug("1024")
-               $("BodyContent").style.height = '760px';
-               
-       } else {
-               alert("unsupported screensize");
-       }*/
-       
+
+
+function recordingPushed() {
+       doRequest(url_timerlist, incomingRecordingPushed, false);
 }
+
+
 function recordingPushedDecision(recordNowNothing,recordNowUndefinitely,recordNowCurrent) {
        var recordNow = recordNowNothing;
-       recordNow = (recordNow == "") ? recordNowUndefinitely: recordNow;
-       recordNow = (recordNow == "") ? recordNowCurrent: recordNow;
-       if(recordNow != "nothing" && recordNow != "") {
+       recordNow = (recordNow === "") ? recordNowUndefinitely: recordNow;
+       recordNow = (recordNow === "") ? recordNowCurrent: recordNow;
+       if(recordNow !== "nothing" && recordNow !== "") {
                doRequest(url_recordnow+"?recordnow="+recordNow, incomingTimerAddResult, false);
        }
 }
@@ -981,353 +1146,529 @@ function ifChecked(rObj) {
                return "";
        }
 }
-function showAbout() {
-       doRequest(url_about, incomingAbout, false);
-}
+
+//About
+/*
+ * Handles an incoming request for /web/about
+ * 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 incomingAbout(request) {
        if(request.readyState == 4){
-               debug("incomingAbout returned");
-               var aboutEntries = getXML(request).getElementsByTagName("e2abouts").item(0).getElementsByTagName("e2about");
-               for (var c =0; c < aboutEntries.length;c++){
-                       var xml = aboutEntries.item(c);
-                       try{
-                               var fptext = "V"+xml.getElementsByTagName('e2fpversion').item(0).firstChild.data;
-                               var tunerinfo = "";
+               debug("[incomingAbout] returned");
+               var xml = getXML(request).getElementsByTagName("e2abouts").item(0).getElementsByTagName("e2about");
 
-                               var nims = xml.getElementsByTagName('e2tunerinfo').item(0).getElementsByTagName("e2nim");
-                               debug("nims: "+nims.length);
-                               for(var i=0;i< nims.length;i++){
-                                       
-                                       name = nims.item(i).getElementsByTagName("name").item(0).firstChild.data;
-                                       type = nims.item(i).getElementsByTagName("type").item(0).firstChild.data;
-                                       debug(name);
-                                       debug(type);
-                                       var ns = { 'name' : name, 'type' : type};
-                                       tunerinfo += RND(tplAboutTuner, ns);
-                                       
-                               }
-
-                               var hdddata = xml.getElementsByTagName('e2hddinfo').item(0);
+               xml = xml.item(0);
+               
+               var namespace = {};
+               var ns = [];
+               
+               try{
+                       var fptext = "V"+xml.getElementsByTagName('e2fpversion').item(0).firstChild.data;
+                       
+                       
+                       var nims = xml.getElementsByTagName('e2tunerinfo').item(0).getElementsByTagName("e2nim");
+                       debug("[incomingAbout] nims: "+nims.length);
+                       for(var i = 0; i < nims.length; i++){
                                
-                               var hddmodel    = hdddata.getElementsByTagName("model").item(0).firstChild.data;
-                               var hddcapacity = hdddata.getElementsByTagName("capacity").item(0).firstChild.data;
-                               var hddfree     = hdddata.getElementsByTagName("free").item(0).firstChild.data;
-
-                               var namespace = {
-                                       'dreamboxmodel':  xml.getElementsByTagName('e2model').item(0).firstChild.data
-                                       ,'enigmaVersion': xml.getElementsByTagName('e2enigmaversion').item(0).firstChild.data
-
-                                       ,'lanDHCP': xml.getElementsByTagName('e2landhcp').item(0).firstChild.data
-                                       ,'lanIP': xml.getElementsByTagName('e2lanip').item(0).firstChild.data
-                                       ,'lanNetmask': xml.getElementsByTagName('e2lanmask').item(0).firstChild.data
-                                       ,'lanGateway': xml.getElementsByTagName('e2langw').item(0).firstChild.data
-
-                                       ,'fpVersion': fptext
-                                       ,'webifversion': xml.getElementsByTagName('e2webifversion').item(0).firstChild.data
-                                       ,'tunerInfo': tunerinfo
-                                       ,'hddmodel': hddmodel
-                                       ,'hddcapacity': hddcapacity
-                                       ,'hddfree': hddfree
-                                       
-                                       ,'serviceName': xml.getElementsByTagName('e2servicename').item(0).firstChild.data
-                                       ,'serviceProvider': xml.getElementsByTagName('e2serviceprovider').item(0).firstChild.data
-                                       ,'serviceAspect': xml.getElementsByTagName('e2serviceaspect').item(0).firstChild.data
-                                       ,'serviceVideosize': xml.getElementsByTagName('e2servicevideosize').item(0).firstChild.data
-                                       ,'serviceNamespace': xml.getElementsByTagName('e2servicenamespace').item(0).firstChild.data
-                                       
-                                       ,'vPIDh': '0x'+d2h(xml.getElementsByTagName('e2vpid').item(0).firstChild.data, 4)
-                                        ,'vPID': ownLazyNumber(xml.getElementsByTagName('e2vpid').item(0).firstChild.data)
-                                       ,'aPIDh': '0x'+d2h(xml.getElementsByTagName('e2apid').item(0).firstChild.data, 4)
-                                        ,'aPID': ownLazyNumber(xml.getElementsByTagName('e2apid').item(0).firstChild.data)
-                                       ,'pcrPIDh': '0x'+d2h(xml.getElementsByTagName('e2pcrid').item(0).firstChild.data, 4)
-                                        ,'pcrPID': ownLazyNumber(xml.getElementsByTagName('e2pcrid').item(0).firstChild.data)
-                                       ,'pmtPIDh': '0x'+d2h(xml.getElementsByTagName('e2pmtpid').item(0).firstChild.data, 4)
-                                        ,'pmtPID': ownLazyNumber(xml.getElementsByTagName('e2pmtpid').item(0).firstChild.data)
-                                       ,'txtPIDh': '0x'+d2h(xml.getElementsByTagName('e2txtpid').item(0).firstChild.data, 4)
-                                        ,'txtPID': ownLazyNumber(xml.getElementsByTagName('e2txtpid').item(0).firstChild.data)
-                                       ,'tsIDh': '0x'+d2h(xml.getElementsByTagName('e2tsid').item(0).firstChild.data, 4)
-                                        ,'tsID': ownLazyNumber(xml.getElementsByTagName('e2tsid').item(0).firstChild.data)
-                                       ,'onIDh': '0x'+d2h(xml.getElementsByTagName('e2onid').item(0).firstChild.data, 4)
-                                        ,'onID': ownLazyNumber(xml.getElementsByTagName('e2onid').item(0).firstChild.data)
-                                       ,'sidh': '0x'+d2h(xml.getElementsByTagName('e2sid').item(0).firstChild.data, 4)
-                                        ,'sid': ownLazyNumber(xml.getElementsByTagName('e2sid').item(0).firstChild.data)
-                                 };                              
-                               $('BodyContent').innerHTML = RND(tplAbout, namespace);
-                               setBodyMainContent('BodyContent');
+                               var name = nims.item(i).getElementsByTagName("name").item(0).firstChild.data;
+                               var type = nims.item(i).getElementsByTagName("type").item(0).firstChild.data;
+                               debug("[incomingAbout]" + name);
+                               debug("[incomingAbout]" + type);
+                               ns[i] = { 'name' : name, 'type' : type};
+                               
+                       }
+                       
+                       
+                       var hdddata = xml.getElementsByTagName('e2hddinfo').item(0);
+                       
+                       var hddmodel    = hdddata.getElementsByTagName("model").item(0).firstChild.data;
+                       var hddcapacity = hdddata.getElementsByTagName("capacity").item(0).firstChild.data;
+                       var hddfree             = hdddata.getElementsByTagName("free").item(0).firstChild.data;
+
+                       namespace = {
+                               'model' : xml.getElementsByTagName('e2model').item(0).firstChild.data,  
+                               'enigmaVersion': xml.getElementsByTagName('e2enigmaversion').item(0).firstChild.data,
+                               'fpVersion': fptext,
+                               'webifversion': xml.getElementsByTagName('e2webifversion').item(0).firstChild.data,     
+                               'lanMac' : xml.getElementsByTagName('e2lanmac').item(0).firstChild.data,
+                               'lanDHCP': xml.getElementsByTagName('e2landhcp').item(0).firstChild.data,
+                               'lanIP': xml.getElementsByTagName('e2lanip').item(0).firstChild.data,
+                               'lanNetmask': xml.getElementsByTagName('e2lanmask').item(0).firstChild.data,
+                               'lanGateway': xml.getElementsByTagName('e2langw').item(0).firstChild.data,
+
+                               'hddmodel': hddmodel,
+                               'hddcapacity': hddcapacity,
+                               'hddfree': hddfree,
                                
-                       } catch (e) {
-                               debug("About parsing Error" + e);
-                       }       
+                               'serviceName': xml.getElementsByTagName('e2servicename').item(0).firstChild.data,
+                               'serviceProvider': xml.getElementsByTagName('e2serviceprovider').item(0).firstChild.data,
+                               'serviceAspect': xml.getElementsByTagName('e2serviceaspect').item(0).firstChild.data,
+                               'serviceVideosize': xml.getElementsByTagName('e2servicevideosize').item(0).firstChild.data,
+                               'serviceNamespace': xml.getElementsByTagName('e2servicenamespace').item(0).firstChild.data,
+                               
+                               'vPidh': '0x'+d2h(xml.getElementsByTagName('e2vpid').item(0).firstChild.data, 4),
+                               'vPid': ownLazyNumber(xml.getElementsByTagName('e2vpid').item(0).firstChild.data),
+                               'aPidh': '0x'+d2h(xml.getElementsByTagName('e2apid').item(0).firstChild.data, 4),
+                               'aPid': ownLazyNumber(xml.getElementsByTagName('e2apid').item(0).firstChild.data),
+                               'pcrPidh': '0x'+d2h(xml.getElementsByTagName('e2pcrid').item(0).firstChild.data, 4),
+                               'pcrPid': ownLazyNumber(xml.getElementsByTagName('e2pcrid').item(0).firstChild.data),
+                               'pmtPidh': '0x'+d2h(xml.getElementsByTagName('e2pmtpid').item(0).firstChild.data, 4),
+                               'pmtPid': ownLazyNumber(xml.getElementsByTagName('e2pmtpid').item(0).firstChild.data),
+                               'txtPidh': '0x'+d2h(xml.getElementsByTagName('e2txtpid').item(0).firstChild.data, 4),
+                               'txtPid': ownLazyNumber(xml.getElementsByTagName('e2txtpid').item(0).firstChild.data),
+                               'tsidh': '0x'+d2h(xml.getElementsByTagName('e2tsid').item(0).firstChild.data, 4),
+                               'tsid': ownLazyNumber(xml.getElementsByTagName('e2tsid').item(0).firstChild.data),
+                               'onidh': '0x'+d2h(xml.getElementsByTagName('e2onid').item(0).firstChild.data, 4),
+                               'onid': ownLazyNumber(xml.getElementsByTagName('e2onid').item(0).firstChild.data),
+                               'sidh': '0x'+d2h(xml.getElementsByTagName('e2sid').item(0).firstChild.data, 4),
+                               'sid': ownLazyNumber(xml.getElementsByTagName('e2sid').item(0).firstChild.data)
+                       };                                
+               } catch (e) {
+                       debug("[incomingAbout] About parsing Error" + e);
                }
+
+               var data = { about : namespace,
+                                tuner : ns};
+               processTpl('tplAbout', data, 'contentMain');
        }
 }
-function quotes2html(txt) {
-       txt = txt.replace(/"/g, '&quot;');
-       return txt.replace(/'/g, "\\\'");
+
+
+/*
+ * Show About Information in contentMain
+ */
+function showAbout() {
+       doRequest(url_about, incomingAbout, false);
 }
 
+
 // Spezial functions, mostly for testing purpose
 function openHiddenFunctions(){
-       openWindow("Extra Hidden Functions",tplExtraHiddenFunctions,300,100,920,0);
-}
-function restartUpdateStream() {
-       clearInterval(UpdateStreamReaderPollTimer);
-       UpdateStreamReaderRequest.abort();
-       UpdateStreamReaderRequest = null;
-       UpdateStreamReaderPollTimerCounter = 0;
-       UpdateStreamReaderStart();
+       openPopup("Extra Hidden Functions",tplExtraHiddenFunctions,300,100,920,0);
 }
+
+
 function startDebugWindow() {
        DBG = true;
-       debugWin = openWindow("DEBUG", "", 300, 300,920,140, "debugWindow");
+       debugWin = openPopup("DEBUG", "", 300, 300,920,140, "debugWindow");
 }
+
+
 function restartTwisted() {
-       new Ajax.Request( "/web/restarttwisted", { asynchronous: true, method: "get" })
+       var request = new Ajax.Request( "/web/restarttwisted", { asynchronous: true, method: "get" });
 }
+
+
 //MediaPlayer
-function loadMediaPlayer(directory){
-       debug("loading loadMediaPlayer");
-       doRequest(url_mediaplayerlist+directory, incomingMediaPlayer, false);
+function sendMediaPlayer(command) {
+       debug("[playFile] loading sendMediaPlayer");
+       var request = new Ajax.Request( url_mediaplayercmd+command, { asynchronous: true, method: 'get' });
 }
+
+
 function incomingMediaPlayer(request){
        if(request.readyState == 4){
                var files = new FileList(getXML(request)).getArray();
-               debug(getXML(request));
-               debug("have "+files.length+" entry in mediaplayer filelist");
-               listerHtml      = tplMediaPlayerHeader;
+               
+               debug("[loadMediaPlayer] Got "+files.length+" entries in mediaplayer filelist");
+               //listerHtml    = tplMediaPlayerHeader;
+               
+               var namespace = {};
 
-               root = files[0].getRoot();
+               var root = files[0].getRoot();
                if (root != "playlist") {
-                       listerHtml      = RND(tplMediaPlayerHeader, {'root': root});
+                       namespace = {'root': root};
                        if(root != '/') {
-                               re = new RegExp(/(.*)\/(.*)\/$/);
+                               var re = new RegExp(/(.*)\/(.*)\/$/);
                                re.exec(root);
-                               newroot = RegExp.$1+'/';
+                               var newroot = RegExp.$1+'/';
                                if(newroot == '//') {
                                        newroot = '/';
                                }
-                               listerHtml += RND(tplMediaPlayerItemBody, 
-                                       {'root': root
-                                       , 'servicereference': newroot
-                                       ,'exec': 'loadMediaPlayer'
-                                       ,'exec_description': 'change to directory ../'
-                                       ,'color': '000000'
-                                       ,'root': newroot
-                                       ,'name': '..'});
+                               namespace = {
+                                               'root': root,
+                                               'servicereference': newroot,
+                                               'exec': 'loadMediaPlayer',
+                                               'exec_description': 'Change to directory ../',
+                                               'color': '000000',
+                                               'newroot': newroot,
+                                               'name': '..'
+                               };      
                        }
                }
+               
+               var itemnamespace = Array();
                for ( var i = 0; i <files.length; i++){
                        var file = files[i];
                        if(file.getNameOnly() == 'None') {
                                continue;
                        }
                        var exec = 'loadMediaPlayer';
-                       var exec_description = 'change to directory' + file.getServiceReference();
-                       var color = '000000';
+                       var exec_description = 'Change to directory' + file.getServiceReference();
+                       var color = '000000';                   
+                       var isdir = 'true';
+                       
                        if (file.getIsDirectory() == "False") {
                                exec = 'playFile';
                                exec_description = 'play file';
                                color = '00BCBC';
+                               isdir = 'false';
                        }
-                       var namespace = {
-                               'servicereference': file.getServiceReference()
-                               ,'exec': exec
-                               ,'exec_description': exec_description
-                               ,'color': color
-                               ,'root': file.getRoot()
-                               ,'name': file.getNameOnly()
+                       
+                       itemnamespace[i] = {
+                               'isdir' : isdir,
+                               'servicereference': file.getServiceReference(),
+                               'exec': exec,
+                               'exec_description': exec_description,
+                               'color': color,                                                 
+                               'root': file.getRoot(),
+                               'name': file.getNameOnly()
                        };
-                       listerHtml += tplMediaPlayerItemHead;
-                       listerHtml += RND(tplMediaPlayerItemBody, namespace);
-                       if (file.getIsDirectory() == "False") {
-                               listerHtml += RND(tplMediaPlayerItemIMG, namespace);
-                       }
-                       listerHtml += tplMediaPlayerItemFooter;
+                       
                }
+               /*
                if (root == "playlist") {
                        listerHtml += tplMediaPlayerFooterPlaylist;
                }
-               listerHtml += tplMediaPlayerFooter;
-               $('BodyContent').innerHTML = listerHtml;
+               */
+               
+               var data = { mp : namespace,
+                                items: itemnamespace
+               };
+               
+               processTpl('tplMediaPlayer', data, 'contentMain');
                var sendMediaPlayerTMP = sendMediaPlayer;
                sendMediaPlayer = false;
-               setBodyMainContent('BodyContent');
+               //setBodyMainContent('BodyContent');
                sendMediaPlayer = sendMediaPlayerTMP;
        }               
 }
+
+
+function loadMediaPlayer(directory){
+       debug("[loadMediaPlayer] called");
+       doRequest(url_mediaplayerlist+directory, incomingMediaPlayer, false);
+}
+
+
 function playFile(file,root) {
-       debug("loading playFile");
+       debug("[playFile] called");
        mediaPlayerStarted = true;
-       new Ajax.Request( url_mediaplayerplay+file+"&root="+root, { asynchronous: true, method: 'get' });
-}
-function sendMediaPlayer(command) {
-       debug("loading sendMediaPlayer");
-       new Ajax.Request( url_mediaplayercmd+command, { asynchronous: true, method: 'get' });
+       var request = new Ajax.Request( url_mediaplayerplay+file+"&root="+root, { asynchronous: true, method: 'get' });
 }
+
+
 function openMediaPlayerPlaylist() {
-       debug("loading openMediaPlayerPlaylist");
+       debug("[playFile] loading openMediaPlayerPlaylist");
        doRequest(url_mediaplayerlist+"playlist", incomingMediaPlayer, false);
 }
+
+
 function writePlaylist() {
-       debug("loading writePlaylist");
-       filename = prompt("Please enter a name for the playlist", "");
-       if(filename != "") {
-               new Ajax.Request( url_mediaplayerwrite+filename, { asynchronous: true, method: 'get' });
+       debug("[playFile] loading writePlaylist");
+       var filename = prompt("Please enter a name for the playlist", "");
+       if(filename !== "") {
+               var request = new Ajax.Request( url_mediaplayerwrite+filename, { asynchronous: true, method: 'get' });
        }
 }
-function showPowerStateSendForm(){
-               $('BodyContent').innerHTML = tplPowerStateSendForm;
-}
+
+
+//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){
-       new Ajax.Request( url_powerstate+'?newstate='+newState, { asynchronous: true, method: 'get' });
-}
-function loadFileBrowser(directory,types){
-       debug("loading loadFileBrowser");
-       doRequest(url_filelist+directory+"&types="+types, incomingFileBrowser, false);  
-}
-function incomingFileBrowser(request){
-       if(request.readyState == 4){
-               var files = new FileList(getXML(request)).getArray();
-               debug(getXML(request));
-               debug("have "+files.length+" entry in filelist");
-               listerHtml      = tplFileBrowserHeader;
-               root = files[0].getRoot();
-               listerHtml      = RND(tplFileBrowserHeader, {'root': root});
-               if(root != '/') {
-                       re = new RegExp(/(.*)\/(.*)\/$/);
-                       re.exec(root);
-                       newroot = RegExp.$1+'/';
-                       if(newroot == '//') {
-                               newroot = '/';
-                       }
-                       listerHtml += RND(tplFileBrowserItemBody, 
-                               {'root': root
-                               , 'servicereference': newroot
-                               ,'exec': 'loadFileBrowser'
-                               ,'exec_description': 'change to directory ../'
-                               ,'color': '000000'
-                               ,'root': newroot
-                               ,'name': '..'});
-               }
-               for ( var i = 0; i <files.length; i++){
-                       var file = files[i];
-                       if(file.getNameOnly() == 'None') {
-                               continue;
-                       }
-                       var exec = 'loadFileBrowser';
-                       var exec_description = 'change to directory' + file.getServiceReference();
-                       var color = '000000';
-                       if (file.getIsDirectory() == "False") {
-                               exec = '';
-                               exec_description = 'do Nothing';
-                               color = '00BCBC';
-                       }
-                       var namespace = {
-                               'servicereference': file.getServiceReference()
-                               ,'exec': exec
-                               ,'exec_description': exec_description
-                               ,'color': color
-                               ,'root': file.getRoot()
-                               ,'name': file.getNameOnly()
-                       };
-                       listerHtml += tplFileBrowserItemHead;
-                       listerHtml += RND(tplFileBrowserItemBody, namespace);
-                       if (file.getIsDirectory() == "False") {
-                               listerHtml += RND(tplFileBrowserItemIMG, namespace);
-                       }
-                       listerHtml += tplFileBrowserItemFooter;
-               }
-               listerHtml += RND(tplFileBrowserFooter, {'root': root});
-               $('BodyContent').innerHTML = listerHtml;
-               setBodyMainContent('BodyContent');
-       }               
-}
+       var request = new Ajax.Request( url_powerstate+'?newstate='+newState, { asynchronous: true, method: 'get' });
+}
+
+
+//FileBrowser
+//function incomingFileBrowser(request){
+//     if(request.readyState == 4){
+//             var files = new FileList(getXML(request)).getArray();
+//
+//             debug("[incomingFileBrowser] Got " + files.length + " entry in filelist");
+//             listerHtml      = tplFileBrowserHeader;
+//             root = files[0].getRoot();
+//             listerHtml      = RND(tplFileBrowserHeader, {'root': root});
+//             if(root != '/') {
+//                     re = new RegExp(/(.*)\/(.*)\/$/);
+//                     re.exec(root);
+//                     newroot = RegExp.$1+'/';
+//                     if(newroot == '//') {
+//                             newroot = '/';
+//                     }
+//                     listerHtml += RND(tplFileBrowserItemBody, 
+//                             {'root': root,
+//                             'servicereference': newroot,
+//                             'exec': 'loadFileBrowser',
+//                             'exec_description': 'change to directory ../',
+//                             'color': '000000',
+//                             'newroot': newroot,
+//                             'name': '..'});
+//             }
+//             for ( var i = 0; i <files.length; i++){
+//                     var file = files[i];
+//                     if(file.getNameOnly() == 'None') {
+//                             continue;
+//                     }
+//                     var exec = 'loadFileBrowser';
+//                     var exec_description = 'change to directory' + file.getServiceReference();
+//                     var color = '000000';
+//                     if (file.getIsDirectory() == "False") {
+//                             exec = '';
+//                             exec_description = 'do Nothing';
+//                             color = '00BCBC';
+//                     }
+//                     var namespace = {
+//                             'servicereference': file.getServiceReference(),
+//                             'exec': exec,
+//                             'exec_description': exec_description,
+//                             'color': color,
+//                             'root': file.getRoot(),
+//                             'name': file.getNameOnly()
+//                     };
+//                     listerHtml += tplFileBrowserItemHead;
+//                     listerHtml += RND(tplFileBrowserItemBody, namespace);
+//                     if (file.getIsDirectory() == "False") {
+//                             listerHtml += RND(tplFileBrowserItemIMG, namespace);
+//                     }
+//                     listerHtml += tplFileBrowserItemFooter;
+//             }
+//             listerHtml += RND(tplFileBrowserFooter, {'root': root});
+//             $('BodyContent').innerHTML = listerHtml;
+////           setBodyMainContent('BodyContent');
+//     }               
+//}
+//
+//
+//function loadFileBrowser(directory,types){
+//     debug("[loadFileBrowser] loading loadFileBrowser");
+//     doRequest(url_filelist+directory+"&types="+types, incomingFileBrowser, false);  
+//}
+//
+//
+//function incomingDelFileResult(request) {
+//     debug("[incomingDelFileResult called]");
+//     if(request.readyState == 4){
+//             var delresult = new SimpleXMLResult(getXML(request));
+//             if(delresult.getState()){
+//                     loadFileBrowser($('path').value);
+//             }else{
+//                     messageBox("Deletion Error","Reason: "+delresult.getStateText());
+//             }
+//     }               
+//}
+
+
 function delFile(file,root) {
-       debug("loading loadMediaPlayer");
+       debug("[delFile] called");
        doRequest(url_delfile+root+file, incomingDelFileResult, false);
 }
-function incomingDelFileResult(request) {
-       debug("incomingDelFileResult");
-       if(request.readyState == 4){
-               var delresult = new SimpleXMLResult(getXML(request));
-               if(delresult.getState()){
-                       loadFileBrowser($('path').value);
-               }else{
-                       messageBox("Deletion Error","Reason: "+delresult.getStateText());
-               }
-       }               
-}
 
-// Notes
-function showNotes(){
-       debug("loading notes");
-       doRequest(url_notelist, incomingNoteList, false);
-}
 
-function incomingNoteList(request){
+//Currently Running Service
+function incomingCurrent(request){
+//     debug("[incomingCurrent called]");
        if(request.readyState == 4){
-               var notes = new NoteList(getXML(request)).getArray();
-               debug("have "+notes.length+" movies");
-               listerHtml      = tplNotesListHeader;           
-               for ( var i = 0; i <notes.length; i++){
-                       var note = notes[i];
-                       var namespace = {       
-                               'name': note.filename,
-                               'size': note.size,
-                               'ctime': note.getCTime(),
-                               'mtime': note.getMTime()
-                       };
-                       listerHtml += RND(tplNotesListItem, namespace);
-               }
-               listerHtml += tplNotesListFooter;
-               $('BodyContent').innerHTML = listerHtml;
-               setBodyMainContent('BodyContent');
+               try{
+                       var xml = getXML(request).getElementsByTagName("e2currentserviceinformation").item(0);
+                       
+                       var servicereference = xml.getElementsByTagName('e2servicereference').item(0).firstChild.data;
+                       var servicename = xml.getElementsByTagName('e2servicename').item(0).firstChild.data;
+                       var currentname = xml.getElementsByTagName('e2eventname').item(0).firstChild.data;
+                       var currentduration     = xml.getElementsByTagName('e2eventduration').item(0).firstChild.data;
+                       
+                       if(servicereference.length > 0){
+                               set('currentName', servicename + ' - ' + currentname );
+                               set('currentDuration', currentduration);
+                       } else {
+                               set('currentName', 'N/A');
+                               set('currentDuration', 'N/A');
+                       }
+               } catch (e){}
                
-       }               
-}
-function showNote(name){
-       debug("loading note "+name);
-       doRequest(url_note+name, incomingNote, false);
+       }
 }
 
-function incomingNote(request){
-       if(request.readyState == 4){
-               var note = new Note(getXML(request));
-               var namespace = {       
-                               'name': note.filename,
-                               'size': note.size,
-                               'content': note.content,
-                               'ctime': note.getCTime(),
-                               'mtime': note.getMTime()
-                       };
-               var html = RND(tplNote, namespace);
-               openWindow("Note '"+note.filename+"'", html, 400, 300,50,60);
-       }               
+
+function getCurrent(){
+       doRequest(url_getcurrent, incomingCurrent, false);
 }
-function saveNote(formid){
-       var nameold = $(formid+'_name').value;
-       var namenew = $(formid+'_namenew').value;
-       var content = $(formid+'_content').value;
-       debug("loading notes"+nameold+namenew+content);
-       doRequest(url_notelist+"?save="+nameold+"&namenew="+namenew+"&content="+content, incomingNoteSavedResult, false);       
-       Windows.closeAll();
+
+
+//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){
+       setAjaxLoad('contentMain');
+
+       var contentHeader = "";
+       switch(sRef){
+               case bouquetsTv:
+                       contentHeader = "Bouquets (TV)";
+                       break;
+               
+               case providerTv:
+                       contentHeader = "Provider (TV)";
+                       break;
+               
+               case bouquetsRadio:
+                       contentHeader = "Bouquets (Radio)";
+                       break;
+               
+               case providerRadio:
+                       contentHeader = "Provider (Radio)";
+                       break;
+               
+               default:
+                       break;
+       }
+       setContentHd(contentHeader);
        
+       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);
+}
+
+/*
+ * 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){
+       setAjaxLoad('contentMain');
+       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);
+       processTpl(template, null, 'contentMain');
+}
+
+
+/*
+ * Opens the given Extra
+ * @param extra - Extra Page as String
+ * Possible Values: power, about, message
+ */
+function openExtra(extra){
+       switch(extra){
+               case "power":
+                       loadContentStatic('tplPower', 'PowerControl');
+                       break;
+       
+               case "about":
+                       loadContentDynamic(showAbout, 'About');
+                       break;
+               
+               case "message":
+                       loadContentStatic('tplSendMessage', 'Send a Message');
+                       break;
+               
+               default:
+                       break;
+       }
 }
-function incomingNoteSavedResult(request){
-       if(request.readyState == 4){
-               var note = new Note(getXML(request));
-               if (note.saved == "True"){
-                       showNote(note.filename);
-                       showNotes();
-               }
+
+/*
+ * 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":
+                       loadContentDynamic(loadMovieList, 'Movies');
+                       break;
+                       
+               case "Timer":
+                       //The Navigation
+                       reloadNav('tplNavTimer', 'Timer');
+                       
+                       //The Timerlist
+                       loadContentDynamic(loadTimerList, 'Timer');
+                       break;
+               
+               case "MediaPlayer":
+                       loadContentDynamic(loadMediaPlayer, 'MediaPlayer');
+                       break;
+                       
+               case "Extras":
+                       reloadNav('tplNavExtras', 'Extras');
+                       break;
+               default:
+                       break;
        }
 }
-function createNote(){
-               doRequest(url_notelist+"?create=new", incomingNoteCreateResult, false);
+
+
+
+
+function updateItems(){
+       getCurrent();
 }
 
-function incomingNoteCreateResult(request){
-       if(request.readyState == 4){
-               showNotes();
+function updateItemsLazy(){
+       getSubServices();
+       getBouquetEpg();
+}
+
+var updateItemsPoller = setInterval(updateItems, 7500);
+var updateItemsLazyPoller = setInterval(updateItemsLazy, 60000);
+/*
+ * Does the everything required on initial pageload
+ */
+
+function init(){
+       if(DBG){
+               loadAndOpenDebug();
        }
+       
+       setAjaxLoad('navContent');
+       setAjaxLoad('contentMain');
+       
+       fetchTpl('tplServiceListEPGItem');
+       reloadNav('tplNavTv', 'TeleVision');
+       
+       initChannelList();
+       initVolumePanel();
+       
+       updateItems();
 }
diff --git a/webinterface/src/web-data/tpl/tplAbout.htm b/webinterface/src/web-data/tpl/tplAbout.htm
new file mode 100644 (file)
index 0000000..82c1903
--- /dev/null
@@ -0,0 +1,174 @@
+
+                                               <table id="contentTable">
+                                                       <tr>
+                                                               <td>
+                                                                       <table cellspacing="0" cellpadding="0" class="aboutSection">
+                                                                               <tr>
+                                                                                       <td class="aboutSectionLeft">
+                                                                                               <table class="fullwidth">
+                                                                                                       <tr>
+                                                                                                               <td class="fullwidth">
+                                                                                                                       <table cellspacing="0" class="about">
+                                                                                                                               <tr>
+                                                                                                                                       <th colspan="2" class="aboutHeader">Hard- & Software</th>
+                                                                                                                               </tr>
+                                                                                                                               <tr>
+                                                                                                                                       <td class="aboutElementLeft">Box Model:</td>
+                                                                                                                                       <td class="aboutElementRight">${about.model}</td>
+                                                                                                                               </tr>
+                                                                                                                               <tr>
+                                                                                                                                       <td class="aboutElementLeft">Enigma Version:</td>
+                                                                                                                                       <td class="aboutElementRight">${about.enigmaVersion}</td>
+                                                                                                                               </tr>
+                                                                                                                               <tr>
+                                                                                                                                       <td class="aboutElementLeft">Frontprozessor Version:</td>
+                                                                                                                                       <td class="aboutElementRight">${about.fpVersion}</td>
+                                                                                                                               </tr>
+                                                                                                                               <tr>
+                                                                                                                                       <td class="aboutElementLeft">Webinterface Version:</td>
+                                                                                                                                       <td class="aboutElementRight">${about.webifversion}</td>
+                                                                                                                               </tr>
+                                                                                                                       </table>
+                                                                                                               </td>
+                                                                                                       </tr>
+                                                                                                       <tr>
+                                                                                                               <td class="fullwidth">
+                                                                                                                       <table cellspacing="0" class="about">
+                                                                                                                               <tr>
+                                                                                                                                       <th colspan="2" class="aboutHeader">Detected Tuners</th>
+                                                                                                                               </tr>
+                                                                                                                               {for t in tuner}
+                                                                                                                               <tr>
+                                                                                                                                       <td class="aboutElementLeft">${t.name}:</td>
+                                                                                                                                       <td class="aboutElementRight">${t.type}</td>
+                                                                                                                               </tr>
+                                                                                                                               {/for}
+                                                                                                                       </table>
+                                                                                                               </td>
+                                                                                                       </tr>
+                                                                                                       <tr>
+                                                                                                               <td class="fullwidth">
+                                                                                                                       <table cellspacing="0" class="about">
+                                                                                                                               <tr>
+                                                                                                                                       <th colspan="2" class="aboutHeader">Harddisk</th>
+                                                                                                                               </tr>
+                                                                                                                               <tr>
+                                                                                                                                       <td class="aboutElementLeft">Model:</td>
+                                                                                                                                       <td class="aboutElementRight">${about.hddmodel}</td>
+                                                                                                                               </tr>
+                                                                                                                               <tr>
+                                                                                                                                       <td class="aboutElementLeft">Capacity:</td>
+                                                                                                                                       <td class="aboutElementRight">${about.hddcapacity}</td>
+                                                                                                                               </tr>
+                                                                                                                               <tr>
+                                                                                                                                       <td class="aboutElementLeft">Free:</td>
+                                                                                                                                       <td class="aboutElementRight">${about.hddfree}</td>
+                                                                                                                               </tr>
+                                                                                                                       </table>
+                                                                                                               </td>
+                                                                                                       </tr>
+                                                                                                       <tr>
+                                                                                                               <td class="fullwidth">
+                                                                                                                       <table cellspacing="0" class="about">
+                                                                                                                               <tr>
+                                                                                                                                       <th colspan="2" class="aboutHeader">Internal Network</th>
+                                                                                                                               </tr>                                                                                                                                                                                                                                   <tr>
+                                                                                                                                       <td class="aboutElementLeft">Mac Address:</td>
+                                                                                                                                       <td class="aboutElementRight">${about.lanMac}</td>
+                                                                                                                               </tr>
+                                                                                                                               <tr>
+                                                                                                                                       <td class="aboutElementLeft">DHCP enabled:</td>
+                                                                                                                                       <td class="aboutElementRight">${about.lanDHCP}</td>
+                                                                                                                               </tr>
+                                                                                                                               <tr>
+                                                                                                                                       <td class="aboutElementLeft">IP:</td>
+                                                                                                                                       <td class="aboutElementRight">${about.lanIP}</td>
+                                                                                                                               </tr>
+                                                                                                                               <tr>
+                                                                                                                                       <td class="aboutElementLeft">Netmask:</td>
+                                                                                                                                       <td class="aboutElementRight">${about.lanNetmask}</td>
+                                                                                                                               </tr>
+                                                                                                                               <tr>
+                                                                                                                                       <td class="aboutElementLeft">Gateway:</td>
+                                                                                                                                       <td class="aboutElementRight">${about.lanGateway}</td>
+                                                                                                                               </tr>
+                                                                                                                       </table>
+                                                                                                               </td>
+                                                                                                       </tr>
+                                                                                               </table>
+                                                                                       </td>
+                                                                                       <td class="aboutSectionRight">
+                                                                                               <table class="fullwidth">
+                                                                                                       <tr>
+                                                                                                               <td class="fullwidth">
+                                                                                                                       <table cellspacing="0" class="about">
+                                                                                                                               <tr>
+                                                                                                                                       <th colspan="2" class="aboutHeader">Serviceinfo</th>
+                                                                                                                               </tr>
+                                                                                                                               <tr>
+                                                                                                                                       <td class="aboutElementLeft">Name:</td>
+                                                                                                                                       <td class="aboutElementRight">${about.serviceName}</td>
+                                                                                                                               </tr>
+                                                                                                                               <tr>
+                                                                                                                                       <td class="aboutElementLeft">Provider:</td>
+                                                                                                                                       <td class="aboutElementRight">${about.serviceProvider}</td>
+                                                                                                                               </tr>
+                                                                                                                               <tr>
+                                                                                                                                       <td class="aboutElementLeft">Videoformat:</td>
+                                                                                                                                       <td class="aboutElementRight">${about.serviceAspect}</td>
+                                                                                                                               </tr>
+                                                                                                                               <tr>
+                                                                                                                                       <td class="aboutElementLeft">Videosize:</td>
+                                                                                                                                       <td class="aboutElementRight">${about.serviceVideosize}</td>
+                                                                                                                               </tr>
+                                                                                                                       </table>
+                                                                                                               </td>
+                                                                                                       </tr>    
+                                                                                                       <tr>
+                                                                                                               <td class="fullwidth">
+                                                                                                                       <table cellspacing="0" class="about">
+                                                                                                                               <tr>
+                                                                                                                                       <th colspan="2" class="aboutHeader">Pids</th>
+                                                                                                                               </tr>
+                                                                                                                               <tr>
+                                                                                                                                       <td class="aboutElementLeft">VideoPid:</td>
+                                                                                                                                       <td class="aboutElementRight">${about.vPidh} (${about.vPid}d)</td>
+                                                                                                                               </tr>
+                                                                                                                               <tr>
+                                                                                                                                       <td class="aboutElementLeft">AudioPid:</td>
+                                                                                                                                       <td class="aboutElementRight">${about.aPidh} (${about.aPid}d)</td>
+                                                                                                                               </tr>
+                                                                                                                               <tr>
+                                                                                                                                       <td class="aboutElementLeft">PCRPid:</td>
+                                                                                                                                       <td class="aboutElementRight">${about.pcrPidh} (${about.pcrPid}d)</td>
+                                                                                                                               </tr>
+                                                                                                                               <tr>
+                                                                                                                                       <td class="aboutElementLeft">PMTPid:</td>
+                                                                                                                                       <td class="aboutElementRight">${about.pmtPidh} (${about.pmtPid}d)</td>
+                                                                                                                               </tr>
+                                                                                                                               <tr>
+                                                                                                                                       <td class="aboutElementLeft">TXTPid:</td>
+                                                                                                                                       <td class="aboutElementRight">${about.txtPidh} (${about.txtPid}d)</td>
+                                                                                                                               </tr>
+                                                                                                                               <tr>
+                                                                                                                                       <td class="aboutElementLeft">TSID:</td>
+                                                                                                                                       <td class="aboutElementRight">${about.tsidh} (${about.tsid}d)</td>
+                                                                                                                               </tr>
+                                                                                                                               <tr>
+                                                                                                                                       <td class="aboutElementLeft">ONID:</td>
+                                                                                                                                       <td class="aboutElementRight">${about.onIDh} (${about.onid}d)</td>
+                                                                                                                               </tr>
+                                                                                                                               <tr>
+                                                                                                                                       <td class="aboutElementLeft">SID:</td>
+                                                                                                                                       <td class="aboutElementRight">${about.sidh} (${about.sid}d)</td>
+                                                                                                                               </tr>
+                                                                                                                       </table>
+                                                                                                               </td>
+                                                                                                       </tr>
+                                                                                               </table>
+                                                                                       </td>
+                                                                               </tr>
+                                                                       </table>
+                                                               </tr>
+                                                       </td>
+                                               </table>
\ No newline at end of file
diff --git a/webinterface/src/web-data/tpl/tplBouquetList.htm b/webinterface/src/web-data/tpl/tplBouquetList.htm
new file mode 100644 (file)
index 0000000..005f7bc
--- /dev/null
@@ -0,0 +1,22 @@
+
+                                               <table id="contentTable">
+                                                       {for s in services}
+                                                       <tr><td>
+                                                               <table>
+                                                                       <tr>
+                                                                               <td>                                                                            
+                                                                                       <div class="sListSName">
+                                                                                               <a id="${s.servicereference}" onclick="{ loadBouquet(this.id, this.innerHTML); }" class="sListSLink">
+                                                                                                       ${s.bouquetname}
+                                                                                               </a>
+                                                                                       </div>
+                                                                               </td>
+                                                                       </tr>
+                                                               </table>
+                                                       </td></tr>
+                                                       {forelse}
+                                                       <tr><td>
+                                                               <table><tr><td>No Bouquets to Display</td></tr></table>
+                                                       </td></tr>
+                                                       {/for}          
+                                               </table>
\ No newline at end of file
diff --git a/webinterface/src/web-data/tpl/tplDebug.htm b/webinterface/src/web-data/tpl/tplDebug.htm
new file mode 100644 (file)
index 0000000..fb5a0fe
--- /dev/null
@@ -0,0 +1,11 @@
+<!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 WebControl - DEBUG</title>
+       </head>
+       <body style="color:#000; scrollbar: auto;">
+               <div id="debugContent" style="font-size: 10px"></div>
+       </body>
+</html>
\ No newline at end of file
diff --git a/webinterface/src/web-data/tpl/tplEpgList.htm b/webinterface/src/web-data/tpl/tplEpgList.htm
new file mode 100644 (file)
index 0000000..6fb9ae7
--- /dev/null
@@ -0,0 +1,51 @@
+<!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 WebControl - EPG</title>
+               
+               <link href="/webdata/style.css" type="text/css" rel="stylesheet">
+       </head>
+       <body style="color:#000; scrollbar: auto;">
+               <table>
+                       <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 target="_blank" ><img src="/webdata/gfx/timer.png" title="Add Timer" border="0" onclick=" if( opener.parentPin( '${e.servicereference}' ) ) { opener.addTimerByID('${e.servicereference}','${e.eventid}','0'); }"></a>&nbsp;&nbsp;
+                                                               <a target="_blank" ><img src="/webdata/gfx/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 target="_blank" ><img src="/webdata/gfx/edit.gif" title="Edit and add timer" border="0" onclick="opener.loadTimerFormSeconds(0,'${e.start}','${e.end}',0,'${e.servicereference}','${e.servicename}','${e.title}','${e.description}','0',0,'${e.eventid}');"></a><br/>
+                                                               <a target="_blank" href="/web/epgsearch.rss?search=${e.title}" ><img src="/webdata/gfx/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="/webdata/gfx/world.png" title="Search IMDb" border="0"></a><br/>
+                                                       </td>
+                                               </tr>
+                                               <tr style="background-color: #AAAAAA;">
+                                                       <td colspan="3">&nbsp;</td>
+                                               </tr>
+                                       </table>
+                                       {/for}
+                               </td>
+                       </tr>
+               </table>
+       </body>
+</html>
\ No newline at end of file
diff --git a/webinterface/src/web-data/tpl/tplGrab.htm b/webinterface/src/web-data/tpl/tplGrab.htm
new file mode 100644 (file)
index 0000000..535d6ad
--- /dev/null
@@ -0,0 +1,8 @@
+
+                                               <table id="contentTable">
+                                                       <tr>
+                                                               <td>
+                                                                       <img id="grabPageImg" src="${img.src}" alt="loading image">
+                                                               </td>
+                                                       </tr>
+                                               </table>
\ No newline at end of file
diff --git a/webinterface/src/web-data/tpl/tplMediaPlayer.htm b/webinterface/src/web-data/tpl/tplMediaPlayer.htm
new file mode 100644 (file)
index 0000000..7e33162
--- /dev/null
@@ -0,0 +1,53 @@
+<table id="contentTable">
+       <tr>
+               <td>
+                       <table border="0" cellpadding="0" cellspacing="0" border="1">
+                               <thead>
+                                       <tr>
+                                               <th>
+                                                       <div class="sListHeader">MediaPlayer ${mp.root}
+                                                               <map name="mpcontrols">
+                                                               <area shape="circle" coords="17, 17, 14" nohref onclick="sendMediaPlayer('back')" alt="jump back">
+                                                               <area shape="circle" coords="54, 17, 14" nohref onclick="sendMediaPlayer('play')" alt="play">
+                                                               <area shape="circle" coords="88, 17, 14" nohref onclick="sendMediaPlayer('pause')" alt="pause">
+                                                               <area shape="circle" coords="125, 17, 14" nohref onclick="sendMediaPlayer('next')" alt="jump forward">
+                                                               <area shape="circle" coords="161, 17, 14" nohref onclick="sendMediaPlayer('stop')" alt="stop">
+                                                               </map><img src="/webdata/gfx/dvr-buttons-small-fs8.png" align="top" title="Control MediaPlayer" border="0" usemap="#mpcontrols">
+                                                               <!--  <img src="/webdata/gfx/edit.gif" onclick="openMediaPlayerPlaylist()">
+                                                                still need some work for editing --> 
+                                                       </div>
+                                                       <div class="sListSearch">
+                                                               <img src="/webdata/gfx/nok.png" align="top" title="Close MediaPlayer" border="0" onclick="sendMediaPlayer('exit')">
+                                                       </div>
+                                               </th>
+                                       </tr>
+                               </thead>
+                               <tbody>
+                                       {for item in items}
+                                       <tr>
+                                               <!-- ItemBody -->
+                                               <td>
+                                                       <div style="color: #${item.color};" onclick="${item.exec}('${item.servicereference}','${item.root}');" class="sListSName" title="${item.servicereference}">${item.name}</div>
+                                               </td>
+                                               <td>
+                                                       {if item.isdir == "false"}                                                      
+                                                       <div class="sListExt">
+                                                               <img src="/webdata/gfx/play.png" onclick="${item.exec}('${item.servicereference}','${item.root}');" title="${item.exec_description}" border="0">
+                                                               <a target="_blank" href="/file/?file=${item.name}&root=${item.root}"><img src="/webdata/gfx/save.png" title="Download File" border="0"></a>
+                                                       </div>
+                                                       {/if}
+                                               </td>
+                                       </tr>
+                                       {forelse}
+                                       <tr>
+                                               <td>Nothing to Display</td>
+                                       </tr>
+                                       {/for}
+                                       <tr>
+                                               <td colspan="7"><button onclick="writePlaylist()">Write Playlist</button></td>
+                                       </tr>
+                               </tbody>
+                       </table>
+               </td>
+       </tr>
+</table>
\ No newline at end of file
diff --git a/webinterface/src/web-data/tpl/tplMovieList.htm b/webinterface/src/web-data/tpl/tplMovieList.htm
new file mode 100644 (file)
index 0000000..08ca004
--- /dev/null
@@ -0,0 +1,56 @@
+
+                                               <table id="contentTable">
+                                                       {for movie in movies}
+                                                       <tr>
+                                                               <td class="${movie.cssclass}" >
+                                                                       <table class="sListItem">
+                                                                               <tr>
+                                                                                       <td style="width: 740px;">                                                                              
+                                                                                               <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>
+                                                                                               <a target="_blank" href="/web/ts.m3u?file=${movie.filelink}">
+                                                                                                       <img src="/webdata/gfx/screen.png" title="Stream ${movie.title}" border="0">
+                                                                                               </a>
+                                                                                       </td>
+                                                                                       <td>
+                                                                                               <a target="_blank" href="/file/?file=${movie.filelink}&root=/hdd/movie/">
+                                                                                                       <img src="/webdata/gfx/save.png" title="Download ${movie.title}" border="0">
+                                                                                               </a>
+                                                                                       </td>
+                                                                                       <td>
+                                                                                               <a target="#" onclick="delMovieFile('${movie.filename}','${movie.servicename}','${movie.title}','${movie.description}');">
+                                                                                                       <img src="/webdata/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>
diff --git a/webinterface/src/web-data/tpl/tplNavExtras.htm b/webinterface/src/web-data/tpl/tplNavExtras.htm
new file mode 100644 (file)
index 0000000..5251b45
--- /dev/null
@@ -0,0 +1,18 @@
+
+<table id="navExtras" class="navTable">
+       <tr>
+               <td><a href="#" onclick="openExtra('power');">PowerControl</a><td>
+       </tr>
+       <tr>
+               <td><a href="#" onclick="openExtra('message');">Send a Message</a><td>
+       </tr>
+       <tr>
+               <td><a href="#" onclick="loadAndOpenWebRemote();">WebRemote</a><td>
+       </tr>
+       <tr>
+               <td><a href="#" onclick="getScreenShot();">Make a Screenshot</a><td>
+       </tr>           
+       <tr>
+               <td><a href="#" onclick="openExtra('about');">About</a><td>
+       </tr>   
+</table>
\ No newline at end of file
diff --git a/webinterface/src/web-data/tpl/tplNavRadio.htm b/webinterface/src/web-data/tpl/tplNavRadio.htm
new file mode 100644 (file)
index 0000000..07ee9cd
--- /dev/null
@@ -0,0 +1,12 @@
+
+<table id="navRadio" class="navTable">
+       <tr>
+               <td><a href="#" onclick="getBouquets(bouquetsRadio);">Bouquets</a><td>
+       </tr>
+       <tr>
+               <td><a href="#" onclick="getBouquets(providerRadio);">Provider</a><td>
+       </tr>
+       <tr>
+               <td>All<td>
+       </tr>
+</table>
\ No newline at end of file
diff --git a/webinterface/src/web-data/tpl/tplNavTimer.htm b/webinterface/src/web-data/tpl/tplNavTimer.htm
new file mode 100644 (file)
index 0000000..3891c65
--- /dev/null
@@ -0,0 +1,9 @@
+
+<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>
\ No newline at end of file
diff --git a/webinterface/src/web-data/tpl/tplNavTv.htm b/webinterface/src/web-data/tpl/tplNavTv.htm
new file mode 100644 (file)
index 0000000..05397df
--- /dev/null
@@ -0,0 +1,12 @@
+
+<table id="navTv" class="navTable">
+       <tr>
+               <td><a href="#" onclick="getBouquets(bouquetsTv);">Bouquets</a><td>
+       </tr>
+       <tr>
+               <td><a href="#" onclick="getBouquets(providerTv);">Provider</a><td>
+       </tr>
+       <tr>
+               <td>All<td>
+       </tr>
+</table>
\ No newline at end of file
diff --git a/webinterface/src/web-data/tpl/tplPower.htm b/webinterface/src/web-data/tpl/tplPower.htm
new file mode 100644 (file)
index 0000000..d5760a1
--- /dev/null
@@ -0,0 +1,21 @@
+
+                                               <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>
\ No newline at end of file
diff --git a/webinterface/src/web-data/tpl/tplSendMessage.htm b/webinterface/src/web-data/tpl/tplSendMessage.htm
new file mode 100644 (file)
index 0000000..d88da72
--- /dev/null
@@ -0,0 +1,31 @@
+
+                                               <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=""></td>
+                                                                               </tr>
+                                                                               <tr>
+                                                                                       <td>Typ</td>
+                                                                                       <td>
+                                                                                               <select id="MessageSendFormType">';
+                                                                                                       <option value="1">Info</option>';
+                                                                                                       <option value="0">YesNo</option>';
+                                                                                                       <option value="2">Warning</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>
\ No newline at end of file
diff --git a/webinterface/src/web-data/tpl/tplServiceList.htm b/webinterface/src/web-data/tpl/tplServiceList.htm
new file mode 100644 (file)
index 0000000..d777f17
--- /dev/null
@@ -0,0 +1,45 @@
+
+                                               <table id="contentTable">
+                                                       {for service in services}
+                                                       <tr>
+                                                               <td class="${service.cssclass}">
+                                                                       <table class="sListItem">
+                                                                               <tr>
+                                                                                       <td style="width: 740px;">                                                                              
+                                                                                               <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 onclick="if ( parentPin( '${service.servicereference}' ) ) { loadEPGByServiceReference( '${service.servicereference}' ); }">
+                                                                                                       <img src="/webdata/gfx/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="/webdata/gfx/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>
\ No newline at end of file
diff --git a/webinterface/src/web-data/tpl/tplServiceListEPGItem.htm b/webinterface/src/web-data/tpl/tplServiceListEPGItem.htm
new file mode 100644 (file)
index 0000000..218cada
--- /dev/null
@@ -0,0 +1,7 @@
+       <table cellspacing="0">
+               <tr>
+                       <td class="epgStart">${epg.starttime}</td>
+                       <td class="epgTitle">${epg.title}</td>
+                       <td class="epgLength">${epg.length}</td>
+               </tr>
+       </table>
diff --git a/webinterface/src/web-data/tpl/tplSignalPanel.htm b/webinterface/src/web-data/tpl/tplSignalPanel.htm
new file mode 100644 (file)
index 0000000..f34ad19
--- /dev/null
@@ -0,0 +1,35 @@
+<!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 WebControl - EPG</title>
+               
+               <link href="/webdata/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>
+</html>
+
diff --git a/webinterface/src/web-data/tpl/tplSubServices.htm b/webinterface/src/web-data/tpl/tplSubServices.htm
new file mode 100644 (file)
index 0000000..1f54fa2
--- /dev/null
@@ -0,0 +1,19 @@
+                                                               
+                                                               {for s in subservices}                          
+                                                                       <table style="width: 776px;">
+                                                                               <tr>
+                                                                                       <td style="width: 756px;">                                                                              
+                                                                                               <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="/webdata/gfx/screen.png" title="Stream ${s.servicename}" border="0">
+                                                                                               </a>
+                                                                                       </td>                                                                                   
+                                                                               </tr>
+                                                                       </table>
+                                                               {/for}
\ No newline at end of file
diff --git a/webinterface/src/web-data/tpl/tplTimerEdit.htm b/webinterface/src/web-data/tpl/tplTimerEdit.htm
new file mode 100644 (file)
index 0000000..b809941
--- /dev/null
@@ -0,0 +1,151 @@
+
+                                               <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">Note: For recurring events start/end day/month are not required.</td>
+                                                                               </tr>
+                                                                               <tr>
+                                                                                       <td colspan="3">Start:</td>
+                                                                                       <td colspan="3">
+                                                                                               <select name="syear" size="1" id="syear" onchange="javascript:addTimerFormChangeTime('syear');">
+                                                                                                       {for year in syear}
+                                                                                                       <option value="${year.value}" ${year.selected}>${year.txt}</option>
+                                                                                                       {/for}
+                                                                                               </select>
+                                                                                               . 
+                                                                                               <select name="smonth" id="smonth" size="1" onchange="javascript:addTimerFormChangeTime('smonth');">
+                                                                                                       {for month in smonth}
+                                                                                                       <option value="${month.value}" ${month.selected}>${month.txt}</option>
+                                                                                                       {/for}
+                                                                                               </select>
+                                                                                               .
+                                                                                               <select name="sday" id="sday" size="1" onchange="javascript:addTimerFormChangeTime('sday');">
+                                                                                                       {for day in sday}
+                                                                                                       <option value="${day.value}" ${day.selected}>${day.txt}</option>
+                                                                                                       {/for}
+                                                                                               </select>
+                                                                                               &nbsp;-&nbsp;
+                                                                                               <select name="shour" id="shour" size="1" onchange="javascript:addTimerFormChangeTime('shour');">
+                                                                                                       {for hour in shour}
+                                                                                                       <option value="${hour.value}" ${hour.selected}>${hour.txt}</option>
+                                                                                                       {/for}
+                                                                                               </select>
+                                                                                               :
+                                                                                               <select name="smin" id="smin" size="1" onchange="javascript:addTimerFormChangeTime('smin');">
+                                                                                                       {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="eyear" id="eyear" size="1" onchange="javascript:addTimerFormChangeTime('eyear');">
+                                                                                                       {for year in eyear}
+                                                                                                       <option value="${year.value}" ${year.selected}>${year.txt}</option>
+                                                                                                       {/for}
+                                                                                               </select>
+                                                                                               .
+                                                                                               <select name="emonth" id="emonth" size="1" onchange="javascript:addTimerFormChangeTime('emonth');">
+                                                                                                       {for month in emonth}
+                                                                                                       <option value="${month.value}" ${month.selected}>${month.txt}</option>
+                                                                                                       {/for}
+                                                                                               </select>
+                                                                                               .
+                                                                                               <select name="eday" id="eday" size="1" onchange="javascript:addTimerFormChangeTime('eday');">
+                                                                                                       {for day in eday}
+                                                                                                       <option value="${day.value}" ${day.selected}>${day.txt}</option>
+                                                                                                       {/for}
+                                                                                               </select>
+                                                                                               &nbsp;-&nbsp;
+                                                                                               <select name="ehour" id="ehour" size="1" onchange="javascript:addTimerFormChangeTime('ehour');">
+                                                                                                       {for hour in ehour}
+                                                                                                       <option value="${hour.value}" ${hour.selected}>${hour.txt}</option>
+                                                                                                       {/for}
+                                                                                               </select>
+                                                                                               :
+                                                                                               <select name="emin" id="emin" size="1" onchange="javascript:addTimerFormChangeTime('emin');">
+                                                                                                       {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">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>
+                                                                                               <p><input type="radio" id="tvradio" name="tvradio" value="tv" checked onchange="javascript:addTimerFormChangeType();">TV</p>
+                                                                                               <p><input type="radio" name="tvradio" value="radio" onchange="javascript:addTimerFormChangeType();">Radio</p>
+                                                                                       <td>
+                                                                                               <p>Channel:</p>
+                                                                                               <select name="channel" id="channel" size="1" onchange="timerFormExtendChannellist($('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="100" maxlength="100" 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="100" maxlength="100" style="color: #000000;" value="${timer.description}">
+                                                                                       </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>
+                                                               </tr>
+                                                       </td>
+                                               </table>
+                                                       
diff --git a/webinterface/src/web-data/tpl/tplTimerList.htm b/webinterface/src/web-data/tpl/tplTimerList.htm
new file mode 100644 (file)
index 0000000..97ca42d
--- /dev/null
@@ -0,0 +1,46 @@
+
+                                               <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}, ${t.descriptionextended}">${t.title} (${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 target="_blank" >
+                                                                                                       <img src="/webdata/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 target="_blank" >
+                                                                                                       <img src="/webdata/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.afterevent}','${t.disabled}' );">
+                                                                                               </a>
+                                                                                               <a target="_blank" >
+                                                                                                       <img src="/webdata/img/edit.png" title="Edit timer ${t.title}" border="0" onclick="loadTimerFormSeconds('${t.justplay}','${t.begin}','${t.end}','${t.repeated}','${t.servicereference}','${t.servicename}','${t.title}','${t.description}','${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>
\ No newline at end of file
diff --git a/webinterface/src/web-data/tpl/tplWebRemote.htm b/webinterface/src/web-data/tpl/tplWebRemote.htm
new file mode 100644 (file)
index 0000000..a564f45
--- /dev/null
@@ -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>
+               
+               <script type="text/javascript" src="/webdata/lib/prototype-1.6.0.2.js"></script>
+       </head>
+       <body>
+                       <center>
+                               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 name="remotecontrol">
+                       <area shape="circle" coords="129, 54, 10" nohref onclick="opener.sendRemoteControlRequest(116)" alt="Power">
+                       <area shape="circle" coords="130, 95, 15" nohref onclick="opener.openGrabPicture()" alt="TV Screenshot">
+                       <area shape="circle" coords="63, 123, 10" nohref onclick="opener.sendRemoteControlRequest(2)" alt="1">
+                       <area shape="circle" coords="109, 123, 10" nohref onclick="opener.sendRemoteControlRequest(3)" alt="2">
+                       <area shape="circle" coords="153, 123, 10" nohref onclick="opener.sendRemoteControlRequest(4)" alt="3">
+                       <area shape="circle" coords="63, 148, 10" nohref onclick="opener.sendRemoteControlRequest(5)" alt="4">
+                       <area shape="circle" coords="109, 148, 10" nohref onclick="opener.sendRemoteControlRequest(6)" alt="5">
+                       <area shape="circle" coords="153, 148, 10" nohref onclick="opener.sendRemoteControlRequest(7)" alt="6">
+                       <area shape="circle" coords="63, 173, 10" nohref onclick="opener.sendRemoteControlRequest(8)" alt="7">
+                       <area shape="circle" coords="109, 173, 10" nohref onclick="opener.sendRemoteControlRequest(9)" alt="8">
+                       <area shape="circle" coords="153, 173, 10" nohref onclick="opener.sendRemoteControlRequest(10)" alt="9">
+                       <area shape="circle" coords="63, 197, 10" nohref onclick="opener.sendRemoteControlRequest(412)" alt="previous">
+                       <area shape="circle" coords="109, 197, 10" nohref onclick="opener.sendRemoteControlRequest(11)" alt="0">
+                       <area shape="circle" coords="153, 197, 10" nohref onclick="opener.sendRemoteControlRequest(407)" alt="next">
+                       <area shape="circle" coords="54, 243, 15" nohref onclick="opener.sendRemoteControlRequest(115)" alt="volume up">
+                       <area shape="circle" coords="107, 233, 10" nohref onclick="opener.sendRemoteControlRequest(113)" alt="mute">
+                       <area shape="circle" coords="159, 243, 15" nohref onclick="opener.sendRemoteControlRequest(402)" alt="bouquet up">
+                       <area shape="circle" coords="66, 274, 15" nohref onclick="opener.sendRemoteControlRequest(114)" alt="volume down">
+                       <area shape="circle" coords="107, 258, 10" nohref onclick="opener.sendRemoteControlRequest(174)" alt="lame">
+                       <area shape="circle" coords="147, 274, 15" nohref onclick="opener.sendRemoteControlRequest(403)" alt="bouquet down">
+                       <area shape="circle" coords="48, 306, 10" nohref onclick="opener.sendRemoteControlRequest(358)" alt="info">
+                       <area shape="circle" coords="106, 310, 15" nohref onclick="opener.sendRemoteControlRequest(103)" alt="up">
+                       <area shape="circle" coords="167, 306, 10" nohref onclick="opener.sendRemoteControlRequest(139)" alt="menu">
+                       <area shape="circle" coords="70, 343, 15" nohref onclick="opener.sendRemoteControlRequest(105)" alt="left">
+                       <area shape="circle" coords="108, 340, 15" nohref onclick="opener.sendRemoteControlRequest(352)" alt="OK">
+                       <area shape="circle" coords="146, 343, 15" nohref onclick="opener.sendRemoteControlRequest(106)" alt="right">
+                       <area shape="circle" coords="53, 381, 10" nohref onclick="opener.sendRemoteControlRequest(392)" alt="audio">
+                       <area shape="circle" coords="106, 374, 15" nohref onclick="opener.sendRemoteControlRequest(108)" alt="down">
+                       <area shape="circle" coords="162, 381, 10" nohref onclick="opener.sendRemoteControlRequest(393)" alt="video">
+                       <area shape="circle" coords="56, 421, 10" nohref onclick="opener.sendRemoteControlRequest(398)" alt="red">
+                       <area shape="circle" coords="90, 422, 10" nohref onclick="opener.sendRemoteControlRequest(399)" alt="green">
+                       <area shape="circle" coords="123, 422, 10" nohref onclick="opener.sendRemoteControlRequest(400)" alt="yellow">
+                       <area shape="circle" coords="158, 421, 10" nohref onclick="opener.sendRemoteControlRequest(401)" alt="blue">
+                       <area shape="circle" coords="61, 460, 10" nohref onclick="opener.sendRemoteControlRequest(377)" alt="tv">
+                       <area shape="circle" coords="90, 461, 10" nohref onclick="opener.sendRemoteControlRequest(385)" alt="radio">
+                       <area shape="circle" coords="123, 461, 10" nohref onclick="opener.sendRemoteControlRequest(388)" alt="text">
+                       <area shape="circle" coords="153, 460, 10" nohref onclick="opener.sendRemoteControlRequest(138)" alt="help">
+               </map>
+               <img src="/webdata/gfx/remotecontrol.jpg" height="607" width="220" border="0)" alt="Remote Control" usemap="#remotecontrol">
+
+       </body>
+</html>
\ No newline at end of file
index 7a4acf5..cab56d3 100644 (file)
@@ -3,6 +3,7 @@
        &lt;e2about>
                &lt;e2enigmaversion><e2:item name="enigmaVersion" filter="xml"/>&lt;/e2enigmaversion>
 
+               &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>
index 8cf49d4..c43bc0a 100644 (file)
@@ -1,5 +1,7 @@
-<e2:screen name="PowerWebScreen">
-       <e2:element source="PowerState" id="newstate">
-               <e2:convert type="web:ReturnEmptyXML" />
-       </e2:element>
+<e2:screen name="PowerWebScreen">&lt;?xml version="1.0" encoding="UTF-8"?>
+&lt;e2powerstate>
+       &lt;e2instandby><e2:element source="PowerState" id="newstate">
+               <e2:convert type="web:TextToHTML" />
+       </e2:element>&lt;/e2instandby>
+&lt;/e2powerstate>
 </e2:screen>
\ No newline at end of file
diff --git a/webinterface/src/web/signal.xml b/webinterface/src/web/signal.xml
new file mode 100644 (file)
index 0000000..1fbf466
--- /dev/null
@@ -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:TextToHTML" />
+               </e2:element>
+       </e2snrdb>
+       <e2snr>
+               <e2:element source="session.FrontendStatus"  id="SNR">
+                       <e2:convert type="FrontendInfo">SNR</e2:convert>
+                       <e2:convert type="web:TextToHTML" />
+               </e2:element>
+       </e2snr>
+       <e2ber>
+               <e2:element source="session.FrontendStatus"  id="BER">
+                       <e2:convert type="FrontendInfo">BER</e2:convert>
+                       <e2:convert type="web:TextToHTML" />
+               </e2:element>
+       </e2ber>
+       <e2acg>
+               <e2:element source="session.FrontendStatus"  id="AGC">
+                       <e2:convert type="FrontendInfo">AGC</e2:convert>
+                       <e2:convert type="web:TextToHTML" />
+               </e2:element>
+       </e2acg>
+</e2frontendstatus>
+</e2:screen>
\ No newline at end of file
index 8f3b69f..95690f7 100644 (file)
@@ -61,55 +61,55 @@ class WebScreen(Screen):
 
 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)
+       def __init__(self, session, request):
+               WebScreen.__init__(self, session, request)
 
 class UpdateWebScreen(WebScreen):
-       def __init__(self, session,request):
-               WebScreen.__init__(self, session,request)
+       def __init__(self, session, request):
+               WebScreen.__init__(self, session, request)
                self["CurrentTime"] = Clock()
                fav = eServiceReference(service_types_tv + ' FROM BOUQUET "bouquets.tv" ORDER BY bouquet')
 
 class MessageWebScreen(WebScreen):
-       def __init__(self, session,request):
-               WebScreen.__init__(self, session,request)
+       def __init__(self, session, request):
+               WebScreen.__init__(self, session, request)
                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)
+       def __init__(self, session, request):
+               WebScreen.__init__(self, session, request)
                self["ServiceListReload"] = ServiceListReload(session)
                
 class AudioWebScreen(WebScreen):
-       def __init__(self, session,request):
-               WebScreen.__init__(self, session,request)
+       def __init__(self, session, request):
+               WebScreen.__init__(self, session, request)
                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)
+       def __init__(self, session, request):
+               WebScreen.__init__(self, session, request)
                self["About"] = About(session)
                
 class VolumeWebScreen(WebScreen):
-       def __init__(self, session,request):
-               WebScreen.__init__(self, session,request)
+       def __init__(self, session, request):
+               WebScreen.__init__(self, session, request)
                self["Volume"] = Volume(session)
 
 class SettingsWebScreen(WebScreen):
-       def __init__(self, session,request):
-               WebScreen.__init__(self, session,request)
+       def __init__(self, session, request):
+               WebScreen.__init__(self, session, request)
                self["Settings"] = Settings(session)
 
 class SubServiceWebScreen(WebScreen):
-       def __init__(self, session,request):
-               WebScreen.__init__(self, session,request)
+       def __init__(self, session, request):
+               WebScreen.__init__(self, session, request)
                self["SubServices"] = SubServices(session)
 
 class ServiceWebScreen(WebScreen):
-       def __init__(self, session,request):
-               WebScreen.__init__(self, session,request)
+       def __init__(self, session, request):
+               WebScreen.__init__(self, session, request)
 
                fav = eServiceReference(service_types_tv + ' FROM BOUQUET "bouquets.tv" ORDER BY bouquet')
                self["SwitchService"] = ServiceList(fav, command_func = self.zapTo, validate_commands=False)
@@ -134,16 +134,16 @@ class ServiceWebScreen(WebScreen):
                """
 
 class EPGWebScreen(WebScreen):
-       def __init__(self, session,request):
-               WebScreen.__init__(self, session,request)
+       def __init__(self, session, request):
+               WebScreen.__init__(self, session, request)
                self["EPGTITLE"] = EPG(session,func=EPG.TITLE)
                self["EPGSERVICE"] = EPG(session,func=EPG.SERVICE)
                self["EPGNOW"] = EPG(session,func=EPG.NOW)
                self["EPGNEXT"] = EPG(session,func=EPG.NEXT)
 
 class MovieWebScreen(WebScreen):
-       def __init__(self, session,request):
-               WebScreen.__init__(self, session,request)
+       def __init__(self, session, request):
+               WebScreen.__init__(self, session, request)
                from Components.MovieList import MovieList
                from Tools.Directories import resolveFilename,SCOPE_HDD
                movielist = MovieList(eServiceReference("2:0:1:0:0:0:0:0:0:0:" + resolveFilename(SCOPE_HDD)))
@@ -152,27 +152,27 @@ class MovieWebScreen(WebScreen):
                self["MovieTags"] = Movie(session,movielist,func = Movie.TAGS)
 
 class MediaPlayerWebScreen(WebScreen):
-       def __init__(self, session,request):
-               WebScreen.__init__(self, session,request)
+       def __init__(self, session, request):
+               WebScreen.__init__(self, session, request)
                self["FileList"] = MP(session,func = MP.LIST)
                self["PlayFile"] = MP(session,func = MP.PLAY)
                self["Command"] = MP(session,func = MP.COMMAND)
                self["WritePlaylist"] = MP(session,func = MP.WRITEPLAYLIST)
                
 class AutoTimerWebScreen(WebScreen):
-       def __init__(self, session,request):
-               WebScreen.__init__(self, session,request)
+       def __init__(self, session, request):
+               WebScreen.__init__(self, session, request)
                self["AutoTimerList"] = AT(session,func = AT.LIST)
                self["AutoTimerWrite"] = AT(session,func = AT.WRITE)
 
 class FilesWebScreen(WebScreen):
-       def __init__(self, session,request):
-               WebScreen.__init__(self, session,request)
+       def __init__(self, session, request):
+               WebScreen.__init__(self, session, request)
                self["DelFile"] = Files(session,func = Files.DEL)
                
 class TimerWebScreen(WebScreen):
-       def __init__(self, session,request):
-               WebScreen.__init__(self, session,request)
+       def __init__(self, session, request):
+               WebScreen.__init__(self, session, request)
                self["TimerList"] = Timer(session,func = Timer.LIST)
                self["TimerAddEventID"] = Timer(session,func = Timer.ADDBYID)
                self["TimerAdd"] = Timer(session,func = Timer.ADD)
@@ -183,23 +183,23 @@ class TimerWebScreen(WebScreen):
                self["RecordNow"] = Timer(session,func = Timer.RECNOW)
 
 class RemoteWebScreen(WebScreen):
-       def __init__(self, session,request):
-               WebScreen.__init__(self, session,request)
+       def __init__(self, session, request):
+               WebScreen.__init__(self, session, request)
                self["RemoteControl"] = RemoteControl(session)
 
 class PowerWebScreen(WebScreen):
-       def __init__(self, session,request):
-               WebScreen.__init__(self, session,request)
+       def __init__(self, session, request):
+               WebScreen.__init__(self, session, request)
                self["PowerState"] = PowerState(session)
 
 class ParentControlWebScreen(WebScreen):
-       def __init__(self, session,request):
-               WebScreen.__init__(self, session,request)
+       def __init__(self, session, request):
+               WebScreen.__init__(self, session, request)
                self["ParentControlList"] = ParentControl(session)
                                
 class WAPWebScreen(WebScreen):
-       def __init__(self, session,request):
-               WebScreen.__init__(self, session,request)
+       def __init__(self, session, request):
+               WebScreen.__init__(self, session, request)
                self["WAPFillOptionListSyear"] = WAPfunctions(session,func = WAPfunctions.LISTTIME)
                self["WAPFillOptionListSday"] = WAPfunctions(session,func = WAPfunctions.LISTTIME)
                self["WAPFillOptionListSmonth"] = WAPfunctions(session,func = WAPfunctions.LISTTIME)
@@ -224,14 +224,14 @@ class WAPWebScreen(WebScreen):
                self["WAPdeleteOldOnSave"] = WAPfunctions(session,func = WAPfunctions.DELETEOLD)
        
 class StreamingWebScreen(WebScreen):
-       def __init__(self, session,request):
-               WebScreen.__init__(self, session,request)
+       def __init__(self, session, request):
+               WebScreen.__init__(self, session, request)
                from Components.Sources.StreamService import StreamService
                self["StreamService"] = StreamService(self.session.nav)
 
 class M3UStreamingWebScreen(WebScreen):
-       def __init__(self, session,request):
-               WebScreen.__init__(self, session,request)
+       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
@@ -239,8 +239,8 @@ class M3UStreamingWebScreen(WebScreen):
                self["localip"] = RequestData(request,what=RequestData.HOST)
 
 class TsM3U(WebScreen):
-       def __init__(self, session,request):
-               WebScreen.__init__(self, session,request)
+       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
@@ -248,14 +248,14 @@ class TsM3U(WebScreen):
                self["localip"] = RequestData(request,what=RequestData.HOST)
 
 class RestartWebScreen(WebScreen):
-       def __init__(self, session,request):
-               WebScreen.__init__(self, session,request)
+       def __init__(self, session, request):
+               WebScreen.__init__(self, session, request)
                import plugin
                plugin.restartWebserver()
                
 class GetPid(WebScreen):
-      def __init__(self, session,request):
-         WebScreen.__init__(self, session,request)
+      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()