New Chameleon theme from
authormoodler <moodler>
Tue, 31 Jan 2006 06:05:33 +0000 (06:05 +0000)
committermoodler <moodler>
Tue, 31 Jan 2006 06:05:33 +0000 (06:05 +0000)
    Urs Hunkler - http://www.unodo.de
    Andrew Walker - http://www.altoncollege.ac.uk

188 files changed:
theme/chameleon/README.html [new file with mode: 0644]
theme/chameleon/config.php [new file with mode: 0644]
theme/chameleon/favicon.ico [new file with mode: 0644]
theme/chameleon/footer.html [new file with mode: 0644]
theme/chameleon/header.html [new file with mode: 0644]
theme/chameleon/pix/c/course.gif [new file with mode: 0644]
theme/chameleon/pix/c/event.gif [new file with mode: 0644]
theme/chameleon/pix/c/group.gif [new file with mode: 0644]
theme/chameleon/pix/c/site.gif [new file with mode: 0644]
theme/chameleon/pix/c/user.gif [new file with mode: 0644]
theme/chameleon/pix/colorstrip.gif [new file with mode: 0644]
theme/chameleon/pix/css.gif [new file with mode: 0644]
theme/chameleon/pix/f/audio.gif [new file with mode: 0644]
theme/chameleon/pix/f/avi.gif [new file with mode: 0644]
theme/chameleon/pix/f/edit.gif [new file with mode: 0644]
theme/chameleon/pix/f/env.gif [new file with mode: 0644]
theme/chameleon/pix/f/excel.gif [new file with mode: 0644]
theme/chameleon/pix/f/explore.gif [new file with mode: 0644]
theme/chameleon/pix/f/flash.gif [new file with mode: 0644]
theme/chameleon/pix/f/folder.gif [new file with mode: 0644]
theme/chameleon/pix/f/help.gif [new file with mode: 0644]
theme/chameleon/pix/f/html.gif [new file with mode: 0644]
theme/chameleon/pix/f/image.gif [new file with mode: 0644]
theme/chameleon/pix/f/jbc.gif [new file with mode: 0644]
theme/chameleon/pix/f/jcl.gif [new file with mode: 0644]
theme/chameleon/pix/f/jcw.gif [new file with mode: 0644]
theme/chameleon/pix/f/jmt.gif [new file with mode: 0644]
theme/chameleon/pix/f/jmx.gif [new file with mode: 0644]
theme/chameleon/pix/f/jqz.gif [new file with mode: 0644]
theme/chameleon/pix/f/move.gif [new file with mode: 0644]
theme/chameleon/pix/f/odt.gif [new file with mode: 0644]
theme/chameleon/pix/f/parent.gif [new file with mode: 0644]
theme/chameleon/pix/f/pdf.gif [new file with mode: 0644]
theme/chameleon/pix/f/powerpoint.gif [new file with mode: 0644]
theme/chameleon/pix/f/text.gif [new file with mode: 0644]
theme/chameleon/pix/f/unknown.gif [new file with mode: 0644]
theme/chameleon/pix/f/video.gif [new file with mode: 0644]
theme/chameleon/pix/f/web.gif [new file with mode: 0644]
theme/chameleon/pix/f/word.gif [new file with mode: 0644]
theme/chameleon/pix/f/xml.gif [new file with mode: 0644]
theme/chameleon/pix/f/zip.gif [new file with mode: 0644]
theme/chameleon/pix/g/f1.png [new file with mode: 0644]
theme/chameleon/pix/g/f2.png [new file with mode: 0644]
theme/chameleon/pix/help.gif [new file with mode: 0644]
theme/chameleon/pix/i/admin.gif [new file with mode: 0644]
theme/chameleon/pix/i/all.gif [new file with mode: 0644]
theme/chameleon/pix/i/backup.gif [new file with mode: 0644]
theme/chameleon/pix/i/course.gif [new file with mode: 0644]
theme/chameleon/pix/i/db.gif [new file with mode: 0644]
theme/chameleon/pix/i/edit.gif [new file with mode: 0644]
theme/chameleon/pix/i/email.gif [new file with mode: 0644]
theme/chameleon/pix/i/files.gif [new file with mode: 0644]
theme/chameleon/pix/i/grades.gif [new file with mode: 0644]
theme/chameleon/pix/i/group.gif [new file with mode: 0644]
theme/chameleon/pix/i/guest.gif [new file with mode: 0644]
theme/chameleon/pix/i/hide.gif [new file with mode: 0644]
theme/chameleon/pix/i/info.gif [new file with mode: 0644]
theme/chameleon/pix/i/key.gif [new file with mode: 0644]
theme/chameleon/pix/i/log.gif [new file with mode: 0644]
theme/chameleon/pix/i/marked.gif [new file with mode: 0644]
theme/chameleon/pix/i/marker.gif [new file with mode: 0644]
theme/chameleon/pix/i/new.gif [new file with mode: 0644]
theme/chameleon/pix/i/news.gif [new file with mode: 0644]
theme/chameleon/pix/i/one.gif [new file with mode: 0644]
theme/chameleon/pix/i/report.gif [new file with mode: 0644]
theme/chameleon/pix/i/restore.gif [new file with mode: 0644]
theme/chameleon/pix/i/rss.gif [new file with mode: 0644]
theme/chameleon/pix/i/rsssitelogo.gif [new file with mode: 0644]
theme/chameleon/pix/i/scales.gif [new file with mode: 0644]
theme/chameleon/pix/i/search.gif [new file with mode: 0644]
theme/chameleon/pix/i/settings.gif [new file with mode: 0644]
theme/chameleon/pix/i/show.gif [new file with mode: 0644]
theme/chameleon/pix/i/switch.gif [new file with mode: 0644]
theme/chameleon/pix/i/user.gif [new file with mode: 0644]
theme/chameleon/pix/i/users.gif [new file with mode: 0644]
theme/chameleon/pix/m/USD.gif [new file with mode: 0644]
theme/chameleon/pix/mod/README.txt [new file with mode: 0644]
theme/chameleon/pix/mod/index.html [new file with mode: 0644]
theme/chameleon/pix/movehere.gif [new file with mode: 0644]
theme/chameleon/pix/pix/b.gif [new file with mode: 0644]
theme/chameleon/pix/pix/help.gif [new file with mode: 0644]
theme/chameleon/pix/rightarrow2.gif [new file with mode: 0644]
theme/chameleon/pix/s/angry.gif [new file with mode: 0644]
theme/chameleon/pix/s/approve.gif [new file with mode: 0644]
theme/chameleon/pix/s/biggrin.gif [new file with mode: 0644]
theme/chameleon/pix/s/blackeye.gif [new file with mode: 0644]
theme/chameleon/pix/s/blush.gif [new file with mode: 0644]
theme/chameleon/pix/s/clown.gif [new file with mode: 0644]
theme/chameleon/pix/s/cool.gif [new file with mode: 0644]
theme/chameleon/pix/s/dead.gif [new file with mode: 0644]
theme/chameleon/pix/s/evil.gif [new file with mode: 0644]
theme/chameleon/pix/s/kiss.gif [new file with mode: 0644]
theme/chameleon/pix/s/mixed.gif [new file with mode: 0644]
theme/chameleon/pix/s/s_r2_c40.gif [new file with mode: 0644]
theme/chameleon/pix/s/sad.gif [new file with mode: 0644]
theme/chameleon/pix/s/shy.gif [new file with mode: 0644]
theme/chameleon/pix/s/sleepy.gif [new file with mode: 0644]
theme/chameleon/pix/s/smiley.gif [new file with mode: 0644]
theme/chameleon/pix/s/surprise.gif [new file with mode: 0644]
theme/chameleon/pix/s/thoughtful.gif [new file with mode: 0644]
theme/chameleon/pix/s/tongueout.gif [new file with mode: 0644]
theme/chameleon/pix/s/toughtful.gif [new file with mode: 0644]
theme/chameleon/pix/s/wideeyes.gif [new file with mode: 0644]
theme/chameleon/pix/s/wink.gif [new file with mode: 0644]
theme/chameleon/pix/section_508.gif [new file with mode: 0644]
theme/chameleon/pix/spacer.gif [new file with mode: 0644]
theme/chameleon/pix/switch_minus.gif [new file with mode: 0644]
theme/chameleon/pix/switch_plus.gif [new file with mode: 0644]
theme/chameleon/pix/t/backup.gif [new file with mode: 0644]
theme/chameleon/pix/t/clear.gif [new file with mode: 0644]
theme/chameleon/pix/t/copy.gif [new file with mode: 0644]
theme/chameleon/pix/t/delete.gif [new file with mode: 0644]
theme/chameleon/pix/t/down.gif [new file with mode: 0644]
theme/chameleon/pix/t/edit.gif [new file with mode: 0644]
theme/chameleon/pix/t/email.gif [new file with mode: 0644]
theme/chameleon/pix/t/emailno.gif [new file with mode: 0644]
theme/chameleon/pix/t/go.gif [new file with mode: 0644]
theme/chameleon/pix/t/groupn.gif [new file with mode: 0644]
theme/chameleon/pix/t/groups.gif [new file with mode: 0644]
theme/chameleon/pix/t/groupv.gif [new file with mode: 0644]
theme/chameleon/pix/t/hide.gif [new file with mode: 0644]
theme/chameleon/pix/t/left.gif [new file with mode: 0644]
theme/chameleon/pix/t/log.gif [new file with mode: 0644]
theme/chameleon/pix/t/message.gif [new file with mode: 0644]
theme/chameleon/pix/t/move.gif [new file with mode: 0644]
theme/chameleon/pix/t/moveleft.gif [new file with mode: 0644]
theme/chameleon/pix/t/moveright.gif [new file with mode: 0644]
theme/chameleon/pix/t/preview.gif [new file with mode: 0644]
theme/chameleon/pix/t/restore.gif [new file with mode: 0644]
theme/chameleon/pix/t/right.gif [new file with mode: 0644]
theme/chameleon/pix/t/show.gif [new file with mode: 0644]
theme/chameleon/pix/t/stop.gif [new file with mode: 0644]
theme/chameleon/pix/t/switch.gif [new file with mode: 0644]
theme/chameleon/pix/t/switch_minus.gif [new file with mode: 0644]
theme/chameleon/pix/t/switch_plus.gif [new file with mode: 0644]
theme/chameleon/pix/t/up.gif [new file with mode: 0644]
theme/chameleon/pix/t/user.gif [new file with mode: 0644]
theme/chameleon/pix/t/usernot.gif [new file with mode: 0644]
theme/chameleon/pix/tab/left.gif [new file with mode: 0644]
theme/chameleon/pix/tab/left2.gif [new file with mode: 0644]
theme/chameleon/pix/tab/left_active.gif [new file with mode: 0644]
theme/chameleon/pix/tab/left_active2.gif [new file with mode: 0644]
theme/chameleon/pix/tab/left_hover.gif [new file with mode: 0644]
theme/chameleon/pix/tab/left_hover2.gif [new file with mode: 0644]
theme/chameleon/pix/tab/left_inactive.gif [new file with mode: 0644]
theme/chameleon/pix/tab/left_inactive2.gif [new file with mode: 0644]
theme/chameleon/pix/tab/right.gif [new file with mode: 0644]
theme/chameleon/pix/tab/right2.gif [new file with mode: 0644]
theme/chameleon/pix/tab/right_active.gif [new file with mode: 0644]
theme/chameleon/pix/tab/right_active2.gif [new file with mode: 0644]
theme/chameleon/pix/tab/right_end.gif [new file with mode: 0644]
theme/chameleon/pix/tab/right_end2.gif [new file with mode: 0644]
theme/chameleon/pix/tab/right_hover.gif [new file with mode: 0644]
theme/chameleon/pix/tab/right_hover2.gif [new file with mode: 0644]
theme/chameleon/pix/tab/right_inactive.gif [new file with mode: 0644]
theme/chameleon/pix/tab/right_inactive2.gif [new file with mode: 0644]
theme/chameleon/pix/tab/tabsbg.gif [new file with mode: 0644]
theme/chameleon/pix/tab/tabsbg2.gif [new file with mode: 0644]
theme/chameleon/pix/tab/tabsbg_x2.gif [new file with mode: 0644]
theme/chameleon/pix/u/f1.png [new file with mode: 0644]
theme/chameleon/pix/u/f1_old.png [new file with mode: 0644]
theme/chameleon/pix/u/f2.png [new file with mode: 0644]
theme/chameleon/pix/u/f2_old.png [new file with mode: 0644]
theme/chameleon/pix/xhtml_1_0.gif [new file with mode: 0644]
theme/chameleon/styles.php [new file with mode: 0644]
theme/chameleon/styles_layout.css [new file with mode: 0644]
theme/chameleon/temp_user_styles.css [new file with mode: 0644]
theme/chameleon/ui/ChameleonCSS.class.php [new file with mode: 0644]
theme/chameleon/ui/ChameleonFileBrowser.class.php [new file with mode: 0644]
theme/chameleon/ui/chameleon_js.php [new file with mode: 0644]
theme/chameleon/ui/chameleon_ui.css [new file with mode: 0644]
theme/chameleon/ui/css.php [new file with mode: 0644]
theme/chameleon/ui/css_query.js [new file with mode: 0644]
theme/chameleon/ui/images/active_tab.gif [new file with mode: 0644]
theme/chameleon/ui/images/error.gif [new file with mode: 0644]
theme/chameleon/ui/images/folder.gif [new file with mode: 0644]
theme/chameleon/ui/images/grad.gif [new file with mode: 0644]
theme/chameleon/ui/images/hotspot.gif [new file with mode: 0644]
theme/chameleon/ui/images/image.gif [new file with mode: 0644]
theme/chameleon/ui/images/inactive_tab.gif [new file with mode: 0644]
theme/chameleon/ui/images/none.gif [new file with mode: 0644]
theme/chameleon/ui/images/notice.gif [new file with mode: 0644]
theme/chameleon/ui/images/ok.gif [new file with mode: 0644]
theme/chameleon/ui/images/parent.gif [new file with mode: 0644]
theme/chameleon/ui/images/tag.gif [new file with mode: 0644]
theme/chameleon/ui/images/working.gif [new file with mode: 0644]
theme/chameleon/ui/sarissa.js [new file with mode: 0644]
theme/chameleon/user_styles.css [new file with mode: 0644]

diff --git a/theme/chameleon/README.html b/theme/chameleon/README.html
new file mode 100644 (file)
index 0000000..4a723fc
--- /dev/null
@@ -0,0 +1,3 @@
+<h3>Chameleon, the flexible Moodle theme.</h3>
+
+<p>A Moodle Theme from <strong>Urs Hunkler, <a href="http://www.unodo.de" target="_blank">unodo</a> and Andrew Walker, <a href="http://www.altoncollege.ac.uk/" title="External link">Alton College</a></strong>.</p>
\ No newline at end of file
diff --git a/theme/chameleon/config.php b/theme/chameleon/config.php
new file mode 100644 (file)
index 0000000..63f01e3
--- /dev/null
@@ -0,0 +1,134 @@
+<?PHP // $Id$\r
+\r
+////////////////////////////////////////////////////////////////////////////////\r
+/// This file contains a few configuration variables that control \r
+/// how Moodle uses this theme.\r
+////////////////////////////////////////////////////////////////////////////////\r
+\r
+\r
+$THEME->sheets = array('styles_layout', 'user_styles');\r
+\r
+/// This variable is an array containing the names of all the \r
+/// stylesheet files you want included in this theme, and in what order\r
+////////////////////////////////////////////////////////////////////////////////\r
+\r
+\r
+$THEME->standardsheets = array('styles_layout');\r
+\r
+/// This variable can be set to an array containing\r
+/// filenames from the *STANDARD* theme.  If the \r
+/// array exists, it will be used to choose the \r
+/// files to include in the standard style sheet.\r
+/// When false, then no files are used.\r
+/// When true or NON-EXISTENT, then ALL standard files are used.\r
+/// This parameter can be used, for example, to prevent \r
+/// having to override too many classes.\r
+/// Note that the trailing .css should not be included\r
+/// eg $THEME->standardsheets = array('styles_layout','styles_fonts','styles_color');\r
+////////////////////////////////////////////////////////////////////////////////\r
+\r
+\r
+$THEME->parent = '';  \r
+\r
+/// This variable can be set to the name of a parent theme\r
+/// which you want to have included before the current theme.\r
+/// This can make it easy to make modifications to another \r
+/// theme without having to actually change the files\r
+/// If this variable is empty or false then a parent theme \r
+/// is not used.\r
+////////////////////////////////////////////////////////////////////////////////\r
+\r
+\r
+$THEME->parentsheets = false;  \r
+\r
+/// This variable can be set to an array containing\r
+/// filenames from a chosen *PARENT* theme.  If the \r
+/// array exists, it will be used to choose the \r
+/// files to include in the standard style sheet.\r
+/// When false, then no files are used.\r
+/// When true or NON-EXISTENT, then ALL standard files are used.\r
+/// This parameter can be used, for example, to prevent \r
+/// having to override too many classes.\r
+/// Note that the trailing .css should not be included\r
+/// eg $THEME->parentsheets = array('styles_layout','styles_fonts','styles_color');\r
+////////////////////////////////////////////////////////////////////////////////\r
+\r
+\r
+$THEME->modsheets = true;  \r
+\r
+/// When this is enabled, then this theme will search for \r
+/// files named "styles.php" inside all Activity modules and \r
+/// include them.   This allows modules to provide some basic \r
+/// layouts so they work out of the box.\r
+/// It is HIGHLY recommended to leave this enabled.\r
+\r
+\r
+$THEME->blocksheets = true;  \r
+\r
+/// When this is enabled, then this theme will search for \r
+/// files named "styles.php" inside all Block modules and \r
+/// include them.   This allows Blocks to provide some basic \r
+/// layouts so they work out of the box.\r
+/// It is HIGHLY recommended to leave this enabled.\r
+\r
+\r
+$THEME->langsheets = false;  \r
+\r
+/// By setting this to true, then this theme will search for \r
+/// a file named "styles.php" inside the current language\r
+/// directory.  This allows different languages to provide \r
+/// different styles.\r
+\r
+\r
+$THEME->navmenuwidth = 5;\r
+\r
+/// You can use this to control the cutoff point for strings \r
+/// in the navmenus (list of activities in popup menu etc)\r
+/// Default is 50 characters wide.\r
+\r
+\r
+$THEME->makenavmenulist = false;\r
+\r
+/// By setting this to true, then you will have access to a\r
+/// new variable in your header.html and footer.html called\r
+/// $navmenulist ... this contains a simple XHTML menu of \r
+/// all activities in the current course, mostly useful for \r
+/// creating popup navigation menus and so on.\r
+\r
+\r
+$THEME->chameleonenabled = true;\r
+\r
+/// By setting this to false it disables editing of the stylsheets\r
+/// this saves the overhead of loading chameleon on each page \r
+/// viewed by a user who can edit pages. it is recommended to \r
+/// set this to false once you're satisfied with your theme.\r
+\r
+\r
+\r
+$THEME->resource_mp3player_colors = \r
+ 'bgColour=000000&btnColour=ffffff&btnBorderColour=cccccc&iconColour=000000&'.\r
+ 'iconOverColour=00cc00&trackColour=cccccc&handleColour=ffffff&loaderColour=ffffff&'.\r
+ 'font=Arial&fontColour=3333FF&buffer=10&waitForPlay=no&autoPlay=yes';\r
+\r
+/// With this you can control the colours of the "big" MP3 player \r
+/// that is used for MP3 resources.\r
+\r
+\r
+$THEME->filter_mediaplugin_colors = \r
+ 'bgColour=000000&btnColour=ffffff&btnBorderColour=cccccc&iconColour=000000&'.\r
+ 'iconOverColour=00cc00&trackColour=cccccc&handleColour=ffffff&loaderColour=ffffff&'.\r
+ 'waitForPlay=yes';\r
+\r
+/// ...And this controls the small embedded player\r
+\r
+\r
+$THEME->custompix = true;\r
+\r
+/// If true, then this theme must have a "pix" \r
+/// subdirectory that contains copies of all \r
+/// files from the moodle/pix directory, plus a\r
+/// "pix/mod" directory containing all the icons \r
+/// for all the activity modules.\r
+////////////////////////////////////////////////////////////////////////////////\r
+\r
+?>\r
diff --git a/theme/chameleon/favicon.ico b/theme/chameleon/favicon.ico
new file mode 100644 (file)
index 0000000..5a7a36a
Binary files /dev/null and b/theme/chameleon/favicon.ico differ
diff --git a/theme/chameleon/footer.html b/theme/chameleon/footer.html
new file mode 100644 (file)
index 0000000..990aa94
--- /dev/null
@@ -0,0 +1,17 @@
+\r
+</div> <!-- end div containerContent -->\r
+<!-- START OF FOOTER -->\r
+<?php global $CFG, $course; ?>\r
+<div id="footer">\r
+<?php echo $loggedinas ?>\r
+<?php echo $homelink ?>\r
+<!-- <p><div class="homelink"><a target="<?php echo $CFG->framename ?>" href="<?php $CFG->wwwroot ?>/course/view.php?id=<?php $course->id ?>"> <?php $course->shortname ?> </a></div></p> -->\r
+<p>\r
+<!-- <<a href="http://validator.w3.org/check?verbose=1&amp;ss=1&amp;uri=<?php echo urlencode(qualified_me()) ?>"><img src="<?php echo "$CFG->wwwroot/theme/$CFG->theme" ?>/xhtml_1_0.gif" alt="XHTML Validator" /></a>\r
+<a href="http://jigsaw.w3.org/css-validator/validator?uri=<?php echo urlencode(qualified_me()) ?>&amp;warning=1&amp;profile=css2&amp;usermedium=all"><img src="<?php echo "$CFG->wwwroot/theme/$CFG->theme" ?>/css.gif" alt="CSS Validator" /></a> \r
+<a href="http://www.contentquality.com/mynewtester/cynthia.exe?rptmode=-1&amp;url1=<?php echo urlencode(qualified_me()) ?>"><img src="<?php echo "$CFG->wwwroot/theme/$CFG->theme" ?>/section_508.gif" alt="Section 508 Validator" /></a> -->\r
+</p>\r
+</div>\r
+</div>\r
+</body>\r
+</html>\r
diff --git a/theme/chameleon/header.html b/theme/chameleon/header.html
new file mode 100644 (file)
index 0000000..873aafa
--- /dev/null
@@ -0,0 +1,85 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">\r
+<html<?php echo $direction ?>>\r
+<head>\r
+    <?php echo $meta ?>\r
+    <meta name="keywords" content="moodle, <?php echo $title ?> " />\r
+    <title><?php echo $title ?></title>\r
+    <link rel="shortcut icon" href="<?php echo "$CFG->wwwroot/theme/$CFG->theme" ?>/favicon.ico" />\r
+    \r
+    <?php\r
+    \r
+       \r
+    if (isset($THEME->chameleonenabled) && $THEME->chameleonenabled) {\r
+        $chameleon_isadmin = isadmin();\r
+        $chameleon_isteacher = false;\r
+        if (isset($course->id)) {\r
+            $chameleon_courseparam = '?id=' . $course->id;\r
+            if (!$chameleon_isadmin) {\r
+                $chameleon_isteacher = (isteacher($course->id) && isset($CFG->coursetheme));\r
+            }\r
+        } else {\r
+            $chameleon_courseparam = '';\r
+        }\r
+\r
+        if ($chameleon_isadmin || $chameleon_isteacher) { \r
+            // either we're an admin or we're a teacher and this is being used as the course theme\r
+            // if we're on a page using a course theme edit that, otherwise edit the main chameleon theme\r
+            $chameleon_theme = (isset($CFG->coursetheme)) ? $CFG->coursetheme : $CFG->theme;\r
+        \r
+    \r
+    ?>\r
+    \r
+    <style type="text/css"> @import '<?php echo "$CFG->wwwroot/theme/$chameleon_theme" ?>/ui/chameleon_ui.css'; </style>\r
+    \r
+    <script type="text/javascript" src="<?php echo "$CFG->wwwroot/theme/$chameleon_theme/ui/css_query.js" ?>"> </script>\r
+    <script type="text/javascript" src="<?php echo "$CFG->wwwroot/theme/$chameleon_theme/ui/sarissa.js" ?>"> </script>\r
+    <script type="text/javascript" src="<?php echo "$CFG->wwwroot/theme/$chameleon_theme/ui/chameleon_js.php$chameleon_courseparam" ?>"> </script>\r
+    \r
+    <?php\r
+    \r
+        }\r
+    }\r
+    \r
+    ?>\r
+\r
+\r
+    <?php include("$CFG->javascript"); ?>\r
+    \r
+\r
+    \r
+    \r
+</head>\r
+\r
+<body<?php\r
+    echo " $bodytags";\r
+    if ($focus) {\r
+        echo " onload=\"setfocus()\"";\r
+    };\r
+    ?>>\r
+    \r
+<div id="page">\r
+    \r
+<?php if ($home) {  // This is what gets printed on the home page only  \r
+?>\r
+    <div id="header-home">\r
+      <div class="headermain"><?php echo $heading ?></div>\r
+      <div class="headermenu"><?php echo $menu ?></div>\r
+    </div>\r
+    <div class="navbar">\r
+    </div>\r
+<?php } else if ($heading) {  // This is what gets printed on any other page with a heading \r
+?>\r
+    <div id="header">\r
+        <div class="headermain"><?php echo $heading ?></div>\r
+        <div class="headermenu"><?php echo $menu ?></div>\r
+        <!-- <div class="headermenu"><div id="new-menu"><?php echo $navmenulist ?></div></div> -->\r
+    </div>\r
+<?php } ?>\r
+<?php if ($navigation) { // This is the navigation table with breadcrumbs  ?>\r
+    <div class="navbar">\r
+        <div class="breadcrumb"><?php print_navigation("$navigation"); ?></div>\r
+        <div class="navbutton"><?php echo $button; ?></div>\r
+    </div>\r
+<?php } ?>\r
+    <!-- END OF HEADER -->\r
+<div id="content">
\ No newline at end of file
diff --git a/theme/chameleon/pix/c/course.gif b/theme/chameleon/pix/c/course.gif
new file mode 100644 (file)
index 0000000..71f1c8b
Binary files /dev/null and b/theme/chameleon/pix/c/course.gif differ
diff --git a/theme/chameleon/pix/c/event.gif b/theme/chameleon/pix/c/event.gif
new file mode 100644 (file)
index 0000000..2c534be
Binary files /dev/null and b/theme/chameleon/pix/c/event.gif differ
diff --git a/theme/chameleon/pix/c/group.gif b/theme/chameleon/pix/c/group.gif
new file mode 100644 (file)
index 0000000..9805d7a
Binary files /dev/null and b/theme/chameleon/pix/c/group.gif differ
diff --git a/theme/chameleon/pix/c/site.gif b/theme/chameleon/pix/c/site.gif
new file mode 100644 (file)
index 0000000..2c534be
Binary files /dev/null and b/theme/chameleon/pix/c/site.gif differ
diff --git a/theme/chameleon/pix/c/user.gif b/theme/chameleon/pix/c/user.gif
new file mode 100644 (file)
index 0000000..626a541
Binary files /dev/null and b/theme/chameleon/pix/c/user.gif differ
diff --git a/theme/chameleon/pix/colorstrip.gif b/theme/chameleon/pix/colorstrip.gif
new file mode 100644 (file)
index 0000000..371bb36
Binary files /dev/null and b/theme/chameleon/pix/colorstrip.gif differ
diff --git a/theme/chameleon/pix/css.gif b/theme/chameleon/pix/css.gif
new file mode 100644 (file)
index 0000000..312cde9
Binary files /dev/null and b/theme/chameleon/pix/css.gif differ
diff --git a/theme/chameleon/pix/f/audio.gif b/theme/chameleon/pix/f/audio.gif
new file mode 100644 (file)
index 0000000..fdea0f5
Binary files /dev/null and b/theme/chameleon/pix/f/audio.gif differ
diff --git a/theme/chameleon/pix/f/avi.gif b/theme/chameleon/pix/f/avi.gif
new file mode 100644 (file)
index 0000000..f32df23
Binary files /dev/null and b/theme/chameleon/pix/f/avi.gif differ
diff --git a/theme/chameleon/pix/f/edit.gif b/theme/chameleon/pix/f/edit.gif
new file mode 100644 (file)
index 0000000..b46b787
Binary files /dev/null and b/theme/chameleon/pix/f/edit.gif differ
diff --git a/theme/chameleon/pix/f/env.gif b/theme/chameleon/pix/f/env.gif
new file mode 100644 (file)
index 0000000..49a211f
Binary files /dev/null and b/theme/chameleon/pix/f/env.gif differ
diff --git a/theme/chameleon/pix/f/excel.gif b/theme/chameleon/pix/f/excel.gif
new file mode 100644 (file)
index 0000000..5f316e5
Binary files /dev/null and b/theme/chameleon/pix/f/excel.gif differ
diff --git a/theme/chameleon/pix/f/explore.gif b/theme/chameleon/pix/f/explore.gif
new file mode 100644 (file)
index 0000000..6e9c042
Binary files /dev/null and b/theme/chameleon/pix/f/explore.gif differ
diff --git a/theme/chameleon/pix/f/flash.gif b/theme/chameleon/pix/f/flash.gif
new file mode 100644 (file)
index 0000000..5dfe018
Binary files /dev/null and b/theme/chameleon/pix/f/flash.gif differ
diff --git a/theme/chameleon/pix/f/folder.gif b/theme/chameleon/pix/f/folder.gif
new file mode 100644 (file)
index 0000000..81230c6
Binary files /dev/null and b/theme/chameleon/pix/f/folder.gif differ
diff --git a/theme/chameleon/pix/f/help.gif b/theme/chameleon/pix/f/help.gif
new file mode 100644 (file)
index 0000000..c1e1d62
Binary files /dev/null and b/theme/chameleon/pix/f/help.gif differ
diff --git a/theme/chameleon/pix/f/html.gif b/theme/chameleon/pix/f/html.gif
new file mode 100644 (file)
index 0000000..7f1e5e5
Binary files /dev/null and b/theme/chameleon/pix/f/html.gif differ
diff --git a/theme/chameleon/pix/f/image.gif b/theme/chameleon/pix/f/image.gif
new file mode 100644 (file)
index 0000000..f436600
Binary files /dev/null and b/theme/chameleon/pix/f/image.gif differ
diff --git a/theme/chameleon/pix/f/jbc.gif b/theme/chameleon/pix/f/jbc.gif
new file mode 100644 (file)
index 0000000..6e0bbb4
Binary files /dev/null and b/theme/chameleon/pix/f/jbc.gif differ
diff --git a/theme/chameleon/pix/f/jcl.gif b/theme/chameleon/pix/f/jcl.gif
new file mode 100644 (file)
index 0000000..d2dd8ad
Binary files /dev/null and b/theme/chameleon/pix/f/jcl.gif differ
diff --git a/theme/chameleon/pix/f/jcw.gif b/theme/chameleon/pix/f/jcw.gif
new file mode 100644 (file)
index 0000000..3d22489
Binary files /dev/null and b/theme/chameleon/pix/f/jcw.gif differ
diff --git a/theme/chameleon/pix/f/jmt.gif b/theme/chameleon/pix/f/jmt.gif
new file mode 100644 (file)
index 0000000..6d61c6f
Binary files /dev/null and b/theme/chameleon/pix/f/jmt.gif differ
diff --git a/theme/chameleon/pix/f/jmx.gif b/theme/chameleon/pix/f/jmx.gif
new file mode 100644 (file)
index 0000000..7ebeee7
Binary files /dev/null and b/theme/chameleon/pix/f/jmx.gif differ
diff --git a/theme/chameleon/pix/f/jqz.gif b/theme/chameleon/pix/f/jqz.gif
new file mode 100644 (file)
index 0000000..d08db41
Binary files /dev/null and b/theme/chameleon/pix/f/jqz.gif differ
diff --git a/theme/chameleon/pix/f/move.gif b/theme/chameleon/pix/f/move.gif
new file mode 100644 (file)
index 0000000..7c3fac1
Binary files /dev/null and b/theme/chameleon/pix/f/move.gif differ
diff --git a/theme/chameleon/pix/f/odt.gif b/theme/chameleon/pix/f/odt.gif
new file mode 100644 (file)
index 0000000..93cba93
Binary files /dev/null and b/theme/chameleon/pix/f/odt.gif differ
diff --git a/theme/chameleon/pix/f/parent.gif b/theme/chameleon/pix/f/parent.gif
new file mode 100644 (file)
index 0000000..3f976b7
Binary files /dev/null and b/theme/chameleon/pix/f/parent.gif differ
diff --git a/theme/chameleon/pix/f/pdf.gif b/theme/chameleon/pix/f/pdf.gif
new file mode 100644 (file)
index 0000000..c46390d
Binary files /dev/null and b/theme/chameleon/pix/f/pdf.gif differ
diff --git a/theme/chameleon/pix/f/powerpoint.gif b/theme/chameleon/pix/f/powerpoint.gif
new file mode 100644 (file)
index 0000000..b6ee352
Binary files /dev/null and b/theme/chameleon/pix/f/powerpoint.gif differ
diff --git a/theme/chameleon/pix/f/text.gif b/theme/chameleon/pix/f/text.gif
new file mode 100644 (file)
index 0000000..93cba93
Binary files /dev/null and b/theme/chameleon/pix/f/text.gif differ
diff --git a/theme/chameleon/pix/f/unknown.gif b/theme/chameleon/pix/f/unknown.gif
new file mode 100644 (file)
index 0000000..58b31e2
Binary files /dev/null and b/theme/chameleon/pix/f/unknown.gif differ
diff --git a/theme/chameleon/pix/f/video.gif b/theme/chameleon/pix/f/video.gif
new file mode 100644 (file)
index 0000000..819f0b5
Binary files /dev/null and b/theme/chameleon/pix/f/video.gif differ
diff --git a/theme/chameleon/pix/f/web.gif b/theme/chameleon/pix/f/web.gif
new file mode 100644 (file)
index 0000000..ee86a74
Binary files /dev/null and b/theme/chameleon/pix/f/web.gif differ
diff --git a/theme/chameleon/pix/f/word.gif b/theme/chameleon/pix/f/word.gif
new file mode 100644 (file)
index 0000000..5a4cca1
Binary files /dev/null and b/theme/chameleon/pix/f/word.gif differ
diff --git a/theme/chameleon/pix/f/xml.gif b/theme/chameleon/pix/f/xml.gif
new file mode 100644 (file)
index 0000000..3bb11f5
Binary files /dev/null and b/theme/chameleon/pix/f/xml.gif differ
diff --git a/theme/chameleon/pix/f/zip.gif b/theme/chameleon/pix/f/zip.gif
new file mode 100644 (file)
index 0000000..09d44d1
Binary files /dev/null and b/theme/chameleon/pix/f/zip.gif differ
diff --git a/theme/chameleon/pix/g/f1.png b/theme/chameleon/pix/g/f1.png
new file mode 100644 (file)
index 0000000..a8e713b
Binary files /dev/null and b/theme/chameleon/pix/g/f1.png differ
diff --git a/theme/chameleon/pix/g/f2.png b/theme/chameleon/pix/g/f2.png
new file mode 100644 (file)
index 0000000..4ea14af
Binary files /dev/null and b/theme/chameleon/pix/g/f2.png differ
diff --git a/theme/chameleon/pix/help.gif b/theme/chameleon/pix/help.gif
new file mode 100644 (file)
index 0000000..78fddd9
Binary files /dev/null and b/theme/chameleon/pix/help.gif differ
diff --git a/theme/chameleon/pix/i/admin.gif b/theme/chameleon/pix/i/admin.gif
new file mode 100644 (file)
index 0000000..3a6b331
Binary files /dev/null and b/theme/chameleon/pix/i/admin.gif differ
diff --git a/theme/chameleon/pix/i/all.gif b/theme/chameleon/pix/i/all.gif
new file mode 100644 (file)
index 0000000..e45d5af
Binary files /dev/null and b/theme/chameleon/pix/i/all.gif differ
diff --git a/theme/chameleon/pix/i/backup.gif b/theme/chameleon/pix/i/backup.gif
new file mode 100644 (file)
index 0000000..25213ff
Binary files /dev/null and b/theme/chameleon/pix/i/backup.gif differ
diff --git a/theme/chameleon/pix/i/course.gif b/theme/chameleon/pix/i/course.gif
new file mode 100644 (file)
index 0000000..71f1c8b
Binary files /dev/null and b/theme/chameleon/pix/i/course.gif differ
diff --git a/theme/chameleon/pix/i/db.gif b/theme/chameleon/pix/i/db.gif
new file mode 100644 (file)
index 0000000..3fc5b22
Binary files /dev/null and b/theme/chameleon/pix/i/db.gif differ
diff --git a/theme/chameleon/pix/i/edit.gif b/theme/chameleon/pix/i/edit.gif
new file mode 100644 (file)
index 0000000..05eafcc
Binary files /dev/null and b/theme/chameleon/pix/i/edit.gif differ
diff --git a/theme/chameleon/pix/i/email.gif b/theme/chameleon/pix/i/email.gif
new file mode 100644 (file)
index 0000000..61e96ec
Binary files /dev/null and b/theme/chameleon/pix/i/email.gif differ
diff --git a/theme/chameleon/pix/i/files.gif b/theme/chameleon/pix/i/files.gif
new file mode 100644 (file)
index 0000000..81230c6
Binary files /dev/null and b/theme/chameleon/pix/i/files.gif differ
diff --git a/theme/chameleon/pix/i/grades.gif b/theme/chameleon/pix/i/grades.gif
new file mode 100644 (file)
index 0000000..b61c585
Binary files /dev/null and b/theme/chameleon/pix/i/grades.gif differ
diff --git a/theme/chameleon/pix/i/group.gif b/theme/chameleon/pix/i/group.gif
new file mode 100644 (file)
index 0000000..4e6e636
Binary files /dev/null and b/theme/chameleon/pix/i/group.gif differ
diff --git a/theme/chameleon/pix/i/guest.gif b/theme/chameleon/pix/i/guest.gif
new file mode 100644 (file)
index 0000000..37b4fc0
Binary files /dev/null and b/theme/chameleon/pix/i/guest.gif differ
diff --git a/theme/chameleon/pix/i/hide.gif b/theme/chameleon/pix/i/hide.gif
new file mode 100644 (file)
index 0000000..ebff28b
Binary files /dev/null and b/theme/chameleon/pix/i/hide.gif differ
diff --git a/theme/chameleon/pix/i/info.gif b/theme/chameleon/pix/i/info.gif
new file mode 100644 (file)
index 0000000..2994a09
Binary files /dev/null and b/theme/chameleon/pix/i/info.gif differ
diff --git a/theme/chameleon/pix/i/key.gif b/theme/chameleon/pix/i/key.gif
new file mode 100644 (file)
index 0000000..b3bb135
Binary files /dev/null and b/theme/chameleon/pix/i/key.gif differ
diff --git a/theme/chameleon/pix/i/log.gif b/theme/chameleon/pix/i/log.gif
new file mode 100644 (file)
index 0000000..8ca969b
Binary files /dev/null and b/theme/chameleon/pix/i/log.gif differ
diff --git a/theme/chameleon/pix/i/marked.gif b/theme/chameleon/pix/i/marked.gif
new file mode 100644 (file)
index 0000000..61ea887
Binary files /dev/null and b/theme/chameleon/pix/i/marked.gif differ
diff --git a/theme/chameleon/pix/i/marker.gif b/theme/chameleon/pix/i/marker.gif
new file mode 100644 (file)
index 0000000..cad8d92
Binary files /dev/null and b/theme/chameleon/pix/i/marker.gif differ
diff --git a/theme/chameleon/pix/i/new.gif b/theme/chameleon/pix/i/new.gif
new file mode 100644 (file)
index 0000000..b0bdf6d
Binary files /dev/null and b/theme/chameleon/pix/i/new.gif differ
diff --git a/theme/chameleon/pix/i/news.gif b/theme/chameleon/pix/i/news.gif
new file mode 100644 (file)
index 0000000..1718f19
Binary files /dev/null and b/theme/chameleon/pix/i/news.gif differ
diff --git a/theme/chameleon/pix/i/one.gif b/theme/chameleon/pix/i/one.gif
new file mode 100644 (file)
index 0000000..f60dd44
Binary files /dev/null and b/theme/chameleon/pix/i/one.gif differ
diff --git a/theme/chameleon/pix/i/report.gif b/theme/chameleon/pix/i/report.gif
new file mode 100644 (file)
index 0000000..7904489
Binary files /dev/null and b/theme/chameleon/pix/i/report.gif differ
diff --git a/theme/chameleon/pix/i/restore.gif b/theme/chameleon/pix/i/restore.gif
new file mode 100644 (file)
index 0000000..2a3c778
Binary files /dev/null and b/theme/chameleon/pix/i/restore.gif differ
diff --git a/theme/chameleon/pix/i/rss.gif b/theme/chameleon/pix/i/rss.gif
new file mode 100644 (file)
index 0000000..8c917ba
Binary files /dev/null and b/theme/chameleon/pix/i/rss.gif differ
diff --git a/theme/chameleon/pix/i/rsssitelogo.gif b/theme/chameleon/pix/i/rsssitelogo.gif
new file mode 100644 (file)
index 0000000..5c0176c
Binary files /dev/null and b/theme/chameleon/pix/i/rsssitelogo.gif differ
diff --git a/theme/chameleon/pix/i/scales.gif b/theme/chameleon/pix/i/scales.gif
new file mode 100644 (file)
index 0000000..47fcd2e
Binary files /dev/null and b/theme/chameleon/pix/i/scales.gif differ
diff --git a/theme/chameleon/pix/i/search.gif b/theme/chameleon/pix/i/search.gif
new file mode 100644 (file)
index 0000000..1a42ad4
Binary files /dev/null and b/theme/chameleon/pix/i/search.gif differ
diff --git a/theme/chameleon/pix/i/settings.gif b/theme/chameleon/pix/i/settings.gif
new file mode 100644 (file)
index 0000000..7bf8a89
Binary files /dev/null and b/theme/chameleon/pix/i/settings.gif differ
diff --git a/theme/chameleon/pix/i/show.gif b/theme/chameleon/pix/i/show.gif
new file mode 100644 (file)
index 0000000..64c9f85
Binary files /dev/null and b/theme/chameleon/pix/i/show.gif differ
diff --git a/theme/chameleon/pix/i/switch.gif b/theme/chameleon/pix/i/switch.gif
new file mode 100644 (file)
index 0000000..a9ddf6d
Binary files /dev/null and b/theme/chameleon/pix/i/switch.gif differ
diff --git a/theme/chameleon/pix/i/user.gif b/theme/chameleon/pix/i/user.gif
new file mode 100644 (file)
index 0000000..e8b1e45
Binary files /dev/null and b/theme/chameleon/pix/i/user.gif differ
diff --git a/theme/chameleon/pix/i/users.gif b/theme/chameleon/pix/i/users.gif
new file mode 100644 (file)
index 0000000..ad8f406
Binary files /dev/null and b/theme/chameleon/pix/i/users.gif differ
diff --git a/theme/chameleon/pix/m/USD.gif b/theme/chameleon/pix/m/USD.gif
new file mode 100644 (file)
index 0000000..df67e2a
Binary files /dev/null and b/theme/chameleon/pix/m/USD.gif differ
diff --git a/theme/chameleon/pix/mod/README.txt b/theme/chameleon/pix/mod/README.txt
new file mode 100644 (file)
index 0000000..5d28268
--- /dev/null
@@ -0,0 +1,42 @@
+ACTIVITY MODULES\r
+----------------\r
+\r
+These are main modules in Moodle, allowing various activities.\r
+\r
+\r
+Each of these modules contains a number of expected components:\r
+\r
+  mod.html: a form to setup/update a module instance\r
+\r
+  version.php: defines some meta-info and provides upgrading code\r
+\r
+  icon.gif: a 16x16 icon for the module\r
+\r
+  db/mysql.sql: an SQL dump of all the required db tables and data\r
\r
+  index.php: a page to list all instances in a course\r
+\r
+  view.php: a page to view a particular instance\r
+\r
+  lib.php: any/all functions defined by the module should be in here.\r
+         constants should be defined using MODULENAME_xxxxxx\r
+         functions should be defined using modulename_xxxxxx\r
+\r
+         There are a number of standard functions:\r
+\r
+         modulename_add_instance()\r
+         modulename_update_instance()\r
+         modulename_delete_instance()\r
+\r
+         modulename_user_complete()\r
+         modulename_user_outline()\r
+\r
+         modulename_cron()\r
+\r
+         modulename_print_recent_activity()\r
+\r
+\r
+If you are a developer and interested in developing new Modules see:\r
+  \r
+   Moodle Documentation:  http://moodle.org/doc\r
+   Moodle Community:      http://moodle.org/community\r
diff --git a/theme/chameleon/pix/mod/index.html b/theme/chameleon/pix/mod/index.html
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/theme/chameleon/pix/movehere.gif b/theme/chameleon/pix/movehere.gif
new file mode 100644 (file)
index 0000000..aaa4e5d
Binary files /dev/null and b/theme/chameleon/pix/movehere.gif differ
diff --git a/theme/chameleon/pix/pix/b.gif b/theme/chameleon/pix/pix/b.gif
new file mode 100644 (file)
index 0000000..3b68f14
Binary files /dev/null and b/theme/chameleon/pix/pix/b.gif differ
diff --git a/theme/chameleon/pix/pix/help.gif b/theme/chameleon/pix/pix/help.gif
new file mode 100644 (file)
index 0000000..78fddd9
Binary files /dev/null and b/theme/chameleon/pix/pix/help.gif differ
diff --git a/theme/chameleon/pix/rightarrow2.gif b/theme/chameleon/pix/rightarrow2.gif
new file mode 100644 (file)
index 0000000..fb0fbe9
Binary files /dev/null and b/theme/chameleon/pix/rightarrow2.gif differ
diff --git a/theme/chameleon/pix/s/angry.gif b/theme/chameleon/pix/s/angry.gif
new file mode 100644 (file)
index 0000000..a8bdd39
Binary files /dev/null and b/theme/chameleon/pix/s/angry.gif differ
diff --git a/theme/chameleon/pix/s/approve.gif b/theme/chameleon/pix/s/approve.gif
new file mode 100644 (file)
index 0000000..32c1b5f
Binary files /dev/null and b/theme/chameleon/pix/s/approve.gif differ
diff --git a/theme/chameleon/pix/s/biggrin.gif b/theme/chameleon/pix/s/biggrin.gif
new file mode 100644 (file)
index 0000000..fae4db8
Binary files /dev/null and b/theme/chameleon/pix/s/biggrin.gif differ
diff --git a/theme/chameleon/pix/s/blackeye.gif b/theme/chameleon/pix/s/blackeye.gif
new file mode 100644 (file)
index 0000000..8daf4a2
Binary files /dev/null and b/theme/chameleon/pix/s/blackeye.gif differ
diff --git a/theme/chameleon/pix/s/blush.gif b/theme/chameleon/pix/s/blush.gif
new file mode 100644 (file)
index 0000000..0764eb9
Binary files /dev/null and b/theme/chameleon/pix/s/blush.gif differ
diff --git a/theme/chameleon/pix/s/clown.gif b/theme/chameleon/pix/s/clown.gif
new file mode 100644 (file)
index 0000000..314322d
Binary files /dev/null and b/theme/chameleon/pix/s/clown.gif differ
diff --git a/theme/chameleon/pix/s/cool.gif b/theme/chameleon/pix/s/cool.gif
new file mode 100644 (file)
index 0000000..283bb8b
Binary files /dev/null and b/theme/chameleon/pix/s/cool.gif differ
diff --git a/theme/chameleon/pix/s/dead.gif b/theme/chameleon/pix/s/dead.gif
new file mode 100644 (file)
index 0000000..c4b1302
Binary files /dev/null and b/theme/chameleon/pix/s/dead.gif differ
diff --git a/theme/chameleon/pix/s/evil.gif b/theme/chameleon/pix/s/evil.gif
new file mode 100644 (file)
index 0000000..b2a121d
Binary files /dev/null and b/theme/chameleon/pix/s/evil.gif differ
diff --git a/theme/chameleon/pix/s/kiss.gif b/theme/chameleon/pix/s/kiss.gif
new file mode 100644 (file)
index 0000000..89c8bfe
Binary files /dev/null and b/theme/chameleon/pix/s/kiss.gif differ
diff --git a/theme/chameleon/pix/s/mixed.gif b/theme/chameleon/pix/s/mixed.gif
new file mode 100644 (file)
index 0000000..501b35b
Binary files /dev/null and b/theme/chameleon/pix/s/mixed.gif differ
diff --git a/theme/chameleon/pix/s/s_r2_c40.gif b/theme/chameleon/pix/s/s_r2_c40.gif
new file mode 100644 (file)
index 0000000..02e4211
Binary files /dev/null and b/theme/chameleon/pix/s/s_r2_c40.gif differ
diff --git a/theme/chameleon/pix/s/sad.gif b/theme/chameleon/pix/s/sad.gif
new file mode 100644 (file)
index 0000000..cef2e8b
Binary files /dev/null and b/theme/chameleon/pix/s/sad.gif differ
diff --git a/theme/chameleon/pix/s/shy.gif b/theme/chameleon/pix/s/shy.gif
new file mode 100644 (file)
index 0000000..1f0960e
Binary files /dev/null and b/theme/chameleon/pix/s/shy.gif differ
diff --git a/theme/chameleon/pix/s/sleepy.gif b/theme/chameleon/pix/s/sleepy.gif
new file mode 100644 (file)
index 0000000..55b10ba
Binary files /dev/null and b/theme/chameleon/pix/s/sleepy.gif differ
diff --git a/theme/chameleon/pix/s/smiley.gif b/theme/chameleon/pix/s/smiley.gif
new file mode 100644 (file)
index 0000000..8f145aa
Binary files /dev/null and b/theme/chameleon/pix/s/smiley.gif differ
diff --git a/theme/chameleon/pix/s/surprise.gif b/theme/chameleon/pix/s/surprise.gif
new file mode 100644 (file)
index 0000000..2a08548
Binary files /dev/null and b/theme/chameleon/pix/s/surprise.gif differ
diff --git a/theme/chameleon/pix/s/thoughtful.gif b/theme/chameleon/pix/s/thoughtful.gif
new file mode 100644 (file)
index 0000000..ea46db1
Binary files /dev/null and b/theme/chameleon/pix/s/thoughtful.gif differ
diff --git a/theme/chameleon/pix/s/tongueout.gif b/theme/chameleon/pix/s/tongueout.gif
new file mode 100644 (file)
index 0000000..6a7f8fa
Binary files /dev/null and b/theme/chameleon/pix/s/tongueout.gif differ
diff --git a/theme/chameleon/pix/s/toughtful.gif b/theme/chameleon/pix/s/toughtful.gif
new file mode 100644 (file)
index 0000000..4d41b2d
Binary files /dev/null and b/theme/chameleon/pix/s/toughtful.gif differ
diff --git a/theme/chameleon/pix/s/wideeyes.gif b/theme/chameleon/pix/s/wideeyes.gif
new file mode 100644 (file)
index 0000000..49705ad
Binary files /dev/null and b/theme/chameleon/pix/s/wideeyes.gif differ
diff --git a/theme/chameleon/pix/s/wink.gif b/theme/chameleon/pix/s/wink.gif
new file mode 100644 (file)
index 0000000..dfc35cc
Binary files /dev/null and b/theme/chameleon/pix/s/wink.gif differ
diff --git a/theme/chameleon/pix/section_508.gif b/theme/chameleon/pix/section_508.gif
new file mode 100644 (file)
index 0000000..89e9c9a
Binary files /dev/null and b/theme/chameleon/pix/section_508.gif differ
diff --git a/theme/chameleon/pix/spacer.gif b/theme/chameleon/pix/spacer.gif
new file mode 100644 (file)
index 0000000..e91556e
Binary files /dev/null and b/theme/chameleon/pix/spacer.gif differ
diff --git a/theme/chameleon/pix/switch_minus.gif b/theme/chameleon/pix/switch_minus.gif
new file mode 100644 (file)
index 0000000..959a5c2
Binary files /dev/null and b/theme/chameleon/pix/switch_minus.gif differ
diff --git a/theme/chameleon/pix/switch_plus.gif b/theme/chameleon/pix/switch_plus.gif
new file mode 100644 (file)
index 0000000..84ac353
Binary files /dev/null and b/theme/chameleon/pix/switch_plus.gif differ
diff --git a/theme/chameleon/pix/t/backup.gif b/theme/chameleon/pix/t/backup.gif
new file mode 100644 (file)
index 0000000..bf7b63e
Binary files /dev/null and b/theme/chameleon/pix/t/backup.gif differ
diff --git a/theme/chameleon/pix/t/clear.gif b/theme/chameleon/pix/t/clear.gif
new file mode 100644 (file)
index 0000000..027a5c3
Binary files /dev/null and b/theme/chameleon/pix/t/clear.gif differ
diff --git a/theme/chameleon/pix/t/copy.gif b/theme/chameleon/pix/t/copy.gif
new file mode 100644 (file)
index 0000000..52c9afb
Binary files /dev/null and b/theme/chameleon/pix/t/copy.gif differ
diff --git a/theme/chameleon/pix/t/delete.gif b/theme/chameleon/pix/t/delete.gif
new file mode 100644 (file)
index 0000000..a84c7bf
Binary files /dev/null and b/theme/chameleon/pix/t/delete.gif differ
diff --git a/theme/chameleon/pix/t/down.gif b/theme/chameleon/pix/t/down.gif
new file mode 100644 (file)
index 0000000..e636cdd
Binary files /dev/null and b/theme/chameleon/pix/t/down.gif differ
diff --git a/theme/chameleon/pix/t/edit.gif b/theme/chameleon/pix/t/edit.gif
new file mode 100644 (file)
index 0000000..3c48aee
Binary files /dev/null and b/theme/chameleon/pix/t/edit.gif differ
diff --git a/theme/chameleon/pix/t/email.gif b/theme/chameleon/pix/t/email.gif
new file mode 100644 (file)
index 0000000..87711f7
Binary files /dev/null and b/theme/chameleon/pix/t/email.gif differ
diff --git a/theme/chameleon/pix/t/emailno.gif b/theme/chameleon/pix/t/emailno.gif
new file mode 100644 (file)
index 0000000..31197fc
Binary files /dev/null and b/theme/chameleon/pix/t/emailno.gif differ
diff --git a/theme/chameleon/pix/t/go.gif b/theme/chameleon/pix/t/go.gif
new file mode 100644 (file)
index 0000000..9bb1532
Binary files /dev/null and b/theme/chameleon/pix/t/go.gif differ
diff --git a/theme/chameleon/pix/t/groupn.gif b/theme/chameleon/pix/t/groupn.gif
new file mode 100644 (file)
index 0000000..398736f
Binary files /dev/null and b/theme/chameleon/pix/t/groupn.gif differ
diff --git a/theme/chameleon/pix/t/groups.gif b/theme/chameleon/pix/t/groups.gif
new file mode 100644 (file)
index 0000000..1357524
Binary files /dev/null and b/theme/chameleon/pix/t/groups.gif differ
diff --git a/theme/chameleon/pix/t/groupv.gif b/theme/chameleon/pix/t/groupv.gif
new file mode 100644 (file)
index 0000000..c14507a
Binary files /dev/null and b/theme/chameleon/pix/t/groupv.gif differ
diff --git a/theme/chameleon/pix/t/hide.gif b/theme/chameleon/pix/t/hide.gif
new file mode 100644 (file)
index 0000000..09bb2b8
Binary files /dev/null and b/theme/chameleon/pix/t/hide.gif differ
diff --git a/theme/chameleon/pix/t/left.gif b/theme/chameleon/pix/t/left.gif
new file mode 100644 (file)
index 0000000..cfbae22
Binary files /dev/null and b/theme/chameleon/pix/t/left.gif differ
diff --git a/theme/chameleon/pix/t/log.gif b/theme/chameleon/pix/t/log.gif
new file mode 100644 (file)
index 0000000..d489c70
Binary files /dev/null and b/theme/chameleon/pix/t/log.gif differ
diff --git a/theme/chameleon/pix/t/message.gif b/theme/chameleon/pix/t/message.gif
new file mode 100644 (file)
index 0000000..87711f7
Binary files /dev/null and b/theme/chameleon/pix/t/message.gif differ
diff --git a/theme/chameleon/pix/t/move.gif b/theme/chameleon/pix/t/move.gif
new file mode 100644 (file)
index 0000000..25cb817
Binary files /dev/null and b/theme/chameleon/pix/t/move.gif differ
diff --git a/theme/chameleon/pix/t/moveleft.gif b/theme/chameleon/pix/t/moveleft.gif
new file mode 100644 (file)
index 0000000..7b18e91
Binary files /dev/null and b/theme/chameleon/pix/t/moveleft.gif differ
diff --git a/theme/chameleon/pix/t/moveright.gif b/theme/chameleon/pix/t/moveright.gif
new file mode 100644 (file)
index 0000000..a95371b
Binary files /dev/null and b/theme/chameleon/pix/t/moveright.gif differ
diff --git a/theme/chameleon/pix/t/preview.gif b/theme/chameleon/pix/t/preview.gif
new file mode 100644 (file)
index 0000000..1f47ced
Binary files /dev/null and b/theme/chameleon/pix/t/preview.gif differ
diff --git a/theme/chameleon/pix/t/restore.gif b/theme/chameleon/pix/t/restore.gif
new file mode 100644 (file)
index 0000000..3151c30
Binary files /dev/null and b/theme/chameleon/pix/t/restore.gif differ
diff --git a/theme/chameleon/pix/t/right.gif b/theme/chameleon/pix/t/right.gif
new file mode 100644 (file)
index 0000000..5981365
Binary files /dev/null and b/theme/chameleon/pix/t/right.gif differ
diff --git a/theme/chameleon/pix/t/show.gif b/theme/chameleon/pix/t/show.gif
new file mode 100644 (file)
index 0000000..7c2aaf6
Binary files /dev/null and b/theme/chameleon/pix/t/show.gif differ
diff --git a/theme/chameleon/pix/t/stop.gif b/theme/chameleon/pix/t/stop.gif
new file mode 100644 (file)
index 0000000..545114b
Binary files /dev/null and b/theme/chameleon/pix/t/stop.gif differ
diff --git a/theme/chameleon/pix/t/switch.gif b/theme/chameleon/pix/t/switch.gif
new file mode 100644 (file)
index 0000000..7538980
Binary files /dev/null and b/theme/chameleon/pix/t/switch.gif differ
diff --git a/theme/chameleon/pix/t/switch_minus.gif b/theme/chameleon/pix/t/switch_minus.gif
new file mode 100644 (file)
index 0000000..9a209d2
Binary files /dev/null and b/theme/chameleon/pix/t/switch_minus.gif differ
diff --git a/theme/chameleon/pix/t/switch_plus.gif b/theme/chameleon/pix/t/switch_plus.gif
new file mode 100644 (file)
index 0000000..7538980
Binary files /dev/null and b/theme/chameleon/pix/t/switch_plus.gif differ
diff --git a/theme/chameleon/pix/t/up.gif b/theme/chameleon/pix/t/up.gif
new file mode 100644 (file)
index 0000000..25a1223
Binary files /dev/null and b/theme/chameleon/pix/t/up.gif differ
diff --git a/theme/chameleon/pix/t/user.gif b/theme/chameleon/pix/t/user.gif
new file mode 100644 (file)
index 0000000..1f260b8
Binary files /dev/null and b/theme/chameleon/pix/t/user.gif differ
diff --git a/theme/chameleon/pix/t/usernot.gif b/theme/chameleon/pix/t/usernot.gif
new file mode 100644 (file)
index 0000000..9c3fcde
Binary files /dev/null and b/theme/chameleon/pix/t/usernot.gif differ
diff --git a/theme/chameleon/pix/tab/left.gif b/theme/chameleon/pix/tab/left.gif
new file mode 100644 (file)
index 0000000..4dc27c5
Binary files /dev/null and b/theme/chameleon/pix/tab/left.gif differ
diff --git a/theme/chameleon/pix/tab/left2.gif b/theme/chameleon/pix/tab/left2.gif
new file mode 100644 (file)
index 0000000..2188d85
Binary files /dev/null and b/theme/chameleon/pix/tab/left2.gif differ
diff --git a/theme/chameleon/pix/tab/left_active.gif b/theme/chameleon/pix/tab/left_active.gif
new file mode 100644 (file)
index 0000000..a85baf5
Binary files /dev/null and b/theme/chameleon/pix/tab/left_active.gif differ
diff --git a/theme/chameleon/pix/tab/left_active2.gif b/theme/chameleon/pix/tab/left_active2.gif
new file mode 100644 (file)
index 0000000..e435359
Binary files /dev/null and b/theme/chameleon/pix/tab/left_active2.gif differ
diff --git a/theme/chameleon/pix/tab/left_hover.gif b/theme/chameleon/pix/tab/left_hover.gif
new file mode 100644 (file)
index 0000000..1b8e856
Binary files /dev/null and b/theme/chameleon/pix/tab/left_hover.gif differ
diff --git a/theme/chameleon/pix/tab/left_hover2.gif b/theme/chameleon/pix/tab/left_hover2.gif
new file mode 100644 (file)
index 0000000..6cdb801
Binary files /dev/null and b/theme/chameleon/pix/tab/left_hover2.gif differ
diff --git a/theme/chameleon/pix/tab/left_inactive.gif b/theme/chameleon/pix/tab/left_inactive.gif
new file mode 100644 (file)
index 0000000..a7b4f3e
Binary files /dev/null and b/theme/chameleon/pix/tab/left_inactive.gif differ
diff --git a/theme/chameleon/pix/tab/left_inactive2.gif b/theme/chameleon/pix/tab/left_inactive2.gif
new file mode 100644 (file)
index 0000000..549fd3f
Binary files /dev/null and b/theme/chameleon/pix/tab/left_inactive2.gif differ
diff --git a/theme/chameleon/pix/tab/right.gif b/theme/chameleon/pix/tab/right.gif
new file mode 100644 (file)
index 0000000..09d7fe6
Binary files /dev/null and b/theme/chameleon/pix/tab/right.gif differ
diff --git a/theme/chameleon/pix/tab/right2.gif b/theme/chameleon/pix/tab/right2.gif
new file mode 100644 (file)
index 0000000..9ef5142
Binary files /dev/null and b/theme/chameleon/pix/tab/right2.gif differ
diff --git a/theme/chameleon/pix/tab/right_active.gif b/theme/chameleon/pix/tab/right_active.gif
new file mode 100644 (file)
index 0000000..43a5958
Binary files /dev/null and b/theme/chameleon/pix/tab/right_active.gif differ
diff --git a/theme/chameleon/pix/tab/right_active2.gif b/theme/chameleon/pix/tab/right_active2.gif
new file mode 100644 (file)
index 0000000..bdc63e0
Binary files /dev/null and b/theme/chameleon/pix/tab/right_active2.gif differ
diff --git a/theme/chameleon/pix/tab/right_end.gif b/theme/chameleon/pix/tab/right_end.gif
new file mode 100644 (file)
index 0000000..cadc812
Binary files /dev/null and b/theme/chameleon/pix/tab/right_end.gif differ
diff --git a/theme/chameleon/pix/tab/right_end2.gif b/theme/chameleon/pix/tab/right_end2.gif
new file mode 100644 (file)
index 0000000..aa0c546
Binary files /dev/null and b/theme/chameleon/pix/tab/right_end2.gif differ
diff --git a/theme/chameleon/pix/tab/right_hover.gif b/theme/chameleon/pix/tab/right_hover.gif
new file mode 100644 (file)
index 0000000..b077d68
Binary files /dev/null and b/theme/chameleon/pix/tab/right_hover.gif differ
diff --git a/theme/chameleon/pix/tab/right_hover2.gif b/theme/chameleon/pix/tab/right_hover2.gif
new file mode 100644 (file)
index 0000000..8a24ff4
Binary files /dev/null and b/theme/chameleon/pix/tab/right_hover2.gif differ
diff --git a/theme/chameleon/pix/tab/right_inactive.gif b/theme/chameleon/pix/tab/right_inactive.gif
new file mode 100644 (file)
index 0000000..ea5c907
Binary files /dev/null and b/theme/chameleon/pix/tab/right_inactive.gif differ
diff --git a/theme/chameleon/pix/tab/right_inactive2.gif b/theme/chameleon/pix/tab/right_inactive2.gif
new file mode 100644 (file)
index 0000000..29a7587
Binary files /dev/null and b/theme/chameleon/pix/tab/right_inactive2.gif differ
diff --git a/theme/chameleon/pix/tab/tabsbg.gif b/theme/chameleon/pix/tab/tabsbg.gif
new file mode 100644 (file)
index 0000000..51950d9
Binary files /dev/null and b/theme/chameleon/pix/tab/tabsbg.gif differ
diff --git a/theme/chameleon/pix/tab/tabsbg2.gif b/theme/chameleon/pix/tab/tabsbg2.gif
new file mode 100644 (file)
index 0000000..5206c71
Binary files /dev/null and b/theme/chameleon/pix/tab/tabsbg2.gif differ
diff --git a/theme/chameleon/pix/tab/tabsbg_x2.gif b/theme/chameleon/pix/tab/tabsbg_x2.gif
new file mode 100644 (file)
index 0000000..5f594d8
Binary files /dev/null and b/theme/chameleon/pix/tab/tabsbg_x2.gif differ
diff --git a/theme/chameleon/pix/u/f1.png b/theme/chameleon/pix/u/f1.png
new file mode 100644 (file)
index 0000000..7b135cc
Binary files /dev/null and b/theme/chameleon/pix/u/f1.png differ
diff --git a/theme/chameleon/pix/u/f1_old.png b/theme/chameleon/pix/u/f1_old.png
new file mode 100644 (file)
index 0000000..a8e713b
Binary files /dev/null and b/theme/chameleon/pix/u/f1_old.png differ
diff --git a/theme/chameleon/pix/u/f2.png b/theme/chameleon/pix/u/f2.png
new file mode 100644 (file)
index 0000000..c831817
Binary files /dev/null and b/theme/chameleon/pix/u/f2.png differ
diff --git a/theme/chameleon/pix/u/f2_old.png b/theme/chameleon/pix/u/f2_old.png
new file mode 100644 (file)
index 0000000..4ea14af
Binary files /dev/null and b/theme/chameleon/pix/u/f2_old.png differ
diff --git a/theme/chameleon/pix/xhtml_1_0.gif b/theme/chameleon/pix/xhtml_1_0.gif
new file mode 100644 (file)
index 0000000..119e2ca
Binary files /dev/null and b/theme/chameleon/pix/xhtml_1_0.gif differ
diff --git a/theme/chameleon/styles.php b/theme/chameleon/styles.php
new file mode 100644 (file)
index 0000000..dbf644b
--- /dev/null
@@ -0,0 +1,19 @@
+<?PHP /*  $Id$ */
+
+/// Every theme should contain a copy of this script.  It lets us 
+/// set up variables and so on before we include the raw CSS files.
+/// The output of this script should be a completely standard CSS file.
+
+/// THERE SHOULD BE NO NEED TO MODIFY THIS FILE!!  USE CONFIG.PHP INSTEAD.
+
+
+    $lifetime  = 600;                                   // Seconds to cache this stylesheet
+    $nomoodlecookie = true;                             // Cookies prevent caching, so don't use them
+    require_once("../../config.php");                   // Load up the Moodle libraries
+    $themename = basename(dirname(__FILE__));           // Name of the folder we are in
+    $forceconfig = optional_param('forceconfig', '', PARAM_FILE);   // Get config from this theme
+    $lang        = optional_param('lang', '', PARAM_FILE);          // Look for styles in this language
+
+    style_sheet_setup(filemtime('styles.php'), $lifetime, $themename, $forceconfig, $lang);
+   
+?>
diff --git a/theme/chameleon/styles_layout.css b/theme/chameleon/styles_layout.css
new file mode 100644 (file)
index 0000000..bac9539
--- /dev/null
@@ -0,0 +1,350 @@
+/*******************************************************************\r
+ styles_layout.css\r
+  \r
+ This CSS file contains all layout definitions like positioning,\r
+ floats, margins, padding, borders etc.\r
+\r
+ Styles are organised into the following sections:\r
+  core\r
+  header\r
+  footer\r
+\r
+  admin\r
+  blocks\r
+  calendar\r
+  course\r
+  doc\r
+  login\r
+  message\r
+  user\r
+\r
+  various modules\r
+\r
+*******************************************************************/\r
+\r
+\r
+/***\r
+ *** Core\r
+ ***/\r
+\r
+body {\r
+  margin:0.5em;\r
+  padding:0\r
+}\r
+h1.main,\r
+h2.main,\r
+h3.main,\r
+h4.main,\r
+h5.main,\r
+h6.main {\r
+  margin-left:1em;\r
+  text-align:left\r
+}\r
+#content {\r
+  clear:both\r
+}\r
+.generalboxcontent {\r
+  text-align:left\r
+}\r
+#layout-table {\r
+  margin-top:0\r
+}\r
+#layout-table #left-column {\r
+  width:22%;\r
+  padding:5px\r
+}\r
+#layout-table #middle-column {\r
+  width:auto;\r
+  padding:5px\r
+}\r
+#layout-table #middle-column .topics {\r
+  width:95%\r
+}\r
+#layout-table #right-column {\r
+  width:22%;\r
+  padding:5px\r
+}\r
+#middle-column .section .content,\r
+#middle-column .section .side {\r
+  border:0 none\r
+}\r
+.generalbox {\r
+  width:90%\r
+}\r
+.generaltable th.header {\r
+  border-left:1px solid;\r
+  border-right:1px solid;\r
+}\r
+.generaltable .smallinfo p {\r
+  margin-top:0\r
+}\r
+.sitetopiccontent {\r
+  border:0 none\r
+}\r
+\r
+/***\r
+ *** Header\r
+ ***/\r
+\r
+#header-home {\r
+  padding:0.7em 0;\r
+  height:2em\r
+}\r
+#header,\r
+#header-main,\r
+.navbar {\r
+  margin:0\r
+}\r
+#header {\r
+  padding:0.1em 0;\r
+  height:50px\r
+}\r
+#header .headermain {\r
+  float:left;\r
+  margin:0.2em 0 0 12px\r
+}\r
+.headermenu {\r
+  float:right;\r
+  text-align:right\r
+}\r
+.headermenu .logininfo {\r
+  margin:0 12px 4px 0\r
+}\r
+.navbar {\r
+  width:100%;\r
+  margin:0;\r
+  padding:0;\r
+  background:url(pix/colorstrip.gif) left no-repeat;\r
+  height:3em;\r
+  border:0 none\r
+}\r
+.navbar .breadcrumb {\r
+  float:left;\r
+  margin:23px 0.2em 0 12px\r
+}\r
+.navbutton {\r
+  float:right;\r
+  padding-top:18px;\r
+  margin:0.2em 1em 0.2em 0\r
+}\r
+.navbar hr {\r
+  height:1px\r
+}\r
+\r
+/***\r
+ *** Footer\r
+ ***/\r
\r
+#footer {\r
+  margin-top:1em\r
+}\r
+#footer br {\r
+  display:none\r
+}\r
+#footer hr {\r
+  display:none\r
+}\r
+#footer .sitelink {\r
+  margin:0.5em 0\r
+}\r
+#footer .homelink {\r
+  margin:0.5em\r
+}\r
+#footer .homelink a {\r
+  border-width:1px\r
+}\r
+\r
+/***\r
+ *** Content\r
+ ***/\r
+\r
+#content {\r
+  clear:both;\r
+  margin:0 12px\r
+}\r
+#course-view #content,\r
+#site-index #content {\r
+  margin:0\r
+}\r
+#user-edit .userpicture,\r
+#user-view .userpicture {\r
+  margin-top:10px\r
+}\r
+\r
+/***\r
+ *** Admin\r
+ ***/\r
\r
+.logtable th.header {\r
+  border-left:1px solid;\r
+  border-right:1px solid;\r
+}\r
+#user-edit #content .generalbox,\r
+#user-view .userinfobox tr {\r
+  border-top:0 none\r
+}\r
+\r
+/***\r
+ *** Blocks\r
+ ***/\r
\r
+.sideblock,\r
+.sideblock .searchform {\r
+  text-align:left\r
+}\r
+.sideblock .header .hide-show img.hide-show-image {\r
+  margin-top:0.1em;\r
+}\r
+.sideblock .searchform a {\r
+  line-height:1.5em\r
+}\r
+#left-column .sideblock {\r
+  margin:0\r
+}\r
+#left-column .sideblock .header,\r
+#left-column .sideblock .content,\r
+#right-column .sideblock .header,\r
+#right-column .sideblock .content {\r
+  border:0 none\r
+}\r
+#right-column .sideblock .content {\r
+  padding:0.2em 0.7em\r
+}\r
+#left-column .sideblock .header {\r
+  border-bottom:1px solid\r
+}\r
+#left-column .sideblock .list .r0,\r
+#left-column .sideblock .list .r1 {\r
+  height:2em\r
+}\r
+#left-column .sideblock .list td {\r
+  vertical-align:middle;\r
+  border-bottom:1px solid\r
+}\r
+#right-column .sideblock {\r
+  margin-bottom:28px\r
+}\r
+.sideblock .head {\r
+  margin-top:0.5em\r
+}\r
+.sideblock .link {\r
+  margin:0.3em 0;\r
+  border-bottom:1px solid\r
+}\r
+.sideblock .post {\r
+  margin-top:0.5em;\r
+  padding-bottom:0.2em;\r
+  border-bottom:1px solid\r
+}\r
+.block_rss_client .link {\r
+  border-top:0 none\r
+}\r
+\r
+/***\r
+ *** Calendar\r
+ ***/\r
+\r
+#calendar .today,\r
+.minicalendar .today {\r
+  padding-top:0;\r
+  padding-bottom:0;\r
+  border:1px solid !important\r
+}\r
+#calendar .maincalendar .calendarmonth {\r
+  width:75%\r
+}\r
+\r
+/***\r
+ *** Course\r
+ ***/\r
+\r
+#site-index .headingblock {\r
+  border:0 none\r
+}\r
+#course-view .headingblock {\r
+  margin-left:1em;\r
+  padding-left:0.7em;\r
+  border:0 none;\r
+  border-left:1.2em solid\r
+}\r
+#course-view .topics {\r
+  margin:0 0.5em 0 1em\r
+}\r
+#course-view .section .left {\r
+  width:0.8em\r
+}\r
+#course-view .section .right {\r
+  width:30px\r
+}\r
+#course-view .section .left a {\r
+  display:none\r
+}\r
+#course-view .section .spacer {\r
+  height:2em\r
+}\r
+#course-view .section .activity .spacer {\r
+  height:12px\r
+}\r
+#course-view .section .content .section {\r
+  margin-top:0;\r
+  margin-left:0.7em\r
+}\r
+#course-view .section .content .section .activity {\r
+  padding:0.3em 0.2em 0.2em;\r
+  border-bottom:1px solid\r
+}\r
+.course .section .content .summary {\r
+  margin:0 0 0 0.7em\r
+}\r
+#course-view .section .content .section .label img {\r
+  margin-right:1em;\r
+  margin-bottom:1em\r
+}\r
+#course-user #content,\r
+#mod-forum-user #content {\r
+  padding-bottom:0.2em\r
+}\r
+\r
+/***\r
+ *** Login\r
+ ***/\r
+\r
+.loginbox {\r
+  margin-top:12px\r
+}\r
+  \r
+/***\r
+ *** Modules:Forum\r
+ ***/\r
\r
+.forumheaderlist {\r
+  width:90%;\r
+  margin-left:auto;\r
+  margin-right:auto\r
+}\r
+.forumheaderlist .header {\r
+  border-left:1px solid;\r
+  border-right:1px solid\r
+}\r
+#mod-forum-index .generalbox {\r
+  width:100%\r
+}\r
+  \r
+/***\r
+ *** Modules:Glossary\r
+ ***/\r
+\r
+.glossarydisplay {\r
+  border-bottom:5px solid\r
+}\r
+.glossarypopup {\r
+  margin-top:0.5em\r
+}\r
+\r
+/***\r
+ *** Modules:Resource\r
+ ***/\r
\r
+.mod-resource #content {\r
+  margin-top:1px\r
+}
\ No newline at end of file
diff --git a/theme/chameleon/temp_user_styles.css b/theme/chameleon/temp_user_styles.css
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/theme/chameleon/ui/ChameleonCSS.class.php b/theme/chameleon/ui/ChameleonCSS.class.php
new file mode 100644 (file)
index 0000000..1ae91f7
--- /dev/null
@@ -0,0 +1,127 @@
+<?php\r
+\r
+class ChameleonCSS {\r
+    var $error;\r
+    var $base;\r
+    \r
+    var $perm;\r
+    var $temp;\r
+\r
+    function ChameleonCSS($base, $perm, $temp) { \r
+        $this->base = $base;\r
+        $this->perm = $perm;\r
+        $this->temp = $temp;\r
+    }\r
+    \r
+    function update($file, $content = '') {\r
+        if (!$fp = fopen($this->base . $this->$file, 'w')) {\r
+            $this->error = 'Couldn\'t open file';\r
+            return false;\r
+        }\r
+        fwrite($fp, stripslashes($content));\r
+        fclose($fp);\r
+        return true;\r
+    }\r
+\r
+    function read() {\r
+        $permCSS = trim(file_get_contents($this->base . $this->perm));\r
+        $tempCSS = trim(file_get_contents($this->base . $this->temp));\r
+           \r
+        if ($permCSS === false || $tempCSS === false) {\r
+            $this->error = 'Couldn\'t read file';\r
+            return false;\r
+        }\r
+        \r
+        if ($tempCSS == '') {\r
+            return $permCSS;\r
+        }\r
+        return $this->_merge($permCSS, $tempCSS);\r
+    }\r
+    \r
+    \r
+    \r
+    \r
+    function _merge($permCSS, $tempCSS) {\r
+        $cssSrcs = array($this->_toObj($permCSS), $this->_toObj($tempCSS));\r
+        \r
+        $merged = array();\r
+        \r
+        for ($i = 0; $i < 2; ++$i) {\r
+            foreach ($cssSrcs[$i] as $sel => $rule) {\r
+                $newSel = false;\r
+                if (!isset($merged[$sel])) {\r
+                    $merged[$sel] = array();\r
+                    $newSel = true;\r
+                }\r
+                foreach ($rule as $prop => $value) {\r
+                    $merged[$sel][$prop] = $value;\r
+                }\r
+                if ($i > 0 && !$newSel) {\r
+                    foreach ($merged[$sel] as $prop => $value) {\r
+                        if (!isset($cssSrcs[$i][$sel][$prop])) {\r
+                            unset($merged[$sel][$prop]);\r
+                        }\r
+                    }\r
+                }\r
+            }\r
+            if ($i > 0) {\r
+                foreach ($merged as $sel => $value) {\r
+                    if (!isset($cssSrcs[$i][$sel])) {\r
+                        unset($merged[$sel]);\r
+                    }\r
+                }\r
+            }\r
+        }\r
+        \r
+        return $this->_toStr($merged);\r
+    }\r
+    \r
+   \r
+    \r
+    \r
+    function _toObj($cssStr) {\r
+        $cssObj = array();\r
+        $end = strpos($cssStr, '}');\r
+        while ($end !== false) {\r
+            $curRule = substr($cssStr, 0, $end);\r
+            $parts = explode('{', $curRule);\r
+            $selector = trim($parts[0]);\r
+            $rules = trim($parts[1]);\r
+            $rulesArr = explode(';', $rules);\r
+\r
+            $num = count($rulesArr);\r
+            for ($i = 0; $i < $num; ++$i) {\r
+                if (strpos($rulesArr[$i], ':') === false) {\r
+                    break;\r
+                }\r
+                $rule = explode(':', $rulesArr[$i]);\r
+                $prop = trim($rule[0]);\r
+                $value = trim($rule[1]);\r
+\r
+                if (!isset($cssObj[$selector])) {\r
+                    $cssObj[$selector] = array();\r
+                }\r
+                $cssObj[$selector][$prop] = $value;\r
+            }\r
+            $cssStr = substr($cssStr, $end + 1);\r
+            $end = strpos($cssStr, '}');\r
+        }\r
+        return $cssObj;\r
+    }\r
+    \r
+    \r
+    function _toStr($cssObj) {\r
+        $cssStr = '';\r
+        foreach ($cssObj as $sel => $rule) {\r
+            $cssStr .= "$sel {\n";\r
+            foreach ($rule as $prop => $value) {\r
+                $cssStr .= "  $prop: $value;\n";\r
+            }\r
+            $cssStr .= "}\n";\r
+        }\r
+        return $cssStr;\r
+    }\r
+}\r
+\r
+\r
+?>
\ No newline at end of file
diff --git a/theme/chameleon/ui/ChameleonFileBrowser.class.php b/theme/chameleon/ui/ChameleonFileBrowser.class.php
new file mode 100644 (file)
index 0000000..ae53b9b
--- /dev/null
@@ -0,0 +1,85 @@
+<?php\r
+\r
+class ChameleonFileBrowser {\r
+    var $root;\r
+    var $path;\r
+    var $dir;\r
+    var $IMAGE_TYPES;\r
+  \r
+    var $foundDirs = array();\r
+    var $foundFiles = array();\r
+\r
+    function ChameleonFileBrowser() {\r
+        $this->IMAGE_TYPES = array('jpeg', 'jpg', 'gif', 'png');\r
+        \r
+        $tmp = explode('/', str_replace('\\', '/', __FILE__));\r
+        array_pop($tmp);\r
+        array_pop($tmp);\r
+        $this->root = implode('/', $tmp);\r
+\r
+        $this->path = $this->sanitisePath($_GET['path']);\r
+        $this->dir = $this->root . '/' . $this->path;\r
+    }\r
+\r
+    function sanitisePath($path) {\r
+        if ($path == 'root') {\r
+            return 'pix';\r
+        }\r
+        \r
+        if (substr($path, 0, 3) != 'pix') {\r
+            $this->send('<chameleon_error>Not a valid directory</chameleon_error>');\r
+        }\r
+        \r
+        return preg_replace('/[.]+/', '', $path);\r
+    }\r
+\r
+    function isImage($file) {\r
+        if (strpos($file, '.') === false) {\r
+            return false;\r
+        }\r
+        return in_array(array_pop(explode('.', $file)), $this->IMAGE_TYPES);\r
+    }\r
+\r
+    function readFiles() {\r
+        if (!is_dir($this->dir)) {\r
+            $this->send('<chameleon_error>Not a valid directory</chameleon_error>');\r
+        }\r
+        \r
+        $handle = opendir($this->dir);       \r
+        while (false !== ($file = readdir($handle))) {\r
+            if ($file == '.' || $file == '..') {\r
+                continue;\r
+            }\r
+            if (is_dir($this->dir . '/' . $file)) {\r
+                $this->foundDirs[] = $file;\r
+            } else if ($this->isImage($file)) {\r
+                $this->foundFiles[] = $file;\r
+            }\r
+        }\r
+        closedir($handle);\r
+\r
+        sort($this->foundDirs, SORT_STRING);\r
+        sort($this->foundFiles, SORT_STRING);\r
+        $this->sendFiles();\r
+    }\r
+\r
+    function sendFiles() {\r
+        $out = "<files path=\"$this->path\">\n";\r
+        foreach ($this->foundDirs as $file) {\r
+            $out .= "  <file type=\"dir\">$this->path/$file</file>\n";\r
+        }\r
+        foreach ($this->foundFiles as $file) {\r
+            $out .= "  <file type=\"img\">$this->path/$file</file>\n";\r
+        }\r
+        $out .= "</files>";\r
+        \r
+        $this->send($out);\r
+    }\r
+    \r
+    function send($out) {\r
+        header("Content-type: application/xml; charset=utf-8");\r
+        die($out);\r
+    }\r
+}\r
+\r
+?>
\ No newline at end of file
diff --git a/theme/chameleon/ui/chameleon_js.php b/theme/chameleon/ui/chameleon_js.php
new file mode 100644 (file)
index 0000000..1d5daae
--- /dev/null
@@ -0,0 +1,2865 @@
+<?php\r
+header("Content-type: text/javascript");\r
+?>\r
+\r
+if (!window.Node) {\r
+     var Node = {\r
+         ELEMENT_NODE : 1,\r
+         ATTRIBUTE_NODE : 2,\r
+         TEXT_NODE : 3,\r
+         CDATA_SECTION_NODE : 4,\r
+         ENTITY_REFERENCE_NODE : 5,\r
+         ENTITY_NODE : 6,\r
+         PROCESSING_INSTRUCTIONS_NODE : 7,\r
+         COMMENT_NODE : 8,\r
+         DOCUMENT_NODE : 9,\r
+         DOCUMENT_TYPE_NODE : 10,\r
+         DOCUMENT_FRAGMENT_NODE : 11,\r
+         NOTATION_NODE : 12\r
+    };\r
+}\r
+\r
+\r
+\r
+String.prototype.trim = function() {\r
+    return this.replace(/^\s+|\s+$/g, '');\r
+};\r
+\r
+<?php\r
+\r
+$chameleon_theme_root = explode('/', $_SERVER['PHP_SELF']);\r
+array_pop($chameleon_theme_root);\r
+array_pop($chameleon_theme_root);\r
+$chameleon_theme_root = implode('/', $chameleon_theme_root);\r
+\r
+?>\r
+\r
+(function() {\r
+    \r
+    var struct = [];\r
+    var hotspotMode = null;\r
+    \r
+    var Config = {\r
+        THEME_ROOT: '<?php echo $chameleon_theme_root; ?>',\r
+        REMOTE_URI: '<?php echo substr($_SERVER['PHP_SELF'], 0, strrpos($_SERVER['PHP_SELF'], '/')); ?>/css.php?id=<?php echo (isset($_GET['id'])) ? (int) $_GET['id'] : 0; ?>',\r
+        FONTS_LIST: ['verdana, arial, helvetica, sans-serif', '"trebuchet ms", verdana, sans-serif', 'georgia, "trebuchet ms", times, serif', 'Other'],\r
+        FONT_WEIGHTS: ['normal', 'bold'],\r
+        FONT_STYLES: ['normal', 'italic'],\r
+        TEXT_DECORATION: ['none', 'underline', 'overline', 'line-through'],\r
+        TEXT_ALIGN: ['left', 'right', 'center', 'justify'],\r
+        REPEAT_LIST: ['repeat', 'repeat-x', 'repeat-y', 'no-repeat'],\r
+        POSITION_LIST: ['left top', 'left center', 'left bottom', 'center top', 'center center', 'center bottom', 'right top', 'right center', 'right bottom'],\r
+        BORDER_LIST: ['solid', 'dotted', 'dashed', 'none'],\r
+        UNITS: ['px', 'pt', 'em', '%']\r
+    };\r
+    \r
+\r
+\r
+    var Util = {\r
+        __registry: {},\r
+        __uniqueId: 0,\r
+\r
+        createElement: function(tag, id) {\r
+            if (!id) var id = 'chameleon-element-' + ++Util.__uniqueId;\r
+            var obj = document.createElement(tag);\r
+            obj.setAttribute('id', id);\r
+            return obj;\r
+        },\r
+        removeElement: function(obj) {\r
+            if (!obj || !obj.parentNode) return false;\r
+\r
+            var kids = obj.getElementsByTagName('*');\r
+            var n = kids.length;\r
+            while (n--) {\r
+                if (kids[n].id && Util.__registry[kids[n].id]) {\r
+                    Util.__removeAllEvents(kids[n]);\r
+                }\r
+            }\r
+            if (Util.__registry[obj.id]) {\r
+                Util.__removeAllEvents(obj);\r
+            }\r
+            obj.parentNode.removeChild(obj); \r
+        },\r
+\r
+        addEvent: function(obj, ev, fn) {\r
+            if (!Util.__addToRegistry(obj, ev, fn)) return;\r
+  \r
+            if (obj.addEventListener) {\r
+                obj.addEventListener(ev, fn, false);\r
+            } else if (obj.attachEvent) {\r
+                obj['e' + ev + fn] = fn;\r
+                obj[ev + fn] = function() { \r
+                    obj['e' + ev + fn](window.event);\r
+                };\r
+                obj.attachEvent('on' + ev, obj[ev + fn]);\r
+            }\r
+        },\r
+        removeEvent: function(obj, ev, fn) {\r
+            if (!Util.__removeFromRegistry(obj, ev, fn)) return;\r
+\r
+            if (obj.removeEventListener) {\r
+                obj.removeEventListener(ev, fn, false);\r
+            } else if (obj.detachEvent) {\r
+                obj.detachEvent('on' + ev, obj[ev + fn]);\r
+                obj[ev + fn] = null;     \r
+            }\r
+        },\r
+\r
+        __getEventId: function(obj) {\r
+            if (obj == document)  return 'chameleon-doc';\r
+            if (obj == window) return 'chameleon-win';\r
+            if (obj.id) return obj.id;\r
+            return false;\r
+        },\r
+        __findEvent: function(id, ev, fn) {\r
+            var i = Util.__registry[id][ev].length;\r
+            while (i--) {\r
+                if (Util.__registry[id][ev][i] == fn) {\r
+                    return i;\r
+                }\r
+            }\r
+            return -1;\r
+        },\r
+        __addToRegistry: function(obj, ev, fn) {\r
+            var id = Util.__getEventId(obj);\r
+\r
+            if (!id) return false;\r
+\r
+            if (!Util.__registry[id]) {\r
+                Util.__registry[id] = {};\r
+            }\r
+            if (!Util.__registry[id][ev]) {\r
+                Util.__registry[id][ev] = [];\r
+            }\r
+            if (Util.__findEvent(id, ev, fn) == -1) {\r
+                Util.__registry[id][ev].push(fn);\r
+                return true;\r
+            }\r
+            return false;\r
+        },\r
+        __removeFromRegistry: function(obj, ev, fn) {\r
+            var id = Util.__getEventId(obj);\r
+     \r
+            if (!id) return false;\r
\r
+            var pos = Util.__findEvent(id, ev, fn);\r
+            if (pos != -1) {\r
+                Util.__registry[id][ev].splice(pos, 1);\r
+                return true;\r
+            }\r
+            return false;\r
+        },\r
+        __removeAllEvents: function(obj) {\r
+            for (var event in Util.__registry[obj.id]) {\r
+                var n = Util.__registry[obj.id][event].length;\r
+                while (n--) {\r
+                    Util.removeEvent(obj, event, Util.__registry[obj.id][event][n]);\r
+                }\r
+            }\r
+        },\r
+\r
+        cleanUp: function() {\r
+            UI.closeAllBoxes();\r
+        }\r
+    };\r
+\r
+\r
+\r
+\r
+\r
+    var Pos = {\r
+        getElement: function(obj) {\r
+            var x = 0; var y = 0;\r
+            if (obj.offsetParent) {\r
+                while (obj.offsetParent) {\r
+                    x += obj.offsetLeft;\r
+                    y += obj.offsetTop;\r
+                    obj = obj.offsetParent;\r
+                }\r
+            }\r
+            return {x: x, y: y};\r
+        },\r
+        getMouse: function(e) {\r
+            var x = 0; var y = 0;\r
+            if (e.pageX || e.pageY) {\r
+                x = e.pageX;\r
+                y = e.pageY;\r
+            } else if (e.clientX || e.clientY) {\r
+                x = e.clientX + (document.documentElement.scrollLeft ? document.documentElement.scrollLeft : document.body.scrollLeft);\r
+                y = e.clientY + (document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop);\r
+            }\r
+            return {x: x, y: y};\r
+        }\r
+    };\r
+    \r
+    \r
+    \r
+\r
+\r
+\r
+\r
+    var CSS = {\r
+        \r
+        __localCSS: {},\r
+        __remoteCSS: {},\r
+        \r
+        __localSaveRequired: false,\r
+        __remoteSaveRequired: false,\r
+        \r
+\r
+        loadRemote: function(doSetup) {\r
+            if (!Sarissa.IS_ENABLED_XMLHTTP) {\r
+                return false;\r
+            }\r
+            var xmlhttp = new XMLHttpRequest();\r
+            xmlhttp.onreadystatechange = function() {\r
+                if (xmlhttp.readyState == 4) {\r
+                    if (xmlhttp.responseText.indexOf('CHAMELEON_ERROR') != -1) {\r
+                        alert('There was an error loading from the server:\n' + xmlhttp.responseText.replace(/CHAMELEON_ERROR /, '') + '.');\r
+                        return;\r
+                    }\r
+                    CSS.__remoteCSS = CSS.toObject(xmlhttp.responseText);\r
+                    CSS.__localCSS = CSS.__clone(CSS.__remoteCSS);\r
+                    CSS.preview();\r
+                    if (doSetup) {\r
+                        setup();\r
+                    }\r
+                    xmlhttp = null;\r
+                }\r
+            };\r
+            xmlhttp.open('GET', Config.REMOTE_URI  + '&nc=' + new Date().getTime(), true);\r
+            xmlhttp.send(null);\r
+            return true;\r
+        },\r
+        \r
+        \r
+        updateTemp: function(e, reset) {\r
+            if (!CSS.__localSaveRequired && !reset) {\r
+                UI.statusMsg('There are no changes that need saving!', 'chameleon-notice');\r
+                return;\r
+            }\r
+            \r
+            if (!reset) {\r
+                UI.statusMsg('Updating temporary styles on the server...', 'chameleon-working');\r
+            } else {\r
+                UI.statusMsg('Deleting temporary styles from the server...', 'chameleon-working');\r
+            }\r
+            \r
+            var css = CSS.toString();\r
+            var xmlhttp = new XMLHttpRequest();\r
+            xmlhttp.onreadystatechange = function() {\r
+                if (xmlhttp.readyState == 4) {\r
+                    if (xmlhttp.responseText.indexOf('CHAMELEON_ERROR') != -1) {\r
+                        UI.statusMsg('There was an error saving to the server:\n' + xmlhttp.responseText.replace(/CHAMELEON_ERROR /, '') + '.', 'chameleon-error');\r
+                        \r
+                    } else {\r
+                        CSS.__localSaveRequired = false;\r
+                        if (!reset) {\r
+                            UI.statusMsg('Temporary styles have been updated.', 'chameleon-ok');\r
+                        } else {\r
+                            UI.statusMsg('Temporary styles have been cleared.', 'chameleon-ok');\r
+                        }        \r
+                    }\r
+                    xmlhttp = null;\r
+                }\r
+            };\r
+            xmlhttp.open('POST', Config.REMOTE_URI + '&temp=1', true);\r
+            xmlhttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');\r
+            xmlhttp.send('css=' + css);\r
+        },\r
+        \r
+\r
+        updateRemote: function() {\r
+            if (!CSS.__remoteSaveRequired) {\r
+                UI.statusMsg('There are no changes that need saving!', 'chameleon-notice');\r
+                return;\r
+            }  \r
+        \r
+            var css = CSS.toString(CSS.__localCSS);\r
+\r
+            UI.statusMsg('Updating styles on the server...', 'chameleon-working');\r
+            var xmlhttp = new XMLHttpRequest();\r
+            xmlhttp.onreadystatechange = function() {\r
+                if (xmlhttp.readyState == 4) {\r
+                    if (xmlhttp.responseText.indexOf('CHAMELEON_ERROR') != -1) {\r
+                        UI.statusMsg('There was an error saving to the server:\n' + xmlhttp.responseText.replace(/CHAMELEON_ERROR /, '') + '.', 'chameleon-error');\r
+                    } else {\r
+                        CSS.__remoteCSS = CSS.toObject(css);\r
+                        CSS.__localSaveRequired = false;\r
+                        CSS.__remoteSaveRequired = false;\r
+                        UI.statusMsg('Styles have been saved to the server.', 'chameleon-ok');\r
+                    }\r
+                    xmlhttp = null;\r
+                }\r
+            };\r
+            xmlhttp.open('POST', Config.REMOTE_URI, true);\r
+            xmlhttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');\r
+            xmlhttp.send('css=' + css);\r
+        },\r
+        \r
+    \r
+        \r
+        \r
+      \r
+      \r
+        hardReset: function(e, noPrompt) {\r
+            if (noPrompt || confirm('Are you sure? This will erase all styles that have not been permanently saved to the server.')) {\r
+                CSS.__localCSS = {};\r
+                CSS.updateTemp(null, true);\r
+                \r
+                CSS.__localCSS = CSS.__clone(CSS.__remoteCSS);\r
+                CSS.__localSaveRequired = false;\r
+                CSS.__remoteSaveRequired = false;\r
+                CSS.preview();\r
+            }\r
+        },\r
+        \r
+        \r
+        \r
+        \r
+        \r
+        setPropValue: function(prop, value, selector) {\r
+            if (!selector) var selector = CSS.Selector.get();\r
+\r
+            if (!CSS.__localCSS[selector]) {\r
+                CSS.__localCSS[selector] = {};\r
+            }\r
+            \r
+            var matches = prop.match(/^border\-([^\-]+)$/);\r
+            if (value) {\r
+                var func = CSS.__requiresFunction(prop);\r
+                if (func && value != 'none') {\r
+                    CSS.__localCSS[selector][prop] = func + '(' + value + ')';\r
+                } else if (matches) {\r
+                    CSS.__localCSS[selector]['border-left-' + matches[1]] = value;\r
+                    CSS.__localCSS[selector]['border-right-' + matches[1]] = value;\r
+                    CSS.__localCSS[selector]['border-top-' + matches[1]] = value;\r
+                    CSS.__localCSS[selector]['border-bottom-' + matches[1]] = value;\r
+                } else {\r
+                    CSS.__localCSS[selector][prop] = value;\r
+                }\r
+            } else {\r
+                if (matches) {\r
+                    CSS.unsetProp('border-left-' + matches[1], selector);\r
+                    CSS.unsetProp('border-right-' + matches[1], selector);\r
+                    CSS.unsetProp('border-top-' + matches[1], selector);\r
+                    CSS.unsetProp('border-bottom-' + matches[1], selector);\r
+                } else {\r
+                    CSS.unsetProp(prop, selector);\r
+                }\r
+            }\r
+            \r
+            CSS.__localSaveRequired = true;\r
+            CSS.__remoteSaveRequired = true;\r
+            CSS.preview(selector);\r
+        },\r
+        \r
+        getPropValue: function(prop, selector) {\r
+            if (!selector) var selector = CSS.Selector.get();\r
+\r
+            if (!CSS.__localCSS[selector] || !CSS.__localCSS[selector][prop]) {\r
+                return '';\r
+            }\r
+            return CSS.__cleanFunctions(CSS.__localCSS[selector][prop]);\r
+        },\r
+\r
+        unsetProp: function(prop, selector) {\r
+            if (!selector) var selector = CSS.Selector.get();\r
+\r
+            if (!CSS.__localCSS[selector] || !CSS.__localCSS[selector][prop]) return;\r
+\r
+            CSS.__localCSS[selector][prop] = null;\r
+            delete CSS.__localCSS[selector][prop];\r
+\r
+            if (!CSS.__hasProps(selector)) {\r
+                CSS.__localCSS[selector] = null;\r
+                delete CSS.__localCSS[selector];\r
+            }\r
+        },\r
+        \r
+        \r
+        __hasProps: function(selector) {\r
+            for (var prop in CSS.__localCSS[selector]) {\r
+                if (prop) {\r
+                    return true;\r
+                }\r
+            }\r
+            return false;\r
+        },\r
+        \r
+        \r
+\r
+\r
+        __cleanFunctions: function(val) {\r
+            var toClean = ['url'];\r
+            for (var i = 0; i < toClean.length; ++i) {\r
+                var start = val.indexOf(toClean[i] + '(');\r
+                var end = val.indexOf(')', start);\r
+                if (start == -1 || end == -1) {\r
+                    continue;\r
+                }\r
+                val = val.slice(start + toClean[i].length + 1, end);\r
+            }\r
+            return val;\r
+        },\r
+\r
+        __requiresFunction: function(prop) {\r
+            var fnProps = {};\r
+            fnProps['background-image'] = 'url';\r
+            if (fnProps[prop]) {\r
+                return fnProps[prop];\r
+            }\r
+            return false;\r
+        },\r
+\r
+\r
+\r
+\r
+        fixPath: function(val) {\r
+            if (val == 'none') return val;\r
+            \r
+            var tmp = val.split('(');\r
+            if (tmp.length > 1) {\r
+                tmp[1] = Config.THEME_ROOT + '/' + tmp[1];\r
+                return tmp.join('(');\r
+            }\r
+            return Config.THEME_ROOT + '/' + val;\r
+        },\r
+        \r
+        \r
+        \r
+        preview: function(sel) {\r
+            var styleId = 'chameleon-preview-styles';\r
+\r
+            var h = document.getElementsByTagName('head')[0];\r
+            var s = document.getElementById(styleId);\r
+            \r
+            if (!s) {\r
+                var s = Util.createElement('style', styleId);\r
+                s.setAttribute('type', 'text/css');\r
+                h.appendChild(s);\r
+            }\r
+            \r
+            if (navigator.userAgent.toLowerCase().indexOf('msie') != -1  && !window.opera && document.styleSheets && document.styleSheets.length > 0) {\r
+                var lastStyle = document.styleSheets[document.styleSheets.length - 1];\r
+                \r
+                if (sel) {\r
+                    var matchedSelectors = [];\r
+                    if (typeof sel == 'string') {\r
+                        sel = [sel];\r
+                    }\r
+                    var n = lastStyle.rules.length;\r
+                    while (n--) {\r
+                        var ns = sel.length;\r
+                        if (ns == 0) {\r
+                            break;\r
+                        }\r
+                        while (ns--) {\r
+                            if (lastStyle.rules[n].selectorText.toLowerCase() == sel[ns].toLowerCase()) {\r
+                                matchedSelectors.push(sel[ns]);\r
+                                sel.splice(ns, 1);\r
+                                lastStyle.removeRule(n);\r
+                                break;\r
+                            }\r
+                        }\r
+\r
+                    }\r
+                    matchedSelectors = matchedSelectors.concat(sel);\r
+                    var sl = matchedSelectors.length;\r
+                    while (sl--) {\r
+                        lastStyle.addRule(matchedSelectors[sl], CSS.__propsToString(CSS.__localCSS[matchedSelectors[sl]], true));\r
+                    }\r
+                } else {\r
+                    for (var sel in CSS.__localCSS) {\r
+                        var dec = CSS.__propsToString(CSS.__localCSS[sel], true);\r
+                        lastStyle.addRule(sel, dec);\r
+                    }\r
+                }\r
+                \r
+            } else {\r
+                s.innerHTML = CSS.toString(CSS.__localCSS, true);\r
+            }\r
+        },\r
+        \r
+        \r
+\r
+        __merge: function() {\r
+            var merged = {};\r
+            for (var i = 0; i < arguments.length; ++i) {\r
+                for (var sel in arguments[i]) {\r
+                    var newSelector = false;\r
+                    if (!merged[sel]) {\r
+                        merged[sel] = {};\r
+                        newSelector = true;\r
+                    }\r
+                    for (var prop in arguments[i][sel]) {\r
+                        merged[sel][prop] = arguments[i][sel][prop];\r
+                    }\r
+\r
+                    if (i > 0 && !newSelector) {\r
+                        for (var prop in merged[sel]) {\r
+                            if (!arguments[i][sel][prop]) {\r
+                                 merged[sel][prop] = null;\r
+                                 delete merged[sel][prop];\r
+                            }\r
+                        }\r
+                    }\r
+                }\r
+                if (i > 0) {\r
+                    for (var sel in merged) {\r
+                        if (!arguments[i][sel]) {\r
+                            merged[sel] = null;\r
+                            delete merged[sel];\r
+                        }\r
+                    }\r
+                }\r
+            }\r
+            return merged;\r
+        },\r
+        \r
+        __clone: function(src) {\r
+            var cloned = {};\r
+            for (var sel in src) {\r
+                if (!cloned[sel]) {\r
+                    cloned[sel] = {};\r
+                }\r
+                for (var prop in src[sel]) {\r
+                    cloned[sel][prop] = src[sel][prop];\r
+                }\r
+            }\r
+            return cloned;\r
+        },\r
+        \r
+        \r
+        toString: function(css, fixpath) {\r
+            if (!css) var css = CSS.__localCSS;\r
+            \r
+            var dec = '';\r
+            for (var sel in css) {\r
+                dec += sel + ' ' + CSS.__propsToString(css[sel], fixpath, sel);\r
+            }\r
+            return dec;\r
+        },\r
+        \r
+        __propsToString: function(css, fixpath) {\r
+            CSS.__Shorthand.border = {};\r
+            \r
+            var hasBorder = false;\r
+            var col = false;\r
+                 \r
+            var dec = '{\n';\r
+            for (var prop in css) {\r
+                \r
+                if (prop.indexOf('border') != -1 && prop.indexOf('spacing') == -1 && prop.indexOf('collapse') == -1) {\r
+                    CSS.__Shorthand.recordBorder(prop, css[prop]);\r
+                    hasBorder = true;\r
+                }\r
+                \r
+                if (prop == 'color') {\r
+                    col = css[prop];\r
+                }\r
+\r
+                if (fixpath && (CSS.__requiresFunction(prop) == 'url') && css[prop] != 'none') {\r
+                    dec += '  ' + prop + ': ' + CSS.fixPath(css[prop]) + ';\n';\r
+                } else {\r
+                    dec += '  ' + prop + ': ' + css[prop] + ';\n';\r
+                }\r
+            }\r
+            \r
+            if (hasBorder) {\r
+                dec += CSS.__Shorthand.getBorderString(col);\r
+            }\r
+\r
+            dec += '}\n';\r
+            return dec;\r
+        },\r
+        \r
+                \r
+        \r
+        \r
+        toObject: function(css) {\r
+            var cssObj = {};\r
+            var end;\r
+\r
+            while (end = css.indexOf('}'), end != -1) {\r
+                var cssRule = css.substr(0, end);\r
+                var parts = cssRule.split('{');\r
+                var selector = parts.shift()\r
+                if (selector.indexOf(',') != -1) {\r
+                    var selectorArr = selector.split(',');\r
+                } else {\r
+                    var selectorArr = [selector];\r
+                }\r
+                \r
+                var rules = parts.pop().trim();\r
+                rules = rules.split(';');\r
+                for (var i = 0; i < rules.length; ++i) {\r
+                    if (rules[i].indexOf(':') == -1) {\r
+                        break;\r
+                    }\r
+                    var rule = rules[i].split(':');\r
+                    var prop = rule.shift().trim();\r
+                    var val = rule.pop().trim();\r
+                    \r
+                    for (var j = 0; j < selectorArr.length; ++j) {\r
+                        var noFontPropReset = {};\r
+                        \r
+                        selector = selectorArr[j].trim();\r
+                        if (!cssObj[selector]) {\r
+                            cssObj[selector] = {};\r
+                        }\r
+                    \r
+                        if (prop != 'font' && (prop.indexOf('font') != -1 || prop == 'line-height')) {\r
+                            noFontPropReset[prop] = true;\r
+                        }\r
+                    \r
+                        if (prop == 'background') {\r
+                            CSS.__Shorthand.setBackground(cssObj, selector, val);\r
+                        } else if (prop == 'font') {    \r
+                            CSS.__Shorthand.setFont(cssObj, selector, val, noFontPropReset);\r
+                        } else if ((prop == 'border' || prop.match(/^border\-([^-]+)$/)) && prop.indexOf('spacing') == -1 && prop.indexOf('collapse') == -1) {\r
+                            CSS.__Shorthand.setBorder(cssObj, selector, val, prop);\r
+                        } else {\r
+                            cssObj[selector][prop] = val;\r
+                        }\r
+                    }\r
+                }\r
+                css = css.substring(end + 1);\r
+            }\r
+            return cssObj;\r
+        },\r
+        \r
+        \r
+        \r
+        \r
+        \r
+        getSelectorCSS: function(selector, asObject) {\r
+            if (!selector) var selector = CSS.Selector.get();\r
+\r
+            var css = (CSS.__localCSS[selector]) ? CSS.__localCSS[selector] : {};\r
+            if (asObject) {\r
+                return css;\r
+            }\r
+            return selector + ' ' + CSS.__propsToString(css);\r
+        },\r
+        \r
+        \r
+        \r
+        saveRequired: function() {\r
+            return CSS.__localSaveRequired || CSS.__serverSaveRequired;\r
+        },\r
+        \r
+        \r
+        checkSpec: function(e, selector) {\r
+            var canMatchAny = function(str) {\r
+                var classPos = str.indexOf('.');\r
+                var idPos = str.indexOf('#');\r
+                if (classPos == 0 || idPos == 0) {\r
+                    return true;\r
+                }\r
+                return false;\r
+            };\r
+            \r
+            if (!selector) var selector = CSS.Selector.get();\r
+            if (selector == '') {\r
+                UI.statusMsg('First you have to choose which item to style!', 'chameleon-notice');\r
+                return;\r
+            }\r
+            var similarSelectors = [];\r
+            \r
+            var thisMatches = selector.split(' ').pop();\r
+            var matchAnyTag = canMatchAny(thisMatches);\r
+            if (matchAnyTag) {\r
+                var curRegExp = new RegExp('([\. ]?)' + thisMatches.split('.').join('\\.') + '([\.:]|$)');\r
+            }\r
+            \r
+            \r
+            for (var sel in CSS.__localCSS) {\r
+                var selMatches = sel.split(' ').pop();\r
+                if (thisMatches == selMatches) {\r
+                    similarSelectors.push(sel);\r
+                } else if (matchAnyTag && selMatches.match(curRegExp)) {\r
+                    similarSelectors.push(sel);\r
+                } else if (canMatchAny(selMatches)) {\r
+                    var selRegExp = new RegExp('([ ]?)' + selMatches.split('.').join('\\.') + '([\.:]|$)');\r
+                    if (thisMatches.match(selRegExp)) {\r
+                        similarSelectors.push(sel);\r
+                    }\r
+                }\r
+            }\r
+\r
+            \r
+            if (similarSelectors.length) {\r
+                UI.Selector.__displayOverview(null, similarSelectors, selector);\r
+            } else {\r
+                UI.statusMsg('You file currently contains no selectors that appear similar to "' + selector + '"', 'chameleon-notice');\r
+            }         \r
+        },\r
+        \r
+        unloadPrompt: function() {\r
+            if (CSS.__localSaveRequired) {\r
+                if (confirm('You have made changes to the CSS on this page since the last time it was saved, these changes will be lost unless you save them now.\nSelect OK to save a temporary copy or Cancel to continue and discard the unsaved CSS.')) {\r
+                    CSS.updateTemp();\r
+                }\r
+            }\r
+        }\r
+\r
+    };\r
+    \r
+    \r
+    \r
+    CSS.Selector = {\r
+        \r
+        trimmed: [],\r
+        full: [],\r
+        selector: '',\r
+        \r
+        create: function() {\r
+            CSS.Selector.trimmed = [];\r
\r
+            var n = struct.length;\r
+            while (n--) {\r
+                if (CSS.Selector.full[n]) {\r
+                    CSS.Selector.trimmed.push(CSS.Selector.full[n].val);\r
+                }\r
+            }\r
+            CSS.Selector.set(CSS.Selector.trimmed.join(' '));\r
+        },\r
+        \r
+        modify: function(e) {\r
+            var target = e.target || e.srcElement;\r
+            var p = target.position;\r
+            \r
+            var sel = CSS.Selector.full;\r
+\r
+            if (!sel[p]) {\r
+                UI.Selector.highlight(target);\r
+                sel[p] = {val: target.selectorValue, id: target.id};\r
+            } else if (sel[p].val != target.selectorValue) {\r
+                UI.Selector.highlight(target);\r
+                UI.Selector.unhighlight(document.getElementById(sel[p].id));\r
+                sel[p] = {val: target.selectorValue, id: target.id};\r
+            } else {\r
+                UI.Selector.unhighlight(target);\r
+                sel[p] = null;\r
+            }\r
+\r
+            CSS.Selector.create();\r
+            UI.Selector.displaySelector(CSS.Selector.trimmed);\r
+        },\r
+        \r
+        set: function(sel) {\r
+            CSS.Selector.selector = sel;\r
+        },\r
+        \r
+        get: function() {\r
+            return CSS.Selector.selector;  \r
+        },\r
+\r
+        reset: function() {\r
+            CSS.Selector.trimmed = [];\r
+            CSS.Selector.full = [];\r
+            CSS.Selector.set('');\r
+        }               \r
+    };\r
+    \r
+    \r
+    \r
+    CSS.__Shorthand = {\r
+        border: {},\r
+        \r
+        recordBorder: function(prop, value) {\r
+            var pr = prop.split('-')\r
+            var p = pr.pop();\r
+            var s = pr.pop();\r
+            if (!CSS.__Shorthand.border[p]) {\r
+                CSS.__Shorthand.border[p] = [];\r
+            }\r
+            if (!CSS.__Shorthand.border[s]) {\r
+                CSS.__Shorthand.border[s] = {};\r
+            }\r
+            if (!CSS.__Shorthand.border[s][p]) {\r
+                CSS.__Shorthand.border[s][p] = [];\r
+            }\r
+            CSS.__Shorthand.border[p].push({prop: prop, value: value});\r
+            CSS.__Shorthand.border[s][p] = value;\r
+        },\r
+        \r
+        getBorderString: function(col) {\r
+            var cb = CSS.__Shorthand.border;\r
+            \r
+            var useHowManyProps = function(prop) {\r
+                if (!cb['top'] || !cb['right'] || !cb['bottom'] || !cb['left']) {\r
+                    return false;\r
+                }\r
+                \r
+                if (!(cb['top'][prop] && cb['right'][prop] && cb['bottom'][prop] && cb['left'][prop])) {\r
+                    return false;\r
+                }\r
+                \r
+                if (cb['top'][prop] == cb['right'][prop] && cb['top'][prop] == cb['bottom'][prop] && cb['top'][prop] == cb['left'][prop]) {\r
+                    return 1;\r
+                }\r
+                if (cb['top'][prop] == cb['bottom'][prop] && cb['right'][prop] == cb['left'][prop]) {\r
+                    return 2;\r
+                }\r
+                if (cb['right'][prop] == cb['left'][prop]) {\r
+                    return 3;\r
+                }\r
+                return 4;\r
+            };\r
+            \r
+            var getPropShorthand = function(prop) {\r
+                var num = useHowManyProps(prop);\r
+                if (!num) {\r
+                    return '';\r
+                }\r
+                \r
+                if (prop.indexOf('color') != -1) {\r
+                    var l = inheritColor(cb['left'][prop]);\r
+                    var r = inheritColor(cb['right'][prop]);\r
+                    var t = inheritColor(cb['top'][prop]);\r
+                    var b = inheritColor(cb['bottom'][prop]);\r
+                } else {\r
+                    var l = cb['left'][prop];\r
+                    var r = cb['right'][prop];\r
+                    var t = cb['top'][prop];\r
+                    var b = cb['bottom'][prop];\r
+                }\r
+                \r
+                var propShorthand = '';\r
+                if (num == 1) {\r
+                    propShorthand += '  border-' + prop + ': ' + l;\r
+                } else if (num == 2) {\r
+                    propShorthand += '  border-' + prop + ': ' + t + ' ' + l;\r
+                } else if (num == 3) {\r
+                    propShorthand += '  border-' + prop + ': ' + t + ' ' + l + ' ' + b;\r
+                } else {\r
+                    propShorthand += '  border-' + prop + ': ' + t + ' ' + r + ' ' + b + ' ' + l;\r
+                }\r
+                return propShorthand + ';\n';\r
+            };\r
+            \r
+            var propsStr = function(props) {\r
+                var str = '';\r
+                for (var i = 0; i < props.length; ++i) {\r
+                    str += '  ' + props[i].prop + ': ' + ((props[i].prop.indexOf('color') != -1) ? inheritColor(props[i].value) : props[i].value) + ';\n';\r
+                }\r
+                return str;\r
+            };\r
+            \r
+            var inheritColor = function(val) {\r
+                if (!col || val != 'inherit') return val;               \r
+                return col;\r
+            };\r
+            \r
+            var setImportant = function(str) {\r
+                if (!str) return '';\r
+                if (str.indexOf('!important') == -1) return str;\r
+                str = str.replace(/ *\!important */g, ' ');\r
+                return str.substr(0, str.lastIndexOf(';')) + ' !important;\n';\r
+            };\r
+                      \r
+            var widthEqual = (cb['width']) ? CSS.__Shorthand.__allPropsEqual(cb['width']) : false;\r
+            var styleEqual = (cb['style']) ? CSS.__Shorthand.__allPropsEqual(cb['style']) : false;\r
+            var colorEqual = (cb['color']) ? CSS.__Shorthand.__allPropsEqual(cb['color']) : false;\r
+            \r
+            if (widthEqual && styleEqual && colorEqual) {\r
+                var propStr = setImportant(cb['width'][0].value + ' ' + cb['style'][0].value + ' ' + inheritColor(cb['color'][0].value) + ';\n');              \r
+                if (cb['left'] && cb['top'] && cb['right'] && cb['bottom']) {\r
+                    return '  border: ' + propStr;\r
+                }\r
+                \r
+                var sideShorthand = '';\r
+                if (cb['top']) {\r
+                    sideShorthand += '  border-top: ' + propStr;\r
+                }\r
+                if (cb['right']) {\r
+                    sideShorthand += '  border-right: ' + propStr;\r
+                }\r
+                if (cb['bottom']) {\r
+                    sideShorthand += '  border-bottom: ' + propStr;\r
+                }\r
+                if (cb['left']) {\r
+                    sideShorthand += '  border-left: ' + propStr;\r
+                }\r
+                return sideShorthand;\r
+            }\r
+\r
+            var widthProps = getPropShorthand('width');\r
+            if (!widthProps) {\r
+                widthProps = (cb['width']) ? propsStr(cb['width']) : '';\r
+            }\r
+            var styleProps = getPropShorthand('style');\r
+            if (!styleProps) {\r
+                styleProps = (cb['style']) ? propsStr(cb['style']) : '';\r
+            }\r
+            var colorProps = getPropShorthand('color');\r
+            if (!colorProps) {\r
+                colorProps = (cb['color']) ? propsStr(cb['color']) : '';\r
+            }\r
+            \r
+            return setImportant(widthProps) + setImportant(styleProps) + setImportant(colorProps);\r
+\r
+        },\r
+        \r
+        \r
+        \r
+        \r
+        \r
+        setBorder: function(css, selector, value, prop) {\r
+            var props = {};\r
+            props['width'] = {\r
+                regexp: /^(thin|medium|thick|0|(\d+(([^%\d]+)|%)))$/,\r
+                def: 'medium'\r
+            };\r
+            props['style'] = {\r
+                regexp: /none|dotted|dashed|solid|double|groove|ridge|inset|outset/,\r
+                def: 'none'\r
+            };\r
+            props['color'] = {\r
+                regexp: /^((rgb\(\d{1,3} *, *\d{1,3} *, *\d{1,3} *\))|(#[A-F0-9]{3}([A-F0-9]{3})?)|([a-z]+))$/i,\r
+                def: 'inherit'\r
+            };\r
+            \r
+            var bits = value.split(' ');\r
+            var imp = (bits[bits.length - 1] == '!important') ? ' ' + bits.pop() : '';\r
+                        \r
+            if (prop == 'border') {\r
+                for (var i in props) {\r
+                    css[selector]['border-top-' + i] = props[i].def;\r
+                    css[selector]['border-right-' + i] = props[i].def;\r
+                    css[selector]['border-bottom-' + i] = props[i].def;\r
+                    css[selector]['border-left-' + i] = props[i].def;\r
+                    var j = bits.length;\r
+                    while (j--) {\r
+                        if (bits[j].match(props[i].regexp)) {\r
+                            css[selector]['border-top-' + i] = bits[j];\r
+                            css[selector]['border-right-' + i] = bits[j];\r
+                            css[selector]['border-bottom-' + i] = bits[j];\r
+                            css[selector]['border-left-' + i] = bits[j];\r
+                            bits.splice(j, 1);\r
+                            break;\r
+                        }\r
+                    }\r
+                }\r
+            } else if (prop == 'border-left' || prop == 'border-right' || prop == 'border-top' || prop == 'border-bottom') {\r
+                for (var i in props) {\r
+                    css[selector][prop + '-' + i] = props[i].def;\r
+                    var j = bits.length;\r
+                    while (j--) {\r
+                        if (bits[j].match(props[i].regexp)) {\r
+                            css[selector][prop + '-' + i] = bits[j];\r
+                            bits.splice(j, 1);\r
+                            break;\r
+                        }\r
+                    }\r
+                }\r
+            } else if (prop == 'border-width' || prop == 'border-style' || prop == 'border-color') {\r
+                var p = prop.split('-').pop();\r
+                var num = bits.length;\r
+                if (num == 1) {\r
+                    css[selector]['border-top-' + p] = bits[0];\r
+                    css[selector]['border-right-' + p] = bits[0];\r
+                    css[selector]['border-bottom-' + p] = bits[0];\r
+                    css[selector]['border-left-' + p] = bits[0];\r
+                } else if (num == 2) {\r
+                    css[selector]['border-top-' + p] = bits[0];\r
+                    css[selector]['border-right-' + p] = bits[1];\r
+                    css[selector]['border-bottom-' + p] = bits[0];\r
+                    css[selector]['border-left-' + p] = bits[1];\r
+                } else if (num == 3) {\r
+                    css[selector]['border-top-' + p] = bits[0];\r
+                    css[selector]['border-right-' + p] = bits[1];\r
+                    css[selector]['border-bottom-' + p] = bits[2];\r
+                    css[selector]['border-left-' + p] = bits[1];\r
+                } else if (num == 4) {\r
+                    css[selector]['border-top-' + p] = bits[0];\r
+                    css[selector]['border-right-' + p] = bits[1];\r
+                    css[selector]['border-bottom-' + p] = bits[2];\r
+                    css[selector]['border-left-' + p] = bits[3];\r
+                }\r
+            }\r
+            \r
+            if (imp != '') {\r
+                var sides = ['top', 'right', 'bottom', 'left'];\r
+                for (var i = 0; i < 4; ++i) {\r
+                    for (var j in props) {\r
+                        if (css[selector]['border-' + sides[i] + '-' + j]) {\r
+                            css[selector]['border-' + sides[i] + '-' + j] += imp;\r
+                        }\r
+                    }\r
+                }\r
+            }\r
+            \r
+        },\r
+        \r
+        \r
+        \r
+        \r
+        setBackground: function(css, selector, value) {\r
+            var imp = (value.indexOf('!important') != -1) ? ' !important' : '';\r
+            if (imp != '') {\r
+                value = value.replace(/ *\!important */g, '');\r
+            }\r
+            //value = value.replace(/[ ]{2, }/, ' ');\r
+            \r
+            var urlPos = value.indexOf('url(');\r
+            if (urlPos == -1 && value.indexOf('none') == -1) {\r
+                css[selector]['background-color'] = value + imp;\r
+                return;\r
+            } else if (urlPos == -1 && value.indexOf(' none') != -1) {\r
+                var bits = value.split(' ');\r
+                css[selector]['background-color'] = bits[0] + imp;\r
+                css[selector]['background-image'] = bits[1] + imp;\r
+                return;\r
+            } else if (value == 'none') {\r
+                css[selector]['background-image'] = value + imp;\r
+                return;\r
+            }\r
+            var bits = value.split('url(');\r
+            var endImg = bits[1].indexOf(')');\r
+            if (endImg == -1) {\r
+                return;\r
+            }\r
+            css[selector]['background-image'] = 'url(' + bits[1].substr(0, endImg).replace(/["']+/g, '') + ')' + imp; //"\r
+            \r
+            var pos = [];\r
+            \r
+            var bgOptions =  bits[1].substring(endImg + 1).split(' ');\r
+            var n = bgOptions.length;\r
+            \r
+            for (var i = 0; i < n; ++i) {\r
+                var opt = bgOptions[i].trim();\r
+                if (opt.indexOf('repeat') != -1) {\r
+                    css[selector]['background-repeat'] = opt + imp;\r
+                } else if (opt == 'fixed' || opt == 'scroll') {\r
+                    css[selector]['background-attachment'] = opt + imp;\r
+                } else if (opt != '') {\r
+                    pos.push(opt);\r
+                }\r
+            }\r
+            if (pos.length == 2) {\r
+                css[selector]['background-position'] = pos.join(' ') + imp;\r
+            }\r
+            var col = bits[0].trim();\r
+            if (col != '') {\r
+                css[selector]['background-color'] = col + imp;\r
+            }\r
+        },\r
+        \r
+        setFont: function(css, selector, value, noreset) {\r
+            var imp = (value.indexOf('!important') != -1) ? ' !important' : '';\r
+            if (imp != '') {\r
+                value = value.replace(/ *\!important */g, '');\r
+            }\r
+            \r
+            var order = ['font-style', 'font-variant', 'font-weight', 'font-size', 'font-family'];\r
+            var numProps = order.length;\r
+            var allowedVals = {};\r
+            allowedVals['font-style'] = /(normal|italic|oblique|inherit)/;\r
+            allowedVals['font-variant'] = /(normal|small\-caps|inherit)/;\r
+            allowedVals['font-weight'] = /(normal|bold|bolder|lighter|100|200|300|400|500|600|700|800|900|inherit)/;\r
+            allowedVals['font-size'] = /([^ ]+)/;\r
+            allowedVals['font-family'] = /(.+$)/;\r
+            \r
+            if (!noreset['font-style']) css[selector]['font-style'] = 'normal';\r
+            if (!noreset['font-variant']) css[selector]['font-variant'] = 'normal';\r
+            if (!noreset['font-weight']) css[selector]['font-weight'] = 'normal';\r
+            if (!noreset['font-size']) css[selector]['font-size'] = 'medium';\r
+            if (!noreset['line-height']) css[selector]['line-height'] = 'normal';\r
+            \r
+            var expandShorthand = function(bits) {\r
+                var numBits = bits.length;\r
+                var startProp = 0;\r
+                for (var i = 0; i < numBits; ++i) {\r
+                    if (i > numProps - 1) {\r
+                        return;\r
+                    }\r
+                    for (var j = startProp; j < numProps; ++j) {\r
+                        if (bits[i].match(allowedVals[order[j]])) {\r
+                            if (order[j] == 'font-size' && bits[i].indexOf('/') != -1) {\r
+                                var fsLh = bits[i].split('/');\r
+                                css[selector]['font-size'] = fsLh[0] + imp;\r
+                                css[selector]['line-height'] = fsLh[1] + imp;\r
+                            } else {\r
+                                css[selector][order[j]] = bits[i] + imp;\r
+                            }\r
+                            startProp = j + 1;\r
+                            break;\r
+                        }\r
+                    }\r
+                }\r
+            };\r
+            \r
+            var removeCommaListSpaces = function(str) {\r
+                var comma = str.indexOf(',');\r
+                if (comma != -1) {\r
+                    return str.substr(0, comma) + str.substring(comma).replace(/ +/g, '');\r
+                }\r
+                return str;\r
+            };\r
+            \r
+            var hasQuote = value.match(/(["'])/); //"\r
+            if (hasQuote) {\r
+                var tmp = value.split(hasQuote[1]);\r
+                var bits = removeCommaListSpaces(tmp.shift()).split(' ');\r
+                var startFont = bits.pop();\r
+                \r
+                expandShorthand(bits);\r
+                \r
+                css[selector]['font-family'] = startFont + hasQuote[1] + tmp.join(hasQuote[1]) + imp;           \r
+            } else {\r
+                value = removeCommaListSpaces(value);            \r
+                expandShorthand(value.split(' '));\r
+            }\r
+        },\r
+        \r
+        \r
+        \r
+\r
+        __allPropsEqual: function(props) {\r
+            var num = props.length - 1;\r
+            if (num < 4) return false;\r
+            \r
+            for (var i = 0; i < num; ++i) {\r
+                if (props[i].value != props[i + 1].value) {\r
+                    return false;\r
+                }\r
+            }\r
+            return true;\r
+        }\r
+        \r
+    };\r
+    \r
+    \r
+    \r
+    CSS.FreeEdit = {\r
+      \r
+        __initial: {},\r
+        \r
+        setInitial: function(e) {\r
+            var target = e.target || e.srcElement;\r
+\r
+            CSS.FreeEdit.__initial = CSS.toObject(target.value);\r
+        },\r
+        \r
+        saveComplete: function(e) {\r
+            var target = e.target || e.srcElement;\r
+            target.value = CSS.FreeEdit.__stripComments(target.value);\r
+\r
+            CSS.__localCSS = CSS.__merge(CSS.__localCSS, CSS.toObject(target.value));\r
+\r
+            CSS.__localSaveRequired = true;\r
+            CSS.__remoteSaveRequired = true;\r
+\r
+            CSS.preview();\r
+        },\r
+        \r
+        saveSelector: function(e) {\r
+            var target = e.target || e.srcElement;\r
+            target.value = CSS.FreeEdit.__stripComments(target.value);\r
+                        \r
+            if (target.value.indexOf('{') != target.value.lastIndexOf('{')) {\r
+               UI.statusMsg('Please note: when you return to this window only the styles for "' + CSS.Selector.get() + '" will be displayed here. Don\'t worry, your other styles aren\'t lost - they can be edited from the overview option.', 'chameleon-notice'); \r
+            }\r
+            \r
+            var changedSelectors = [];\r
+            \r
+\r
+            var css = CSS.toObject(target.value);\r
+            for (var sel in css) {\r
+                changedSelectors.push(sel);\r
+                if (!CSS.__localCSS[sel]) {\r
+                    CSS.__localCSS[sel] = {};\r
+                }\r
+                for (var prop in css[sel]) {\r
+                    CSS.__localCSS[sel][prop] = css[sel][prop];\r
+                }\r
+            }\r
+\r
+            for (var sel in CSS.FreeEdit.__initial) {\r
+                if (!css[sel] && CSS.__localCSS[sel]) {\r
+                    changedSelectors.push(sel);\r
+                    CSS.__localCSS[sel] = null;\r
+                    delete CSS.__localCSS[sel];\r
+                    continue;\r
+                }\r
+                for (var prop in CSS.FreeEdit.__initial[sel]) {\r
+                    if (!css[sel][prop] && CSS.__localCSS[sel][prop]) {\r
+                        CSS.__localCSS[sel][prop] = null;\r
+                        delete CSS.__localCSS[sel][prop];\r
+                    }\r
+                }\r
+            }\r
+            \r
+            CSS.__localSaveRequired = true;\r
+            CSS.__remoteSaveRequired = true;\r
+            CSS.preview(changedSelectors);\r
+        },\r
+        \r
+        __stripComments: function(str) {\r
+            return str.replace(/\/\*([\s\S])*?\*\//g, '');\r
+        }\r
+        \r
+    };\r
+    \r
+    \r
+    \r
+    \r
+    \r
+    \r
+    var FileHandler = {\r
+        \r
+        getFiles: function(path) {\r
+            if (!path) path = '';\r
+            var xmlhttp = new XMLHttpRequest();\r
+            xmlhttp.onreadystatechange = function() {\r
+                if (xmlhttp.readyState == 4) {\r
+                    UI.CSS.displayImagePicker(xmlhttp.responseXML);\r
+                    xmlhttp = null;\r
+                }\r
+            };\r
+            xmlhttp.open('GET', Config.REMOTE_URI  + '&path=' + escape(path) + '&nc=' + new Date().getTime(), true);\r
+            xmlhttp.send(null);\r
+            return true;\r
+        }\r
+    };\r
+    \r
+    \r
+    \r
+    \r
+    \r
+    var UI = {\r
+        boxes: [],\r
+        boxOffsetX: 35,\r
+        boxOffsetY: 30,\r
+        zIndex: 9999,\r
+\r
+        __dragTargetId: null,\r
+\r
+        statusMsg: function(msg, cls) {\r
+            UI.clearStatusMsg();\r
+            \r
+            var target = UI.__getBox();\r
+            if (!target) {\r
+                var box = Util.createElement('div', 'chameleon-status-msg');\r
+                box.appendChild(document.createTextNode(msg));\r
+                box.style.zIndex = ++UI.zIndex;\r
+                UI.addToDoc(box);\r
+            } else {\r
+         \r
+                var statusTable = Util.createElement('table', 'chameleon-status-msg');\r
+                var statusTableBody = Util.createElement('tbody');\r
+                var statusRow = Util.createElement('tr');\r
+                var statusIconCell = Util.createElement('td');\r
+                var statusMsgCell = Util.createElement('td');\r
+                var statusBtnCell = Util.createElement('td');\r
+                \r
+                if (cls) {\r
+                    statusIconCell.className = cls;\r
+                }\r
+                statusMsgCell.appendChild(document.createTextNode(msg));\r
+                statusBtnCell.appendChild(UI.createButton('chameleon-status-msg-btn', 'OK', 'Clear this message', UI.clearStatusMsg));\r
+                \r
+                statusRow.appendChild(statusIconCell);\r
+                statusRow.appendChild(statusMsgCell);\r
+                statusRow.appendChild(statusBtnCell);\r
+                statusTableBody.appendChild(statusRow);\r
+                statusTable.appendChild(statusTableBody);\r
+                \r
+                target.appendChild(statusTable);\r
+            }\r
+        },\r
+\r
+        clearStatusMsg: function() {\r
+            var obj = document.getElementById('chameleon-status-msg');\r
+            if (obj) {\r
+                Util.removeElement(obj);\r
+            }\r
+        },\r
+\r
+        addToDoc: function(content) {\r
+            document.getElementsByTagName('body')[0].appendChild(content);\r
+        },\r
+\r
+        makeDraggableBox: function(id, x, y) {\r
+            if ((x + 500) > screen.width) {\r
+                var offset = x + 525 - screen.width;\r
+                x -= offset;\r
+            }\r
+            \r
+            var box = Util.createElement('div', id);\r
+            box.style.left = x + 'px';\r
+            box.style.top = y + 'px';\r
+            box.style.zIndex = ++UI.zIndex;\r
+\r
+            var topBar = Util.createElement('div', id + '-handle');\r
+            var closeBtn = Util.createElement('div', id + '-close');\r
+            closeBtn.appendChild(document.createTextNode('x'));\r
+            closeBtn.setAttribute('title', 'Close');\r
+            topBar.setAttribute('title', 'Drag me!');\r
+            \r
+            UI.__dragTargetId = id + '-handle';\r
+\r
+            Util.addEvent(closeBtn, 'click', UI.closeBoxes);\r
+            Util.addEvent(topBar, 'mousedown', UI.__startDrag);\r
+            Util.addEvent(topBar, 'mousedown', UI.__bringToFront);\r
+            Util.addEvent(topBar, 'mouseup', UI.__stopDrag);\r
+\r
+            topBar.appendChild(closeBtn);\r
+            box.appendChild(topBar);\r
+   \r
+            UI.boxes.push(id);\r
+\r
+            return box;\r
+        },\r
+        \r
+        closeAllBoxes: function() {\r
+            var n = UI.boxes.length;\r
+            while (n--) {\r
+                Util.removeElement(document.getElementById(UI.boxes[n]));\r
+                UI.boxes.splice(n, 1);\r
+            }\r
+            UI.__dragTargetId = null;\r
+        },\r
+\r
+        closeBoxes: function(e, box) {\r
+            if (!box) {\r
+                var target = e.target || e.srcElement;\r
+                var box = target.parentNode.parentNode;\r
+            }\r
+            var n = UI.boxes.length;\r
+            while (n--) {\r
+                if (UI.boxes[n] == box.id) {\r
+                    break;\r
+                }\r
+                Util.removeElement(document.getElementById(UI.boxes[n]));\r
+                UI.boxes.splice(n, 1);\r
+            }\r
+            Util.removeElement(box);\r
+            UI.boxes.splice(n, 1);\r
+            UI.__dragTargetId = (UI.boxes.length) ? UI.boxes[UI.boxes.length - 1] + '-handle' : null;\r
+        },\r
+\r
+        __startDrag: function(e) {\r
+            var target = e.target || e.srcElement;\r
+            var mouseCoords = Pos.getMouse(e);\r
+            var elementCoords = Pos.getElement(target);\r
+            target.mouseX = mouseCoords.x - elementCoords.x;\r
+            target.mouseY = mouseCoords.y - elementCoords.y;    \r
+\r
+            UI.__dragTargetId = target.id;\r
+\r
+            Util.addEvent(document, 'mousemove', UI.__drag);\r
+        },\r
+\r
+        __stopDrag: function(e) {\r
+            Util.removeEvent(document, 'mousemove', UI.__drag);\r
+        },\r
+\r
+        __drag: function(e) {\r
+            var target = document.getElementById(UI.__dragTargetId);\r
+\r
+            var mouseCoords = Pos.getMouse(e);\r
+            target.parentNode.style.left = (mouseCoords.x - target.mouseX) + 'px';\r
+            target.parentNode.style.top = (mouseCoords.y - target.mouseY) + 'px';\r
+        },\r
+\r
+        __bringToFront: function(e) {\r
+            var target = e.target || e.srcElement;\r
+            target.parentNode.style.zIndex = ++UI.zIndex;\r
+        },\r
+        \r
+        __getBox: function() {\r
+            var obj = document.getElementById(UI.__dragTargetId);\r
+            if (obj && obj.parentNode) {\r
+                return obj.parentNode;\r
+            }\r
+            return false;\r
+        },\r
+        \r
+        \r
+        \r
+        \r
+        setupPane: function(tabs, parentId, tabId, active) {\r
+            for (var i = 0; i < tabs.length; ++i) {\r
+                var obj = document.getElementById(tabId + '-tab-' + tabs[i]);\r
+                if (obj) {\r
+                    obj.className = tabId + ((active == tabs[i]) ? '-tab-active' : '-tab');\r
+                }\r
+            }\r
+\r
+            var parent = document.getElementById(parentId);\r
+            if (parent && parent.firstChild) {\r
+                Util.removeElement(parent.firstChild);\r
+            }\r
+            return parent;\r
+        },\r
+        \r
+        setupButtons: function() {\r
+            var parentId = arguments[0];\r
+            var parent = document.getElementById(parentId);\r
+            if (!parent) return;\r
+\r
+            var btns = parent.getElementsByTagName('input');\r
+            for (var i = 0; i < btns.length; ++i) {\r
+                btns[i].style.display = 'none';\r
+            }\r
+\r
+            for (var i = 1; i < arguments.length; ++i) {\r
+                var id = parentId + '-' + arguments[i];\r
+                var btn = document.getElementById(id);\r
+                if (btn) {\r
+                    btn.style.display = 'inline';\r
+                }\r
+            }\r
+        },\r
+        \r
+        createButton: function(id, value, title, fn, hidden) {\r
+            var btn = Util.createElement('input', id);\r
+            btn.setAttribute('type', 'submit');\r
+            btn.setAttribute('value', value);\r
+            btn.setAttribute('title', title);\r
+            btn.className = 'chameleon-btn';\r
+            if (hidden) {\r
+                btn.style.display = 'none';\r
+            }\r
+\r
+            Util.addEvent(btn, 'click', fn);\r
+            return btn;\r
+        },\r
+\r
+        setOverflow: function(obj, height, forced) {\r
+            if (obj.offsetHeight > height || forced) {\r
+                obj.style.height = height + 'px';\r
+                obj.style.overflow = 'scroll';\r
+            }\r
+        }\r
+    };\r
+    \r
+    \r
+    UI.Selector = {\r
+        controlsId: 'chameleon-selector-controls',\r
+        sections: ['selector', 'overview', 'free-edit'],\r
+        \r
+        \r
+        editWindow: function(e) {\r
+            if (!e.shiftKey) {\r
+                return;\r
+            }\r
+\r
+            var target = e.target || e.srcElement;\r
+            var tmpStruct = climbTree(target);\r
+            if (typeof tmpStruct == 'string') {\r
+                return;\r
+            }\r
+            \r
+            hotspotMode = false;\r
+\r
+            var box = document.getElementById('chameleon-selector-box');\r
+            if (box) UI.closeBoxes(true, box);\r
+\r
+            struct = tmpStruct;\r
+            CSS.Selector.reset();\r
+\r
+            var coords = Pos.getMouse(e);\r
+            var box = UI.makeDraggableBox('chameleon-selector-box', coords.x, coords.y);\r
+\r
+\r
+            var instructions = Util.createElement('p');\r
+            instructions.appendChild(document.createTextNode('Create a CSS selector to edit, browse an overview of your edited styles or edit your complete stylesheet by hand.'));\r
+            instructions.className = 'chameleon-instructions';\r
+            box.appendChild(instructions);\r
+\r
+            var tabsContainer = Util.createElement('table', 'chameleon-selector-tabs');\r
+            var tabsBody = Util.createElement('tbody');\r
+            var tabs = Util.createElement('tr');\r
\r
+            tabs.appendChild(UI.Selector.__createTab('Selector', UI.Selector.__editSelector, true));\r
+            tabs.appendChild(UI.Selector.__createTab('Overview', UI.Selector.__displayOverview));\r
+            tabs.appendChild(UI.Selector.__createTab('Free Edit', UI.Selector.__editCode));\r
+\r
+            tabsBody.appendChild(tabs);\r
+            tabsContainer.appendChild(tabsBody);\r
+\r
+            box.appendChild(tabsContainer);\r
+\r
+            var styleControls = Util.createElement('div', UI.Selector.controlsId);\r
+            box.appendChild(styleControls);\r
+            box.appendChild(UI.Selector.__addButtons());\r
+\r
+            UI.addToDoc(box);\r
+\r
+            UI.Selector.__editSelector();\r
+            \r
+            if (e.preventDefault) {\r
+                e.preventDefault();\r
+            } else if (window.event) {\r
+                window.event.returnValue = false;\r
+            }\r
+        },\r
+        \r
+  \r
+        \r
+        \r
+        __editSelector: function() {\r
+            var parent = UI.setupPane(UI.Selector.sections, UI.Selector.controlsId, 'chameleon-selector', 'selector');\r
+            UI.setupButtons('chameleon-selector-buttons', 'edit', 'check');\r
+\r
+            var container = Util.createElement('div');\r
+\r
+            var instructions = Util.createElement('p');\r
+            instructions.appendChild(document.createTextNode('Choose the element you would like to style.'));\r
+            container.appendChild(instructions);\r
+            container.appendChild(UI.Selector.__elementList());\r
+\r
+            parent.appendChild(container);\r
+\r
+            UI.Selector.displaySelector(CSS.Selector.trimmed);\r
+        },\r
+        \r
+        __displayOverview: function(e, selectors, selector) {\r
+            var parent = UI.setupPane(UI.Selector.sections, UI.Selector.controlsId, 'chameleon-selector', 'overview');\r
+            UI.setupButtons('chameleon-selector-buttons');\r
+            \r
+            var container = Util.createElement('div', 'chameleon-style-overview-container');\r
+            parent.appendChild(container); // much faster to insert the container and apply the overflow before creating the table\r
+            UI.setOverflow(container, 350, true);\r
+            \r
+            var overviewTable = Util.createElement('table', 'chameleon-style-overview');\r
+            var overviewTableBody = Util.createElement('tbody');\r
+            \r
+            if (!selectors) {\r
+\r
+                for (var sel in CSS.__localCSS) {\r
+                    var overviewTableRow = Util.createElement('tr');\r
+                \r
+                    var overviewTableCell = Util.createElement('th');\r
+                    overviewTableCell.className = 'selector';\r
+                    overviewTableCell.appendChild(document.createTextNode(sel));\r
+                    overviewTableRow.appendChild(overviewTableCell);\r
+                    overviewTableCell = Util.createElement('td');\r
+\r
+                    var overviewEditLink = Util.createElement('a');\r
+                    overviewEditLink.value = sel;\r
+                    overviewEditLink.appendChild(document.createTextNode('[edit]'));\r
+                    Util.addEvent(overviewEditLink, 'click', UI.CSS.launchEditWindow);\r
+                    overviewTableCell.className = 'selector';\r
+                    overviewTableCell.appendChild(overviewEditLink);\r
+\r
+                    overviewTableRow.appendChild(overviewTableCell);\r
+                    overviewTableBody.appendChild(overviewTableRow);\r
+                    for (var prop in CSS.__localCSS[sel]) {\r
+                        overviewTableRow = Util.createElement('tr');\r
+                        overviewTableCell = Util.createElement('td');\r
+                        overviewTableCell.className = 'prop';\r
+                        overviewTableCell.appendChild(document.createTextNode(prop));\r
+                        overviewTableRow.appendChild(overviewTableCell);\r
+                        overviewTableCell = Util.createElement('td');\r
+                        overviewTableCell.className = 'value';\r
+                        overviewTableCell.appendChild(document.createTextNode(CSS.__localCSS[sel][prop]));\r
+                        overviewTableRow.appendChild(overviewTableCell);\r
+                        overviewTableBody.appendChild(overviewTableRow);\r
+                    }\r
+                }\r
+            } else {\r
+            \r
+                var n = selectors.length;\r
+                \r
+                if (!CSS.__localCSS[selector]) {\r
+                    var overviewTableRow = Util.createElement('tr');\r
+                \r
+                    var overviewTableCell = Util.createElement('th');\r
+                    overviewTableCell.className = 'current-selector';\r
+                    overviewTableCell.appendChild(document.createTextNode(selector));\r
+                    overviewTableRow.appendChild(overviewTableCell);\r
+                    overviewTableCell = Util.createElement('td');\r
+\r
+                    var overviewEditLink = Util.createElement('a');\r
+                    overviewEditLink.value = selector;\r
+                    overviewEditLink.appendChild(document.createTextNode('[edit]'));\r
+                    Util.addEvent(overviewEditLink, 'click', UI.CSS.launchEditWindow);\r
+                    overviewTableCell.className = 'current-selector';\r
+                    overviewTableCell.appendChild(overviewEditLink);\r
+\r
+                    overviewTableRow.appendChild(overviewTableCell);\r
+                    overviewTableBody.appendChild(overviewTableRow);\r
+                }\r
+                \r
+                for (var i = 0; i < n; ++i) {\r
+                    var sel = selectors[i];\r
+                    \r
+                    var overviewTableRow = Util.createElement('tr');\r
+                \r
+                    var overviewTableCell = Util.createElement('th');\r
+                    overviewTableCell.className = (sel == selector) ? 'current-selector' : 'selector';\r
+                    overviewTableCell.appendChild(document.createTextNode(sel));\r
+                    overviewTableRow.appendChild(overviewTableCell);\r
+                    overviewTableCell = Util.createElement('td');\r
+\r
+                    var overviewEditLink = Util.createElement('a');\r
+                    overviewEditLink.value = sel;\r
+                    overviewEditLink.appendChild(document.createTextNode('[edit]'));\r
+                    Util.addEvent(overviewEditLink, 'click', UI.CSS.launchEditWindow);\r
+                    overviewTableCell.className = (sel == selector) ? 'current-selector' : 'selector';\r
+                    overviewTableCell.appendChild(overviewEditLink);\r
+\r
+                    overviewTableRow.appendChild(overviewTableCell);\r
+                    overviewTableBody.appendChild(overviewTableRow);\r
+                    for (var prop in CSS.__localCSS[sel]) {\r
+                        overviewTableRow = Util.createElement('tr');\r
+                        overviewTableCell = Util.createElement('td');\r
+                        overviewTableCell.className = 'prop';\r
+                        overviewTableCell.appendChild(document.createTextNode(prop));\r
+                        overviewTableRow.appendChild(overviewTableCell);\r
+                        overviewTableCell = Util.createElement('td');\r
+                        overviewTableCell.className = 'value';\r
+                        overviewTableCell.appendChild(document.createTextNode(CSS.__localCSS[sel][prop]));\r
+                        overviewTableRow.appendChild(overviewTableCell);\r
+                        overviewTableBody.appendChild(overviewTableRow);\r
+                    }\r
+                }\r
+            \r
+            }\r
+\r
+            overviewTable.appendChild(overviewTableBody);            \r
+            container.appendChild(overviewTable);\r
+        },\r
+        \r
+        __elementList: function() {\r
+            var list = Util.createElement('ol');\r
+            var n = struct.length;\r
+            var classStr = '';\r
+            var idStr = '';\r
+\r
+            var pseudoClasses = ['active', 'visited', 'hover', 'focus'];\r
+\r
+            while (n--) {\r
+                var item = Util.createElement('li');\r
+                var tag = Util.createElement('span', 'chameleon-tag-name-' + n);\r
+                tag.appendChild(document.createTextNode(struct[n].tagname));\r
+                tag.selectorValue = struct[n].tagname;\r
+                tag.position = n;\r
+               \r
+                UI.Selector.__autoHighlight(tag);\r
+\r
+                Util.addEvent(tag, 'click', CSS.Selector.modify);\r
+\r
+                item.appendChild(tag);\r
+\r
+                if (idStr = struct[n].id) {\r
+                    var id = Util.createElement('span', 'chameleon-id-attr-' + n);\r
+                    id.selectorValue = struct[n].tagname + '#' + idStr; \r
+                    id.position = n;      \r
+                    id.appendChild(document.createTextNode('#' + idStr));\r
+\r
+                    UI.Selector.__autoHighlight(id);\r
+\r
+                    Util.addEvent(id, 'click', CSS.Selector.modify);\r
+                    item.appendChild(id);\r
+                }\r
+\r
+                if (struct[n].classname) {\r
+                    var classArr = struct[n].classname.split(' ');\r
+                    for (var i = 0; i < classArr.length; ++i) {\r
+                        var cn = Util.createElement('span', 'chameleon-class-attr-' + n + '-' + i);\r
+                        cn.selectorValue = struct[n].tagname + '.' + classArr[i];\r
+                        cn.position = n;      \r
+                        cn.appendChild(document.createTextNode('.' + classArr[i]));\r
+\r
+                        UI.Selector.__autoHighlight(cn);\r
+\r
+                        Util.addEvent(cn, 'click', CSS.Selector.modify);\r
+                        item.appendChild(cn);\r
+                    }\r
+                }\r
+                if (struct[n].tagname == 'a') {\r
+                    for (var i = 0; i < pseudoClasses.length; ++i) {\r
+                        var pc = Util.createElement('span', 'chameleon-pseudo-class' + n + '-' + i);\r
+                        pc.selectorValue = struct[n].tagname + ':' + pseudoClasses[i];\r
+\r
+                        pc.position = n;      \r
+                        pc.appendChild(document.createTextNode(':' + pseudoClasses[i]));\r
+\r
+                        UI.Selector.__autoHighlight(pc);\r
+\r
+                        Util.addEvent(pc, 'click', CSS.Selector.modify);\r
+                        item.appendChild(pc);\r
+                    }\r
+                }\r
+                list.appendChild(item);\r
+            }\r
+            \r
+            return list;\r
+        },\r
+        \r
+        \r
+        __editCode: function() {\r
+            var parent = UI.setupPane(UI.Selector.sections, UI.Selector.controlsId, 'chameleon-selector', 'free-edit');\r
+            UI.setupButtons('chameleon-selector-buttons', 'revert', 'save-local', 'save-server');\r
+\r
+            var container = Util.createElement('div');\r
+            var textarea = Util.createElement('textarea', 'chameleon-free-edit-all-field');\r
+            textarea.value = CSS.toString();\r
+            textarea.style.width = '100%';\r
+            textarea.style.height = '350px';\r
+            Util.addEvent(textarea, 'blur', CSS.FreeEdit.saveComplete);\r
+\r
+            container.appendChild(textarea);\r
+\r
+            parent.appendChild(container);\r
+\r
+        },\r
+        \r
+        \r
+        \r
+        \r
+        __selectorList: function() {\r
+            return Util.createElement('ol', 'chameleon-selector-list');\r
+        },\r
+        \r
+        \r
+        \r
+        \r
+        __createTab: function(str, fn, active) {\r
+            var id = 'chameleon-selector-tab-' + str.replace(/ +/, '-').toLowerCase();\r
+            var tab = Util.createElement('td', id);\r
+            tab.appendChild(document.createTextNode(str));\r
+            tab.className = (active) ? 'chameleon-selector-tab-active' : 'chameleon-selector-tab';\r
+            Util.addEvent(tab, 'click', fn);\r
+            return tab;\r
+        },\r
+\r
+        __addButtons: function() {\r
+            var p = Util.createElement('p', 'chameleon-selector-buttons');\r
+            p.style.textAlign = 'right';\r
+\r
+            p.appendChild(UI.createButton('chameleon-selector-buttons-check', 'Compare', 'Check for other similar selectors already in your styles', CSS.checkSpec));\r
+            p.appendChild(UI.createButton('chameleon-selector-buttons-revert', 'Revert', 'Revert to the version currently on the server', CSS.hardReset));\r
+            p.appendChild(UI.createButton('chameleon-selector-buttons-save-local', 'Save Temp', 'Save these changes to a temporary file on the server', CSS.updateTemp));\r
+            p.appendChild(UI.createButton('chameleon-selector-buttons-save-server', 'Save Server', 'Save these changes to the server', CSS.updateRemote))\r
+            p.appendChild(UI.createButton('chameleon-selector-buttons-edit', 'Set Styles', 'Create and edit styles for this CSS selector', UI.CSS.editWindow));\r
+\r
+            return p;\r
+        },\r
+        \r
+        \r
+        \r
+        \r
+        __autoHighlight: function(el) {\r
+            if (CSS.Selector.full[el.position] && CSS.Selector.full[el.position].val == el.selectorValue) {\r
+                UI.Selector.highlight(el);\r
+            } else {\r
+                UI.Selector.unhighlight(el);\r
+            }\r
+        },\r
+        \r
+        highlight: function(el) {\r
+            UI.Selector.unhighlight(el);\r
+            el.className += 'active-selector';\r
+        },\r
+\r
+        unhighlight: function(el) {\r
+            el.className = el.className.replace(/\bactive-selector\b/, '');\r
+        },\r
+        \r
+        \r
+        \r
+        \r
+        displaySelector: function(selector) {\r
+            var n = selector.length;\r
+\r
+            var list = document.getElementById('chameleon-selector-list');\r
+            if (!list && n != 0) {\r
+                var parent = document.getElementById(UI.Selector.controlsId).firstChild;\r
+                list = UI.Selector.__selectorList();\r
+                parent.appendChild(list);\r
+            } else if (list && n == 0) {\r
+                Util.removeElement(list);\r
+            } else if (list) {\r
+                while (list.hasChildNodes()) {\r
+                    Util.removeElement(list.firstChild);\r
+                }\r
+            }\r
+\r
+            if (n == 0) return;\r
+\r
+            var item = Util.createElement('li');\r
+            item.appendChild(document.createTextNode('Style ' + UI.Selector.__describe(selector[--n])));\r
+            list.appendChild(item);\r
+            while (n--) {\r
+                item = Util.createElement('li');\r
+                item.appendChild(document.createTextNode('That are descended from ' + UI.Selector.__describe(selector[n])));\r
+                list.appendChild(item);\r
+            }\r
+        },\r
+\r
+        __describe: function(txt) {\r
+            if (!txt) return '';\r
+            \r
+            if (txt.indexOf(':') != -1) {\r
+                var parts = txt.split(':');\r
+                var pc = ' the "' + parts.pop() + '" state of ';\r
+                txt = parts.shift();\r
+            } else {\r
+                var pc = '';\r
+            }\r
+\r
+            if (txt.indexOf('#') != -1) {\r
+                var parts = txt.split('#');\r
+                return pc + parts[0] + ' tags with the id "' + parts[1] + '"';\r
+            }\r
+            if (txt.indexOf('.') != -1) {\r
+                var parts = txt.split('.');\r
+                return pc + parts[0] + ' tags with the class "' + parts[1] + '"';\r
+            }\r
+            return pc + txt + ' tags';\r
+        }\r
+    };\r
+    \r
+    \r
+    \r
+    UI.CSS = {\r
+        redraw: null,\r
+        colorType: null,\r
+        controlsId: 'chameleon-style-controls',\r
+        sections: ['text', 'backgrounds', 'borders-all', 'borders-separate', 'free-edit'],\r
+        \r
+        __borderEditGroup: true,\r
+        \r
+        editWindow: function(e) {\r
+            if (CSS.Selector.get() == '') {\r
+                UI.statusMsg('First you have to choose which item to style!', 'chameleon-notice');\r
+                return;\r
+            }\r
+            \r
+            var box = document.getElementById('chameleon-style-box');\r
+            if (box) UI.closeBoxes(true, box);\r
+\r
+            var coords = Pos.getElement(document.getElementById('chameleon-selector-box'));\r
+            var box = UI.makeDraggableBox('chameleon-style-box', coords.x + UI.boxOffsetX, coords.y + UI.boxOffsetY);\r
+\r
+            var instructions = Util.createElement('p');\r
+            if (!hotspotMode) {\r
+                instructions.appendChild(document.createTextNode('Add/Edit styles for the CSS selector "' + CSS.Selector.get() + '"'));\r
+                //UI.CSS.sections = ['text', 'backgrounds', 'borders-all', 'borders-separate', 'free-edit'];\r
+            } else {\r
+                instructions.appendChild(document.createTextNode('Add/Edit styles for ' + UI.HotSpots.getString()));\r
+                //UI.CSS.sections = ['text', 'backgrounds', 'borders-all', 'borders-separate'];\r
+            }\r
+            instructions.className = 'chameleon-instructions';\r
+            box.appendChild(instructions);\r
+\r
+            var tabsContainer = Util.createElement('table', 'chameleon-style-tabs');\r
+            var tabsBody = Util.createElement('tbody');\r
+            var tabs = Util.createElement('tr');\r
\r
+            tabs.appendChild(UI.CSS.__createTab('Text', UI.CSS.__editText, true));\r
+            tabs.appendChild(UI.CSS.__createTab('Backgrounds', UI.CSS.__editBackgrounds));\r
+            tabs.appendChild(UI.CSS.__createTab('Borders (All)', UI.CSS.__editBordersAll));\r
+            tabs.appendChild(UI.CSS.__createTab('Borders (Separate)', UI.CSS.__editBordersSeparate));\r
+            //if (!hotspotMode) {\r
+                tabs.appendChild(UI.CSS.__createTab('Free Edit', UI.CSS.__editCode));\r
+            //}\r
+\r
+            tabsBody.appendChild(tabs);\r
+            tabsContainer.appendChild(tabsBody);\r
+\r
+            box.appendChild(tabsContainer);\r
+\r
+            var styleControls = Util.createElement('div', UI.CSS.controlsId);\r
+            box.appendChild(styleControls);\r
+            box.appendChild(UI.CSS.__addButtons());\r
+\r
+            UI.addToDoc(box);\r
+            \r
+            UI.CSS.__editText();\r
+        },\r
+        \r
+        \r
+        \r
+        launchEditWindow: function(e) {\r
+            var target = e.target || e.srcElement;\r
+            CSS.Selector.set(target.value);\r
+            UI.CSS.editWindow(e);\r
+        },\r
+        \r
+        \r
+        __editText: function(e, redraw) {\r
+            UI.CSS.redraw = arguments.callee;\r
+            UI.CSS.colorType = 'color';\r
+\r
+            var containerTable = document.getElementById('chameleon-style-edit-text-container');\r
+            if (!containerTable) {\r
+                var parent = UI.setupPane(UI.CSS.sections, UI.CSS.controlsId, 'chameleon-style', 'text');\r
+                containerTable = Util.createElement('table', 'chameleon-style-edit-text-container');\r
+                var container = Util.createElement('tbody');\r
+\r
+                var row = UI.CSS.__inputField('color', '-input-color', Check.color);\r
+                container.appendChild(row.node);\r
+\r
+                row = UI.CSS.__selectBox('font-family', '-select-font-family', Check.fontFamily, Config.FONTS_LIST);\r
+                container.appendChild(row.node);        \r
+\r
+                row = UI.CSS.__inputField('font-family', '-input-font-family', Check.fontFamily, !row.meta.sel);\r
+                container.appendChild(row.node);\r
+\r
+                row = UI.CSS.__inputField('font-size', '-input-font-size', Check.fontSize);\r
+                container.appendChild(row.node);\r
+\r
+                row = UI.CSS.__inputField('line-height', '-input-line-height', Check.lineHeight);\r
+                container.appendChild(row.node);\r
+\r
+                row = UI.CSS.__selectBox('font-weight', '-select-font-weight', Check.fontWeight, Config.FONT_WEIGHTS);\r
+                container.appendChild(row.node);\r
+\r
+                row = UI.CSS.__selectBox('font-style', '-select-font-style', Check.fontStyle, Config.FONT_STYLES);\r
+                container.appendChild(row.node);\r
+                \r
+                row = UI.CSS.__selectBox('text-align', '-select-text-align', Check.textAlign, Config.TEXT_ALIGN);\r
+                container.appendChild(row.node);\r
+\r
+                row = UI.CSS.__selectBox('text-decoration', '-select-text-decoration', Check.textDecoration, Config.TEXT_DECORATION);\r
+                container.appendChild(row.node);\r
+\r
+                containerTable.appendChild(container);\r
+                parent.appendChild(containerTable);\r
+            } else {\r
+                if (redraw == 'color') {\r
+                    UI.CSS.__setColorDisplay(UI.CSS.colorType, UI.CSS.__getPropValue(UI.CSS.colorType));\r
+                }\r
+            }\r
+        },\r
+        \r
+        __editBackgrounds: function(e, redraw) {\r
+            UI.CSS.redraw = arguments.callee;\r
+            UI.CSS.colorType = 'background-color';\r
+\r
+            var containerTable = document.getElementById('chameleon-style-edit-backgrounds-container');\r
+            if (!containerTable) {\r
+                var parent = UI.setupPane(UI.CSS.sections, UI.CSS.controlsId, 'chameleon-style', 'backgrounds');\r
+                containerTable = Util.createElement('table', 'chameleon-style-edit-backgrounds-container');\r
+                var container = Util.createElement('tbody');\r
+\r
+                var row = UI.CSS.__inputField('background-color', '-input-background-color', Check.color);\r
+                container.appendChild(row.node);\r
+\r
+                row = UI.CSS.__inputField('background-image', '-input-background-image', Check.backgroundImage);\r
+                container.appendChild(row.node);\r
+\r
+                var extraFields = row.meta;\r
+                \r
+                row = UI.CSS.__selectBox('background-repeat', '-select-background-repeat', Check.backgroundRepeat, Config.REPEAT_LIST, !extraFields);\r
+                container.appendChild(row.node);\r
+\r
+                row = UI.CSS.__selectBox('background-position', '-select-background-position', Check.backgroundPosition, Config.POSITION_LIST, !extraFields);\r
+                container.appendChild(row.node);   \r
+\r
+                containerTable.appendChild(container);\r
+                parent.appendChild(containerTable);\r
+            } else {\r
+                if (redraw == 'color') {\r
+                    UI.CSS.__setColorDisplay(UI.CSS.colorType, UI.CSS.__getPropValue(UI.CSS.colorType));\r
+                } else if (redraw == 'image') {\r
+                    var val = UI.CSS.__getPropValue('background-image');\r
+                    UI.CSS.__setImageDisplay(val);\r
+                    if (val == 'none' || val == '') {\r
+                        document.getElementById(UI.CSS.controlsId + '-row-select-background-repeat').style.display = 'none';\r
+                        document.getElementById(UI.CSS.controlsId + '-row-select-background-position').style.display = 'none';\r
+                    } else {\r
+                        try {\r
+                            document.getElementById(UI.CSS.controlsId + '-row-select-background-repeat').style.display = 'table-row';\r
+                            document.getElementById(UI.CSS.controlsId + '-row-select-background-position').style.display = 'table-row';\r
+                        } catch(e) {\r
+                            document.getElementById(UI.CSS.controlsId + '-row-select-background-repeat').style.display = 'block';\r
+                            document.getElementById(UI.CSS.controlsId + '-row-select-background-position').style.display = 'block';\r
+                        }\r
+                    }\r
+                }\r
+            }\r
+            var imgPreview = document.getElementById('chameleon-image-preview');\r
+            if (imgPreview) {\r
+                imgPreview.setAttribute('width', '20');\r
+                imgPreview.setAttribute('height', '20');\r
+            }\r
+        },\r
+        \r
+        __editBordersAll: function(e, redraw) {\r
+            UI.CSS.redraw = arguments.callee;\r
+            UI.CSS.colorType = 'border-color';\r
+                        \r
+            var containerTable = document.getElementById('chameleon-style-edit-borders-all-container');\r
+            if (!containerTable) {\r
+               \r
+                var parent = UI.setupPane(UI.CSS.sections, UI.CSS.controlsId, 'chameleon-style', 'borders-all');\r
+                containerTable = Util.createElement('table', 'chameleon-style-edit-borders-all-container');\r
+                var container = Util.createElement('tbody');\r
+\r
+                var row = UI.CSS.__inputField('border-width', '-input-border-width', Check.borderWidth);\r
+                container.appendChild(row.node);\r
+  \r
+                row = UI.CSS.__inputField('border-color', '-input-border-color', Check.color);\r
+                container.appendChild(row.node);\r
+             \r
+                row = UI.CSS.__selectBox('border-style', '-select-border-style', Check.borderStyle, Config.BORDER_LIST);\r
+                container.appendChild(row.node);\r
+\r
+                containerTable.appendChild(container);\r
+                parent.appendChild(containerTable);\r
+            } else {\r
+                if (redraw == 'color') {\r
+                    UI.CSS.__setColorDisplay(UI.CSS.colorType, UI.CSS.__getPropValue(UI.CSS.colorType));\r
+                }\r
+            }\r
+        },\r
+        \r
+        __editBordersSeparate: function(e, redraw) {\r
+            UI.CSS.redraw = arguments.callee;\r
+            \r
+            var containerTable = document.getElementById('chameleon-style-edit-borders-separate-container');\r
+            if (!containerTable) {\r
+                var parent = UI.setupPane(UI.CSS.sections, UI.CSS.controlsId, 'chameleon-style', 'borders-separate');\r
+                containerTable = Util.createElement('table', 'chameleon-style-edit-borders-separate-container');\r
+                var container = Util.createElement('tbody');\r
+\r
+                var row = UI.CSS.__inputField('border-top-width', '-input-border-top-width', Check.borderWidth);\r
+                container.appendChild(row.node);\r
+  \r
+                row = UI.CSS.__inputField('border-top-color', '-input-border-top-color', Check.color, false, UI.CSS.__setColorType);\r
+                container.appendChild(row.node);\r
+             \r
+                row = UI.CSS.__selectBox('border-top-style', '-select-border-top-style', Check.borderStyle, Config.BORDER_LIST);\r
+                container.appendChild(row.node); \r
+\r
+\r
+                row = UI.CSS.__inputField('border-right-width', '-input-border-right-width', Check.borderWidth);\r
+                container.appendChild(row.node);\r
\r
+                row = UI.CSS.__inputField('border-right-color', '-input-border-right-color', Check.color, false, UI.CSS.__setColorType);\r
+                container.appendChild(row.node);\r
+\r
+                row = UI.CSS.__selectBox('border-right-style', '-select-border-right-style', Check.borderStyle, Config.BORDER_LIST);\r
+                container.appendChild(row.node);  \r
+\r
\r
+                row = UI.CSS.__inputField('border-bottom-width', '-input-border-bottom-width', Check.borderWidth);\r
+                container.appendChild(row.node);\r
+\r
+                row = UI.CSS.__inputField('border-bottom-color', '-input-border-bottom-color', Check.color, false, UI.CSS.__setColorType);\r
+                container.appendChild(row.node);\r
+\r
+                row = UI.CSS.__selectBox('border-bottom-style', '-select-border-bottom-style', Check.borderStyle, Config.BORDER_LIST);\r
+                container.appendChild(row.node);   \r
+\r
\r
+                row = UI.CSS.__inputField('border-left-width', '-input-border-left-width', Check.borderWidth);\r
+                container.appendChild(row.node);\r
+\r
+                row = UI.CSS.__inputField('border-left-color', '-input-border-left-color', Check.color, false, UI.CSS.__setColorType);\r
+                container.appendChild(row.node);\r
+\r
+                row = UI.CSS.__selectBox('border-left-style', '-select-border-left-style', Check.borderStyle, Config.BORDER_LIST);\r
+                container.appendChild(row.node);\r
+                \r
+                containerTable.appendChild(container);\r
+                parent.appendChild(containerTable);\r
+            } else {\r
+                if (redraw == 'color') {\r
+                    UI.CSS.__setColorDisplay(UI.CSS.colorType, UI.CSS.__getPropValue(UI.CSS.colorType));\r
+                }\r
+            }\r
+        },\r
+        \r
+        __editCode: function(e) {\r
+            UI.CSS.redraw = arguments.callee;\r
+\r
+            var parent = UI.setupPane(UI.CSS.sections, UI.CSS.controlsId, 'chameleon-style', 'free-edit');\r
+\r
+            var container = Util.createElement('div');\r
+            var textarea = Util.createElement('textarea', 'chameleon-free-edit-field');\r
+            textarea.value = CSS.getSelectorCSS();\r
+            textarea.style.width = '100%';\r
+            textarea.style.height = '350px';\r
+\r
+            Util.addEvent(textarea, 'focus', CSS.FreeEdit.setInitial);\r
+            Util.addEvent(textarea, 'blur', CSS.FreeEdit.saveSelector);\r
+\r
+            container.appendChild(textarea);\r
+            parent.appendChild(container);  \r
+        },\r
+        \r
+        \r
+        \r
+        \r
+        \r
+        \r
+        \r
+        __getPropValue: function(prop) {\r
+            var val = UI.CSS.__getBorderPropValue(prop);\r
+            if (val === '') {\r
+                return false;\r
+            }\r
+            \r
+            if (val === false) {\r
+                val = CSS.getPropValue(prop);\r
+            }\r
+            return val;\r
+        },\r
+        \r
+        \r
+        __setColorDisplay: function(prop, value, field, picker) {\r
+            if (!field) var field = document.getElementById(UI.CSS.controlsId + '-input-' + prop);\r
+            if (!picker) var picker = document.getElementById(UI.CSS.controlsId + '-color-picker-' + prop);\r
+            \r
+            if (!field || !picker) return;\r
+            \r
+            field.value = value;\r
+            try {\r
+                picker.style.backgroundColor = (value != '') ? value.replace(/[ ]*\!important/, '') : '#000';\r
+                if (!picker.style.backgroundColor) {\r
+                    UI.statusMsg(value + ' is an Invalid color!', 'chameleon-error');\r
+                }\r
+            } catch(e) {\r
+                UI.statusMsg(value + ' is an Invalid color!', 'chameleon-error');\r
+            }\r
+        },\r
+        \r
+        __setImageDisplay: function(value, field, picker) {\r
+            if (!field) var field = document.getElementById(UI.CSS.controlsId + '-input-background-image');\r
+            if (!picker) var picker = document.getElementById(UI.CSS.controlsId + '-background-image-picker');\r
+            \r
+            var preview = document.getElementById('chameleon-image-preview');\r
+            \r
+            if (!field || !picker) return;\r
+            \r
+            field.value = value;\r
+            if (value != '') {\r
+                if (!preview) {\r
+                    preview = Util.createElement('img', 'chameleon-image-preview');\r
+                    picker.appendChild(preview);\r
+                }\r
+                \r
+                if (field.value != 'none') {\r
+                    preview.setAttribute('src', CSS.fixPath(value.replace(/[ ]*\!important/, '')));\r
+                } else {\r
+                    preview.setAttribute('src', CSS.fixPath('ui/images/none.gif'));\r
+                }\r
+                preview.setAttribute('title', 'Open image picker');\r
+                Util.addEvent(preview, 'click', UI.CSS.__loadImagePicker);\r
+\r
+                picker.style.backgroundColor = 'transparent';\r
+            } else {\r
+                if (preview) {\r
+                    Util.removeElement(preview);\r
+                }\r
+                picker.style.backgroundColor = '#000';\r
+                picker.setAttribute('title', 'Open image picker');\r
+                Util.addEvent(picker, 'click', UI.CSS.__loadImagePicker);\r
+            }\r
+            \r
+            \r
+        },\r
+        \r
+        __shorthandWarningIcon: function() {\r
+             var img = Util.createElement('img');\r
+             img.setAttribute('src', CSS.fixPath('ui/images/notice.gif'));\r
+             img.style.margin = '0 2px -5px 0';\r
+             img.setAttribute('title', 'You currently have set values of this property for one or more individual sides. Updating the value here will set the property for all sides, overwriting the individual values.');  \r
+             return img;\r
+        },\r
+        \r
+        __inputField: function(prop, id, validate, hidden, init) {\r
+            var row = Util.createElement('tr', UI.CSS.controlsId + '-row' + id);\r
+            id = UI.CSS.controlsId + id;\r
+            \r
+            var labelCell = Util.createElement('td');\r
+            var fieldCell = Util.createElement('td');\r
+\r
+            var field = Util.createElement('input', id);\r
+            field.setAttribute('type', 'text');\r
+            field.className = 'chameleon-input-text';\r
+            \r
+            \r
+            var val = UI.CSS.__getPropValue(prop);\r
+            if (val !== false) {\r
+                field.value = val;\r
+            } else {\r
+                //field.className = 'longhand-warning';\r
+                labelCell.appendChild(UI.CSS.__shorthandWarningIcon());\r
+            }\r
+            \r
+            Util.addEvent(field, 'blur', validate);\r
+            if (init) {\r
+                Util.addEvent(field, 'focus', init);\r
+            }\r
+            \r
+            labelCell.appendChild(document.createTextNode(UI.CSS.__formatProp(prop) + ': '));\r
+            labelCell.className = 'label';\r
+\r
+            fieldCell.appendChild(field);\r
+             \r
+            row.appendChild(labelCell);\r
+            row.appendChild(fieldCell);\r
+            \r
+            if (prop == 'color' || prop.indexOf('-color') != -1) {\r
+                var colorCell = Util.createElement('td');\r
+                var colorPicker = Util.createElement('div', UI.CSS.controlsId + '-color-picker-' + prop);\r
+\r
+                colorPicker.setAttribute('title', 'Open color picker');\r
+                UI.CSS.__setColorDisplay(prop, field.value, field, colorPicker);\r
+                \r
+                Util.addEvent(colorPicker, 'click', UI.CSS.__displayColorPicker);\r
+                if (init) {\r
+                    Util.addEvent(colorPicker, 'click', init);\r
+                }\r
+\r
+                colorCell.appendChild(colorPicker);\r
+                row.appendChild(colorCell);\r
+            } else if (prop.indexOf('-image') != -1) {\r
+                var imgCell = Util.createElement('td');\r
+                var imgPicker = Util.createElement('div', UI.CSS.controlsId + '-background-image-picker');\r
+                \r
+                UI.CSS.__setImageDisplay(field.value, field, imgPicker);\r
+\r
+                imgCell.appendChild(imgPicker);\r
+                row.appendChild(imgCell);\r
+                \r
+            } else {\r
+                fieldCell.setAttribute('colspan', '2');\r
+            }\r
+            if (hidden) {\r
+                row.style.display = 'none';\r
+            }\r
+            return {node: row, meta: (field.value == 'none') ? false : field.value};\r
+        },\r
+        \r
+        \r
+        __selectBox: function(prop, id, validate, src, hidden) {\r
+            var row = Util.createElement('tr', UI.CSS.controlsId + '-row' + id);\r
+            id = UI.CSS.controlsId + id;\r
+\r
+            var labelCell = Util.createElement('td');\r
+            var fieldCell = Util.createElement('td');\r
+            fieldCell.setAttribute('colspan', '2');\r
+            \r
+            var currentValue = UI.CSS.__getPropValue(prop);\r
+            if (currentValue === false) {\r
+                labelCell.appendChild(UI.CSS.__shorthandWarningIcon());\r
+                currentValue = '';\r
+            }\r
+\r
+            labelCell.appendChild(document.createTextNode(UI.CSS.__formatProp(prop) + ': '));\r
+            labelCell.className = 'label';\r
+\r
+            var field = Util.createElement('select', id);\r
+            var op = Util.createElement('option');\r
+            op.setAttribute('value', '');\r
+            op.appendChild(document.createTextNode('Please select'));\r
+            field.appendChild(op);\r
+\r
+            var selected = false;\r
+            var otherSelected = false;\r
+        \r
+            for (var i = 0; i < src.length; ++i) {\r
+                op = Util.createElement('option');\r
+                op.setAttribute('value', src[i]);\r
+                op.appendChild(document.createTextNode(src[i]));\r
+                if (src[i] != 'other' && src[i] == currentValue) {\r
+                    op.setAttribute('selected', 'selected');\r
+                    selected = true;\r
+                } else if (src[i].toLowerCase() == 'other' && currentValue != '' && !selected) {\r
+                    op.setAttribute('selected', 'selected');\r
+                    selected = true;\r
+                    otherSelected = true;\r
+                }\r
+                field.appendChild(op);\r
+            }\r
+\r
+            Util.addEvent(field, 'change', validate);\r
+\r
+            fieldCell.appendChild(field);\r
+            row.appendChild(labelCell);\r
+            row.appendChild(fieldCell);\r
+\r
+            if (hidden) {\r
+                row.style.display = 'none';\r
+            }\r
+\r
+            return {node: row, meta: {sel: otherSelected, value: currentValue}};\r
+        },\r
+        \r
+        \r
+        \r
+        __createTab: function(str, fn, active) {\r
+            var id = 'chameleon-style-tab-' + str.replace(/[\( ]+/, '-').replace(/[\)]+/, '').toLowerCase();\r
+            var tab = Util.createElement('td', id);\r
+            tab.appendChild(document.createTextNode(str));\r
+            tab.className = (active) ? 'chameleon-style-tab-active' : 'chameleon-style-tab';\r
+            Util.addEvent(tab, 'click', fn);\r
+            return tab;\r
+        },\r
+        \r
+        __addButtons: function() {\r
+            var p = Util.createElement('p', 'chameleon-style-buttons');\r
+            p.style.textAlign = 'right';\r
+\r
+            p.appendChild(UI.createButton('chameleon-style-buttons-revert', 'Revert', 'Discard all temporarily saved changes', CSS.hardReset));\r
+            p.appendChild(UI.createButton('chameleon-style-buttons-save-local', 'Save Temp', 'Save these changes in a temporary file on the server', CSS.updateTemp));\r
+            p.appendChild(UI.createButton('chameleon-style-buttons-save-server', 'Save Server', 'Save these changes to the server', CSS.updateRemote));\r
+\r
+            return p;\r
+        },\r
+        \r
+        __formatProp: function(txt) {\r
+            if (txt.length > 15 && txt.indexOf('-') != -1) {\r
+                return txt.split('-').slice(1).join('-');\r
+            }\r
+            return txt;\r
+        },\r
+\r
+\r
+\r
+\r
+        __loadImagePicker: function(e) {\r
+            var target = e.target || e.srcElement;\r
+        \r
+            if (target.value) {\r
+                UI.statusMsg('Loading file list for ' + target.value + '...', 'chameleon-working');\r
+                FileHandler.getFiles(target.value);\r
+            } else {\r
+                UI.statusMsg('Loading file list...', 'chameleon-working');\r
+                FileHandler.getFiles('root');\r
+            }\r
+        },\r
+        \r
+        displayImagePicker: function(xmldata) {\r
+            UI.clearStatusMsg();\r
+\r
+            var box = document.getElementById('chameleon-file-box');\r
+            if (box) UI.closeBoxes(true, box);\r
+\r
+            var coords = Pos.getElement(document.getElementById('chameleon-style-box'));\r
+            box = UI.makeDraggableBox('chameleon-file-box', coords.x + UI.boxOffsetX, coords.y + UI.boxOffsetY);\r
+            \r
+            if (xmldata.firstChild.nodeName.toLowerCase() == 'chameleon_error') {\r
+                UI.statusMsg('There was an error reading files from the server:\n' + xmldata.firstChild.firstChild.nodeValue + '.', 'chameleon-error');\r
+                return;\r
+            }\r
+            \r
+            var files = xmldata.firstChild;\r
+            var hasFiles = false;\r
+        \r
+            var infoTable = Util.createElement('table');\r
+            var infoTableBody = Util.createElement('tbody');\r
+            var infoTableRow = Util.createElement('tr');\r
+\r
+            var path = files.getAttribute('path');\r
+            if (path.indexOf('/') != -1) {\r
+                var parentPath = path.substring(0, path.lastIndexOf('/'));\r
+                var parentCell = Util.createElement('td');\r
+                var parentLink = Util.createElement('p', 'chameleon-files-parent');\r
+                parentLink.value = parentPath;\r
+                parentLink.className = 'chameleon-image-folder';\r
+                parentLink.appendChild(document.createTextNode('Parent folder'));\r
+                Util.addEvent(parentLink, 'click', UI.CSS.__loadImagePicker);\r
+                parentCell.appendChild(parentLink);\r
+                infoTableRow.appendChild(parentCell);\r
+            } \r
+\r
+            var location = Util.createElement('td', 'chameleon-files-location');\r
+            var locationPara = Util.createElement('p');\r
+            var locationTxt = Util.createElement('span');\r
+            locationTxt.appendChild(document.createTextNode('Location: '));\r
+            locationPara.appendChild(locationTxt);\r
+            locationPara.appendChild(document.createTextNode(path));\r
+            location.appendChild(locationPara);\r
+\r
+            infoTableRow.appendChild(location);\r
+            infoTableBody.appendChild(infoTableRow);\r
+            infoTable.appendChild(infoTableBody);\r
+            box.appendChild(infoTable);\r
+        \r
+            var fileList = Util.createElement('div');\r
+\r
+            for (var i = 0; i < files.childNodes.length; ++i) {\r
+                if (files.childNodes[i].nodeType != Node.ELEMENT_NODE) {\r
+                    continue;\r
+                }\r
+                hasFiles = true;\r
+\r
+                var fileItemContainer = Util.createElement('p');\r
+                var fileItem = Util.createElement('span');\r
+                fileItem.value = files.childNodes[i].firstChild.nodeValue;\r
+                fileItem.appendChild(document.createTextNode(fileItem.value.split('/').pop()));\r
+                if (files.childNodes[i].getAttribute('type') == 'img') {\r
+                    Util.addEvent(fileItem, 'click', Check.backgroundImage);\r
+                } else {\r
+                    fileItemContainer.className = 'chameleon-image-folder';\r
+                    Util.addEvent(fileItem, 'click', UI.CSS.__loadImagePicker);\r
+                }\r
+                fileItemContainer.appendChild(fileItem);\r
+                fileList.appendChild(fileItemContainer);\r
+            }\r
+\r
+            if (!hasFiles) {\r
+                var fileItem = Util.createElement('p');\r
+                fileItem.appendChild(document.createTextNode('No images were found in this folder'));\r
+                fileList.appendChild(fileItem);\r
+            }\r
+\r
+            box.appendChild(fileList);\r
+            UI.addToDoc(box);\r
+\r
+            UI.setOverflow(fileList, 350);\r
+        },\r
+        \r
+        \r
+   \r
+   \r
+        __displayColorPicker: function(e) {\r
+            var box = document.getElementById('chameleon-color-box');\r
+            if (box) UI.closeBoxes(true, box);\r
+            \r
+            var extraColors = ['000000', '333333', '666666', '999999', 'cccccc', 'ffffff', 'ff0000', '00ff00', '0000ff', 'ffff00', 'ff00ff', '00ffff'];\r
+\r
+            var coords = Pos.getElement(document.getElementById('chameleon-style-box'));\r
+            box = UI.makeDraggableBox('chameleon-color-box', coords.x + UI.boxOffsetX, coords.y + UI.boxOffsetY);\r
+\r
+            var container = Util.createElement('div', 'chameleon-color-palette');\r
+            box.appendChild(container);\r
+\r
+            var x = 0; var y = 0; var xx = 0; var yi = 0;\r
+            for (var r = 0; r < 256; r += 51) {\r
+                for (var g = 0; g < 256; g += 51) {\r
+                    for (var b = 0; b < 256; b += 51) {\r
+                        var col = (r << 16 | g << 8 | b).toString(16);\r
+                        while (col.length < 6) {\r
+                            col = '0' + col;\r
+                        }\r
+                        \r
+                        yi = (xx > 17) ? 5 : 0;\r
+                                                \r
+                        var colorTab = Util.createElement('div');\r
+                        colorTab.style.position = 'absolute';\r
+                        colorTab.style.left = ((15 * x) + 17) + 'px';\r
+                        colorTab.style.top = (15 * (yi + y)) + 'px';\r
+                        colorTab.style.width = colorTab.style.height = '15px';\r
+                        colorTab.style.backgroundColor = colorTab.value = '#' + col;\r
+\r
+                        colorTab.setAttribute('title', '#' + col);\r
+\r
+                        container.appendChild(colorTab);\r
+                        \r
+                        if (x == 17) {\r
+                            x = 0;\r
+                            if (xx == 35) {\r
+                                xx = 0;\r
+                            } else {\r
+                                ++xx;\r
+                                ++y;\r
+                            }\r
+                        } else {\r
+                            ++x;\r
+                            ++xx;\r
+                        }\r
+                    }                \r
+                }\r
+            }\r
+            \r
+            for (var i = 0; i < extraColors.length; ++i) {\r
+                var colorTab = Util.createElement('div');\r
+                colorTab.style.position = 'absolute';\r
+                colorTab.style.left = '0px';\r
+                colorTab.style.top = (15 * i) + 'px';\r
+                colorTab.style.width = colorTab.style.height = '15px';\r
+                colorTab.style.backgroundColor = colorTab.value = '#' + extraColors[i];\r
+\r
+                colorTab.setAttribute('title', '#' + extraColors[i]);\r
+\r
+                container.appendChild(colorTab);\r
+            }\r
+            \r
+            Util.addEvent(container, 'click', Check.color);\r
+\r
+            container.style.height = (((y + yi) * 15) + 20) + 'px';\r
+\r
+            UI.addToDoc(box);\r
+        },\r
+        \r
+      \r
+      \r
+        __setColorType: function(e) {\r
+            var target = e.target || e.srcElement;\r
+\r
+            UI.CSS.colorType = UI.CSS.getBorderProp(target.id);\r
+        },\r
+        \r
+        \r
+        getBorderProp: function(id) {\r
+            var separators = ['color-picker', 'input', 'select'];\r
+            for (var i = 0; i < separators.length; ++i) {\r
+                if (id.indexOf('-' + separators[i] + '-') != -1) {\r
+                    return id.split('-' + separators[i] + '-').pop();\r
+                }\r
+            }\r
+            return '';\r
+        },\r
+\r
+        __getBorderPropValue: function(prop) {\r
+            var matches = prop.match(/^border\-([^\-]+)$/);\r
+            if (matches) {\r
+                var p1 = CSS.getPropValue('border-left-' + matches[1]);\r
+                var p2 = CSS.getPropValue('border-right-' + matches[1]);\r
+                var p3 = CSS.getPropValue('border-top-' + matches[1]);\r
+                var p4 = CSS.getPropValue('border-bottom-' + matches[1]);\r
+                if (!p1 && !p2 && !p3 && !p4) {\r
+                    return false;\r
+                }\r
+                \r
+                if (!(p1 && p2 && p3 && p4)) {\r
+                    return '';\r
+                }\r
+                \r
+                return (p1 == p2 && p2 == p3 && p3 == p4) ?  p1 : ''; \r
+            }\r
+            return false;\r
+        }\r
+          \r
+    };\r
+   \r
+    \r
+    \r
+    UI.HotSpots = {\r
+        __selectors: null,\r
+        __counter: 0,\r
+        \r
+        init: function() {\r
+            var box = Util.createElement('div', 'chameleon-launch-hotspots');\r
+            box.appendChild(document.createTextNode('Load hotspots'));\r
+            box.style.zIndex = ++UI.zIndex;\r
+            box.hotSpotsOn = false;\r
+            Util.addEvent(box, 'click', UI.HotSpots.__load);\r
+            \r
+            UI.addToDoc(box);\r
+        },\r
+        \r
+        getString: function() {\r
+            var sel = CSS.Selector.get();\r
+            if (UI.HotSpots.__selectors[sel]) {\r
+                return UI.HotSpots.__selectors[sel] + '.';\r
+            }\r
+            return '"' + sel + '"';\r
+        },\r
+        \r
+        __load: function(e) {\r
+            var target = e.target || e.srcElement;\r
+            target.hotSpotsOn = !target.hotSpotsOn;\r
+            \r
+            UI.HotSpots.__counter = 0;\r
+            \r
+            if (!target.hotSpotsOn) {\r
+                target.firstChild.nodeValue = 'Show hotspots';\r
+                UI.HotSpots.__clear();\r
+                return;\r
+            }\r
+            target.firstChild.nodeValue = 'Hide hotspots';\r
+          \r
+            if (!UI.HotSpots.__selectors) {\r
+                UI.HotSpots.__selectors = {};\r
+                UI.HotSpots.__selectors['div#header'] = 'Header bar';\r
+                UI.HotSpots.__selectors['div#header-home'] = 'Header bar on the homepage';\r
+                UI.HotSpots.__selectors['div#header-home div.headermain'] = 'The header text on the homepage';\r
+                UI.HotSpots.__selectors['div#header div.headermain'] = 'The header text';\r
+                UI.HotSpots.__selectors['td#right-column div.sideblock div.header'] = 'The block headings in the right hand column';\r
+                UI.HotSpots.__selectors['div.sideblock div.title'] = 'The text in the block headings';\r
+            }\r
+            \r
+            UI.HotSpots.__parse();\r
+        },\r
+        \r
+        __parse: function() {\r
+            for (var sel in UI.HotSpots.__selectors) {\r
+                var matches = cssQuery(sel);\r
+                var nm = matches.length;\r
+                if (!nm) {\r
+                    continue;\r
+                }\r
+                \r
+                for (var j = 0; j < nm; ++j) {\r
+                    if (matches[j].hasAttribute && matches[j].hasAttribute('id') && matches[j].getAttribute('id').indexOf('chameleon') != -1) {\r
+                        continue;\r
+                    }\r
+                    if (!matches[j].mySelectors) {\r
+                        matches[j].appendChild(UI.HotSpots.__makeButton(UI.HotSpots.__selectors[sel]));\r
+                        matches[j].mySelectors = sel;\r
+                    } else {\r
+                        matches[j].mySelectors += '|' + sel;\r
+                    }\r
+                }\r
+            }\r
+        },\r
+        \r
+        \r
+        __clear: function() {\r
+            var i = 0;\r
+            var obj;\r
+            while (obj = document.getElementById('chameleon-hotspot-' + ++i)) {\r
+                obj.parentNode.mySelectors = null;\r
+                Util.removeElement(obj);\r
+            }            \r
+        },\r
+     \r
+        \r
+        __makeButton: function(title) {\r
+            var d = Util.createElement('img', 'chameleon-hotspot-' + ++UI.HotSpots.__counter);\r
+            d.style.width = d.style.height = '20px'; d.style.cssFloat = 'left'; d.style.cursor = 'pointer';\r
+            d.setAttribute('src', CSS.fixPath('ui/images/hotspot.gif'));\r
+            d.setAttribute('title', title);\r
+            Util.addEvent(d, 'click', UI.HotSpots.__launch);\r
+            return d;\r
+        },\r
+        \r
+        __launch: function(e) {\r
+            var target = (e.target || e.srcElement).parentNode;\r
+            var selectors = target.mySelectors.split('|');\r
+            \r
+            var coords = Pos.getMouse(e);\r
+            \r
+            hotspotMode = true;\r
+                \r
+            var box = document.getElementById('chameleon-selector-box');\r
+            if (box) UI.closeBoxes(true, box);\r
+                \r
+            var box = UI.makeDraggableBox('chameleon-selector-box', coords.x, coords.y);\r
+            \r
+            if (selectors.length > 1) {\r
+                var instructions = Util.createElement('p');\r
+                instructions.appendChild(document.createTextNode('This element matches more than one selector, please choose which you would like to style.'));\r
+                instructions.className = 'chameleon-instructions';\r
+                box.appendChild(instructions);\r
+            }\r
+            \r
+            var selList = Util.createElement('ul');\r
+            for (var i = 0; i < selectors.length; ++i) {\r
+                var item = Util.createElement('li');\r
+                var itemLink = Util.createElement('a');\r
+                itemLink.appendChild(document.createTextNode('Add/Edit styles for ' + UI.HotSpots.__selectors[selectors[i]]));\r
+                itemLink.value = selectors[i];\r
+                Util.addEvent(itemLink, 'click', UI.HotSpots.__launchCSSEditor);\r
+                    \r
+                item.appendChild(itemLink);\r
+                    \r
+                selList.appendChild(item);\r
+                    \r
+                box.appendChild(selList);   \r
+            }\r
+            UI.addToDoc(box);\r
+        },\r
+        \r
+        __launchCSSEditor: function(e, value) {\r
+            var target = e.target || e.srcElement;\r
+            \r
+            if (!value) {\r
+                var value = target.value;\r
+            }\r
+            CSS.Selector.set(value);\r
+            UI.CSS.editWindow(e);\r
+        }\r
+        \r
+    };\r
+   \r
+\r
+    \r
+   \r
+    \r
+    \r
+    var Check = {\r
+        color: function(e) {\r
+            var target = e.target || e.srcElement;\r
+            if (e.type == 'click' && !target.value) return;\r
+            \r
+            var originalColor = UI.CSS.__getPropValue(UI.CSS.colorType);\r
+            if (originalColor != target.value) {\r
+                CSS.setPropValue(UI.CSS.colorType, target.value);\r
+                UI.CSS.redraw.call(null, null, 'color');\r
+            }\r
+            if (e.type == 'click') {\r
+                UI.closeBoxes(true, target.parentNode.parentNode);\r
+            }\r
+        },\r
+        \r
+        backgroundImage: function(e) {\r
+            var target = e.target || e.srcElement;\r
+\r
+            CSS.setPropValue('background-image', target.value);\r
+            UI.CSS.redraw.call(null, null, 'image');\r
+            if (e.type == 'click') {\r
+                UI.closeBoxes(true, document.getElementById('chameleon-file-box'));\r
+            }\r
+        },   \r
+        \r
+        backgroundRepeat: function(e) {\r
+            var target = e.target || e.srcElement;\r
+            var value = target.options[target.options.selectedIndex].value.toLowerCase();\r
+            CSS.setPropValue('background-repeat', value);\r
+        },\r
+        \r
+        backgroundPosition: function(e) {\r
+            var target = e.target || e.srcElement;\r
+            var value = target.options[target.options.selectedIndex].value.toLowerCase();\r
+            CSS.setPropValue('background-position', value);\r
+        },\r
+        \r
+        borderWidth: function(e) {\r
+            var target = e.target || e.srcElement;\r
+\r
+            var hasUnits = false;\r
+            for (var i = 0; i < Config.UNITS.length; ++i) {\r
+                if (target.value.indexOf(Config.UNITS[i]) > 0) {\r
+                    hasUnits = true;\r
+                    break;\r
+                }\r
+            }\r
+\r
+            var val = parseInt(target.value);\r
+            if (isNaN(val)) {\r
+                if (!target.value.match(/thin|medium|thick/)) {\r
+                    target.value = '';\r
+                }\r
+            } else if (!hasUnits) {\r
+                target.value = val + 'px';\r
+            }\r
+            CSS.setPropValue(UI.CSS.getBorderProp(target.id), target.value);  \r
+        },\r
+        \r
+        borderStyle: function(e) {\r
+            var target = e.target || e.srcElement;\r
+            var value = target.options[target.options.selectedIndex].value.toLowerCase();\r
+            CSS.setPropValue(UI.CSS.getBorderProp(target.id), value);\r
+        },\r
+        \r
+        fontStyle: function(e) {\r
+            var target = e.target || e.srcElement;\r
+            var value = target.options[target.options.selectedIndex].value.toLowerCase();\r
+            CSS.setPropValue('font-style', value);\r
+        },\r
+        \r
+        fontWeight: function(e) {\r
+            var target = e.target || e.srcElement;\r
+            var value = target.options[target.options.selectedIndex].value.toLowerCase();\r
+            CSS.setPropValue('font-weight', value);\r
+        },\r
+        \r
+        fontSize: function(e) {\r
+            var target = e.target || e.srcElement;\r
+            CSS.setPropValue('font-size', target.value);\r
+        },\r
+        \r
+        lineHeight: function(e) {\r
+            var target = e.target || e.srcElement;\r
+            CSS.setPropValue('line-height', target.value);\r
+        },\r
+        \r
+        fontFamily: function(e) {\r
+            var target = e.target || e.srcElement;\r
+            var n = target.nodeName.toLowerCase();\r
+            \r
+            if (n == 'select') {\r
+                var value = target.options[target.options.selectedIndex].value.toLowerCase();\r
+                var fontFamilyInputRow = target.parentNode.parentNode.nextSibling;\r
+                if (value == 'other') {\r
+                   try {\r
+                       fontFamilyInputRow.style.display = 'table-row';\r
+                   } catch(e) {\r
+                       fontFamilyInputRow.style.display = 'block';\r
+                   }\r
+                } else {\r
+                   if (value != '') {\r
+                       fontFamilyInputRow.style.display = 'none';\r
+                   }\r
+                   CSS.setPropValue('font-family', value);\r
+                }\r
+            } else {\r
+                CSS.setPropValue('font-family', target.value);\r
+            }\r
+        },\r
+        \r
+        textDecoration: function(e) {\r
+            var target = e.target || e.srcElement;\r
+            var value = target.options[target.options.selectedIndex].value.toLowerCase();\r
+            CSS.setPropValue('text-decoration', value);\r
+        },\r
+        \r
+        textAlign: function(e) {\r
+            var target = e.target || e.srcElement;\r
+            var value = target.options[target.options.selectedIndex].value.toLowerCase();\r
+            CSS.setPropValue('text-align', value);\r
+        }\r
+    };\r
+    \r
+    \r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+    var debugMsg = function(msg) {\r
+        //if (window.opera) window.opera.postError(msg);\r
+    };\r
+\r
+\r
+\r
+\r
+    var climbTree = function(src) {\r
+        var struct = [];\r
+        while (src.nodeName.toLowerCase() != 'html') {\r
+            if (src.nodeType == Node.ELEMENT_NODE) {\r
+                if (src.hasAttribute && src.hasAttribute('id') && src.getAttribute('id').indexOf('chameleon-') != -1) {\r
+                    return src.getAttribute('id');\r
+                }\r
+                var elementObj = {tagname: src.nodeName.toLowerCase()};\r
+                if (src.hasAttribute && src.hasAttribute('id')) {\r
+                    elementObj.id = src.getAttribute('id');\r
+                }\r
+                if (src.className) {\r
+                    elementObj.classname = src.className;\r
+                }\r
+                struct.push(elementObj);\r
+            }\r
+            src = src.parentNode;\r
+        }\r
+        return struct;\r
+    };\r
+\r
+\r
+\r
+    var setup = function() {\r
+        UI.clearStatusMsg();\r
+        \r
+        //UI.HotSpots.init();\r
+        \r
+        Util.addEvent(window, 'unload', CSS.unloadPrompt);\r
+        Util.addEvent(window, 'unload', Util.cleanUp);\r
+        Util.addEvent(document, 'mousedown', UI.Selector.editWindow);\r
+    };\r
+\r
+    var startSetup = function() {\r
+        UI.statusMsg('Chameleon is loading...');\r
+\r
+        if (!CSS.loadRemote(true)) {\r
+            alert('Your browser must support XMLHttpRequest! Supported browsers include Internet Explorer 6, Mozilla Firefox and Opera 8.01+');\r
+        }\r
+    };\r
+\r
+    Util.addEvent(window, 'load', startSetup);\r
+\r
+})();\r
diff --git a/theme/chameleon/ui/chameleon_ui.css b/theme/chameleon/ui/chameleon_ui.css
new file mode 100644 (file)
index 0000000..30c6b4c
--- /dev/null
@@ -0,0 +1,363 @@
+/* sorry about the massive abuse of !important ;-) this tries to prevent user changes in CSS being \r
+inherited by the user interface */\r
+\r
+/* general box styles */\r
+#chameleon-selector-box, #chameleon-style-box, \r
+#chameleon-color-box, #chameleon-file-box, \r
+#chameleon-export-box, #chameleon-status-msg {\r
+  position: absolute !important;\r
+  left: 0; top: 0;\r
+  margin: 0 !important; padding: 0 !important;\r
+  width: 400px !important;\r
+  background: #eee !important;\r
+  border: 1px solid #ccc !important;\r
+  font: 9pt/1.4 arial,helvetica,sans-serif !important;\r
+  color: #000 !important;\r
+}\r
+\r
+/* reset */\r
+#chameleon-selector-box div, #chameleon-style-box div, #chameleon-color-box div, #chameleon-file-box div,\r
+#chameleon-selector-box a, #chameleon-style-box a, #chameleon-color-box a, #chameleon-file-box a {\r
+  margin: 0 !important; padding: 0 !important;\r
+  color: #000 !important;\r
+  font: 9pt/1.4 arial,helvetica,sans-serif !important;\r
+  border: 0 !important;\r
+  background: none;\r
+}\r
+\r
+#chameleon-selector-box a, #chameleon-style-box a, #chameleon-color-box a, #chameleon-file-box a {\r
+  cursor: pointer !important;\r
+}\r
+\r
+#chameleon-selector-box td, #chameleon-style-box td, #chameleon-color-box td, #chameleon-file-box td,\r
+#chameleon-selector-box th, #chameleon-style-box th, #chameleon-color-box th, #chameleon-file-box th  {\r
+  padding: 0 !important;\r
+  color: #000 !important;\r
+  font: 9pt/1.4 arial,helvetica,sans-serif !important;\r
+  border: 0 !important;\r
+  background: none !important;\r
+}\r
+\r
+#chameleon-selector-box p, #chameleon-style-box p, #chameleon-color-box p, #chameleon-file-box p {\r
+  margin: 0 !important; padding: 5px 10px 0 10px !important;\r
+  color: #000 !important;\r
+  font: 9pt/1.4 arial,helvetica,sans-serif !important;\r
+  border: 0 !important;\r
+  background: none !important;\r
+}\r
+\r
+/* drag handles */\r
+#chameleon-selector-box #chameleon-selector-box-handle, \r
+#chameleon-style-box #chameleon-style-box-handle, \r
+#chameleon-color-box #chameleon-color-box-handle,\r
+#chameleon-file-box #chameleon-file-box-handle,\r
+#chameleon-export-box #chameleon-export-box-handle {\r
+  width: 100% !important; min-height: 20px !important; _height: 20px !important;\r
+  background: #ddd !important;\r
+}\r
+\r
+#chameleon-selector-box #chameleon-selector-box-close, \r
+#chameleon-style-box #chameleon-style-box-close, \r
+#chameleon-color-box #chameleon-color-box-close,\r
+#chameleon-file-box #chameleon-file-box-close {\r
+  padding: 1px 5px !important;\r
+  float: right !important;\r
+  cursor: pointer !important;\r
+}\r
+\r
+/* selector box specific stuff */\r
+#chameleon-selector-box ol {\r
+  list-style-type: none !important;\r
+  margin: 0 !important; padding: 10px 20px 10px 10px !important;\r
+}\r
+\r
+#chameleon-selector-box li {\r
+  margin: 0 0 2px 0 !important; padding: 0 0 0 20px !important;\r
+  color: #000 !important;\r
+  font: 9pt/1.4 arial,helvetica,sans-serif !important;\r
+  background: url(images/tag.gif) no-repeat 0 0 !important;\r
+}\r
+\r
+#chameleon-selector-box #chameleon-selector-list li {\r
+  background-image: none !important;\r
+}\r
+\r
+#chameleon-selector-box #chameleon-selector-list {\r
+  border: 1px solid #ccc !important;\r
+  background: #f6f6f6 !important;\r
+  margin: 2px !important;\r
+}\r
+\r
+#chameleon-selector-box #chameleon-selector-list li {\r
+  margin: 2px !important; padding: 0 !important;\r
+}\r
+\r
+#chameleon-selector-box span {\r
+  padding: 1px 3px !important;\r
+  font: 9pt/1.4 arial,helvetica,sans-serif !important;\r
+  cursor: pointer !important;\r
+}\r
+\r
+#chameleon-selector-box span.active-selector {\r
+  background: #fff !important;\r
+  font-weight: bold !important;\r
+}\r
+\r
+#chameleon-selector-box #chameleon-style-overview-container {\r
+  background: #f6f6f6 url(images/grad.gif) repeat-x 0 100% !important;\r
+}\r
+\r
+#chameleon-selector-box #chameleon-style-overview {\r
+  margin: 0 !important; padding: 0 !important;\r
+  width: 100% !important;\r
+  border-collapse: collapse !important;\r
+}\r
+\r
+#chameleon-selector-box #chameleon-style-overview th.selector,\r
+#chameleon-selector-box #chameleon-style-overview th.current-selector {\r
+  padding: 1px 5px !important;\r
+  background: #000 !important;\r
+  color: #fff !important;\r
+  font-weight: bold !important;\r
+  text-align: left !important;\r
+}\r
+\r
+#chameleon-selector-box #chameleon-style-overview th.current-selector,\r
+#chameleon-selector-box #chameleon-style-overview td.current-selector {\r
+  border-top: 2px solid #f90 !important;\r
+  border-bottom: 2px solid #f90 !important;\r
+}\r
+\r
+#chameleon-selector-box #chameleon-style-overview td.selector,\r
+#chameleon-selector-box #chameleon-style-overview td.current-selector {\r
+  padding: 1px 5px !important;\r
+  background: #000 !important;\r
+  color: #fff !important;\r
+  font-weight: normal !important;\r
+  text-align: left !important;\r
+}\r
+\r
+#chameleon-selector-box #chameleon-style-overview td.selector a,\r
+#chameleon-selector-box #chameleon-style-overview td.current-selector a {\r
+  color: #f90 !important;\r
+  font-weight: bold !important;\r
+}\r
+\r
+#chameleon-selector-box #chameleon-style-overview td.prop {\r
+  padding: 1px 0 1px 5px !important;\r
+  width: 150px !important;\r
+}\r
+\r
+#chameleon-selector-box #chameleon-style-overview td.value {\r
+  padding: 1px 5px 1px 0 !important;\r
+}\r
+\r
+/* style box specific stuff */\r
+\r
+#chameleon-style-box input.chameleon-input-text {\r
+  border: 1px solid #999 !important;\r
+  color: #000 !important;\r
+}\r
+\r
+#chameleon-style-box input.chameleon-input-text:focus {\r
+  border: 1px solid #000 !important;\r
+}\r
+\r
+#chameleon-selector-box input.chameleon-btn,\r
+#chameleon-style-box input.chameleon-btn {\r
+  border: 1px solid #000 !important;\r
+  background: #aaa !important;\r
+  color: #000 !important;\r
+  font-size: 9pt !important;\r
+  padding: 2px 5px !important; margin: 0 2px;\r
+}\r
+\r
+#chameleon-selector-box input.chameleon-btn:hover,\r
+#chameleon-style-box input.chameleon-btn:hover {\r
+  background: #000 !important;\r
+  color: #fff !important;\r
+}\r
+\r
+\r
+#chameleon-style-box table {\r
+  margin: 3px 3px 0 1px !important;\r
+  position: relative !important;\r
+  z-index: 2 !important;\r
+}\r
+\r
+#chameleon-style-box #chameleon-style-controls, #chameleon-selector-box #chameleon-selector-controls {\r
+  position: relative !important;\r
+  border: 1px solid #999 !important;\r
+  background: #f6f6f6 !important;\r
+  margin: -1px 3px 3px 2px !important;\r
+  z-index: 1 !important;\r
+}\r
+\r
+#chameleon-style-box #chameleon-style-tabs, #chameleon-selector-box #chameleon-selector-tabs {\r
+  position: relative !important;\r
+  margin: 3px 3px 0 3px !important;\r
+  z-index: 2 !important;\r
+}\r
+\r
+#chameleon-style-box td.chameleon-style-tab, #chameleon-selector-box td.chameleon-selector-tab {\r
+  border: 1px solid #999 !important;\r
+  border-bottom: 0 !important;\r
+  background: transparent url(images/inactive_tab.gif) 0 100% repeat-x !important;\r
+  padding: 2px 5px 1px 5px !important;\r
+  cursor: pointer !important;\r
+}\r
+\r
+#chameleon-style-box td.chameleon-style-tab-active, #chameleon-selector-box td.chameleon-selector-tab-active {\r
+  border: 1px solid #999 !important;\r
+  border-bottom: 0 !important;\r
+  background: transparent url(images/active_tab.gif) 0 100% repeat-x !important;\r
+  padding: 2px 5px 1px 5px !important;\r
+}\r
+\r
+\r
+#chameleon-style-controls td {\r
+  text-align: left !important;\r
+  padding: 2px !important;\r
+}\r
+\r
+#chameleon-style-controls td.label {\r
+  width: 120px !important;\r
+  text-align: right !important;\r
+}\r
+\r
+/* the open color picker/image browser icons */\r
+#chameleon-style-controls #chameleon-style-controls-color-picker-color,\r
+#chameleon-style-controls #chameleon-style-controls-color-picker-background-color,\r
+#chameleon-style-controls #chameleon-style-controls-color-picker-border-color,\r
+#chameleon-style-controls #chameleon-style-controls-color-picker-border-left-color,\r
+#chameleon-style-controls #chameleon-style-controls-color-picker-border-right-color,\r
+#chameleon-style-controls #chameleon-style-controls-color-picker-border-top-color,\r
+#chameleon-style-controls #chameleon-style-controls-color-picker-border-bottom-color,\r
+#chameleon-style-controls #chameleon-style-controls-background-image-picker {\r
+  width: 20px !important; height: 20px !important;\r
+  border: 1px solid #000 !important;\r
+  margin: 0 0 0 2px !important;\r
+  cursor: pointer !important;\r
+}\r
+\r
+/* color picker */\r
+#chameleon-color-box #chameleon-color-palette {\r
+  position: relative !important;\r
+  margin: 10px 12px !important;\r
+}\r
+\r
+body #chameleon-color-box {\r
+  width: 312px !important;\r
+}\r
+\r
+#chameleon-color-box #chameleon-color-palette div {\r
+  cursor: pointer !important;\r
+}\r
+\r
+#chameleon-file-box table {\r
+  margin: 2px 0 !important;\r
+}\r
+\r
+#chameleon-file-box #chameleon-files-parent {\r
+  width: 100px !important;\r
+  cursor: pointer !important;\r
+}\r
+\r
+#chameleon-file-box #chameleon-files-location p {\r
+  font-weight: bold !important;\r
+}\r
+\r
+#chameleon-file-box #chameleon-files-location p span {\r
+  font-weight: normal !important;\r
+}\r
+\r
+#chameleon-file-box div p, #chameleon-file-box table p {\r
+  padding: 0 0 0 20px !important; margin: 5px 10px !important;\r
+}\r
+\r
+#chameleon-file-box div p {\r
+  background: url(images/image.gif) no-repeat 0 0 !important;\r
+}\r
+\r
+#chameleon-file-box div p.chameleon-image-folder {\r
+  background: url(images/folder.gif) no-repeat 0 0 !important;\r
+}\r
+\r
+#chameleon-file-box table p.chameleon-image-folder {\r
+  background: url(images/parent.gif) no-repeat 0 0 !important;\r
+}\r
+\r
+#chameleon-file-box div p span {\r
+  cursor: pointer !important;\r
+}\r
+\r
+/* the buttons */\r
+\r
+#chameleon-selector-box input.chameleon-btn, \r
+#chameleon-style-box input.chameleon-btn, \r
+#chameleon-color-box input.chameleon-btn, \r
+#chameleon-file-box input.chameleon-btn {\r
+  cursor: pointer !important;\r
+  margin-bottom: 3px !important;\r
+}\r
+\r
+#chameleon-selector-box p.chameleon-instructions, #chameleon-style-box p.chameleon-instructions {\r
+  font-size: 9pt !important;\r
+  padding: 10px !important;\r
+}\r
+\r
+#chameleon-status-msg {\r
+  text-align: center !important;\r
+}\r
+\r
+#chameleon-status-msg input {\r
+  margin-top: 2px !important;\r
+}\r
+\r
+\r
+div table#chameleon-status-msg {\r
+  position: relative !important;\r
+  background: #f6f6f6 !important;\r
+  width: 390px !important;\r
+  margin: 5px auto !important;\r
+  border: 1px solid #999 !important;\r
+}\r
+\r
+div table#chameleon-status-msg td.chameleon-ok {\r
+  background: #f6f6f6 url(images/ok.gif) no-repeat 50% 50% !important;\r
+  width: 25px !important; height: 25px !important;\r
+}\r
+\r
+div table#chameleon-status-msg td.chameleon-working {\r
+  background: #f6f6f6 url(images/working.gif) no-repeat 50% 50% !important;\r
+  width: 25px !important; height: 25px !important;\r
+}\r
+\r
+div table#chameleon-status-msg td.chameleon-notice {\r
+  background: #f6f6f6 url(images/notice.gif) no-repeat 50% 50% !important;\r
+  width: 25px !important; height: 25px !important;\r
+}\r
+\r
+div table#chameleon-status-msg td.chameleon-error {\r
+  background: #f6f6f6 url(images/error.gif) no-repeat 50% 50% !important;\r
+  width: 25px !important; height: 25px !important;\r
+}\r
+\r
+div#chameleon-launch-hotspots {\r
+  position: absolute !important;\r
+  top: 0 !important; left: 0 !important;\r
+  z-index: 2 !important;\r
+  background: #f6f6f6 !important;\r
+  border: 1px solid #999 !important;\r
+  padding: 2px 10px !important;\r
+  cursor: pointer !important;\r
+}\r
+\r
+body > div#chameleon-launch-hotspots  {\r
+  position: fixed !important;\r
+}\r
+\r
+#chameleon-selector-box ul {\r
+  list-style-type: none !important;\r
+}\r
+\r
diff --git a/theme/chameleon/ui/css.php b/theme/chameleon/ui/css.php
new file mode 100644 (file)
index 0000000..24e5107
--- /dev/null
@@ -0,0 +1,52 @@
+<?php\r
+\r
+require_once('../../../config.php');\r
+require_once('../config.php');\r
+\r
+\r
+if (!isset($THEME->chameleonenabled) || !$THEME->chameleonenabled) {\r
+    die('CHAMELEON_ERROR Editing this theme has been disabled');\r
+}\r
+\r
+\r
+$chameleon_id = isset($_GET['id']) ? (int) $_GET['id'] : 0;\r
+if ($chameleon_id != 0) {\r
+    if (!isteacher($chameleon_id)) {\r
+        die('CHAMELEON_ERROR You are not logged in');\r
+    }\r
+} else if (!isadmin()) {\r
+    die('CHAMELEON_ERROR You are not logged in');\r
+}\r
+\r
+\r
+require_once('ChameleonCSS.class.php');\r
+require_once('ChameleonFileBrowser.class.php');\r
+\r
+\r
+\r
+if (isset($_GET['path'])) {\r
+    $fm = new ChameleonFileBrowser;\r
+    die($fm->readFiles());\r
+}\r
+\r
+$chameleon = new ChameleonCSS('../', 'user_styles.css', 'temp_user_styles.css');\r
+if (isset($_POST['css'])) {\r
+    if (!isset($_GET['temp'])) {\r
+        $chameleon->update('perm', $_POST['css']);\r
+        $chameleon->update('temp');\r
+    } else {\r
+        $chameleon->update('temp', $_POST['css']);\r
+    }\r
+    \r
+} else {\r
+\r
+    $css = $chameleon->read();\r
+    if ($css === false) {\r
+        echo 'CHAMELEON_ERROR ' . $chameleon->error;\r
+    } else {\r
+        echo $css;\r
+    }\r
+}\r
+\r
+\r
+?>
\ No newline at end of file
diff --git a/theme/chameleon/ui/css_query.js b/theme/chameleon/ui/css_query.js
new file mode 100644 (file)
index 0000000..1fcab4a
--- /dev/null
@@ -0,0 +1,356 @@
+/*\r
+       cssQuery, version 2.0.2 (2005-08-19)\r
+       Copyright: 2004-2005, Dean Edwards (http://dean.edwards.name/)\r
+       License: http://creativecommons.org/licenses/LGPL/2.1/\r
+*/\r
+\r
+// the following functions allow querying of the DOM using CSS selectors\r
+var cssQuery = function() {\r
+var version = "2.0.2";\r
+\r
+// -----------------------------------------------------------------------\r
+// main query function\r
+// -----------------------------------------------------------------------\r
+\r
+var $COMMA = /\s*,\s*/;\r
+var cssQuery = function($selector, $$from) {\r
+try {\r
+       var $match = [];\r
+       var $useCache = arguments.callee.caching && !$$from;\r
+       var $base = ($$from) ? ($$from.constructor == Array) ? $$from : [$$from] : [document];\r
+       // process comma separated selectors\r
+       var $$selectors = parseSelector($selector).split($COMMA), i;\r
+       for (i = 0; i < $$selectors.length; i++) {\r
+               // convert the selector to a stream\r
+               $selector = _toStream($$selectors[i]);\r
+               // faster chop if it starts with id (MSIE only)\r
+               if (isMSIE && $selector.slice(0, 3).join("") == " *#") {\r
+                       $selector = $selector.slice(2);\r
+                       $$from = _msie_selectById([], $base, $selector[1]);\r
+               } else $$from = $base;\r
+               // process the stream\r
+               var j = 0, $token, $filter, $arguments, $cacheSelector = "";\r
+               while (j < $selector.length) {\r
+                       $token = $selector[j++];\r
+                       $filter = $selector[j++];\r
+                       $cacheSelector += $token + $filter;\r
+                       // some pseudo-classes allow arguments to be passed\r
+                       //  e.g. nth-child(even)\r
+                       $arguments = "";\r
+                       if ($selector[j] == "(") {\r
+                               while ($selector[j++] != ")" && j < $selector.length) {\r
+                                       $arguments += $selector[j];\r
+                               }\r
+                               $arguments = $arguments.slice(0, -1);\r
+                               $cacheSelector += "(" + $arguments + ")";\r
+                       }\r
+                       // process a token/filter pair use cached results if possible\r
+                       $$from = ($useCache && cache[$cacheSelector]) ?\r
+                               cache[$cacheSelector] : select($$from, $token, $filter, $arguments);\r
+                       if ($useCache) cache[$cacheSelector] = $$from;\r
+               }\r
+               $match = $match.concat($$from);\r
+       }\r
+       delete cssQuery.error;\r
+       return $match;\r
+} catch ($error) {\r
+       cssQuery.error = $error;\r
+       return [];\r
+}};\r
+\r
+// -----------------------------------------------------------------------\r
+// public interface\r
+// -----------------------------------------------------------------------\r
+\r
+cssQuery.toString = function() {\r
+       return "function cssQuery() {\n  [version " + version + "]\n}";\r
+};\r
+\r
+// caching\r
+var cache = {};\r
+cssQuery.caching = false;\r
+cssQuery.clearCache = function($selector) {\r
+       if ($selector) {\r
+               $selector = _toStream($selector).join("");\r
+               delete cache[$selector];\r
+       } else cache = {};\r
+};\r
+\r
+// allow extensions\r
+var modules = {};\r
+var loaded = false;\r
+cssQuery.addModule = function($name, $script) {\r
+       if (loaded) eval("$script=" + String($script));\r
+       modules[$name] = new $script();;\r
+};\r
+\r
+// hackery\r
+cssQuery.valueOf = function($code) {\r
+       return $code ? eval($code) : this;\r
+};\r
+\r
+// -----------------------------------------------------------------------\r
+// declarations\r
+// -----------------------------------------------------------------------\r
+\r
+var selectors = {};\r
+var pseudoClasses = {};\r
+// a safari bug means that these have to be declared here\r
+var AttributeSelector = {match: /\[([\w-]+(\|[\w-]+)?)\s*(\W?=)?\s*([^\]]*)\]/};\r
+var attributeSelectors = [];\r
+\r
+// -----------------------------------------------------------------------\r
+// selectors\r
+// -----------------------------------------------------------------------\r
+\r
+// descendant selector\r
+selectors[" "] = function($results, $from, $tagName, $namespace) {\r
+       // loop through current selection\r
+       var $element, i, j;\r
+       for (i = 0; i < $from.length; i++) {\r
+               // get descendants\r
+               var $subset = getElementsByTagName($from[i], $tagName, $namespace);\r
+               // loop through descendants and add to results selection\r
+               for (j = 0; ($element = $subset[j]); j++) {\r
+                       if (thisElement($element) && compareNamespace($element, $namespace))\r
+                               $results.push($element);\r
+               }\r
+       }\r
+};\r
+\r
+// ID selector\r
+selectors["#"] = function($results, $from, $id) {\r
+       // loop through current selection and check ID\r
+       var $element, j;\r
+       for (j = 0; ($element = $from[j]); j++) if ($element.id == $id) $results.push($element);\r
+};\r
+\r
+// class selector\r
+selectors["."] = function($results, $from, $className) {\r
+       // create a RegExp version of the class\r
+       $className = new RegExp("(^|\\s)" + $className + "(\\s|$)");\r
+       // loop through current selection and check class\r
+       var $element, i;\r
+       for (i = 0; ($element = $from[i]); i++)\r
+               if ($className.test($element.className)) $results.push($element);\r
+};\r
+\r
+// pseudo-class selector\r
+selectors[":"] = function($results, $from, $pseudoClass, $arguments) {\r
+       // retrieve the cssQuery pseudo-class function\r
+       var $test = pseudoClasses[$pseudoClass], $element, i;\r
+       // loop through current selection and apply pseudo-class filter\r
+       if ($test) for (i = 0; ($element = $from[i]); i++)\r
+               // if the cssQuery pseudo-class function returns "true" add the element\r
+               if ($test($element, $arguments)) $results.push($element);\r
+};\r
+\r
+// -----------------------------------------------------------------------\r
+// pseudo-classes\r
+// -----------------------------------------------------------------------\r
+\r
+pseudoClasses["link"] = function($element) {\r
+       var $document = getDocument($element);\r
+       if ($document.links) for (var i = 0; i < $document.links.length; i++) {\r
+               if ($document.links[i] == $element) return true;\r
+       }\r
+};\r
+\r
+pseudoClasses["visited"] = function($element) {\r
+       // can't do this without jiggery-pokery\r
+};\r
+\r
+// -----------------------------------------------------------------------\r
+// DOM traversal\r
+// -----------------------------------------------------------------------\r
+\r
+// IE5/6 includes comments (LOL) in it's elements collections.\r
+// so we have to check for this. the test is tagName != "!". LOL (again).\r
+var thisElement = function($element) {\r
+       return ($element && $element.nodeType == 1 && $element.tagName != "!") ? $element : null;\r
+};\r
+\r
+// return the previous element to the supplied element\r
+//  previousSibling is not good enough as it might return a text or comment node\r
+var previousElementSibling = function($element) {\r
+       while ($element && ($element = $element.previousSibling) && !thisElement($element)) continue;\r
+       return $element;\r
+};\r
+\r
+// return the next element to the supplied element\r
+var nextElementSibling = function($element) {\r
+       while ($element && ($element = $element.nextSibling) && !thisElement($element)) continue;\r
+       return $element;\r
+};\r
+\r
+// return the first child ELEMENT of an element\r
+//  NOT the first child node (though they may be the same thing)\r
+var firstElementChild = function($element) {\r
+       return thisElement($element.firstChild) || nextElementSibling($element.firstChild);\r
+};\r
+\r
+var lastElementChild = function($element) {\r
+       return thisElement($element.lastChild) || previousElementSibling($element.lastChild);\r
+};\r
+\r
+// return child elements of an element (not child nodes)\r
+var childElements = function($element) {\r
+       var $childElements = [];\r
+       $element = firstElementChild($element);\r
+       while ($element) {\r
+               $childElements.push($element);\r
+               $element = nextElementSibling($element);\r
+       }\r
+       return $childElements;\r
+};\r
+\r
+// -----------------------------------------------------------------------\r
+// browser compatibility\r
+// -----------------------------------------------------------------------\r
+\r
+// all of the functions in this section can be overwritten. the default\r
+//  configuration is for IE. The functions below reflect this. standard\r
+//  methods are included in a separate module. It would probably be better\r
+//  the other way round of course but this makes it easier to keep IE7 trim.\r
+\r
+var isMSIE = true;\r
+\r
+var isXML = function($element) {\r
+       var $document = getDocument($element);\r
+       return (typeof $document.mimeType == "unknown") ?\r
+               /\.xml$/i.test($document.URL) :\r
+               Boolean($document.mimeType == "XML Document");\r
+};\r
+\r
+// return the element's containing document\r
+var getDocument = function($element) {\r
+       return $element.ownerDocument || $element.document;\r
+};\r
+\r
+var getElementsByTagName = function($element, $tagName) {\r
+       return ($tagName == "*" && $element.all) ? $element.all : $element.getElementsByTagName($tagName);\r
+};\r
+\r
+var compareTagName = function($element, $tagName, $namespace) {\r
+       if ($tagName == "*") return thisElement($element);\r
+       if (!compareNamespace($element, $namespace)) return false;\r
+       if (!isXML($element)) $tagName = $tagName.toUpperCase();\r
+       return $element.tagName == $tagName;\r
+};\r
+\r
+var compareNamespace = function($element, $namespace) {\r
+       return !$namespace || ($namespace == "*") || ($element.scopeName == $namespace);\r
+};\r
+\r
+var getTextContent = function($element) {\r
+       return $element.innerText;\r
+};\r
+\r
+function _msie_selectById($results, $from, id) {\r
+       var $match, i, j;\r
+       for (i = 0; i < $from.length; i++) {\r
+               if ($match = $from[i].all.item(id)) {\r
+                       if ($match.id == id) $results.push($match);\r
+                       else if ($match.length != null) {\r
+                               for (j = 0; j < $match.length; j++) {\r
+                                       if ($match[j].id == id) $results.push($match[j]);\r
+                               }\r
+                       }\r
+               }\r
+       }\r
+       return $results;\r
+};\r
+\r
+// for IE5.0\r
+if (![].push) Array.prototype.push = function() {\r
+       for (var i = 0; i < arguments.length; i++) {\r
+               this[this.length] = arguments[i];\r
+       }\r
+       return this.length;\r
+};\r
+\r
+// -----------------------------------------------------------------------\r
+// query support\r
+// -----------------------------------------------------------------------\r
+\r
+// select a set of matching elements.\r
+// "from" is an array of elements.\r
+// "token" is a character representing the type of filter\r
+//  e.g. ">" means child selector\r
+// "filter" represents the tag name, id or class name that is being selected\r
+// the function returns an array of matching elements\r
+var $NAMESPACE = /\|/;\r
+function select($$from, $token, $filter, $arguments) {\r
+       if ($NAMESPACE.test($filter)) {\r
+               $filter = $filter.split($NAMESPACE);\r
+               $arguments = $filter[0];\r
+               $filter = $filter[1];\r
+       }\r
+       var $results = [];\r
+       if (selectors[$token]) {\r
+               selectors[$token]($results, $$from, $filter, $arguments);\r
+       }\r
+       return $results;\r
+};\r
+\r
+// -----------------------------------------------------------------------\r
+// parsing\r
+// -----------------------------------------------------------------------\r
+\r
+// convert css selectors to a stream of tokens and filters\r
+//  it's not a real stream. it's just an array of strings.\r
+var $STANDARD_SELECT = /^[^\s>+~]/;\r
+var $$STREAM = /[\s#.:>+~()@]|[^\s#.:>+~()@]+/g;\r
+function _toStream($selector) {\r
+       if ($STANDARD_SELECT.test($selector)) $selector = " " + $selector;\r
+       return $selector.match($$STREAM) || [];\r
+};\r
+\r
+var $WHITESPACE = /\s*([\s>+~(),]|^|$)\s*/g;\r
+var $IMPLIED_ALL = /([\s>+~,]|[^(]\+|^)([#.:@])/g;\r
+var parseSelector = function($selector) {\r
+       return $selector\r
+       // trim whitespace\r
+       .replace($WHITESPACE, "$1")\r
+       // e.g. ".class1" --> "*.class1"\r
+       .replace($IMPLIED_ALL, "$1*$2");\r
+};\r
+\r
+var Quote = {\r
+       toString: function() {return "'"},\r
+       match: /^('[^']*')|("[^"]*")$/,\r
+       test: function($string) {\r
+               return this.match.test($string);\r
+       },\r
+       add: function($string) {\r
+               return this.test($string) ? $string : this + $string + this;\r
+       },\r
+       remove: function($string) {\r
+               return this.test($string) ? $string.slice(1, -1) : $string;\r
+       }\r
+};\r
+\r
+var getText = function($text) {\r
+       return Quote.remove($text);\r
+};\r
+\r
+var $ESCAPE = /([\/()[\]?{}|*+-])/g;\r
+function regEscape($string) {\r
+       return $string.replace($ESCAPE, "\\$1");\r
+};\r
+\r
+// -----------------------------------------------------------------------\r
+// modules\r
+// -----------------------------------------------------------------------\r
+\r
+// -------- >>      insert modules here for packaging       << -------- \\\r
+\r
+loaded = true;\r
+\r
+// -----------------------------------------------------------------------\r
+// return the query function\r
+// -----------------------------------------------------------------------\r
+\r
+return cssQuery;\r
+\r
+}(); // cssQuery\r
diff --git a/theme/chameleon/ui/images/active_tab.gif b/theme/chameleon/ui/images/active_tab.gif
new file mode 100644 (file)
index 0000000..8cd27e9
Binary files /dev/null and b/theme/chameleon/ui/images/active_tab.gif differ
diff --git a/theme/chameleon/ui/images/error.gif b/theme/chameleon/ui/images/error.gif
new file mode 100644 (file)
index 0000000..c318cf5
Binary files /dev/null and b/theme/chameleon/ui/images/error.gif differ
diff --git a/theme/chameleon/ui/images/folder.gif b/theme/chameleon/ui/images/folder.gif
new file mode 100644 (file)
index 0000000..81230c6
Binary files /dev/null and b/theme/chameleon/ui/images/folder.gif differ
diff --git a/theme/chameleon/ui/images/grad.gif b/theme/chameleon/ui/images/grad.gif
new file mode 100644 (file)
index 0000000..21669ac
Binary files /dev/null and b/theme/chameleon/ui/images/grad.gif differ
diff --git a/theme/chameleon/ui/images/hotspot.gif b/theme/chameleon/ui/images/hotspot.gif
new file mode 100644 (file)
index 0000000..870f5c0
Binary files /dev/null and b/theme/chameleon/ui/images/hotspot.gif differ
diff --git a/theme/chameleon/ui/images/image.gif b/theme/chameleon/ui/images/image.gif
new file mode 100644 (file)
index 0000000..f436600
Binary files /dev/null and b/theme/chameleon/ui/images/image.gif differ
diff --git a/theme/chameleon/ui/images/inactive_tab.gif b/theme/chameleon/ui/images/inactive_tab.gif
new file mode 100644 (file)
index 0000000..0c58287
Binary files /dev/null and b/theme/chameleon/ui/images/inactive_tab.gif differ
diff --git a/theme/chameleon/ui/images/none.gif b/theme/chameleon/ui/images/none.gif
new file mode 100644 (file)
index 0000000..8fd24d7
Binary files /dev/null and b/theme/chameleon/ui/images/none.gif differ
diff --git a/theme/chameleon/ui/images/notice.gif b/theme/chameleon/ui/images/notice.gif
new file mode 100644 (file)
index 0000000..a68fe98
Binary files /dev/null and b/theme/chameleon/ui/images/notice.gif differ
diff --git a/theme/chameleon/ui/images/ok.gif b/theme/chameleon/ui/images/ok.gif
new file mode 100644 (file)
index 0000000..2103c5c
Binary files /dev/null and b/theme/chameleon/ui/images/ok.gif differ
diff --git a/theme/chameleon/ui/images/parent.gif b/theme/chameleon/ui/images/parent.gif
new file mode 100644 (file)
index 0000000..3f976b7
Binary files /dev/null and b/theme/chameleon/ui/images/parent.gif differ
diff --git a/theme/chameleon/ui/images/tag.gif b/theme/chameleon/ui/images/tag.gif
new file mode 100644 (file)
index 0000000..3bb11f5
Binary files /dev/null and b/theme/chameleon/ui/images/tag.gif differ
diff --git a/theme/chameleon/ui/images/working.gif b/theme/chameleon/ui/images/working.gif
new file mode 100644 (file)
index 0000000..45353f6
Binary files /dev/null and b/theme/chameleon/ui/images/working.gif differ
diff --git a/theme/chameleon/ui/sarissa.js b/theme/chameleon/ui/sarissa.js
new file mode 100644 (file)
index 0000000..7b2cd26
--- /dev/null
@@ -0,0 +1,648 @@
+\r
+/**\r
+ * ====================================================================\r
+ * About\r
+ * ====================================================================\r
+ * Sarissa is an ECMAScript library acting as a cross-browser wrapper for native XML APIs.\r
+ * The library supports Gecko based browsers like Mozilla and Firefox,\r
+ * Internet Explorer (5.5+ with MSXML3.0+), Konqueror, Safari and a little of Opera\r
+ * @version 0.9.6.1\r
+ * @author: Manos Batsis, mailto: mbatsis at users full stop sourceforge full stop net\r
+ * ====================================================================\r
+ * Licence\r
+ * ====================================================================\r
+ * This program is free software; you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License version 2 or\r
+ * the GNU Lesser General Public License version 2.1 as published by\r
+ * the Free Software Foundation (your choice between the two).\r
+ *\r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ * GNU General Public License or GNU Lesser General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * or GNU Lesser General Public License along with this program; if not,\r
+ * write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.\r
+ * or visit http://www.gnu.org\r
+ *\r
+ */\r
+/**\r
+ * <p>Sarissa is a utility class. Provides "static" methods for DOMDocument and \r
+ * XMLHTTP objects, DOM Node serializatrion to XML strings and other goodies.</p>\r
+ * @constructor\r
+ */\r
+function Sarissa(){};\r
+/** @private */\r
+Sarissa.PARSED_OK = "Document contains no parsing errors";\r
+/**\r
+ * Tells you whether transformNode and transformNodeToObject are available. This functionality\r
+ * is contained in sarissa_ieemu_xslt.js and is deprecated. If you want to control XSLT transformations\r
+ * use the XSLTProcessor\r
+ * @deprecated\r
+ * @type boolean\r
+ */\r
+Sarissa.IS_ENABLED_TRANSFORM_NODE = false;\r
+/**\r
+ * tells you whether XMLHttpRequest (or equivalent) is available\r
+ * @type boolean\r
+ */\r
+Sarissa.IS_ENABLED_XMLHTTP = false;\r
+/**\r
+ * tells you whether selectNodes/selectSingleNode is available\r
+ * @type boolean\r
+ */\r
+Sarissa.IS_ENABLED_SELECT_NODES = false;\r
+var _sarissa_iNsCounter = 0;\r
+var _SARISSA_IEPREFIX4XSLPARAM = "";\r
+var _SARISSA_HAS_DOM_IMPLEMENTATION = document.implementation && true;\r
+var _SARISSA_HAS_DOM_CREATE_DOCUMENT = _SARISSA_HAS_DOM_IMPLEMENTATION && document.implementation.createDocument;\r
+var _SARISSA_HAS_DOM_FEATURE = _SARISSA_HAS_DOM_IMPLEMENTATION && document.implementation.hasFeature;\r
+var _SARISSA_IS_MOZ = _SARISSA_HAS_DOM_CREATE_DOCUMENT && _SARISSA_HAS_DOM_FEATURE;\r
+var _SARISSA_IS_SAFARI = (navigator.userAgent && navigator.vendor && (navigator.userAgent.toLowerCase().indexOf("applewebkit") != -1 || navigator.vendor.indexOf("Apple") != -1));\r
+var _SARISSA_IS_IE = document.all && window.ActiveXObject && navigator.userAgent.toLowerCase().indexOf("msie") > -1  && navigator.userAgent.toLowerCase().indexOf("opera") == -1;\r
+if(!window.Node || !window.Node.ELEMENT_NODE){\r
+    var 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};\r
+};\r
+\r
+// IE initialization\r
+if(_SARISSA_IS_IE){\r
+    // for XSLT parameter names, prefix needed by IE\r
+    _SARISSA_IEPREFIX4XSLPARAM = "xsl:";\r
+    // used to store the most recent ProgID available out of the above\r
+    var _SARISSA_DOM_PROGID = "";\r
+    var _SARISSA_XMLHTTP_PROGID = "";\r
+    /**\r
+     * Called when the Sarissa_xx.js file is parsed, to pick most recent\r
+     * ProgIDs for IE, then gets destroyed.\r
+     * @param idList an array of MSXML PROGIDs from which the most recent will be picked for a given object\r
+     * @param enabledList an array of arrays where each array has two items; the index of the PROGID for which a certain feature is enabled\r
+     */\r
+    pickRecentProgID = function (idList, enabledList){\r
+        // found progID flag\r
+        var bFound = false;\r
+        for(var i=0; i < idList.length && !bFound; i++){\r
+            try{\r
+                var oDoc = new ActiveXObject(idList[i]);\r
+                o2Store = idList[i];\r
+                bFound = true;\r
+                for(var j=0;j<enabledList.length;j++)\r
+                    if(i <= enabledList[j][1])\r
+                        Sarissa["IS_ENABLED_"+enabledList[j][0]] = true;\r
+            }catch (objException){\r
+                // trap; try next progID\r
+            };\r
+        };\r
+        if (!bFound)\r
+            throw "Could not retreive a valid progID of Class: " + idList[idList.length-1]+". (original exception: "+e+")";\r
+        idList = null;\r
+        return o2Store;\r
+    };\r
+    // pick best available MSXML progIDs\r
+    _SARISSA_DOM_PROGID = pickRecentProgID(["Msxml2.DOMDocument.5.0", "Msxml2.DOMDocument.4.0", "Msxml2.DOMDocument.3.0", "MSXML2.DOMDocument", "MSXML.DOMDocument", "Microsoft.XMLDOM"], [["SELECT_NODES", 2],["TRANSFORM_NODE", 2]]);\r
+    _SARISSA_XMLHTTP_PROGID = pickRecentProgID(["Msxml2.XMLHTTP.5.0", "Msxml2.XMLHTTP.4.0", "MSXML2.XMLHTTP.3.0", "MSXML2.XMLHTTP", "Microsoft.XMLHTTP"], [["XMLHTTP", 4]]);\r
+    _SARISSA_THREADEDDOM_PROGID = pickRecentProgID(["Msxml2.FreeThreadedDOMDocument.5.0", "MSXML2.FreeThreadedDOMDocument.4.0", "MSXML2.FreeThreadedDOMDocument.3.0"]);\r
+    _SARISSA_XSLTEMPLATE_PROGID = pickRecentProgID(["Msxml2.XSLTemplate.5.0", "Msxml2.XSLTemplate.4.0", "MSXML2.XSLTemplate.3.0"], [["XSLTPROC", 2]]);\r
+    // we dont need this anymore\r
+    pickRecentProgID = null;\r
+    //============================================\r
+    // Factory methods (IE)\r
+    //============================================\r
+    // see non-IE version\r
+    Sarissa.getDomDocument = function(sUri, sName){\r
+        var oDoc = new ActiveXObject(_SARISSA_DOM_PROGID);\r
+        // if a root tag name was provided, we need to load it in the DOM\r
+        // object\r
+        if (sName){\r
+            // if needed, create an artifical namespace prefix the way Moz\r
+            // does\r
+            if (sUri){\r
+                oDoc.loadXML("<a" + _sarissa_iNsCounter + ":" + sName + " xmlns:a" + _sarissa_iNsCounter + "=\"" + sUri + "\" />");\r
+                // don't use the same prefix again\r
+                ++_sarissa_iNsCounter;\r
+            }\r
+            else\r
+                oDoc.loadXML("<" + sName + "/>");\r
+        };\r
+        return oDoc;\r
+    };\r
+    // see non-IE version   \r
+    Sarissa.getParseErrorText = function (oDoc) {\r
+        var parseErrorText = Sarissa.PARSED_OK;\r
+        if(oDoc.parseError != 0){\r
+            parseErrorText = "XML Parsing Error: " + oDoc.parseError.reason + \r
+                "\nLocation: " + oDoc.parseError.url + \r
+                "\nLine Number " + oDoc.parseError.line + ", Column " + \r
+                oDoc.parseError.linepos + \r
+                ":\n" + oDoc.parseError.srcText +\r
+                "\n";\r
+            for(var i = 0;  i < oDoc.parseError.linepos;i++){\r
+                parseErrorText += "-";\r
+            };\r
+            parseErrorText +=  "^\n";\r
+        };\r
+        return parseErrorText;\r
+    };\r
+    // see non-IE version\r
+    Sarissa.setXpathNamespaces = function(oDoc, sNsSet) {\r
+        oDoc.setProperty("SelectionLanguage", "XPath");\r
+        oDoc.setProperty("SelectionNamespaces", sNsSet);\r
+    };   \r
+    /**\r
+     * Basic implementation of Mozilla's XSLTProcessor for IE. \r
+     * Reuses the same XSLT stylesheet for multiple transforms\r
+     * @constructor\r
+     */\r
+    XSLTProcessor = function(){\r
+        this.template = new ActiveXObject(_SARISSA_XSLTEMPLATE_PROGID);\r
+        this.processor = null;\r
+    };\r
+    /**\r
+     * Impoprts the given XSLT DOM and compiles it to a reusable transform\r
+     * @argument xslDoc The XSLT DOMDocument to import\r
+     */\r
+    XSLTProcessor.prototype.importStylesheet = function(xslDoc){\r
+        // convert stylesheet to free threaded\r
+        var converted = new ActiveXObject(_SARISSA_THREADEDDOM_PROGID); \r
+        converted.loadXML(xslDoc.xml);\r
+        this.template.stylesheet = converted;\r
+        this.processor = this.template.createProcessor();\r
+        // (re)set default param values\r
+        this.paramsSet = new Array();\r
+    };\r
+    /**\r
+     * Transform the given XML DOM\r
+     * @argument sourceDoc The XML DOMDocument to transform\r
+     * @return The transformation result as a DOM Document\r
+     */\r
+    XSLTProcessor.prototype.transformToDocument = function(sourceDoc){\r
+        this.processor.input = sourceDoc;\r
+        var outDoc = new ActiveXObject(_SARISSA_DOM_PROGID);\r
+        this.processor.output = outDoc; \r
+        this.processor.transform();\r
+        return outDoc;\r
+    };\r
+    /**\r
+     * Set global XSLT parameter of the imported stylesheet\r
+     * @argument nsURI The parameter namespace URI\r
+     * @argument name The parameter base name\r
+     * @argument value The new parameter value\r
+     */\r
+    XSLTProcessor.prototype.setParameter = function(nsURI, name, value){\r
+        /* nsURI is optional but cannot be null */\r
+        if(nsURI){\r
+            this.processor.addParameter(name, value, nsURI);\r
+        }else{\r
+            this.processor.addParameter(name, value);\r
+        };\r
+        /* update updated params for getParameter */\r
+        if(!this.paramsSet[""+nsURI]){\r
+            this.paramsSet[""+nsURI] = new Array();\r
+        };\r
+        this.paramsSet[""+nsURI][name] = value;\r
+    };\r
+    /**\r
+     * Gets a parameter if previously set by setParameter. Returns null\r
+     * otherwise\r
+     * @argument name The parameter base name\r
+     * @argument value The new parameter value\r
+     * @return The parameter value if reviously set by setParameter, null otherwise\r
+     */\r
+    XSLTProcessor.prototype.getParameter = function(nsURI, name){\r
+        nsURI = nsURI || "";\r
+        if(nsURI in this.paramsSet && name in this.paramsSet[nsURI]){\r
+            return this.paramsSet[nsURI][name];\r
+        }else{\r
+            return null;\r
+        };\r
+    };\r
+}\r
+else{ /* end IE initialization, try to deal with real browsers now ;-) */\r
+    if(_SARISSA_HAS_DOM_CREATE_DOCUMENT){\r
+        /**\r
+         * <p>Ensures the document was loaded correctly, otherwise sets the\r
+         * parseError to -1 to indicate something went wrong. Internal use</p>\r
+         * @private\r
+         */\r
+        Sarissa.__handleLoad__ = function(oDoc){\r
+            if (!oDoc.documentElement || oDoc.documentElement.tagName == "parsererror")\r
+                oDoc.parseError = -1;\r
+            Sarissa.__setReadyState__(oDoc, 4);\r
+        };\r
+        /**\r
+        * <p>Attached by an event handler to the load event. Internal use.</p>\r
+        * @private\r
+        */\r
+        _sarissa_XMLDocument_onload = function(){\r
+            Sarissa.__handleLoad__(this);\r
+        };\r
+        /**\r
+         * <p>Sets the readyState property of the given DOM Document object.\r
+         * Internal use.</p>\r
+         * @private\r
+         * @argument oDoc the DOM Document object to fire the\r
+         *          readystatechange event\r
+         * @argument iReadyState the number to change the readystate property to\r
+         */\r
+        Sarissa.__setReadyState__ = function(oDoc, iReadyState){\r
+            oDoc.readyState = iReadyState;\r
+            if (oDoc.onreadystatechange != null && typeof oDoc.onreadystatechange == "function")\r
+                oDoc.onreadystatechange();\r
+        };\r
+        Sarissa.getDomDocument = function(sUri, sName){\r
+            var oDoc = document.implementation.createDocument(sUri?sUri:"", sName?sName:"", null);\r
+            oDoc.addEventListener("load", _sarissa_XMLDocument_onload, false);\r
+            return oDoc;\r
+        };\r
+        if(window.XMLDocument){\r
+            /**\r
+            * <p>Emulate IE's onreadystatechange attribute</p>\r
+            */\r
+            XMLDocument.prototype.onreadystatechange = null;\r
+            /**\r
+            * <p>Emulates IE's readyState property, which always gives an integer from 0 to 4:</p>\r
+            * <ul><li>1 == LOADING,</li>\r
+            * <li>2 == LOADED,</li>\r
+            * <li>3 == INTERACTIVE,</li>\r
+            * <li>4 == COMPLETED</li></ul>\r
+            */\r
+            XMLDocument.prototype.readyState = 0;\r
+            /**\r
+            * <p>Emulate IE's parseError attribute</p>\r
+            */\r
+            XMLDocument.prototype.parseError = 0;\r
+\r
+            // NOTE: setting async to false will only work with documents\r
+            // called over HTTP (meaning a server), not the local file system,\r
+            // unless you are using Moz 1.4+.\r
+            // BTW the try>catch block is for 1.4; I haven't found a way to check if\r
+            // the property is implemented without\r
+            // causing an error and I dont want to use user agent stuff for that...\r
+            var _SARISSA_SYNC_NON_IMPLEMENTED = false;// ("async" in XMLDocument.prototype) ? false: true;\r
+            /**\r
+            * <p>Keeps a handle to the original load() method. Internal use and only\r
+            * if Mozilla version is lower than 1.4</p>\r
+            * @private\r
+            */\r
+            XMLDocument.prototype._sarissa_load = XMLDocument.prototype.load;\r
+\r
+            /**\r
+            * <p>Overrides the original load method to provide synchronous loading for\r
+            * Mozilla versions prior to 1.4, using an XMLHttpRequest object (if\r
+            * async is set to false)</p>\r
+            * @returns the DOM Object as it was before the load() call (may be  empty)\r
+            */\r
+            XMLDocument.prototype.load = function(sURI) {\r
+                var oDoc = document.implementation.createDocument("", "", null);\r
+                Sarissa.copyChildNodes(this, oDoc);\r
+                this.parseError = 0;\r
+                Sarissa.__setReadyState__(this, 1);\r
+                try {\r
+                    if(this.async == false && _SARISSA_SYNC_NON_IMPLEMENTED) {\r
+                        var tmp = new XMLHttpRequest();\r
+                        tmp.open("GET", sURI, false);\r
+                        tmp.send(null);\r
+                        Sarissa.__setReadyState__(this, 2);\r
+                        Sarissa.copyChildNodes(tmp.responseXML, this);\r
+                        Sarissa.__setReadyState__(this, 3);\r
+                    }\r
+                    else {\r
+                        this._sarissa_load(sURI);\r
+                    };\r
+                }\r
+                catch (objException) {\r
+                    this.parseError = -1;\r
+                }\r
+                finally {\r
+                    if(this.async == false){\r
+                        Sarissa.__handleLoad__(this);\r
+                    };\r
+                };\r
+                return oDoc;\r
+            };\r
+            \r
+            \r
+        }//if(window.XMLDocument)\r
+        else if(document.implementation && document.implementation.hasFeature && document.implementation.hasFeature('LS', '3.0')){\r
+            Document.prototype.async = true;\r
+            Document.prototype.onreadystatechange = null;\r
+            Document.prototype.parseError = 0;\r
+            Document.prototype.load = function(sURI) {\r
+                var parser = document.implementation.createLSParser(this.async ? document.implementation.MODE_ASYNCHRONOUS : document.implementation.MODE_SYNCHRONOUS, null);\r
+                if(this.async){\r
+                    var self = this;\r
+                    parser.addEventListener("load", \r
+                        function(e) { \r
+                            self.readyState = 4;\r
+                            Sarissa.copyChildNodes(e.newDocument, self.documentElement, false);\r
+                            self.onreadystatechange.call(); \r
+                        }, \r
+                        false); \r
+                };\r
+                try {\r
+                    var oDoc = parser.parseURI(sURI);\r
+                }\r
+                catch(e){\r
+                    this.parseError = -1;\r
+                };\r
+                if(!this.async)\r
+                   Sarissa.copyChildNodes(oDoc, this.documentElement, false);\r
+                return oDoc;\r
+            };\r
+            /**\r
+            * <p>Factory method to obtain a new DOM Document object</p>\r
+            * @argument sUri the namespace of the root node (if any)\r
+            * @argument sUri the local name of the root node (if any)\r
+            * @returns a new DOM Document\r
+            */\r
+            Sarissa.getDomDocument = function(sUri, sName){\r
+                return document.implementation.createDocument(sUri?sUri:"", sName?sName:"", null);\r
+            };        \r
+        };\r
+    };//if(_SARISSA_HAS_DOM_CREATE_DOCUMENT)\r
+};\r
+//==========================================\r
+// Common stuff\r
+//==========================================\r
+if(!window.DOMParser){\r
+    /*\r
+    * DOMParser is a utility class, used to construct DOMDocuments from XML strings\r
+    * @constructor\r
+    */\r
+    DOMParser = function() {\r
+    };\r
+    if(_SARISSA_IS_SAFARI){\r
+        /** \r
+        * Construct a new DOM Document from the given XMLstring\r
+        * @param sXml the given XML string\r
+        * @param contentType the content type of the document the given string represents (one of text/xml, application/xml, application/xhtml+xml). \r
+        * @return a new DOM Document from the given XML string\r
+        */\r
+        DOMParser.prototype.parseFromString = function(sXml, contentType){\r
+            if(contentType.toLowerCase() != "application/xml"){\r
+                throw "Cannot handle content type: \"" + contentType + "\"";\r
+            };\r
+            var xmlhttp = new XMLHttpRequest();\r
+            xmlhttp.open("GET", "data:text/xml;charset=utf-8," + encodeURIComponent(str), false);\r
+            xmlhttp.send(null);\r
+            return xmlhttp.responseXML;\r
+        };\r
+    }else if(Sarissa.getDomDocument && Sarissa.getDomDocument() && "loadXML" in Sarissa.getDomDocument()){\r
+        DOMParser.prototype.parseFromString = function(sXml, contentType){\r
+            var doc = Sarissa.getDomDocument();\r
+            doc.loadXML(sXml);\r
+            return doc;\r
+        };\r
+    };\r
+};\r
+\r
+if(window.XMLHttpRequest){\r
+    Sarissa.IS_ENABLED_XMLHTTP = true;\r
+}\r
+else if(_SARISSA_IS_IE){\r
+    /**\r
+     * Emulate XMLHttpRequest\r
+     * @constructor\r
+     */\r
+    XMLHttpRequest = function() {\r
+        return new ActiveXObject(_SARISSA_XMLHTTP_PROGID);\r
+    };\r
+    Sarissa.IS_ENABLED_XMLHTTP = true;\r
+};\r
+\r
+if(!window.document.importNode && _SARISSA_IS_IE){\r
+    try{\r
+        /**\r
+        * Implements importNode for the current window document in IE using innerHTML.\r
+        * Testing showed that DOM was multiple times slower than innerHTML for this,\r
+        * sorry folks. If you encounter trouble (who knows what IE does behind innerHTML)\r
+        * please gimme a call.\r
+        * @param oNode the Node to import\r
+        * @param bChildren whether to include the children of oNode\r
+        * @returns the imported node for further use\r
+        */\r
+        window.document.importNode = function(oNode, bChildren){\r
+            var importNode = document.createElement("div");\r
+            if(bChildren)\r
+                importNode.innerHTML = Sarissa.serialize(oNode);\r
+            else\r
+                importNode.innerHTML = Sarissa.serialize(oNode.cloneNode(false));\r
+            return importNode.firstChild;\r
+        };\r
+        }catch(e){};\r
+};\r
+if(!Sarissa.getParseErrorText){\r
+    /**\r
+     * <p>Returns a human readable description of the parsing error. Usefull\r
+     * for debugging. Tip: append the returned error string in a &lt;pre&gt;\r
+     * element if you want to render it.</p>\r
+     * <p>Many thanks to Christian Stocker for the initial patch.</p>\r
+     * @argument oDoc The target DOM document\r
+     * @returns The parsing error description of the target Document in\r
+     *          human readable form (preformated text)\r
+     */\r
+    Sarissa.getParseErrorText = function (oDoc){\r
+        var parseErrorText = Sarissa.PARSED_OK;\r
+        if(oDoc && oDoc.parseError && oDoc.parseError != 0){\r
+            /*moz*/\r
+            if(oDoc.documentElement.tagName == "parsererror"){\r
+                parseErrorText = oDoc.documentElement.firstChild.data;\r
+                parseErrorText += "\n" +  oDoc.documentElement.firstChild.nextSibling.firstChild.data;\r
+            }/*konq*/\r
+            else{\r
+                parseErrorText = Sarissa.getText(oDoc.documentElement);/*.getElementsByTagName("h1")[0], false) + "\n";\r
+                parseErrorText += Sarissa.getText(oDoc.documentElement.getElementsByTagName("body")[0], false) + "\n";\r
+                parseErrorText += Sarissa.getText(oDoc.documentElement.getElementsByTagName("pre")[0], false);*/\r
+            };\r
+        };\r
+        return parseErrorText;\r
+    };\r
+};\r
+Sarissa.getText = function(oNode, deep){\r
+    var s = "";\r
+    var nodes = oNode.childNodes;\r
+    for(var i=0; i < nodes.length; i++){\r
+        var node = nodes[i];\r
+        var nodeType = node.nodeType;\r
+        if(nodeType == Node.TEXT_NODE || nodeType == Node.CDATA_SECTION_NODE){\r
+            s += node.data;\r
+        }else if(deep == true\r
+                    && (nodeType == Node.ELEMENT_NODE\r
+                        || nodeType == Node.DOCUMENT_NODE\r
+                        || nodeType == Node.DOCUMENT_FRAGMENT_NODE)){\r
+            s += Sarissa.getText(node, true);\r
+        };\r
+    };\r
+    return s;\r
+};\r
+if(window.XMLSerializer){\r
+    /**\r
+     * <p>Factory method to obtain the serialization of a DOM Node</p>\r
+     * @returns the serialized Node as an XML string\r
+     */\r
+    Sarissa.serialize = function(oDoc){\r
+        var s = null;\r
+        if(oDoc){\r
+            s = oDoc.innerHTML?oDoc.innerHTML:(new XMLSerializer()).serializeToString(oDoc);\r
+        };\r
+        return s;\r
+    };\r
+}else{\r
+    if(Sarissa.getDomDocument && (Sarissa.getDomDocument("","foo", null)).xml){\r
+        // see non-IE version\r
+        Sarissa.serialize = function(oDoc) {\r
+            var s = null;\r
+            if(oDoc){\r
+                s = oDoc.innerHTML?oDoc.innerHTML:oDoc.xml;\r
+            };\r
+            return s;\r
+        };\r
+        /**\r
+         * Utility class to serialize DOM Node objects to XML strings\r
+         * @constructor\r
+         */\r
+        XMLSerializer = function(){};\r
+        /**\r
+         * Serialize the given DOM Node to an XML string\r
+         * @param oNode the DOM Node to serialize\r
+         */\r
+        XMLSerializer.prototype.serializeToString = function(oNode) {\r
+            return oNode.xml;\r
+        };\r
+    };\r
+};\r
+\r
+/**\r
+ * strips tags from a markup string\r
+ */\r
+Sarissa.stripTags = function (s) {\r
+    return s.replace(/<[^>]+>/g,"");\r
+};\r
+/**\r
+ * <p>Deletes all child nodes of the given node</p>\r
+ * @argument oNode the Node to empty\r
+ */\r
+Sarissa.clearChildNodes = function(oNode) {\r
+    // need to check for firstChild due to opera 8 bug with hasChildNodes\r
+    while(oNode.firstChild){\r
+        oNode.removeChild(oNode.firstChild);\r
+    };\r
+};\r
+/**\r
+ * <p> Copies the childNodes of nodeFrom to nodeTo</p>\r
+ * <p> <b>Note:</b> The second object's original content is deleted before \r
+ * the copy operation, unless you supply a true third parameter</p>\r
+ * @argument nodeFrom the Node to copy the childNodes from\r
+ * @argument nodeTo the Node to copy the childNodes to\r
+ * @argument bPreserveExisting whether to preserve the original content of nodeTo, default is false\r
+ */\r
+Sarissa.copyChildNodes = function(nodeFrom, nodeTo, bPreserveExisting) {\r
+    if((!nodeFrom) || (!nodeTo)){\r
+        throw "Both source and destination nodes must be provided";\r
+    };\r
+    if(!bPreserveExisting){\r
+        Sarissa.clearChildNodes(nodeTo);\r
+    };\r
+    var ownerDoc = nodeTo.nodeType == Node.DOCUMENT_NODE ? nodeTo : nodeTo.ownerDocument;\r
+    var nodes = nodeFrom.childNodes;\r
+    if(ownerDoc.importNode && (!_SARISSA_IS_IE)) {\r
+        for(var i=0;i < nodes.length;i++) {\r
+            nodeTo.appendChild(ownerDoc.importNode(nodes[i], true));\r
+        };\r
+    }\r
+    else{\r
+        for(var i=0;i < nodes.length;i++) {\r
+            nodeTo.appendChild(nodes[i].cloneNode(true));\r
+        };\r
+    };\r
+};\r
+\r
+/**\r
+ * <p> Moves the childNodes of nodeFrom to nodeTo</p>\r
+ * <p> <b>Note:</b> The second object's original content is deleted before \r
+ * the move operation, unless you supply a true third parameter</p>\r
+ * @argument nodeFrom the Node to copy the childNodes from\r
+ * @argument nodeTo the Node to copy the childNodes to\r
+ * @argument bPreserveExisting whether to preserve the original content of nodeTo, default is\r
+ */ \r
+Sarissa.moveChildNodes = function(nodeFrom, nodeTo, bPreserveExisting) {\r
+    if((!nodeFrom) || (!nodeTo)){\r
+        throw "Both source and destination nodes must be provided";\r
+    };\r
+    if(!bPreserveExisting){\r
+        Sarissa.clearChildNodes(nodeTo);\r
+    };\r
+    var nodes = nodeFrom.childNodes;\r
+    // if within the same doc, just move, else copy and delete\r
+    if(nodeFrom.ownerDocument == nodeTo.ownerDocument){\r
+        while(nodeFrom.firstChild){\r
+            nodeTo.appendChild(nodeFrom.firstChild);\r
+        };\r
+    }else{\r
+        var ownerDoc = nodeTo.nodeType == Node.DOCUMENT_NODE ? nodeTo : nodeTo.ownerDocument;\r
+        if(ownerDoc.importNode && (!_SARISSA_IS_IE)) {\r
+           for(var i=0;i < nodes.length;i++) {\r
+               nodeTo.appendChild(ownerDoc.importNode(nodes[i], true));\r
+           };\r
+        }else{\r
+           for(var i=0;i < nodes.length;i++) {\r
+               nodeTo.appendChild(nodes[i].cloneNode(true));\r
+           };\r
+        };\r
+        Sarissa.clearChildNodes(nodeFrom);\r
+    };\r
+};\r
+\r
+/** \r
+ * <p>Serialize any object to an XML string. All properties are serialized using the property name\r
+ * as the XML element name. Array elements are rendered as <code>array-item</code> elements, \r
+ * using their index/key as the value of the <code>key</code> attribute.</p>\r
+ * @argument anyObject the object to serialize\r
+ * @argument objectName a name for that object\r
+ * @return the XML serializationj of the given object as a string\r
+ */\r
+Sarissa.xmlize = function(anyObject, objectName, indentSpace){\r
+    indentSpace = indentSpace?indentSpace:'';\r
+    var s = indentSpace  + '<' + objectName + '>';\r
+    var isLeaf = false;\r
+    if(!(anyObject instanceof Object) || anyObject instanceof Number || anyObject instanceof String \r
+        || anyObject instanceof Boolean || anyObject instanceof Date){\r
+        s += Sarissa.escape(""+anyObject);\r
+        isLeaf = true;\r
+    }else{\r
+        s += "\n";\r
+        var itemKey = '';\r
+        var isArrayItem = anyObject instanceof Array;\r
+        for(var name in anyObject){\r
+            s += Sarissa.xmlize(anyObject[name], (isArrayItem?"array-item key=\""+name+"\"":name), indentSpace + "   ");\r
+        };\r
+        s += indentSpace;\r
+    };\r
+    return s += (objectName.indexOf(' ')!=-1?"</array-item>\n":"</" + objectName + ">\n");\r
+};\r
+\r
+/** \r
+ * Escape the given string chacters that correspond to the five predefined XML entities\r
+ * @param sXml the string to escape\r
+ */\r
+Sarissa.escape = function(sXml){\r
+    return sXml.replace(/&/g, "&amp;")\r
+        .replace(/</g, "&lt;")\r
+        .replace(/>/g, "&gt;")\r
+        .replace(/"/g, "&quot;")\r
+        .replace(/'/g, "&apos;");\r
+};\r
+\r
+/** \r
+ * Unescape the given string. This turns the occurences of the predefined XML \r
+ * entities to become the characters they represent correspond to the five predefined XML entities\r
+ * @param sXml the string to unescape\r
+ */\r
+Sarissa.unescape = function(sXml){\r
+    return sXml.replace(/&apos;/g,"'")\r
+        .replace(/&quot;/g,"\"")\r
+        .replace(/&gt;/g,">")\r
+        .replace(/&lt;/g,"<")\r
+        .replace(/&amp;/g,"&");\r
+};\r
+// 
\ No newline at end of file
diff --git a/theme/chameleon/user_styles.css b/theme/chameleon/user_styles.css
new file mode 100644 (file)
index 0000000..94b95c0
--- /dev/null
@@ -0,0 +1,523 @@
+div.headermain {
+  color: #009900;
+  font-weight: bold;
+  font-size: 3em;
+  font-family: georgia, "trebuchet ms", times, serif;
+}
+td.courseboxcontent {
+  font-family: "trebuchet ms", verdana, sans-serif;
+  font-weight: normal;
+  font-style: italic;
+  text-decoration: underline;
+  background-color: #99ff99;
+  background-image: none;
+  border-top-width: 1px;
+  border-right-width: 1px;
+  border-bottom-width: 1px;
+  border-left-width: 1px;
+  border-top-style: groove;
+  border-right-style: groove;
+  border-bottom-style: groove;
+  border-left-style: groove;
+  border-top-color: red;
+  border-right-color: red;
+  border-bottom-color: red;
+  border-left-color: red;
+  border-width: 1px;
+  border-style: groove;
+  border-color: red;
+}
+body {
+  font-family: georgia, "trebuchet ms", times, serif;
+  font-size: 100%;