[Jifty-commit] r440 - in jifty/trunk: share/web/static/js

jifty-commit at lists.jifty.org jifty-commit at lists.jifty.org
Sun Jan 1 20:55:51 EST 2006


Author: glasser
Date: Sun Jan  1 20:55:48 2006
New Revision: 440

Modified:
   jifty/trunk/   (props changed)
   jifty/trunk/share/web/static/js/rico.js

Log:
 r52919 at david-glassers-powerbook-g4-15:  glasser | 2006-01-01 16:45:36 -0500
 Upgrade Rico lib to 1.1.0.


Modified: jifty/trunk/share/web/static/js/rico.js
==============================================================================
--- jifty/trunk/share/web/static/js/rico.js	(original)
+++ jifty/trunk/share/web/static/js/rico.js	Sun Jan  1 20:55:48 2006
@@ -1,2666 +1,2933 @@
-/**
-  *
-  *  Copyright 2005 Sabre Airline Solutions
-  *
-  *  Licensed under the Apache License, Version 2.0 (the "License"); you may not use this
-  *  file except in compliance with the License. You may obtain a copy of the License at
-  *
-  *         http://www.apache.org/licenses/LICENSE-2.0
-  *
-  *  Unless required by applicable law or agreed to in writing, software distributed under the
-  *  License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
-  *  either express or implied. See the License for the specific language governing permissions
-  *  and limitations under the License.
-  **/
-
-
-//-------------------- rico.js
-var Rico = {
-  Version: '1.1-beta2'
-}
-
-Rico.ArrayExtensions = new Array();
-
-if (Object.prototype.extend) {
-   // in prototype.js...
-   Rico.ArrayExtensions[ Rico.ArrayExtensions.length ] = Object.prototype.extend;
-}
-
-if (Array.prototype.push) {
-   // in prototype.js...
-   Rico.ArrayExtensions[ Rico.ArrayExtensions.length ] = Array.prototype.push;
-}
-
-if (!Array.prototype.remove) {
-   Array.prototype.remove = function(dx) {
-      if( isNaN(dx) || dx > this.length )
-         return false;
-      for( var i=0,n=0; i<this.length; i++ )
-         if( i != dx )
-            this[n++]=this[i];
-      this.length-=1;
-   };
-  Rico.ArrayExtensions[ Rico.ArrayExtensions.length ] = Array.prototype.remove;
-}
-
-if (!Array.prototype.removeItem) {
-   Array.prototype.removeItem = function(item) {
-      for ( var i = 0 ; i < this.length ; i++ )
-         if ( this[i] == item ) {
-            this.remove(i);
-            break;
-         }
-   };
-  Rico.ArrayExtensions[ Rico.ArrayExtensions.length ] = Array.prototype.removeItem;
-}
-
-if (!Array.prototype.indices) {
-   Array.prototype.indices = function() {
-      var indexArray = new Array();
-      for ( index in this ) {
-         var ignoreThis = false;
-         for ( var i = 0 ; i < Rico.ArrayExtensions.length ; i++ ) {
-            if ( this[index] == Rico.ArrayExtensions[i] ) {
-               ignoreThis = true;
-               break;
-            }
-         }
-         if ( !ignoreThis )
-            indexArray[ indexArray.length ] = index;
-      }
-      return indexArray;
-   }
-  Rico.ArrayExtensions[ Rico.ArrayExtensions.length ] = Array.prototype.indices;
-}
-
-// Create the loadXML method and xml getter for Mozilla
-if ( window.DOMParser &&
-	  window.XMLSerializer &&
-	  window.Node && Node.prototype && Node.prototype.__defineGetter__ ) {
-
-   if (!Document.prototype.loadXML) {
-      Document.prototype.loadXML = function (s) {
-         var doc2 = (new DOMParser()).parseFromString(s, "text/xml");
-         while (this.hasChildNodes())
-            this.removeChild(this.lastChild);
-
-         for (var i = 0; i < doc2.childNodes.length; i++) {
-            this.appendChild(this.importNode(doc2.childNodes[i], true));
-         }
-      };
-	}
-
-	Document.prototype.__defineGetter__( "xml",
-	   function () {
-		   return (new XMLSerializer()).serializeToString(this);
-	   }
-	 );
-}
-
-document.getElementsByTagAndClassName = function(tagName, className) {
-  if ( tagName == null )
-     tagName = '*';
-
-  var children = document.getElementsByTagName(tagName) || document.all;
-  var elements = new Array();
-
-  if ( className == null )
-    return children;
-
-  for (var i = 0; i < children.length; i++) {
-    var child = children[i];
-    var classNames = child.className.split(' ');
-    for (var j = 0; j < classNames.length; j++) {
-      if (classNames[j] == className) {
-        elements.push(child);
-        break;
-      }
-    }
-  }
-
-  return elements;
-}
-
-
-//-------------------- ricoAccordion.js
-
-Rico.Accordion = Class.create();
-
-Rico.Accordion.prototype = {
-
-   initialize: function(container, options) {
-      this.container            = $(container);
-      this.lastExpandedTab      = null;
-      this.accordionTabs        = new Array();
-      this.setOptions(options);
-      this._attachBehaviors();
-
-      this.container.style.borderBottom = '1px solid ' + this.options.borderColor;
-
-      // set the initial visual state...
-      for ( var i=1 ; i < this.accordionTabs.length ; i++ )
-      {
-         this.accordionTabs[i].collapse();
-         this.accordionTabs[i].content.style.display = 'none';
-      }
-      this.lastExpandedTab = this.accordionTabs[0];
-      this.lastExpandedTab.content.style.height = this.options.panelHeight + "px";
-      this.lastExpandedTab.showExpanded();
-      this.lastExpandedTab.titleBar.style.fontWeight = this.options.expandedFontWeight;
-   },
-
-   setOptions: function(options) {
-      this.options = {
-         expandedBg          : '#63699c',
-         hoverBg             : '#63699c',
-         collapsedBg         : '#6b79a5',
-         expandedTextColor   : '#ffffff',
-         expandedFontWeight  : 'bold',
-         hoverTextColor      : '#ffffff',
-         collapsedTextColor  : '#ced7ef',
-         collapsedFontWeight : 'normal',
-         hoverTextColor      : '#ffffff',
-         borderColor         : '#1f669b',
-         panelHeight         : 200,
-         onHideTab           : null,
-         onShowTab           : null
-      }.extend(options || {});
-   },
-
-   showTabByIndex: function( anIndex, animate ) {
-      var doAnimate = arguments.length == 1 ? true : animate;
-      this.showTab( this.accordionTabs[anIndex], doAnimate );
-   },
-
-   showTab: function( accordionTab, animate ) {
-
-      var doAnimate = arguments.length == 1 ? true : animate;
-
-      if ( this.options.onHideTab )
-         this.options.onHideTab(this.lastExpandedTab);
-
-      this.lastExpandedTab.showCollapsed(); 
-      var accordion = this;
-      var lastExpandedTab = this.lastExpandedTab;
-
-      this.lastExpandedTab.content.style.height = (this.options.panelHeight - 1) + 'px';
-      accordionTab.content.style.display = '';
-
-      accordionTab.titleBar.style.fontWeight = this.options.expandedFontWeight;
-
-      if ( doAnimate ) {
-         new Effect.AccordionSize( this.lastExpandedTab.content,
-                                   accordionTab.content,
-                                   1,
-                                   this.options.panelHeight,
-                                   100, 10,
-                                   { complete: function() {accordion.showTabDone(lastExpandedTab)} } );
-         this.lastExpandedTab = accordionTab;
-      }
-      else {
-         this.lastExpandedTab.content.style.height = "1px";
-         accordionTab.content.style.height = this.options.panelHeight + "px";
-         this.lastExpandedTab = accordionTab;
-         this.showTabDone(lastExpandedTab);
-      }
-   },
-
-   showTabDone: function(collapsedTab) {
-      collapsedTab.content.style.display = 'none';
-      this.lastExpandedTab.showExpanded();
-      if ( this.options.onShowTab )
-         this.options.onShowTab(this.lastExpandedTab);
-   },
-
-   _attachBehaviors: function() {
-      var panels = this._getDirectChildrenByTag(this.container, 'DIV');
-      for ( var i = 0 ; i < panels.length ; i++ ) {
-
-         var tabChildren = this._getDirectChildrenByTag(panels[i],'DIV');
-         if ( tabChildren.length != 2 )
-            continue; // unexpected
-
-         var tabTitleBar   = tabChildren[0];
-         var tabContentBox = tabChildren[1];
-         this.accordionTabs.push( new Rico.Accordion.Tab(this,tabTitleBar,tabContentBox) );
-      }
-   },
-
-   _getDirectChildrenByTag: function(e, tagName) {
-      var kids = new Array();
-      var allKids = e.childNodes;
-      for( var i = 0 ; i < allKids.length ; i++ )
-         if ( allKids[i] && allKids[i].tagName && allKids[i].tagName == tagName )
-            kids.push(allKids[i]);
-      return kids;
-   }
-
-};
-
-Rico.Accordion.Tab = Class.create();
-
-Rico.Accordion.Tab.prototype = {
-
-   initialize: function(accordion, titleBar, content) {
-      this.accordion = accordion;
-      this.titleBar  = titleBar;
-      this.content   = content;
-      this._attachBehaviors();
-   },
-
-   collapse: function() {
-      this.showCollapsed();
-      this.content.style.height = "1px";
-   },
-
-   showCollapsed: function() {
-      this.expanded = false;
-      this.titleBar.style.backgroundColor = this.accordion.options.collapsedBg;
-      this.titleBar.style.color           = this.accordion.options.collapsedTextColor;
-      this.titleBar.style.fontWeight      = this.accordion.options.collapsedFontWeight;
-      this.content.style.overflow = "hidden";
-   },
-
-   showExpanded: function() {
-      this.expanded = true;
-      this.titleBar.style.backgroundColor = this.accordion.options.expandedBg;
-      this.titleBar.style.color           = this.accordion.options.expandedTextColor;
-      this.content.style.overflow         = "visible";
-   },
-
-   titleBarClicked: function(e) {
-      if ( this.accordion.lastExpandedTab == this )
-         return;
-      this.accordion.showTab(this);
-   },
-
-   hover: function(e) {
-		this.titleBar.style.backgroundColor = this.accordion.options.hoverBg;
-		this.titleBar.style.color           = this.accordion.options.hoverTextColor;
-   },
-
-   unhover: function(e) {
-      if ( this.expanded ) {
-         this.titleBar.style.backgroundColor = this.accordion.options.expandedBg;
-         this.titleBar.style.color           = this.accordion.options.expandedTextColor;
-      }
-      else {
-         this.titleBar.style.backgroundColor = this.accordion.options.collapsedBg;
-         this.titleBar.style.color           = this.accordion.options.collapsedTextColor;
-      }
-   },
-
-   _attachBehaviors: function() {
-      this.content.style.border = "1px solid " + this.accordion.options.borderColor;
-      this.content.style.borderTopWidth    = "0px";
-      this.content.style.borderBottomWidth = "0px";
-      this.content.style.margin            = "0px";
-
-      this.titleBar.onclick     = this.titleBarClicked.bindAsEventListener(this);
-      this.titleBar.onmouseover = this.hover.bindAsEventListener(this);
-      this.titleBar.onmouseout  = this.unhover.bindAsEventListener(this);
-   }
-
-};
-
-
-//-------------------- ricoAjaxEngine.js
-
-Rico.AjaxEngine = Class.create();
-
-Rico.AjaxEngine.prototype = {
-
-   initialize: function() {
-      this.ajaxElements = new Array();
-      this.ajaxObjects  = new Array();
-      this.requestURLS  = new Array();
-   },
-
-   registerAjaxElement: function( anId, anElement ) {
-      if ( arguments.length == 1 )
-         anElement = $(anId);
-      this.ajaxElements[anId] = anElement;
-   },
-
-   registerAjaxObject: function( anId, anObject ) {
-      this.ajaxObjects[anId] = anObject;
-   },
-
-   registerRequest: function (requestLogicalName, requestURL) {
-      this.requestURLS[requestLogicalName] = requestURL;
-   },
-
-   sendRequest: function(requestName) {
-      var requestURL = this.requestURLS[requestName];
-      if ( requestURL == null )
-         return;
-
-      var queryString = "";
-      if ( arguments.length > 1 )
-         queryString = this._createQueryString(arguments, 1);
-
-      new Ajax.Request(requestURL, this._requestOptions(queryString));
-   },
-
-   sendRequestWithData: function(requestName, xmlDocument) {
-      var requestURL = this.requestURLS[requestName];
-      if ( requestURL == null )
-         return;
-
-      var queryString = "";
-      if ( arguments.length > 2 )
-         queryString = this._createQueryString(arguments, 2);
-
-      new Ajax.Request(requestURL + "?" + queryString, this._requestOptions(null,xmlDocument));
-   },
-
-   sendRequestAndUpdate: function(requestName,container,options) {
-      var requestURL = this.requestURLS[requestName];
-      if ( requestURL == null )
-         return;
-
-      var queryString = "";
-      if ( arguments.length > 3 )
-         queryString = this._createQueryString(arguments, 3);
-
-      var updaterOptions = this._requestOptions(queryString);
-      updaterOptions.onComplete = null;
-      updaterOptions.extend(options);
-
-      new Ajax.Updater(container, requestURL, updaterOptions);
-   },
-
-   sendRequestWithDataAndUpdate: function(requestName,xmlDocument,container,options) {
-      var requestURL = this.requestURLS[requestName];
-      if ( requestURL == null )
-         return;
-
-      var queryString = "";
-      if ( arguments.length > 4 )
-         queryString = this._createQueryString(arguments, 4);
-
-
-      var updaterOptions = this._requestOptions(queryString,xmlDocument);
-      updaterOptions.onComplete = null;
-      updaterOptions.extend(options);
-
-      new Ajax.Updater(container, requestURL + "?" + queryString, updaterOptions);
-   },
-
-   // Private -- not part of intended engine API --------------------------------------------------------------------
-
-   _requestOptions: function(queryString,xmlDoc) {
-      var self = this;
-
-      var requestHeaders = ['X-Rico-Version', Rico.Version ];
-      var sendMethod = "post"
-      if ( arguments[1] )
-         requestHeaders.push( 'Content-type', 'text/xml' );
-      else
-         sendMethod = "get";
-
-      return { requestHeaders: requestHeaders,
-               parameters:     queryString,
-               postBody:       arguments[1] ? xmlDoc : null,
-               method:         sendMethod,
-               onComplete:     self._onRequestComplete.bind(self) };
-   },
-
-   _createQueryString: function( theArgs, offset ) {
-      var queryString = ""
-      for ( var i = offset ; i < theArgs.length ; i++ ) {
-          if ( i != offset )
-            queryString += "&";
-
-          var anArg = theArgs[i];
-
-          if ( anArg.name != undefined && anArg.value != undefined ) {
-            queryString += anArg.name +  "=" + escape(anArg.value);
-          }
-          else {
-             var ePos  = anArg.indexOf('=');
-             var argName  = anArg.substring( 0, ePos );
-             var argValue = anArg.substring( ePos + 1 );
-             queryString += argName + "=" + escape(argValue);
-          }
-      }
-
-      return queryString;
-   },
-
-   _onRequestComplete : function(request) {
-
-      //!!TODO: error handling infrastructure?? 
-      if (request.status != 200)
-        return;
-
-      var response = request.responseXML.getElementsByTagName("ajax-response");
-      if (response == null || response.length != 1)
-         return;
-      this._processAjaxResponse( response[0].childNodes );
-   },
-
-   _processAjaxResponse: function( xmlResponseElements ) {
-      for ( var i = 0 ; i < xmlResponseElements.length ; i++ ) {
-         var responseElement = xmlResponseElements[i];
-
-         // only process nodes of type element.....
-         if ( responseElement.nodeType != 1 )
-            continue;
-
-         var responseType = responseElement.getAttribute("type");
-         var responseId   = responseElement.getAttribute("id");
-
-         if ( responseType == "object" )
-            this._processAjaxObjectUpdate( this.ajaxObjects[ responseId ], responseElement );
-         else if ( responseType == "element" )
-            this._processAjaxElementUpdate( this.ajaxElements[ responseId ], responseElement );
-         else
-            alert('unrecognized AjaxResponse type : ' + responseType );
-      }
-   },
-
-   _processAjaxObjectUpdate: function( ajaxObject, responseElement ) {
-      ajaxObject.ajaxUpdate( responseElement );
-   },
-
-   _processAjaxElementUpdate: function( ajaxElement, responseElement ) {
-      ajaxElement.innerHTML = RicoUtil.getContentAsString(responseElement);
-   }
-
-}
-
-var ajaxEngine = new Rico.AjaxEngine();
-
-
-//-------------------- ricoColor.js
-Rico.Color = Class.create();
-
-Rico.Color.prototype = {
-
-   initialize: function(red, green, blue) {
-      this.rgb = { r: red, g : green, b : blue };
-   },
-
-   setRed: function(r) {
-      this.rgb.r = r;
-   },
-
-   setGreen: function(g) {
-      this.rgb.g = g;
-   },
-
-   setBlue: function(b) {
-      this.rgb.b = b;
-   },
-
-   setHue: function(h) {
-
-      // get an HSB model, and set the new hue...
-      var hsb = this.asHSB();
-      hsb.h = h;
-
-      // convert back to RGB...
-      this.rgb = Rico.Color.HSBtoRGB(hsb.h, hsb.s, hsb.b);
-   },
-
-   setSaturation: function(s) {
-      // get an HSB model, and set the new hue...
-      var hsb = this.asHSB();
-      hsb.s = s;
-
-      // convert back to RGB and set values...
-      this.rgb = Rico.Color.HSBtoRGB(hsb.h, hsb.s, hsb.b);
-   },
-
-   setBrightness: function(b) {
-      // get an HSB model, and set the new hue...
-      var hsb = this.asHSB();
-      hsb.b = b;
-
-      // convert back to RGB and set values...
-      this.rgb = Rico.Color.HSBtoRGB( hsb.h, hsb.s, hsb.b );
-   },
-
-   darken: function(percent) {
-      var hsb  = this.asHSB();
-      this.rgb = Rico.Color.HSBtoRGB(hsb.h, hsb.s, Math.max(hsb.b - percent,0));
-   },
-
-   brighten: function(percent) {
-      var hsb  = this.asHSB();
-      this.rgb = Rico.Color.HSBtoRGB(hsb.h, hsb.s, Math.min(hsb.b + percent,1));
-   },
-
-   blend: function(other) {
-      this.rgb.r = Math.floor((this.rgb.r + other.rgb.r)/2);
-      this.rgb.g = Math.floor((this.rgb.g + other.rgb.g)/2);
-      this.rgb.b = Math.floor((this.rgb.b + other.rgb.b)/2);
-   },
-
-   isBright: function() {
-      var hsb = this.asHSB();
-      return this.asHSB().b > 0.5;
-   },
-
-   isDark: function() {
-      return ! this.isBright();
-   },
-
-   asRGB: function() {
-      return "rgb(" + this.rgb.r + "," + this.rgb.g + "," + this.rgb.b + ")";
-   },
-
-   asHex: function() {
-      return "#" + this.rgb.r.toColorPart() + this.rgb.g.toColorPart() + this.rgb.b.toColorPart();
-   },
-
-   asHSB: function() {
-      return Rico.Color.RGBtoHSB(this.rgb.r, this.rgb.g, this.rgb.b);
-   },
-
-   toString: function() {
-      return this.asHex();
-   }
-
-};
-
-Rico.Color.createFromHex = function(hexCode) {
-
-   if ( hexCode.indexOf('#') == 0 )
-      hexCode = hexCode.substring(1);
-   var red   = hexCode.substring(0,2);
-   var green = hexCode.substring(2,4);
-   var blue  = hexCode.substring(4,6);
-   return new Rico.Color( parseInt(red,16), parseInt(green,16), parseInt(blue,16) );
-}
-
-/**
- * Factory method for creating a color from the background of
- * an HTML element.
- */
-Rico.Color.createColorFromBackground = function(elem) {
-
-   var actualColor = RicoUtil.getElementsComputedStyle($(elem), "backgroundColor", "background-color");
-
-   if ( actualColor == "transparent" && elem.parent )
-      return Rico.Color.createColorFromBackground(elem.parent);
-
-   if ( actualColor == null )
-      return new Rico.Color(255,255,255);
-
-   if ( actualColor.indexOf("rgb(") == 0 ) {
-      var colors = actualColor.substring(4, actualColor.length - 1 );
-      var colorArray = colors.split(",");
-      return new Rico.Color( parseInt( colorArray[0] ),
-                            parseInt( colorArray[1] ),
-                            parseInt( colorArray[2] )  );
-
-   }
-   else if ( actualColor.indexOf("#") == 0 ) {
-      var redPart   = parseInt(actualColor.substring(1,3), 16);
-      var greenPart = parseInt(actualColor.substring(3,5), 16);
-      var bluePart  = parseInt(actualColor.substring(5), 16);
-      return new Rico.Color( redPart, greenPart, bluePart );
-   }
-   else
-      return new Rico.Color(255,255,255);
-}
-
-Rico.Color.HSBtoRGB = function(hue, saturation, brightness) {
-
-   var red   = 0;
-	var green = 0;
-	var blue  = 0;
-
-   if (saturation == 0) {
-      red = parseInt(brightness * 255.0 + 0.5);
-	   green = red;
-	   blue = red;
-	}
-	else {
-      var h = (hue - Math.floor(hue)) * 6.0;
-      var f = h - Math.floor(h);
-      var p = brightness * (1.0 - saturation);
-      var q = brightness * (1.0 - saturation * f);
-      var t = brightness * (1.0 - (saturation * (1.0 - f)));
-
-      switch (parseInt(h)) {
-         case 0:
-            red   = (brightness * 255.0 + 0.5);
-            green = (t * 255.0 + 0.5);
-            blue  = (p * 255.0 + 0.5);
-            break;
-         case 1:
-            red   = (q * 255.0 + 0.5);
-            green = (brightness * 255.0 + 0.5);
-            blue  = (p * 255.0 + 0.5);
-            break;
-         case 2:
-            red   = (p * 255.0 + 0.5);
-            green = (brightness * 255.0 + 0.5);
-            blue  = (t * 255.0 + 0.5);
-            break;
-         case 3:
-            red   = (p * 255.0 + 0.5);
-            green = (q * 255.0 + 0.5);
-            blue  = (brightness * 255.0 + 0.5);
-            break;
-         case 4:
-            red   = (t * 255.0 + 0.5);
-            green = (p * 255.0 + 0.5);
-            blue  = (brightness * 255.0 + 0.5);
-            break;
-          case 5:
-            red   = (brightness * 255.0 + 0.5);
-            green = (p * 255.0 + 0.5);
-            blue  = (q * 255.0 + 0.5);
-            break;
-	    }
-	}
-
-   return { r : parseInt(red), g : parseInt(green) , b : parseInt(blue) };
-}
-
-Rico.Color.RGBtoHSB = function(r, g, b) {
-
-   var hue;
-   var saturaton;
-   var brightness;
-
-   var cmax = (r > g) ? r : g;
-   if (b > cmax)
-      cmax = b;
-
-   var cmin = (r < g) ? r : g;
-   if (b < cmin)
-      cmin = b;
-
-   brightness = cmax / 255.0;
-   if (cmax != 0)
-      saturation = (cmax - cmin)/cmax;
-   else
-      saturation = 0;
-
-   if (saturation == 0)
-      hue = 0;
-   else {
-      var redc   = (cmax - r)/(cmax - cmin);
-    	var greenc = (cmax - g)/(cmax - cmin);
-    	var bluec  = (cmax - b)/(cmax - cmin);
-
-    	if (r == cmax)
-    	   hue = bluec - greenc;
-    	else if (g == cmax)
-    	   hue = 2.0 + redc - bluec;
-      else
-    	   hue = 4.0 + greenc - redc;
-
-    	hue = hue / 6.0;
-    	if (hue < 0)
-    	   hue = hue + 1.0;
-   }
-
-   return { h : hue, s : saturation, b : brightness };
-}
-
-
-//-------------------- ricoCorner.js
-
-Rico.Corner = {
-
-   round: function(e, options) {
-      var e = $(e);
-      this._setOptions(options);
-
-      var color = this.options.color;
-      if ( this.options.color == "fromElement" )
-         color = this._background(e);
-
-      var bgColor = this.options.bgColor;
-      if ( this.options.bgColor == "fromParent" )
-         bgColor = this._background(e.offsetParent);
-
-      this._roundCornersImpl(e, color, bgColor);
-   },
-
-   _roundCornersImpl: function(e, color, bgColor) {
-      if(this.options.border)
-         this._renderBorder(e,bgColor);
-      if(this._isTopRounded())
-         this._roundTopCorners(e,color,bgColor);
-      if(this._isBottomRounded())
-         this._roundBottomCorners(e,color,bgColor);
-   },
-
-   _renderBorder: function(el,bgColor) {
-      var borderValue = "1px solid " + this._borderColor(bgColor);
-      var borderL = "border-left: "  + borderValue;
-      var borderR = "border-right: " + borderValue;
-      var style   = "style='" + borderL + ";" + borderR +  "'";
-      el.innerHTML = "<div " + style + ">" + el.innerHTML + "</div>"
-   },
-
-   _roundTopCorners: function(el, color, bgColor) {
-      var corner = this._createCorner(bgColor);
-      for(var i=0 ; i < this.options.numSlices ; i++ )
-         corner.appendChild(this._createCornerSlice(color,bgColor,i,"top"));
-      el.style.paddingTop = 0;
-      el.insertBefore(corner,el.firstChild);
-   },
-
-   _roundBottomCorners: function(el, color, bgColor) {
-      var corner = this._createCorner(bgColor);
-      for(var i=(this.options.numSlices-1) ; i >= 0 ; i-- )
-         corner.appendChild(this._createCornerSlice(color,bgColor,i,"bottom"));
-      el.style.paddingBottom = 0;
-      el.appendChild(corner);
-   },
-
-   _createCorner: function(bgColor) {
-      var corner = document.createElement("div");
-      corner.style.backgroundColor = (this._isTransparent() ? "transparent" : bgColor);
-      return corner;
-   },
-
-   _createCornerSlice: function(color,bgColor, n, position) {
-      var slice = document.createElement("span");
-
-      var inStyle = slice.style;
-      inStyle.backgroundColor = color;
-      inStyle.display  = "block";
-      inStyle.height   = "1px";
-      inStyle.overflow = "hidden";
-      inStyle.fontSize = "1px";
-
-      var borderColor = this._borderColor(color,bgColor);
-      if ( this.options.border && n == 0 ) {
-         inStyle.borderTopStyle    = "solid";
-         inStyle.borderTopWidth    = "1px";
-         inStyle.borderLeftWidth   = "0px";
-         inStyle.borderRightWidth  = "0px";
-         inStyle.borderBottomWidth = "0px";
-         inStyle.height            = "0px"; // assumes css compliant box model
-         inStyle.borderColor       = borderColor;
-      }
-      else if(borderColor) {
-         inStyle.borderColor = borderColor;
-         inStyle.borderStyle = "solid";
-         inStyle.borderWidth = "0px 1px";
-      }
-
-      if ( !this.options.compact && (n == (this.options.numSlices-1)) )
-         inStyle.height = "2px";
-
-      this._setMargin(slice, n, position);
-      this._setBorder(slice, n, position);
-
-      return slice;
-   },
-
-   _setOptions: function(options) {
-      this.options = {
-         corners : "all",
-         color   : "fromElement",
-         bgColor : "fromParent",
-         blend   : true,
-         border  : false,
-         compact : false
-      }.extend(options || {});
-
-      this.options.numSlices = this.options.compact ? 2 : 4;
-      if ( this._isTransparent() )
-         this.options.blend = false;
-   },
-
-   _whichSideTop: function() {
-      if ( this._hasString(this.options.corners, "all", "top") )
-         return "";
-
-      if ( this.options.corners.indexOf("tl") >= 0 && this.options.corners.indexOf("tr") >= 0 )
-         return "";
-
-      if (this.options.corners.indexOf("tl") >= 0)
-         return "left";
-      else if (this.options.corners.indexOf("tr") >= 0)
-          return "right";
-      return "";
-   },
-
-   _whichSideBottom: function() {
-      if ( this._hasString(this.options.corners, "all", "bottom") )
-         return "";
-
-      if ( this.options.corners.indexOf("bl")>=0 && this.options.corners.indexOf("br")>=0 )
-         return "";
-
-      if(this.options.corners.indexOf("bl") >=0)
-         return "left";
-      else if(this.options.corners.indexOf("br")>=0)
-         return "right";
-      return "";
-   },
-
-   _borderColor : function(color,bgColor) {
-      if ( color == "transparent" )
-         return bgColor;
-      else if ( this.options.border )
-         return this.options.border;
-      else if ( this.options.blend )
-         return this._blend( bgColor, color );
-      else
-         return "";
-   },
-
-
-   _setMargin: function(el, n, corners) {
-      var marginSize = this._marginSize(n);
-      var whichSide = corners == "top" ? this._whichSideTop() : this._whichSideBottom();
-
-      if ( whichSide == "left" ) {
-         el.style.marginLeft = marginSize + "px"; el.style.marginRight = "0px";
-      }
-      else if ( whichSide == "right" ) {
-         el.style.marginRight = marginSize + "px"; el.style.marginLeft  = "0px";
-      }
-      else {
-         el.style.marginLeft = marginSize + "px"; el.style.marginRight = marginSize + "px";
-      }
-   },
-
-   _setBorder: function(el,n,corners) {
-      var borderSize = this._borderSize(n);
-      var whichSide = corners == "top" ? this._whichSideTop() : this._whichSideBottom();
-
-      if ( whichSide == "left" ) {
-         el.style.borderLeftWidth = borderSize + "px"; el.style.borderRightWidth = "0px";
-      }
-      else if ( whichSide == "right" ) {
-         el.style.borderRightWidth = borderSize + "px"; el.style.borderLeftWidth  = "0px";
-      }
-      else {
-         el.style.borderLeftWidth = borderSize + "px"; el.style.borderRightWidth = borderSize + "px";
-      }
-   },
-
-   _marginSize: function(n) {
-      if ( this._isTransparent() )
-         return 0;
-
-      var marginSizes          = [ 5, 3, 2, 1 ];
-      var blendedMarginSizes   = [ 3, 2, 1, 0 ];
-      var compactMarginSizes   = [ 2, 1 ];
-      var smBlendedMarginSizes = [ 1, 0 ];
-
-      if ( this.options.compact && this.options.blend )
-         return smBlendedMarginSizes[n];
-      else if ( this.options.compact )
-         return compactMarginSizes[n];
-      else if ( this.options.blend )
-         return blendedMarginSizes[n];
-      else
-         return marginSizes[n];
-   },
-
-   _borderSize: function(n) {
-      var transparentBorderSizes = [ 5, 3, 2, 1 ];
-      var blendedBorderSizes     = [ 2, 1, 1, 1 ];
-      var compactBorderSizes     = [ 1, 0 ];
-      var actualBorderSizes      = [ 0, 2, 0, 0 ];
-
-      if ( this.options.compact && (this.options.blend || this._isTransparent()) )
-         return 1;
-      else if ( this.options.compact )
-         return compactBorderSizes[n];
-      else if ( this.options.blend )
-         return blendedBorderSizes[n];
-      else if ( this.options.border )
-         return actualBorderSizes[n];
-      else if ( this._isTransparent() )
-         return transparentBorderSizes[n];
-      return 0;
-   },
-
-   _hasString: function(str) { for(var i=1 ; i<arguments.length ; i++) if (str.indexOf(arguments[i]) >= 0) return true; return false; },
-   _blend: function(c1, c2) { var cc1 = Rico.Color.createFromHex(c1); cc1.blend(Rico.Color.createFromHex(c2)); return cc1; },
-   _background: function(el) { try { return Rico.Color.createColorFromBackground(el).asHex(); } catch(err) { return "#ffffff"; } },
-   _isTransparent: function() { return this.options.color == "transparent"; },
-   _isTopRounded: function() { return this._hasString(this.options.corners, "all", "top", "tl", "tr"); },
-   _isBottomRounded: function() { return this._hasString(this.options.corners, "all", "bottom", "bl", "br"); },
-   _hasSingleTextChild: function(el) { return el.childNodes.length == 1 && el.childNodes[0].nodeType == 3; }
-}
-
-
-//-------------------- ricoDragAndDrop.js
-Rico.DragAndDrop = Class.create();
-
-Rico.DragAndDrop.prototype = {
-
-   initialize: function() {
-      this.dropZones                = new Array();
-      this.draggables               = new Array();
-      this.currentDragObjects       = new Array();
-      this.dragElement              = null;
-      this.lastSelectedDraggable    = null;
-      this.currentDragObjectVisible = false;
-      this.interestedInMotionEvents = false;
-   },
-
-   registerDropZone: function(aDropZone) {
-      this.dropZones[ this.dropZones.length ] = aDropZone;
-   },
-
-   deregisterDropZone: function(aDropZone) {
-      var newDropZones = new Array();
-      var j = 0;
-      for ( var i = 0 ; i < this.dropZones.length ; i++ ) {
-         if ( this.dropZones[i] != aDropZone )
-            newDropZones[j++] = this.dropZones[i];
-      }
-
-      this.dropZones = newDropZones;
-   },
-
-   clearDropZones: function() {
-      this.dropZones = new Array();
-   },
-
-   registerDraggable: function( aDraggable ) {
-      this.draggables[ this.draggables.length ] = aDraggable;
-      this._addMouseDownHandler( aDraggable );
-   },
-
-   clearSelection: function() {
-      for ( var i = 0 ; i < this.currentDragObjects.length ; i++ )
-         this.currentDragObjects[i].deselect();
-      this.currentDragObjects = new Array();
-      this.lastSelectedDraggable = null;
-   },
-
-   hasSelection: function() {
-      return this.currentDragObjects.length > 0;
-   },
-
-   setStartDragFromElement: function( e, mouseDownElement ) {
-      this.origPos = RicoUtil.toDocumentPosition(mouseDownElement);
-      this.startx = e.screenX - this.origPos.x
-      this.starty = e.screenY - this.origPos.y
-      //this.startComponentX = e.layerX ? e.layerX : e.offsetX;
-      //this.startComponentY = e.layerY ? e.layerY : e.offsetY;
-      //this.adjustedForDraggableSize = false;
-
-      this.interestedInMotionEvents = this.hasSelection();
-      this._terminateEvent(e);
-   },
-
-   updateSelection: function( draggable, extendSelection ) {
-      if ( ! extendSelection )
-         this.clearSelection();
-
-      if ( draggable.isSelected() ) {
-         this.currentDragObjects.removeItem(draggable);
-         draggable.deselect();
-         if ( draggable == this.lastSelectedDraggable )
-            this.lastSelectedDraggable = null;
-      }
-      else {
-         this.currentDragObjects[ this.currentDragObjects.length ] = draggable;
-         draggable.select();
-         this.lastSelectedDraggable = draggable;
-      }
-   },
-
-   _mouseDownHandler: function(e) {
-      if ( arguments.length == 0 )
-         e = event;
-
-      // if not button 1 ignore it...
-      var nsEvent = e.which != undefined;
-      if ( (nsEvent && e.which != 1) || (!nsEvent && e.button != 1))
-         return;
-
-      var eventTarget      = e.target ? e.target : e.srcElement;
-      var draggableObject  = eventTarget.draggable;
-
-      var candidate = eventTarget;
-      while (draggableObject == null && candidate.parentNode) {
-         candidate = candidate.parentNode;
-         draggableObject = candidate.draggable;
-      }
-   
-      if ( draggableObject == null )
-         return;
-
-      this.updateSelection( draggableObject, e.ctrlKey );
-
-      // clear the drop zones postion cache...
-      if ( this.hasSelection() )
-         for ( var i = 0 ; i < this.dropZones.length ; i++ )
-            this.dropZones[i].clearPositionCache();
-
-      this.setStartDragFromElement( e, draggableObject.getMouseDownHTMLElement() );
-   },
-
-
-   _mouseMoveHandler: function(e) {
-      var nsEvent = e.which != undefined;
-      if ( !this.interestedInMotionEvents ) {
-         this._terminateEvent(e);
-         return;
-      }
-
-      if ( ! this.hasSelection() )
-         return;
-
-      if ( ! this.currentDragObjectVisible )
-         this._startDrag(e);
-
-      if ( !this.activatedDropZones )
-         this._activateRegisteredDropZones();
-
-      //if ( !this.adjustedForDraggableSize )
-      //   this._adjustForDraggableSize(e);
-
-      this._updateDraggableLocation(e);
-      this._updateDropZonesHover(e);
-
-      this._terminateEvent(e);
-   },
-
-   _makeDraggableObjectVisible: function(e)
-   {
-      if ( !this.hasSelection() )
-         return;
-
-      var dragElement;
-      if ( this.currentDragObjects.length > 1 )
-         dragElement = this.currentDragObjects[0].getMultiObjectDragGUI(this.currentDragObjects);
-      else
-         dragElement = this.currentDragObjects[0].getSingleObjectDragGUI();
-
-      // go ahead and absolute position it...
-      if ( RicoUtil.getElementsComputedStyle(dragElement, "position")  != "absolute" )
-         dragElement.style.position = "absolute";
-
-      // need to parent him into the document...
-      if ( dragElement.parentNode == null || dragElement.parentNode.nodeType == 11 )
-         document.body.appendChild(dragElement);
-
-      this.dragElement = dragElement;
-      this._updateDraggableLocation(e);
-
-      this.currentDragObjectVisible = true;
-   },
-
-   /**
-   _adjustForDraggableSize: function(e) {
-      var dragElementWidth  = this.dragElement.offsetWidth;
-      var dragElementHeight = this.dragElement.offsetHeight;
-      if ( this.startComponentX > dragElementWidth )
-         this.startx -= this.startComponentX - dragElementWidth + 2;
-      if ( e.offsetY ) {
-         if ( this.startComponentY > dragElementHeight )
-            this.starty -= this.startComponentY - dragElementHeight + 2;
-      }
-      this.adjustedForDraggableSize = true;
-   },
-   **/
-
-   _updateDraggableLocation: function(e) {
-      var dragObjectStyle = this.dragElement.style;
-      dragObjectStyle.left = (e.screenX - this.startx) + "px"
-      dragObjectStyle.top  = (e.screenY - this.starty) + "px";
-   },
-
-   _updateDropZonesHover: function(e) {
-      var n = this.dropZones.length;
-      for ( var i = 0 ; i < n ; i++ ) {
-         if ( ! this._mousePointInDropZone( e, this.dropZones[i] ) )
-            this.dropZones[i].hideHover();
-      }
-
-      for ( var i = 0 ; i < n ; i++ ) {
-         if ( this._mousePointInDropZone( e, this.dropZones[i] ) ) {
-            if ( this.dropZones[i].canAccept(this.currentDragObjects) )
-               this.dropZones[i].showHover();
-         }
-      }
-   },
-
-   _startDrag: function(e) {
-      for ( var i = 0 ; i < this.currentDragObjects.length ; i++ )
-         this.currentDragObjects[i].startDrag();
-
-      this._makeDraggableObjectVisible(e);
-   },
-
-   _mouseUpHandler: function(e) {
-      if ( ! this.hasSelection() )
-         return;
-
-      var nsEvent = e.which != undefined;
-      if ( (nsEvent && e.which != 1) || (!nsEvent && e.button != 1))
-         return;
-
-      this.interestedInMotionEvents = false;
-
-      if ( this.dragElement == null ) {
-         this._terminateEvent(e);
-         return;
-      }
-
-      if ( this._placeDraggableInDropZone(e) )
-         this._completeDropOperation(e);
-      else {
-         this._terminateEvent(e);
-         new Effect.Position( this.dragElement,
-                              this.origPos.x,
-                              this.origPos.y,
-                              200,
-                              20,
-                              { complete : this._doCancelDragProcessing.bind(this) } );
-      }
-   },
-
-   _completeDropOperation: function(e) {
-      if ( this.dragElement != this.currentDragObjects[0].getMouseDownHTMLElement() ) {
-         if ( this.dragElement.parentNode != null )
-            this.dragElement.parentNode.removeChild(this.dragElement);
-      }
-
-      this._deactivateRegisteredDropZones();
-      this._endDrag();
-      this.clearSelection();
-      this.dragElement = null;
-      this.currentDragObjectVisible = false;
-      this._terminateEvent(e);
-   },
-
-   _doCancelDragProcessing: function() {
-      this._cancelDrag();
-
-      if ( this.dragElement != this.currentDragObjects[0].getMouseDownHTMLElement() ) {
-         if ( this.dragElement.parentNode != null ) {
-            this.dragElement.parentNode.removeChild(this.dragElement);
-         }
-      }
-
-      this._deactivateRegisteredDropZones();
-      this.dragElement = null;
-      this.currentDragObjectVisible = false;
-   },
-
-   _placeDraggableInDropZone: function(e) {
-      var foundDropZone = false;
-      var n = this.dropZones.length;
-      for ( var i = 0 ; i < n ; i++ ) {
-         if ( this._mousePointInDropZone( e, this.dropZones[i] ) ) {
-            if ( this.dropZones[i].canAccept(this.currentDragObjects) ) {
-               this.dropZones[i].hideHover();
-               this.dropZones[i].accept(this.currentDragObjects);
-               foundDropZone = true;
-               break;
-            }
-         }
-      }
-
-      return foundDropZone;
-   },
-
-   _cancelDrag: function() {
-      for ( var i = 0 ; i < this.currentDragObjects.length ; i++ )
-         this.currentDragObjects[i].cancelDrag();
-   },
-
-   _endDrag: function() {
-      for ( var i = 0 ; i < this.currentDragObjects.length ; i++ )
-         this.currentDragObjects[i].endDrag();
-   },
-
-   _mousePointInDropZone: function( e, dropZone ) {
-
-      var absoluteRect = dropZone.getAbsoluteRect();
-
-      return e.clientX  > absoluteRect.left  &&
-             e.clientX  < absoluteRect.right &&
-             e.clientY  > absoluteRect.top   &&
-             e.clientY  < absoluteRect.bottom;
-   },
-
-   _addMouseDownHandler: function( aDraggable )
-   {
-      var htmlElement = aDraggable.getMouseDownHTMLElement();
-      if ( htmlElement != null ) {
-         htmlElement.draggable = aDraggable;
-         this._addMouseDownEvent( htmlElement );
-      }
-   },
-
-   _activateRegisteredDropZones: function() {
-      var n = this.dropZones.length;
-      for ( var i = 0 ; i < n ; i++ ) {
-         var dropZone = this.dropZones[i];
-         if ( dropZone.canAccept(this.currentDragObjects) )
-            dropZone.activate();
-      }
-
-      this.activatedDropZones = true;
-   },
-
-   _deactivateRegisteredDropZones: function() {
-      var n = this.dropZones.length;
-      for ( var i = 0 ; i < n ; i++ )
-         this.dropZones[i].deactivate();
-      this.activatedDropZones = false;
-   },
-
-   _addMouseDownEvent: function( htmlElement ) {
-      if ( typeof document.implementation != "undefined" &&
-         document.implementation.hasFeature("HTML",   "1.0") &&
-         document.implementation.hasFeature("Events", "2.0") &&
-         document.implementation.hasFeature("CSS",    "2.0") ) {
-         htmlElement.addEventListener("mousedown", this._mouseDownHandler.bindAsEventListener(this), false);
-      }
-      else {
-         htmlElement.attachEvent( "onmousedown", this._mouseDownHandler.bindAsEventListener(this) );
-      }
-   },
-
-   _terminateEvent: function(e) {
-      if ( e.stopPropagation != undefined )
-         e.stopPropagation();
-      else if ( e.cancelBubble != undefined )
-         e.cancelBubble = true;
-
-      if ( e.preventDefault != undefined )
-         e.preventDefault();
-      else
-         e.returnValue = false;
-   },
-
-   initializeEventHandlers: function() {
-      if ( typeof document.implementation != "undefined" &&
-         document.implementation.hasFeature("HTML",   "1.0") &&
-         document.implementation.hasFeature("Events", "2.0") &&
-         document.implementation.hasFeature("CSS",    "2.0") ) {
-         document.addEventListener("mouseup",   this._mouseUpHandler.bindAsEventListener(this),  false);
-         document.addEventListener("mousemove", this._mouseMoveHandler.bindAsEventListener(this), false);
-      }
-      else {
-         document.attachEvent( "onmouseup",   this._mouseUpHandler.bindAsEventListener(this) );
-         document.attachEvent( "onmousemove", this._mouseMoveHandler.bindAsEventListener(this) );
-      }
-   }
-}
-
-var dndMgr = new Rico.DragAndDrop();
-dndMgr.initializeEventHandlers();
-
-
-//-------------------- ricoDraggable.js
-Rico.Draggable = Class.create();
-
-Rico.Draggable.prototype = {
-
-   initialize: function( type, htmlElement ) {
-      this.type          = type;
-      this.htmlElement   = $(htmlElement);
-      this.selected      = false;
-   },
-
-   /**
-    *   Returns the HTML element that should have a mouse down event
-    *   added to it in order to initiate a drag operation
-    *
-    **/
-   getMouseDownHTMLElement: function() {
-      return this.htmlElement;
-   },
-
-   select: function() {
-      this.selected = true;
-
-      if ( this.showingSelected )
-         return;
-
-      var htmlElement = this.getMouseDownHTMLElement();
-
-      var color = Rico.Color.createColorFromBackground(htmlElement);
-      color.isBright() ? color.darken(0.033) : color.brighten(0.033);
-
-      this.saveBackground = RicoUtil.getElementsComputedStyle(htmlElement, "backgroundColor", "background-color");
-      htmlElement.style.backgroundColor = color.asHex();
-      this.showingSelected = true;
-   },
-
-   deselect: function() {
-      this.selected = false;
-      if ( !this.showingSelected )
-         return;
-
-      var htmlElement = this.getMouseDownHTMLElement();
-
-      htmlElement.style.backgroundColor = this.saveBackground;
-      this.showingSelected = false;
-   },
-
-   isSelected: function() {
-      return this.selected;
-   },
-
-   startDrag: function() {
-   },
-
-   cancelDrag: function() {
-   },
-
-   endDrag: function() {
-   },
-
-   getSingleObjectDragGUI: function() {
-      return this.htmlElement;
-   },
-
-   getMultiObjectDragGUI: function( draggables ) {
-      return this.htmlElement;
-   },
-
-   getDroppedGUI: function() {
-      return this.htmlElement;
-   },
-
-   toString: function() {
-      return this.type + ":" + this.htmlElement + ":";
-   }
-
-}
-
-
-//-------------------- ricoDropzone.js
-Rico.Dropzone = Class.create();
-
-Rico.Dropzone.prototype = {
-
-   initialize: function( htmlElement ) {
-      this.htmlElement  = $(htmlElement);
-      this.absoluteRect = null;
-   },
-
-   getHTMLElement: function() {
-      return this.htmlElement;
-   },
-
-   clearPositionCache: function() {
-      this.absoluteRect = null;
-   },
-
-   getAbsoluteRect: function() {
-      if ( this.absoluteRect == null ) {
-         var htmlElement = this.getHTMLElement();
-         var pos = RicoUtil.toViewportPosition(htmlElement);
-
-         this.absoluteRect = {
-            top:    pos.y,
-            left:   pos.x,
-            bottom: pos.y + htmlElement.offsetHeight,
-            right:  pos.x + htmlElement.offsetWidth
-         };
-      }
-      return this.absoluteRect;
-   },
-
-   activate: function() {
-      var htmlElement = this.getHTMLElement();
-      if (htmlElement == null  || this.showingActive)
-         return;
-
-      this.showingActive = true;
-      this.saveBackgroundColor = htmlElement.style.backgroundColor;
-
-      var fallbackColor = "#ffea84";
-      var currentColor = Rico.Color.createColorFromBackground(htmlElement);
-      if ( currentColor == null )
-         htmlElement.style.backgroundColor = fallbackColor;
-      else {
-         currentColor.isBright() ? currentColor.darken(0.2) : currentColor.brighten(0.2);
-         htmlElement.style.backgroundColor = currentColor.asHex();
-      }
-   },
-
-   deactivate: function() {
-      var htmlElement = this.getHTMLElement();
-      if (htmlElement == null || !this.showingActive)
-         return;
-
-      htmlElement.style.backgroundColor = this.saveBackgroundColor;
-      this.showingActive = false;
-      this.saveBackgroundColor = null;
-   },
-
-   showHover: function() {
-      var htmlElement = this.getHTMLElement();
-      if ( htmlElement == null || this.showingHover )
-         return;
-
-      this.saveBorderWidth = htmlElement.style.borderWidth;
-      this.saveBorderStyle = htmlElement.style.borderStyle;
-      this.saveBorderColor = htmlElement.style.borderColor;
-
-      this.showingHover = true;
-      htmlElement.style.borderWidth = "1px";
-      htmlElement.style.borderStyle = "solid";
-      //htmlElement.style.borderColor = "#ff9900";
-      htmlElement.style.borderColor = "#ffff00";
-   },
-
-   hideHover: function() {
-      var htmlElement = this.getHTMLElement();
-      if ( htmlElement == null || !this.showingHover )
-         return;
-
-      htmlElement.style.borderWidth = this.saveBorderWidth;
-      htmlElement.style.borderStyle = this.saveBorderStyle;
-      htmlElement.style.borderColor = this.saveBorderColor;
-      this.showingHover = false;
-   },
-
-   canAccept: function(draggableObjects) {
-      return true;
-   },
-
-   accept: function(draggableObjects) {
-      var htmlElement = this.getHTMLElement();
-      if ( htmlElement == null )
-         return;
-
-      n = draggableObjects.length;
-      for ( var i = 0 ; i < n ; i++ )
-      {
-         var theGUI = draggableObjects[i].getDroppedGUI();
-         if ( RicoUtil.getElementsComputedStyle( theGUI, "position" ) == "absolute" )
-         {
-            theGUI.style.position = "static";
-            theGUI.style.top = "";
-            theGUI.style.top = "";
-         }
-         htmlElement.appendChild(theGUI);
-      }
-   }
-}
-
-
-//-------------------- ricoEffects.js
-
-/**
-  *  Use the Effect namespace for effects.  If using scriptaculous effects
-  *  this will already be defined, otherwise we'll just create an empty
-  *  object for it...
- **/
-if ( window.Effect == undefined )
-   Effect = {};
-
-Effect.SizeAndPosition = Class.create();
-Effect.SizeAndPosition.prototype = {
-
-   initialize: function(element, x, y, w, h, duration, steps, options) {
-      this.element = $(element);
-      this.x = x;
-      this.y = y;
-      this.w = w;
-      this.h = h;
-      this.duration = duration;
-      this.steps    = steps;
-      this.options  = arguments[7] || {};
-
-      this.sizeAndPosition();
-   },
-
-   sizeAndPosition: function() {
-      if (this.isFinished()) {
-         if(this.options.complete) this.options.complete(this);
-         return;
-      }
-
-      if (this.timer)
-         clearTimeout(this.timer);
-
-      var stepDuration = Math.round(this.duration/this.steps) ;
-
-      // Get original values: x,y = top left corner;  w,h = width height
-      var currentX = this.element.offsetLeft;
-      var currentY = this.element.offsetTop;
-      var currentW = this.element.offsetWidth;
-      var currentH = this.element.offsetHeight;
-
-      // If values not set, or zero, we do not modify them, and take original as final as well
-      this.x = (this.x) ? this.x : currentX;
-      this.y = (this.y) ? this.y : currentY;
-      this.w = (this.w) ? this.w : currentW;
-      this.h = (this.h) ? this.h : currentH;
-
-      // how much do we need to modify our values for each step?
-      var difX = this.steps >  0 ? (this.x - currentX)/this.steps : 0;
-      var difY = this.steps >  0 ? (this.y - currentY)/this.steps : 0;
-      var difW = this.steps >  0 ? (this.w - currentW)/this.steps : 0;
-      var difH = this.steps >  0 ? (this.h - currentH)/this.steps : 0;
-
-      this.moveBy(difX, difY);
-      this.resizeBy(difW, difH);
-
-      this.duration -= stepDuration;
-      this.steps--;
-
-      this.timer = setTimeout(this.sizeAndPosition.bind(this), stepDuration);
-   },
-
-   isFinished: function() {
-      return this.steps <= 0;
-   },
-
-   moveBy: function( difX, difY ) {
-      var currentLeft = this.element.offsetLeft;
-      var currentTop  = this.element.offsetTop;
-      var intDifX     = parseInt(difX);
-      var intDifY     = parseInt(difY);
-
-      var style = this.element.style;
-      if ( intDifX != 0 )
-         style.left = (currentLeft + intDifX) + "px";
-      if ( intDifY != 0 )
-         style.top  = (currentTop + intDifY) + "px";
-   },
-
-   resizeBy: function( difW, difH ) {
-      var currentWidth  = this.element.offsetWidth;
-      var currentHeight = this.element.offsetHeight;
-      var intDifW       = parseInt(difW);
-      var intDifH       = parseInt(difH);
-
-      var style = this.element.style;
-      if ( intDifW != 0 )
-         style.width   = (currentWidth  + intDifW) + "px";
-      if ( intDifH != 0 )
-         style.height  = (currentHeight + intDifH) + "px";
-   }
-}
-
-Effect.Size = Class.create();
-Effect.Size.prototype = {
-
-   initialize: function(element, w, h, duration, steps, options) {
-      new Effect.SizeAndPosition(element, null, null, w, h, duration, steps, options);
-  }
-}
-
-Effect.Position = Class.create();
-Effect.Position.prototype = {
-
-   initialize: function(element, x, y, duration, steps, options) {
-      new Effect.SizeAndPosition(element, x, y, null, null, duration, steps, options);
-  }
-}
-
-Effect.Round = Class.create();
-Effect.Round.prototype = {
-
-   initialize: function(tagName, className, options) {
-      var elements = document.getElementsByTagAndClassName(tagName,className);
-      for ( var i = 0 ; i < elements.length ; i++ )
-         Rico.Corner.round( elements[i], options );
-   }
-};
-
-Effect.FadeTo = Class.create();
-Effect.FadeTo.prototype = {
-
-   initialize: function( element, opacity, duration, steps, options) {
-      this.element  = $(element);
-      this.opacity  = opacity;
-      this.duration = duration;
-      this.steps    = steps;
-      this.options  = arguments[4] || {};
-      this.fadeTo();
-   },
-
-   fadeTo: function() {
-      if (this.isFinished()) {
-         if(this.options.complete) this.options.complete(this);
-         return;
-      }
-
-      if (this.timer)
-         clearTimeout(this.timer);
-
-      var stepDuration = Math.round(this.duration/this.steps) ;
-      var currentOpacity = this.getElementOpacity();
-      var delta = this.steps > 0 ? (this.opacity - currentOpacity)/this.steps : 0;
-
-      this.changeOpacityBy(delta);
-      this.duration -= stepDuration;
-      this.steps--;
-
-      this.timer = setTimeout(this.fadeTo.bind(this), stepDuration);
-   },
-
-   changeOpacityBy: function(v) {
-      var currentOpacity = this.getElementOpacity();
-      var newOpacity = Math.max(0, Math.min(currentOpacity+v, 1));
-      this.element.ricoOpacity = newOpacity;
-
-      this.element.style.filter = "alpha(opacity:"+Math.round(newOpacity*100)+")";
-      this.element.style.opacity = newOpacity; /*//*/;
-   },
-
-   isFinished: function() {
-      return this.steps <= 0;
-   },
-
-   getElementOpacity: function() {
-      if ( this.element.ricoOpacity == undefined ) {
-         var opacity;
-         if ( this.element.currentStyle ) {
-            opacity = this.element.currentStyle.opacity;
-         }
-         else if ( document.defaultView.getComputedStyle != undefined ) {
-            var computedStyle = document.defaultView.getComputedStyle;
-            opacity = computedStyle(this.element, null).getPropertyValue('opacity');
-         }
-
-         this.element.ricoOpacity = opacity != undefined ? opacity : 1.0;
-      }
-
-      return parseFloat(this.element.ricoOpacity);
-   }
-}
-
-Effect.AccordionSize = Class.create();
-
-Effect.AccordionSize.prototype = {
-
-   initialize: function(e1, e2, start, end, duration, steps, options) {
-      this.e1       = $(e1);
-      this.e2       = $(e2);
-      this.start    = start;
-      this.end      = end;
-      this.duration = duration;
-      this.steps    = steps;
-      this.options  = arguments[6] || {};
-
-      this.accordionSize();
-   },
-
-   accordionSize: function() {
-
-      if (this.isFinished()) {
-         // just in case there are round errors or such...
-         this.e1.style.height = this.start + "px";
-         this.e2.style.height = this.end + "px";
-
-         if(this.options.complete)
-            this.options.complete(this);
-         return;
-      }
-
-      if (this.timer)
-         clearTimeout(this.timer);
-
-      var stepDuration = Math.round(this.duration/this.steps) ;
-
-      var diff = this.steps > 0 ? (parseInt(this.e1.offsetHeight) - this.start)/this.steps : 0;
-      this.resizeBy(diff);
-
-      this.duration -= stepDuration;
-      this.steps--;
-
-      this.timer = setTimeout(this.accordionSize.bind(this), stepDuration);
-   },
-
-   isFinished: function() {
-      return this.steps <= 0;
-   },
-
-   resizeBy: function(diff) {
-      var h1Height = this.e1.offsetHeight;
-      var h2Height = this.e2.offsetHeight;
-      var intDiff = parseInt(diff);
-      if ( diff != 0 ) {
-         this.e1.style.height = (h1Height - intDiff) + "px";
-         this.e2.style.height = (h2Height + intDiff) + "px";
-      }
-   }
-
-};
-
-
-//-------------------- ricoLiveGrid.js
-
-// Rico.LiveGridMetaData -----------------------------------------------------
-
-Rico.LiveGridMetaData = Class.create();
-
-Rico.LiveGridMetaData.prototype = {
-
-   initialize: function( pageSize, totalRows, columnCount, options ) {
-      this.pageSize  = pageSize;
-      this.totalRows = totalRows;
-      this.setOptions(options);
-      this.scrollArrowHeight = 16;
-      this.columnCount = columnCount;
-   },
-
-   setOptions: function(options) {
-      this.options = {
-         largeBufferSize    : 7.0,   // 7 pages
-         nearLimitFactor    : 0.2    // 20% of buffer
-      }.extend(options || {});
-   },
-
-   getPageSize: function() {
-      return this.pageSize;
-   },
-
-   getTotalRows: function() {
-      return this.totalRows;
-   },
-
-   setTotalRows: function(n) {
-      this.totalRows = n;
-   },
-
-   getLargeBufferSize: function() {
-      return parseInt(this.options.largeBufferSize * this.pageSize);
-   },
-
-   getLimitTolerance: function() {
-      return parseInt(this.getLargeBufferSize() * this.options.nearLimitFactor);
-   }
-};
-
-// Rico.LiveGridScroller -----------------------------------------------------
-
-Rico.LiveGridScroller = Class.create();
-
-Rico.LiveGridScroller.prototype = {
-
-   initialize: function(liveGrid, viewPort) {
-      this.isIE = navigator.userAgent.toLowerCase().indexOf("msie") >= 0;
-      this.liveGrid = liveGrid;
-      this.metaData = liveGrid.metaData;
-      this.createScrollBar();
-      this.scrollTimeout = null;
-      this.lastScrollPos = 0;
-      this.viewPort = viewPort;
-      this.rows = new Array();
-   },
-
-   isUnPlugged: function() {
-      return this.scrollerDiv.onscroll == null;
-   },
-
-   plugin: function() {
-      this.scrollerDiv.onscroll = this.handleScroll.bindAsEventListener(this);
-   },
-
-   unplug: function() {
-      this.scrollerDiv.onscroll = null;
-   },
-
-   sizeIEHeaderHack: function() {
-      if ( !this.isIE ) return;
-      var headerTable = $(this.liveGrid.tableId + "_header");
-      if ( headerTable )
-         headerTable.rows[0].cells[0].style.width =
-            (headerTable.rows[0].cells[0].offsetWidth + 1) + "px";
-   },
-
-   createScrollBar: function() {
-      var visibleHeight = this.liveGrid.viewPort.visibleHeight();
-      // create the outer div...
-      this.scrollerDiv  = document.createElement("div");
-      var scrollerStyle = this.scrollerDiv.style;
-      scrollerStyle.borderRight = "1px solid #ababab"; // hard coded color!!!
-      scrollerStyle.position    = "relative";
-      scrollerStyle.left        = this.isIE ? "-6px" : "-3px";
-      scrollerStyle.width       = "19px";
-      scrollerStyle.height      = visibleHeight + "px";
-      scrollerStyle.overflow    = "auto";
-
-      // create the inner div...
-      this.heightDiv = document.createElement("div");
-      this.heightDiv.style.width  = "1px";
-
-      this.heightDiv.style.height = parseInt(visibleHeight *
-                        this.metaData.getTotalRows()/this.metaData.getPageSize()) + "px" ;
-      this.scrollerDiv.appendChild(this.heightDiv);
-      this.scrollerDiv.onscroll = this.handleScroll.bindAsEventListener(this);
-
-     var table = this.liveGrid.table;
-     table.parentNode.parentNode.insertBefore( this.scrollerDiv, table.parentNode.nextSibling );
-   },
-
-   updateSize: function() {
-      var table = this.liveGrid.table;
-      var visibleHeight = this.viewPort.visibleHeight();
-      this.heightDiv.style.height = parseInt(visibleHeight *
-                                  this.metaData.getTotalRows()/this.metaData.getPageSize()) + "px";
-   },
-
-   rowToPixel: function(rowOffset) {
-      return (rowOffset / this.metaData.getTotalRows()) * this.heightDiv.offsetHeight
-   },
-   
-   moveScroll: function(rowOffset) {
-      this.scrollerDiv.scrollTop = this.rowToPixel(rowOffset);
-      if ( this.metaData.options.onscroll )
-         this.metaData.options.onscroll( this.liveGrid, rowOffset );    
-   },
-
-   handleScroll: function() {
-     if ( this.scrollTimeout )
-         clearTimeout( this.scrollTimeout );
-
-      var contentOffset = parseInt(this.scrollerDiv.scrollTop / this.viewPort.rowHeight);
-      this.liveGrid.requestContentRefresh(contentOffset);
-      this.viewPort.scrollTo(this.scrollerDiv.scrollTop);
-      
-      if ( this.metaData.options.onscroll )
-         this.metaData.options.onscroll( this.liveGrid, contentOffset );
-
-      this.scrollTimeout = setTimeout( this.scrollIdle.bind(this), 1200 );
-   },
-
-   scrollIdle: function() {
-      if ( this.metaData.options.onscrollidle )
-         this.metaData.options.onscrollidle();
-   }
-};
-
-// Rico.LiveGridBuffer -----------------------------------------------------
-
-Rico.LiveGridBuffer = Class.create();
-
-Rico.LiveGridBuffer.prototype = {
-
-   initialize: function(metaData, viewPort) {
-      this.startPos = 0;
-      this.size     = 0;
-      this.metaData = metaData;
-      this.rows     = new Array();
-      this.updateInProgress = false;
-      this.viewPort = viewPort;
-      this.maxBufferSize = metaData.getLargeBufferSize() * 2;
-      this.maxFetchSize = metaData.getLargeBufferSize();
-      this.lastOffset = 0;
-   },
-
-   getBlankRow: function() {
-      if (!this.blankRow ) {
-         this.blankRow = new Array();
-         for ( var i=0; i < this.metaData.columnCount ; i++ ) 
-            this.blankRow[i] = "&nbsp;";
-     }
-     return this.blankRow;
-   },
-   
-   loadRows: function(ajaxResponse) {
-      var rowsElement = ajaxResponse.getElementsByTagName('rows')[0];
-      this.updateUI = rowsElement.getAttribute("update_ui") == "true"
-      var newRows = new Array()
-      var trs = rowsElement.getElementsByTagName("tr");
-      for ( var i=0 ; i < trs.length; i++ ) {
-         var row = newRows[i] = new Array(); 
-         var cells = trs[i].getElementsByTagName("td");
-         for ( var j=0; j < cells.length ; j++ ) {
-            var cell = cells[j];
-            var convertSpaces = cell.getAttribute("convert_spaces") == "true";
-            var cellContent = RicoUtil.getContentAsString(cell);
-            row[j] = convertSpaces ? this.convertSpaces(cellContent) : cellContent;
-            if (!row[j]) 
-               row[j] = '&nbsp;';
-         }
-      }
-      return newRows;
-   },
-      
-   update: function(ajaxResponse, start) {
-     var newRows = this.loadRows(ajaxResponse);
-      if (this.rows.length == 0) { // initial load
-         this.rows = newRows;
-         this.size = this.rows.length;
-         this.startPos = start;
-         return;
-      }
-      if (start > this.startPos) { //appending
-         if (this.startPos + this.rows.length < start) {
-            this.rows =  newRows;
-            this.startPos = start;//
-         } else {
-              this.rows = this.rows.concat( newRows.slice(0, newRows.length));
-            if (this.rows.length > this.maxBufferSize) {
-               var fullSize = this.rows.length;
-               this.rows = this.rows.slice(this.rows.length - this.maxBufferSize, this.rows.length)
-               this.startPos = this.startPos +  (fullSize - this.rows.length);
-            }
-         }
-      } else { //prepending
-         if (start + newRows.length < this.startPos) {
-            this.rows =  newRows;
-         } else {
-            this.rows = newRows.slice(0, this.startPos).concat(this.rows);
-            if (this.rows.length > this.maxBufferSize) 
-               this.rows = this.rows.slice(0, this.maxBufferSize)
-         }
-         this.startPos =  start;
-      }
-      this.size = this.rows.length;
-   },
-   
-   clear: function() {
-      this.rows = new Array();
-      this.startPos = 0;
-      this.size = 0;
-   },
-
-   isOverlapping: function(start, size) {
-      return ((start < this.endPos()) && (this.startPos < start + size)) || (this.endPos() == 0)
-   },
-
-   isInRange: function(position) {
-      return (position >= this.startPos) && (position + this.metaData.getPageSize() <= this.endPos()); 
-             //&& this.size()  != 0;
-   },
-
-   isNearingTopLimit: function(position) {
-      return position - this.startPos < this.metaData.getLimitTolerance();
-   },
-
-   endPos: function() {
-      return this.startPos + this.rows.length;
-   },
-   
-   isNearingBottomLimit: function(position) {
-      return this.endPos() - (position + this.metaData.getPageSize()) < this.metaData.getLimitTolerance();
-   },
-
-   isAtTop: function() {
-      return this.startPos == 0;
-   },
-
-   isAtBottom: function() {
-      return this.endPos() == this.metaData.getTotalRows();
-   },
-
-   isNearingLimit: function(position) {
-      return ( !this.isAtTop()    && this.isNearingTopLimit(position)) ||
-             ( !this.isAtBottom() && this.isNearingBottomLimit(position) )
-   },
-
-   getFetchSize: function(offset) {
-      var adjustedOffset = this.getFetchOffset(offset);
-      var adjustedSize = 0;
-      if (adjustedOffset >= this.startPos) { //apending
-         var endFetchOffset = this.maxFetchSize  + adjustedOffset;
-         if (endFetchOffset > this.metaData.totalRows)
-            endFetchOffset = this.metaData.totalRows;
-         adjustedSize = endFetchOffset - adjustedOffset;   
-      } else {//prepending
-         var adjustedSize = this.startPos - adjustedOffset;
-         if (adjustedSize > this.maxFetchSize)
-            adjustedSize = this.maxFetchSize;
-      }
-      return adjustedSize;
-   }, 
-
-   getFetchOffset: function(offset) {
-      var adjustedOffset = offset;
-      if (offset > this.startPos)  //apending
-         adjustedOffset = (offset > this.endPos()) ? offset :  this.endPos(); 
-      else { //prepending
-         if (offset + this.maxFetchSize >= this.startPos) {
-            var adjustedOffset = this.startPos - this.maxFetchSize;
-            if (adjustedOffset < 0)
-               adjustedOffset = 0;
-         }
-      }
-      this.lastOffset = adjustedOffset;
-      return adjustedOffset;
-   },
-
-   getRows: function(start, count) {
-      var begPos = start - this.startPos
-      var endPos = begPos + count
-
-      // er? need more data...
-      if ( endPos > this.size )
-         endPos = this.size
-
-      var results = new Array()
-      var index = 0;
-      for ( var i=begPos ; i < endPos; i++ ) {
-         results[index++] = this.rows[i]
-      }
-      return results
-   },
-
-   convertSpaces: function(s) {
-      return s.split(" ").join("&nbsp;");
-   }
-
-};
-
-
-//Rico.GridViewPort --------------------------------------------------
-Rico.GridViewPort = Class.create();
-
-Rico.GridViewPort.prototype = {
-
-   initialize: function(table, rowHeight, visibleRows, buffer, liveGrid) {
-      this.lastDisplayedStartPos = 0;
-      this.div = table.parentNode;
-      this.table = table
-      this.rowHeight = rowHeight;
-      this.div.style.height = this.rowHeight * visibleRows;
-      this.div.style.overflow = "hidden";
-      this.buffer = buffer;
-      this.liveGrid = liveGrid;
-      this.visibleRows = visibleRows + 1;
-      this.lastPixelOffset = 0;
-      this.startPos = 0;
-   },
-
-   populateRow: function(htmlRow, row) {
-      for (var j=0; j < row.length; j++) {
-         htmlRow.cells[j].innerHTML = row[j]
-      }
-   },
-   
-   bufferChanged: function() {
-      this.refreshContents( parseInt(this.lastPixelOffset / this.rowHeight));
-   },
-   
-   clearRows: function() {
-      if (!this.isBlank) {
-         for (var i=0; i < this.visibleRows; i++)
-            this.populateRow(this.table.rows[i], this.buffer.getBlankRow());
-         this.isBlank = true;
-      }
-   },
-   
-   clearContents: function() {   
-      this.clearRows();
-      this.scrollTo(0);
-      this.startPos = 0;
-      this.lastStartPos = -1;   
-   },
-   
-   refreshContents: function(startPos) {
-      if (startPos == this.lastRowPos && !this.isPartialBlank && !this.isBlank) {
-         return;
-      }
-      if ((startPos + this.visibleRows < this.buffer.startPos)  
-          || (this.buffer.startPos + this.buffer.size < startPos) 
-          || (this.buffer.size == 0)) {
-         this.clearRows();
-         return;
-      }
-      this.isBlank = false;
-      var viewPrecedesBuffer = this.buffer.startPos > startPos
-      var contentStartPos = viewPrecedesBuffer ? this.buffer.startPos: startPos;
-   
-      var contentEndPos = (this.buffer.startPos + this.buffer.size < startPos + this.visibleRows) 
-                                 ? this.buffer.startPos + this.buffer.size
-                                 : startPos + this.visibleRows;       
-      var rowSize = contentEndPos - contentStartPos;
-      var rows = this.buffer.getRows(contentStartPos, rowSize ); 
-      var blankSize = this.visibleRows - rowSize;
-      var blankOffset = viewPrecedesBuffer ? 0: rowSize;
-      var contentOffset = viewPrecedesBuffer ? blankSize: 0;
-
-      for (var i=0; i < rows.length; i++) {//initialize what we have
-        this.populateRow(this.table.rows[i + contentOffset], rows[i]);
-      }       
-      for (var i=0; i < blankSize; i++) {// blank out the rest 
-        this.populateRow(this.table.rows[i + blankOffset], this.buffer.getBlankRow());
-      }
-      this.isPartialBlank = blankSize > 0;
-      this.lastRowPos = startPos;   
-   },
-
-   scrollTo: function(pixelOffset) {      
-      if (this.lastPixelOffset == pixelOffset)
-         return;
-
-      this.refreshContents(parseInt(pixelOffset / this.rowHeight))
-      this.div.scrollTop = pixelOffset % this.rowHeight        
-      
-      this.lastPixelOffset = pixelOffset;
-   },
-   
-   visibleHeight: function() {
-      return parseInt(this.div.style.height);
-   }
-   
-};
-
-
-Rico.LiveGridRequest = Class.create();
-Rico.LiveGridRequest.prototype = {
-   initialize: function( requestOffset, options ) {
-      this.requestOffset = requestOffset;
-   }
-};
-
-// Rico.LiveGrid -----------------------------------------------------
-
-Rico.LiveGrid = Class.create();
-
-Rico.LiveGrid.prototype = {
-
-   initialize: function( tableId, visibleRows, totalRows, url, options ) {
-      if ( options == null )
-         options = {};
-
-      this.tableId     = tableId; 
-      this.table       = $(tableId);
-      var columnCount  = this.table.rows[0].cells.length
-      this.metaData    = new Rico.LiveGridMetaData(visibleRows, totalRows, columnCount, options);
-      this.buffer      = new Rico.LiveGridBuffer(this.metaData);
-
-      var rowCount = this.table.rows.length;
-      this.viewPort =  new Rico.GridViewPort(this.table, 
-                                            this.table.offsetHeight/rowCount,
-                                            visibleRows,
-                                            this.buffer, this);
-      this.scroller    = new Rico.LiveGridScroller(this,this.viewPort);
-      
-      this.additionalParms       = options.requestParameters || [];
-      
-      options.sortHandler = this.sortHandler.bind(this);
-
-      if ( $(tableId + '_header') )
-         this.sort = new Rico.LiveGridSort(tableId + '_header', options)
-
-      this.processingRequest = null;
-      this.unprocessedRequest = null;
-
-      this.initAjax(url);
-      if ( options.prefetchBuffer || options.prefetchOffset > 0) {
-         var offset = 0;
-         if (options.offset ) {
-            offset = options.offset;            
-            this.scroller.moveScroll(offset);
-            this.viewPort.scrollTo(this.scroller.rowToPixel(offset));            
-         }
-         if (options.sortCol) {
-             this.sortCol = options.sortCol;
-             this.sortDir = options.sortDir;
-         }
-         this.requestContentRefresh(offset);
-      }
-   },
-
-   resetContents: function() {
-      this.scroller.moveScroll(0);
-      this.buffer.clear();
-      this.viewPort.clearContents();
-   },
-   
-   sortHandler: function(column) {
-      this.sortCol = column.name;
-      this.sortDir = column.currentSort;
-
-      this.resetContents();
-      this.requestContentRefresh(0) 
-   },
-   
-   setRequestParams: function() {
-      this.additionalParms = [];
-      for ( var i=0 ; i < arguments.length ; i++ )
-         this.additionalParms[i] = arguments[i];
-   },
-
-   setTotalRows: function( newTotalRows ) {
-      this.resetContents();
-      this.metaData.setTotalRows(newTotalRows);
-      this.scroller.updateSize();
-   },
-
-   initAjax: function(url) {
-      ajaxEngine.registerRequest( this.tableId + '_request', url );
-      ajaxEngine.registerAjaxObject( this.tableId + '_updater', this );
-   },
-
-   invokeAjax: function() {
-   },
-
-   handleTimedOut: function() {
-      //server did not respond in 4 seconds... assume that there could have been
-      //an error or something, and allow requests to be processed again...
-      this.processingRequest = null;
-      this.processQueuedRequest();
-   },
-
-   fetchBuffer: function(offset) {
-      if ( this.buffer.isInRange(offset) &&
-         !this.buffer.isNearingLimit(offset)) {
-         return;
-      }
-      if (this.processingRequest) {
-          this.unprocessedRequest = new Rico.LiveGridRequest(offset);
-         return;
-      }
-      var bufferStartPos = this.buffer.getFetchOffset(offset);
-      this.processingRequest = new Rico.LiveGridRequest(offset);
-      this.processingRequest.bufferOffset = bufferStartPos;   
-      var fetchSize = this.buffer.getFetchSize(offset);
-      var partialLoaded = false;
-      var callParms = []; 
-      callParms.push(this.tableId + '_request');
-      callParms.push('id='        + this.tableId);
-      callParms.push('page_size=' + fetchSize);
-      callParms.push('offset='    + bufferStartPos);
-      if ( this.sortCol) {
-         callParms.push('sort_col='    + this.sortCol);
-         callParms.push('sort_dir='    + this.sortDir);
-      }
-      
-      for( var i=0 ; i < this.additionalParms.length ; i++ )
-         callParms.push(this.additionalParms[i]);
-      ajaxEngine.sendRequest.apply( ajaxEngine, callParms );
-        
-      this.timeoutHandler = setTimeout( this.handleTimedOut.bind(this), 20000 ); //todo: make as option
-   },
-
-   requestContentRefresh: function(contentOffset) {
-      this.fetchBuffer(contentOffset);
-   },
-
-   ajaxUpdate: function(ajaxResponse) {
-      try {
-         clearTimeout( this.timeoutHandler );
-         this.buffer.update(ajaxResponse,this.processingRequest.bufferOffset);
-         this.viewPort.bufferChanged();
-      }
-      catch(err) {}
-      finally {this.processingRequest = null; }
-      this.processQueuedRequest();
-   },
-
-   processQueuedRequest: function() {
-      if (this.unprocessedRequest != null) {
-         this.requestContentRefresh(this.unprocessedRequest.requestOffset);
-         this.unprocessedRequest = null
-      }  
-   }
- 
-};
-
-
-//-------------------- ricoLiveGridSort.js
-Rico.LiveGridSort = Class.create();
-
-Rico.LiveGridSort.prototype = {
-
-   initialize: function(headerTableId, options) {
-      this.headerTableId = headerTableId;
-      this.headerTable   = $(headerTableId);
-      this.setOptions(options);
-      this.applySortBehavior();
-
-      if ( this.options.sortCol ) {
-         this.setSortUI( this.options.sortCol, this.options.sortDir );
-      }
-   },
-
-   setSortUI: function( columnName, sortDirection ) {
-      var cols = this.options.columns;
-      for ( var i = 0 ; i < cols.length ; i++ ) {
-         if ( cols[i].name == columnName ) {
-            this.setColumnSort(i, sortDirection);
-            break;
-         }
-      }
-   },
-
-   setOptions: function(options) {
-      this.options = {
-         sortAscendImg:    'images/sort_asc.gif',
-         sortDescendImg:   'images/sort_desc.gif',
-         imageWidth:       9,
-         imageHeight:      5,
-         ajaxSortURLParms: []
-      }.extend(options);
-
-      // preload the images...
-      new Image().src = this.options.sortAscendImg;
-      new Image().src = this.options.sortDescendImg;
-
-      this.sort = options.sortHandler;
-      if ( !this.options.columns )
-         this.options.columns = this.introspectForColumnInfo();
-      else {
-         // allow client to pass { columns: [ ["a", true], ["b", false] ] }
-         // and convert to an array of Rico.TableColumn objs...
-         this.options.columns = this.convertToTableColumns(this.options.columns);
-      }
-   },
-
-   applySortBehavior: function() {
-      var headerRow   = this.headerTable.rows[0];
-      var headerCells = headerRow.cells;
-      for ( var i = 0 ; i < headerCells.length ; i++ ) {
-         this.addSortBehaviorToColumn( i, headerCells[i] );
-      }
-   },
-
-   addSortBehaviorToColumn: function( n, cell ) {
-      if ( this.options.columns[n].isSortable() ) {
-         cell.id            = this.headerTableId + '_' + n;
-         cell.style.cursor  = 'pointer';
-         cell.onclick       = this.headerCellClicked.bindAsEventListener(this);
-         cell.innerHTML     = cell.innerHTML + '<span id="' + this.headerTableId + '_img_' + n + '">'
-                           + '&nbsp;&nbsp;&nbsp;</span>';
-      }
-   },
-
-   // event handler....
-   headerCellClicked: function(evt) {
-      var eventTarget = evt.target ? evt.target : evt.srcElement;
-      var cellId = eventTarget.id;
-      var columnNumber = parseInt(cellId.substring( cellId.lastIndexOf('_') + 1 ));
-      var sortedColumnIndex = this.getSortedColumnIndex();
-      if ( sortedColumnIndex != -1 ) {
-         if ( sortedColumnIndex != columnNumber ) {
-            this.removeColumnSort(sortedColumnIndex);
-            this.setColumnSort(columnNumber, Rico.TableColumn.SORT_ASC);
-         }
-         else
-            this.toggleColumnSort(sortedColumnIndex);
-      }
-      else
-         this.setColumnSort(columnNumber, Rico.TableColumn.SORT_ASC);
-
-      if (this.options.sortHandler) {
-         this.options.sortHandler(this.options.columns[columnNumber]);
-      }
-   },
-
-   removeColumnSort: function(n) {
-      this.options.columns[n].setUnsorted();
-      this.setSortImage(n);
-   },
-
-   setColumnSort: function(n, direction) {
-      this.options.columns[n].setSorted(direction);
-      this.setSortImage(n);
-   },
-
-   toggleColumnSort: function(n) {
-      this.options.columns[n].toggleSort();
-      this.setSortImage(n);
-   },
-
-   setSortImage: function(n) {
-      var sortDirection = this.options.columns[n].getSortDirection();
-
-      var sortImageSpan = $( this.headerTableId + '_img_' + n );
-      if ( sortDirection == Rico.TableColumn.UNSORTED )
-         sortImageSpan.innerHTML = '&nbsp;&nbsp;';
-      else if ( sortDirection == Rico.TableColumn.SORT_ASC )
-         sortImageSpan.innerHTML = '&nbsp;&nbsp;<img width="'  + this.options.imageWidth    + '" ' +
-                                                     'height="'+ this.options.imageHeight   + '" ' +
-                                                     'src="'   + this.options.sortAscendImg + '"/>';
-      else if ( sortDirection == Rico.TableColumn.SORT_DESC )
-         sortImageSpan.innerHTML = '&nbsp;&nbsp;<img width="'  + this.options.imageWidth    + '" ' +
-                                                     'height="'+ this.options.imageHeight   + '" ' +
-                                                     'src="'   + this.options.sortDescendImg + '"/>';
-   },
-
-   getSortedColumnIndex: function() {
-      var cols = this.options.columns;
-      for ( var i = 0 ; i < cols.length ; i++ ) {
-         if ( cols[i].isSorted() )
-            return i;
-      }
-
-      return -1;
-   },
-
-   introspectForColumnInfo: function() {
-      var columns = new Array();
-      var headerRow   = this.headerTable.rows[0];
-      var headerCells = headerRow.cells;
-      for ( var i = 0 ; i < headerCells.length ; i++ )
-         columns.push( new Rico.TableColumn( this.deriveColumnNameFromCell(headerCells[i],i), true ) );
-      return columns;
-   },
-
-   convertToTableColumns: function(cols) {
-      var columns = new Array();
-      for ( var i = 0 ; i < cols.length ; i++ )
-         columns.push( new Rico.TableColumn( cols[i][0], cols[i][1] ) );
-   },
-
-   deriveColumnNameFromCell: function(cell,columnNumber) {
-      var cellContent = cell.innerText != undefined ? cell.innerText : cell.textContent;
-      return cellContent ? cellContent.toLowerCase().split(' ').join('_') : "col_" + columnNumber;
-   }
-};
-
-Rico.TableColumn = Class.create();
-
-Rico.TableColumn.UNSORTED  = 0;
-Rico.TableColumn.SORT_ASC  = "ASC";
-Rico.TableColumn.SORT_DESC = "DESC";
-
-Rico.TableColumn.prototype = {
-   initialize: function(name, sortable) {
-      this.name        = name;
-      this.sortable    = sortable;
-      this.currentSort = Rico.TableColumn.UNSORTED;
-   },
-
-   isSortable: function() {
-      return this.sortable;
-   },
-
-   isSorted: function() {
-      return this.currentSort != Rico.TableColumn.UNSORTED;
-   },
-
-   getSortDirection: function() {
-      return this.currentSort;
-   },
-
-   toggleSort: function() {
-      if ( this.currentSort == Rico.TableColumn.UNSORTED || this.currentSort == Rico.TableColumn.SORT_DESC )
-         this.currentSort = Rico.TableColumn.SORT_ASC;
-      else if ( this.currentSort == Rico.TableColumn.SORT_ASC )
-         this.currentSort = Rico.TableColumn.SORT_DESC;
-   },
-
-   setUnsorted: function(direction) {
-      this.setSorted(Rico.TableColumn.UNSORTED);
-   },
-
-   setSorted: function(direction) {
-      // direction must by one of Rico.TableColumn.UNSORTED, .SORT_ASC, or .SET_DESC...
-      this.currentSort = direction;
-   }
-
-};
-
-
-//-------------------- ricoUtil.js
-
-var RicoUtil = {
-
-   getElementsComputedStyle: function ( htmlElement, cssProperty, mozillaEquivalentCSS) {
-      if ( arguments.length == 2 )
-         mozillaEquivalentCSS = cssProperty;
-
-      var el = $(htmlElement);
-      if ( el.currentStyle )
-         return el.currentStyle[cssProperty];
-      else
-         return document.defaultView.getComputedStyle(el, null).getPropertyValue(mozillaEquivalentCSS);
-   },
-
-   createXmlDocument : function() {
-      if (document.implementation && document.implementation.createDocument) {
-         var doc = document.implementation.createDocument("", "", null);
-
-         if (doc.readyState == null) {
-            doc.readyState = 1;
-            doc.addEventListener("load", function () {
-               doc.readyState = 4;
-               if (typeof doc.onreadystatechange == "function")
-                  doc.onreadystatechange();
-            }, false);
-         }
-
-         return doc;
-      }
-
-      if (window.ActiveXObject)
-          return Try.these(
-            function() { return new ActiveXObject('MSXML2.DomDocument')   },
-            function() { return new ActiveXObject('Microsoft.DomDocument')},
-            function() { return new ActiveXObject('MSXML.DomDocument')    },
-            function() { return new ActiveXObject('MSXML3.DomDocument')   }
-          ) || false;
-
-      return null;
-   },
-
-   getContentAsString: function( parentNode ) {
-      return parentNode.xml != undefined ? 
-         this._getContentAsStringIE(parentNode) :
-         this._getContentAsStringMozilla(parentNode);
-   },
-
-   _getContentAsStringIE: function(parentNode) {
-      var contentStr = "";
-      for ( var i = 0 ; i < parentNode.childNodes.length ; i++ )
-         contentStr += parentNode.childNodes[i].xml;
-      return contentStr;
-   },
-
-   _getContentAsStringMozilla: function(parentNode) {
-      var xmlSerializer = new XMLSerializer();
-      var contentStr = "";
-      for ( var i = 0 ; i < parentNode.childNodes.length ; i++ )
-         contentStr += xmlSerializer.serializeToString(parentNode.childNodes[i]);
-      return contentStr;
-   },
-
-   toViewportPosition: function(element) {
-      return this._toAbsolute(element,true);
-   },
-
-   toDocumentPosition: function(element) {
-      return this._toAbsolute(element,false);
-   },
-
-   /**
-    *  Compute the elements position in terms of the window viewport
-    *  so that it can be compared to the position of the mouse (dnd)
-    *  This is additions of all the offsetTop,offsetLeft values up the
-    *  offsetParent hierarchy, ...taking into account any scrollTop,
-    *  scrollLeft values along the way...
-    *
-    * IE has a bug reporting a correct offsetLeft of elements within a
-    * a relatively positioned parent!!!
-    **/
-   _toAbsolute: function(element,accountForDocScroll) {
-
-      if ( navigator.userAgent.toLowerCase().indexOf("msie") == -1 )
-         return this._toAbsoluteMozilla(element,accountForDocScroll);
-
-      var x = 0;
-      var y = 0;
-      var parent = element;
-      while ( parent ) {
-
-         var borderXOffset = 0;
-         var borderYOffset = 0;
-         if ( parent != element ) {
-            var borderXOffset = parseInt(this.getElementsComputedStyle(parent, "borderLeftWidth" ));
-            var borderYOffset = parseInt(this.getElementsComputedStyle(parent, "borderTopWidth" ));
-            borderXOffset = isNaN(borderXOffset) ? 0 : borderXOffset;
-            borderYOffset = isNaN(borderYOffset) ? 0 : borderYOffset;
-         }
-
-         x += parent.offsetLeft - parent.scrollLeft + borderXOffset;
-         y += parent.offsetTop - parent.scrollTop + borderYOffset;
-         parent = parent.offsetParent;
-      }
-
-      if ( accountForDocScroll ) {
-         x -= this.docScrollLeft();
-         y -= this.docScrollTop();
-      }
-
-      return { x:x, y:y };
-   },
-
-   /**
-    *  Mozilla did not report all of the parents up the hierarchy via the
-    *  offsetParent property that IE did.  So for the calculation of the
-    *  offsets we use the offsetParent property, but for the calculation of
-    *  the scrollTop/scrollLeft adjustments we navigate up via the parentNode
-    *  property instead so as to get the scroll offsets...
-    *
-    **/
-   _toAbsoluteMozilla: function(element,accountForDocScroll) {
-      var x = 0;
-      var y = 0;
-      var parent = element;
-      while ( parent ) {
-         x += parent.offsetLeft;
-         y += parent.offsetTop;
-         parent = parent.offsetParent;
-      }
-
-      parent = element;
-      while ( parent &&
-              parent != document.body &&
-              parent != document.documentElement ) {
-         if ( parent.scrollLeft  )
-            x -= parent.scrollLeft;
-         if ( parent.scrollTop )
-            y -= parent.scrollTop;
-         parent = parent.parentNode;
-      }
-
-      if ( accountForDocScroll ) {
-         x -= this.docScrollLeft();
-         y -= this.docScrollTop();
-      }
-
-      return { x:x, y:y };
-   },
-
-   docScrollLeft: function() {
-      if ( window.pageXOffset )
-         return window.pageXOffset;
-      else if ( document.documentElement && document.documentElement.scrollLeft )
-         return document.documentElement.scrollLeft;
-      else if ( document.body )
-         return document.body.scrollLeft;
-      else
-         return 0;
-   },
-
-   docScrollTop: function() {
-      if ( window.pageYOffset )
-         return window.pageYOffset;
-      else if ( document.documentElement && document.documentElement.scrollTop )
-         return document.documentElement.scrollTop;
-      else if ( document.body )
-         return document.body.scrollTop;
-      else
-         return 0;
-   }
-
-};
+/**
+  *
+  *  Copyright 2005 Sabre Airline Solutions
+  *
+  *  Licensed under the Apache License, Version 2.0 (the "License"); you may not use this
+  *  file except in compliance with the License. You may obtain a copy of the License at
+  *
+  *         http://www.apache.org/licenses/LICENSE-2.0
+  *
+  *  Unless required by applicable law or agreed to in writing, software distributed under the
+  *  License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
+  *  either express or implied. See the License for the specific language governing permissions
+  *  and limitations under the License.
+  **/
+
+
+//-------------------- rico.js
+var Rico = {
+  Version: '1.1.0',
+  prototypeVersion: parseFloat(Prototype.Version.split(".")[0] + "." + Prototype.Version.split(".")[1])
+}
+
+if((typeof Prototype=='undefined') || Rico.prototypeVersion < 1.3)
+      throw("Rico requires the Prototype JavaScript framework >= 1.3");
+
+Rico.ArrayExtensions = new Array();
+
+if (Object.prototype.extend) {
+   Rico.ArrayExtensions[ Rico.ArrayExtensions.length ] = Object.prototype.extend;
+}else{
+  Object.prototype.extend = function(object) {
+    return Object.extend.apply(this, [this, object]);
+  }
+  Rico.ArrayExtensions[ Rico.ArrayExtensions.length ] = Object.prototype.extend;
+}
+
+if (Array.prototype.push) {
+   Rico.ArrayExtensions[ Rico.ArrayExtensions.length ] = Array.prototype.push;
+}
+
+if (!Array.prototype.remove) {
+   Array.prototype.remove = function(dx) {
+      if( isNaN(dx) || dx > this.length )
+         return false;
+      for( var i=0,n=0; i<this.length; i++ )
+         if( i != dx )
+            this[n++]=this[i];
+      this.length-=1;
+   };
+  Rico.ArrayExtensions[ Rico.ArrayExtensions.length ] = Array.prototype.remove;
+}
+
+if (!Array.prototype.removeItem) {
+   Array.prototype.removeItem = function(item) {
+      for ( var i = 0 ; i < this.length ; i++ )
+         if ( this[i] == item ) {
+            this.remove(i);
+            break;
+         }
+   };
+  Rico.ArrayExtensions[ Rico.ArrayExtensions.length ] = Array.prototype.removeItem;
+}
+
+if (!Array.prototype.indices) {
+   Array.prototype.indices = function() {
+      var indexArray = new Array();
+      for ( index in this ) {
+         var ignoreThis = false;
+         for ( var i = 0 ; i < Rico.ArrayExtensions.length ; i++ ) {
+            if ( this[index] == Rico.ArrayExtensions[i] ) {
+               ignoreThis = true;
+               break;
+            }
+         }
+         if ( !ignoreThis )
+            indexArray[ indexArray.length ] = index;
+      }
+      return indexArray;
+   }
+  Rico.ArrayExtensions[ Rico.ArrayExtensions.length ] = Array.prototype.indices;
+}
+
+// Create the loadXML method and xml getter for Mozilla
+if ( window.DOMParser &&
+	  window.XMLSerializer &&
+	  window.Node && Node.prototype && Node.prototype.__defineGetter__ ) {
+
+   if (!Document.prototype.loadXML) {
+      Document.prototype.loadXML = function (s) {
+         var doc2 = (new DOMParser()).parseFromString(s, "text/xml");
+         while (this.hasChildNodes())
+            this.removeChild(this.lastChild);
+
+         for (var i = 0; i < doc2.childNodes.length; i++) {
+            this.appendChild(this.importNode(doc2.childNodes[i], true));
+         }
+      };
+	}
+
+	Document.prototype.__defineGetter__( "xml",
+	   function () {
+		   return (new XMLSerializer()).serializeToString(this);
+	   }
+	 );
+}
+
+document.getElementsByTagAndClassName = function(tagName, className) {
+  if ( tagName == null )
+     tagName = '*';
+
+  var children = document.getElementsByTagName(tagName) || document.all;
+  var elements = new Array();
+
+  if ( className == null )
+    return children;
+
+  for (var i = 0; i < children.length; i++) {
+    var child = children[i];
+    var classNames = child.className.split(' ');
+    for (var j = 0; j < classNames.length; j++) {
+      if (classNames[j] == className) {
+        elements.push(child);
+        break;
+      }
+    }
+  }
+
+  return elements;
+}
+
+
+//-------------------- ricoAccordion.js
+Rico.Accordion = Class.create();
+
+Rico.Accordion.prototype = {
+
+   initialize: function(container, options) {
+      this.container            = $(container);
+      this.lastExpandedTab      = null;
+      this.accordionTabs        = new Array();
+      this.setOptions(options);
+      this._attachBehaviors();
+      if(!container) return;
+
+      this.container.style.borderBottom = '1px solid ' + this.options.borderColor;
+      // validate onloadShowTab
+       if (this.options.onLoadShowTab >= this.accordionTabs.length)
+        this.options.onLoadShowTab = 0;
+
+      // set the initial visual state...
+      for ( var i=0 ; i < this.accordionTabs.length ; i++ )
+      {
+        if (i != this.options.onLoadShowTab){
+         this.accordionTabs[i].collapse();
+         this.accordionTabs[i].content.style.display = 'none';
+        }
+      }
+      this.lastExpandedTab = this.accordionTabs[this.options.onLoadShowTab];
+      if (this.options.panelHeight == 'auto'){
+          var tabToCheck = (this.options.onloadShowTab === 0)? 1 : 0;
+          var titleBarSize = parseInt(RicoUtil.getElementsComputedStyle(this.accordionTabs[tabToCheck].titleBar, 'height'));
+          if (isNaN(titleBarSize))
+            titleBarSize = this.accordionTabs[tabToCheck].titleBar.offsetHeight;
+          
+          var totalTitleBarSize = this.accordionTabs.length * titleBarSize;
+          var parentHeight = parseInt(RicoUtil.getElementsComputedStyle(this.container.parentNode, 'height'));
+          if (isNaN(parentHeight))
+            parentHeight = this.container.parentNode.offsetHeight;
+          
+          this.options.panelHeight = parentHeight - totalTitleBarSize-2;
+      }
+      
+      this.lastExpandedTab.content.style.height = this.options.panelHeight + "px";
+      this.lastExpandedTab.showExpanded();
+      this.lastExpandedTab.titleBar.style.fontWeight = this.options.expandedFontWeight;
+
+   },
+
+   setOptions: function(options) {
+      this.options = {
+         expandedBg          : '#63699c',
+         hoverBg             : '#63699c',
+         collapsedBg         : '#6b79a5',
+         expandedTextColor   : '#ffffff',
+         expandedFontWeight  : 'bold',
+         hoverTextColor      : '#ffffff',
+         collapsedTextColor  : '#ced7ef',
+         collapsedFontWeight : 'normal',
+         hoverTextColor      : '#ffffff',
+         borderColor         : '#1f669b',
+         panelHeight         : 200,
+         onHideTab           : null,
+         onShowTab           : null,
+         onLoadShowTab       : 0
+      }
+      Object.extend(this.options, options || {});
+   },
+
+   showTabByIndex: function( anIndex, animate ) {
+      var doAnimate = arguments.length == 1 ? true : animate;
+      this.showTab( this.accordionTabs[anIndex], doAnimate );
+   },
+
+   showTab: function( accordionTab, animate ) {
+
+      var doAnimate = arguments.length == 1 ? true : animate;
+
+      if ( this.options.onHideTab )
+         this.options.onHideTab(this.lastExpandedTab);
+
+      this.lastExpandedTab.showCollapsed(); 
+      var accordion = this;
+      var lastExpandedTab = this.lastExpandedTab;
+
+      this.lastExpandedTab.content.style.height = (this.options.panelHeight - 1) + 'px';
+      accordionTab.content.style.display = '';
+
+      accordionTab.titleBar.style.fontWeight = this.options.expandedFontWeight;
+
+      if ( doAnimate ) {
+         new Rico.Effect.AccordionSize( this.lastExpandedTab.content,
+                                   accordionTab.content,
+                                   1,
+                                   this.options.panelHeight,
+                                   100, 10,
+                                   { complete: function() {accordion.showTabDone(lastExpandedTab)} } );
+         this.lastExpandedTab = accordionTab;
+      }
+      else {
+         this.lastExpandedTab.content.style.height = "1px";
+         accordionTab.content.style.height = this.options.panelHeight + "px";
+         this.lastExpandedTab = accordionTab;
+         this.showTabDone(lastExpandedTab);
+      }
+   },
+
+   showTabDone: function(collapsedTab) {
+      collapsedTab.content.style.display = 'none';
+      this.lastExpandedTab.showExpanded();
+      if ( this.options.onShowTab )
+         this.options.onShowTab(this.lastExpandedTab);
+   },
+
+   _attachBehaviors: function() {
+      var panels = this._getDirectChildrenByTag(this.container, 'DIV');
+      for ( var i = 0 ; i < panels.length ; i++ ) {
+
+         var tabChildren = this._getDirectChildrenByTag(panels[i],'DIV');
+         if ( tabChildren.length != 2 )
+            continue; // unexpected
+
+         var tabTitleBar   = tabChildren[0];
+         var tabContentBox = tabChildren[1];
+         this.accordionTabs.push( new Rico.Accordion.Tab(this,tabTitleBar,tabContentBox) );
+      }
+   },
+
+   _getDirectChildrenByTag: function(e, tagName) {
+      var kids = new Array();
+      var allKids = e.childNodes;
+      for( var i = 0 ; i < allKids.length ; i++ )
+         if ( allKids[i] && allKids[i].tagName && allKids[i].tagName == tagName )
+            kids.push(allKids[i]);
+      return kids;
+   }
+
+};
+
+Rico.Accordion.Tab = Class.create();
+
+Rico.Accordion.Tab.prototype = {
+
+   initialize: function(accordion, titleBar, content) {
+      this.accordion = accordion;
+      this.titleBar  = titleBar;
+      this.content   = content;
+      this._attachBehaviors();
+   },
+
+   collapse: function() {
+      this.showCollapsed();
+      this.content.style.height = "1px";
+   },
+
+   showCollapsed: function() {
+      this.expanded = false;
+      this.titleBar.style.backgroundColor = this.accordion.options.collapsedBg;
+      this.titleBar.style.color           = this.accordion.options.collapsedTextColor;
+      this.titleBar.style.fontWeight      = this.accordion.options.collapsedFontWeight;
+      this.content.style.overflow = "hidden";
+   },
+
+   showExpanded: function() {
+      this.expanded = true;
+      this.titleBar.style.backgroundColor = this.accordion.options.expandedBg;
+      this.titleBar.style.color           = this.accordion.options.expandedTextColor;
+      this.content.style.overflow         = "visible";
+   },
+
+   titleBarClicked: function(e) {
+      if ( this.accordion.lastExpandedTab == this )
+         return;
+      this.accordion.showTab(this);
+   },
+
+   hover: function(e) {
+		this.titleBar.style.backgroundColor = this.accordion.options.hoverBg;
+		this.titleBar.style.color           = this.accordion.options.hoverTextColor;
+   },
+
+   unhover: function(e) {
+      if ( this.expanded ) {
+         this.titleBar.style.backgroundColor = this.accordion.options.expandedBg;
+         this.titleBar.style.color           = this.accordion.options.expandedTextColor;
+      }
+      else {
+         this.titleBar.style.backgroundColor = this.accordion.options.collapsedBg;
+         this.titleBar.style.color           = this.accordion.options.collapsedTextColor;
+      }
+   },
+
+   _attachBehaviors: function() {
+      this.content.style.border = "1px solid " + this.accordion.options.borderColor;
+      this.content.style.borderTopWidth    = "0px";
+      this.content.style.borderBottomWidth = "0px";
+      this.content.style.margin            = "0px";
+
+      this.titleBar.onclick     = this.titleBarClicked.bindAsEventListener(this);
+      this.titleBar.onmouseover = this.hover.bindAsEventListener(this);
+      this.titleBar.onmouseout  = this.unhover.bindAsEventListener(this);
+   }
+
+};
+
+
+//-------------------- ricoAjaxEngine.js
+Rico.AjaxEngine = Class.create();
+
+Rico.AjaxEngine.prototype = {
+
+   initialize: function() {
+      this.ajaxElements = new Array();
+      this.ajaxObjects  = new Array();
+      this.requestURLS  = new Array();
+      this.options = {};
+   },
+
+   registerAjaxElement: function( anId, anElement ) {
+      if ( !anElement )
+         anElement = $(anId);
+      this.ajaxElements[anId] = anElement;
+   },
+
+   registerAjaxObject: function( anId, anObject ) {
+      this.ajaxObjects[anId] = anObject;
+   },
+
+   registerRequest: function (requestLogicalName, requestURL) {
+      this.requestURLS[requestLogicalName] = requestURL;
+   },
+
+   sendRequest: function(requestName, options) {
+      // Allow for backwards Compatibility
+      if ( arguments.length >= 2 )
+       if (typeof arguments[1] == 'string')
+         options = {parameters: this._createQueryString(arguments, 1)};
+      this.sendRequestWithData(requestName, null, options);
+   },
+
+   sendRequestWithData: function(requestName, xmlDocument, options) {
+      var requestURL = this.requestURLS[requestName];
+      if ( requestURL == null )
+         return;
+
+      // Allow for backwards Compatibility
+      if ( arguments.length >= 3 )
+        if (typeof arguments[2] == 'string')
+          options.parameters = this._createQueryString(arguments, 2);
+
+      new Ajax.Request(requestURL, this._requestOptions(options,xmlDocument));
+   },
+
+   sendRequestAndUpdate: function(requestName,container,options) {
+      // Allow for backwards Compatibility
+      if ( arguments.length >= 3 )
+        if (typeof arguments[2] == 'string')
+          options.parameters = this._createQueryString(arguments, 2);
+
+      this.sendRequestWithDataAndUpdate(requestName, null, container, options);
+   },
+
+   sendRequestWithDataAndUpdate: function(requestName,xmlDocument,container,options) {
+      var requestURL = this.requestURLS[requestName];
+      if ( requestURL == null )
+         return;
+
+      // Allow for backwards Compatibility
+      if ( arguments.length >= 4 )
+        if (typeof arguments[3] == 'string')
+          options.parameters = this._createQueryString(arguments, 3);
+
+      var updaterOptions = this._requestOptions(options,xmlDocument);
+
+      new Ajax.Updater(container, requestURL, updaterOptions);
+   },
+
+   // Private -- not part of intended engine API --------------------------------------------------------------------
+
+   _requestOptions: function(options,xmlDoc) {
+      var requestHeaders = ['X-Rico-Version', Rico.Version ];
+      var sendMethod = 'post';
+      if ( xmlDoc == null )
+        if (Rico.prototypeVersion < 1.4)
+        requestHeaders.push( 'Content-type', 'text/xml' );
+      else
+          sendMethod = 'get';
+      (!options) ? options = {} : '';
+
+      if (!options._RicoOptionsProcessed){
+      // Check and keep any user onComplete functions
+        if (options.onComplete)
+             options.onRicoComplete = options.onComplete;
+        // Fix onComplete
+        if (options.overrideOnComplete)
+          options.onComplete = options.overrideOnComplete;
+        else
+          options.onComplete = this._onRequestComplete.bind(this);
+        options._RicoOptionsProcessed = true;
+      }
+
+     // Set the default options and extend with any user options
+     this.options = {
+                     requestHeaders: requestHeaders,
+                     parameters:     options.parameters,
+                     postBody:       xmlDoc,
+                     method:         sendMethod,
+                     onComplete:     options.onComplete
+                    };
+     // Set any user options:
+     Object.extend(this.options, options);
+     return this.options;
+   },
+
+   _createQueryString: function( theArgs, offset ) {
+      var queryString = ""
+      for ( var i = offset ; i < theArgs.length ; i++ ) {
+          if ( i != offset )
+            queryString += "&";
+
+          var anArg = theArgs[i];
+
+          if ( anArg.name != undefined && anArg.value != undefined ) {
+            queryString += anArg.name +  "=" + escape(anArg.value);
+          }
+          else {
+             var ePos  = anArg.indexOf('=');
+             var argName  = anArg.substring( 0, ePos );
+             var argValue = anArg.substring( ePos + 1 );
+             queryString += argName + "=" + escape(argValue);
+          }
+      }
+      return queryString;
+   },
+
+   _onRequestComplete : function(request) {
+      if(!request)
+          return;
+      // User can set an onFailure option - which will be called by prototype
+      if (request.status != 200)
+        return;
+
+      var response = request.responseXML.getElementsByTagName("ajax-response");
+      if (response == null || response.length != 1)
+         return;
+      this._processAjaxResponse( response[0].childNodes );
+      
+      // Check if user has set a onComplete function
+      var onRicoComplete = this.options.onRicoComplete;
+      if (onRicoComplete != null)
+          onRicoComplete();
+   },
+
+   _processAjaxResponse: function( xmlResponseElements ) {
+      for ( var i = 0 ; i < xmlResponseElements.length ; i++ ) {
+         var responseElement = xmlResponseElements[i];
+
+         // only process nodes of type element.....
+         if ( responseElement.nodeType != 1 )
+            continue;
+
+         var responseType = responseElement.getAttribute("type");
+         var responseId   = responseElement.getAttribute("id");
+
+         if ( responseType == "object" )
+            this._processAjaxObjectUpdate( this.ajaxObjects[ responseId ], responseElement );
+         else if ( responseType == "element" )
+            this._processAjaxElementUpdate( this.ajaxElements[ responseId ], responseElement );
+         else
+            alert('unrecognized AjaxResponse type : ' + responseType );
+      }
+   },
+
+   _processAjaxObjectUpdate: function( ajaxObject, responseElement ) {
+      ajaxObject.ajaxUpdate( responseElement );
+   },
+
+   _processAjaxElementUpdate: function( ajaxElement, responseElement ) {
+      ajaxElement.innerHTML = RicoUtil.getContentAsString(responseElement);
+   }
+
+}
+
+var ajaxEngine = new Rico.AjaxEngine();
+
+
+//-------------------- ricoColor.js
+Rico.Color = Class.create();
+
+Rico.Color.prototype = {
+
+   initialize: function(red, green, blue) {
+      this.rgb = { r: red, g : green, b : blue };
+   },
+
+   setRed: function(r) {
+      this.rgb.r = r;
+   },
+
+   setGreen: function(g) {
+      this.rgb.g = g;
+   },
+
+   setBlue: function(b) {
+      this.rgb.b = b;
+   },
+
+   setHue: function(h) {
+
+      // get an HSB model, and set the new hue...
+      var hsb = this.asHSB();
+      hsb.h = h;
+
+      // convert back to RGB...
+      this.rgb = Rico.Color.HSBtoRGB(hsb.h, hsb.s, hsb.b);
+   },
+
+   setSaturation: function(s) {
+      // get an HSB model, and set the new hue...
+      var hsb = this.asHSB();
+      hsb.s = s;
+
+      // convert back to RGB and set values...
+      this.rgb = Rico.Color.HSBtoRGB(hsb.h, hsb.s, hsb.b);
+   },
+
+   setBrightness: function(b) {
+      // get an HSB model, and set the new hue...
+      var hsb = this.asHSB();
+      hsb.b = b;
+
+      // convert back to RGB and set values...
+      this.rgb = Rico.Color.HSBtoRGB( hsb.h, hsb.s, hsb.b );
+   },
+
+   darken: function(percent) {
+      var hsb  = this.asHSB();
+      this.rgb = Rico.Color.HSBtoRGB(hsb.h, hsb.s, Math.max(hsb.b - percent,0));
+   },
+
+   brighten: function(percent) {
+      var hsb  = this.asHSB();
+      this.rgb = Rico.Color.HSBtoRGB(hsb.h, hsb.s, Math.min(hsb.b + percent,1));
+   },
+
+   blend: function(other) {
+      this.rgb.r = Math.floor((this.rgb.r + other.rgb.r)/2);
+      this.rgb.g = Math.floor((this.rgb.g + other.rgb.g)/2);
+      this.rgb.b = Math.floor((this.rgb.b + other.rgb.b)/2);
+   },
+
+   isBright: function() {
+      var hsb = this.asHSB();
+      return this.asHSB().b > 0.5;
+   },
+
+   isDark: function() {
+      return ! this.isBright();
+   },
+
+   asRGB: function() {
+      return "rgb(" + this.rgb.r + "," + this.rgb.g + "," + this.rgb.b + ")";
+   },
+
+   asHex: function() {
+      return "#" + this.rgb.r.toColorPart() + this.rgb.g.toColorPart() + this.rgb.b.toColorPart();
+   },
+
+   asHSB: function() {
+      return Rico.Color.RGBtoHSB(this.rgb.r, this.rgb.g, this.rgb.b);
+   },
+
+   toString: function() {
+      return this.asHex();
+   }
+
+};
+
+Rico.Color.createFromHex = function(hexCode) {
+  if(hexCode.length==4) {
+    var shortHexCode = hexCode; 
+    var hexCode = '#';
+    for(var i=1;i<4;i++) hexCode += (shortHexCode.charAt(i) + 
+shortHexCode.charAt(i));
+  }
+   if ( hexCode.indexOf('#') == 0 )
+      hexCode = hexCode.substring(1);
+   var red   = hexCode.substring(0,2);
+   var green = hexCode.substring(2,4);
+   var blue  = hexCode.substring(4,6);
+   return new Rico.Color( parseInt(red,16), parseInt(green,16), parseInt(blue,16) );
+}
+
+/**
+ * Factory method for creating a color from the background of
+ * an HTML element.
+ */
+Rico.Color.createColorFromBackground = function(elem) {
+
+   var actualColor = RicoUtil.getElementsComputedStyle($(elem), "backgroundColor", "background-color");
+
+   if ( actualColor == "transparent" && elem.parentNode )
+      return Rico.Color.createColorFromBackground(elem.parentNode);
+
+   if ( actualColor == null )
+      return new Rico.Color(255,255,255);
+
+   if ( actualColor.indexOf("rgb(") == 0 ) {
+      var colors = actualColor.substring(4, actualColor.length - 1 );
+      var colorArray = colors.split(",");
+      return new Rico.Color( parseInt( colorArray[0] ),
+                            parseInt( colorArray[1] ),
+                            parseInt( colorArray[2] )  );
+
+   }
+   else if ( actualColor.indexOf("#") == 0 ) {
+      return Rico.Color.createFromHex(actualColor);
+   }
+   else
+      return new Rico.Color(255,255,255);
+}
+
+Rico.Color.HSBtoRGB = function(hue, saturation, brightness) {
+
+   var red   = 0;
+	var green = 0;
+	var blue  = 0;
+
+   if (saturation == 0) {
+      red = parseInt(brightness * 255.0 + 0.5);
+	   green = red;
+	   blue = red;
+	}
+	else {
+      var h = (hue - Math.floor(hue)) * 6.0;
+      var f = h - Math.floor(h);
+      var p = brightness * (1.0 - saturation);
+      var q = brightness * (1.0 - saturation * f);
+      var t = brightness * (1.0 - (saturation * (1.0 - f)));
+
+      switch (parseInt(h)) {
+         case 0:
+            red   = (brightness * 255.0 + 0.5);
+            green = (t * 255.0 + 0.5);
+            blue  = (p * 255.0 + 0.5);
+            break;
+         case 1:
+            red   = (q * 255.0 + 0.5);
+            green = (brightness * 255.0 + 0.5);
+            blue  = (p * 255.0 + 0.5);
+            break;
+         case 2:
+            red   = (p * 255.0 + 0.5);
+            green = (brightness * 255.0 + 0.5);
+            blue  = (t * 255.0 + 0.5);
+            break;
+         case 3:
+            red   = (p * 255.0 + 0.5);
+            green = (q * 255.0 + 0.5);
+            blue  = (brightness * 255.0 + 0.5);
+            break;
+         case 4:
+            red   = (t * 255.0 + 0.5);
+            green = (p * 255.0 + 0.5);
+            blue  = (brightness * 255.0 + 0.5);
+            break;
+          case 5:
+            red   = (brightness * 255.0 + 0.5);
+            green = (p * 255.0 + 0.5);
+            blue  = (q * 255.0 + 0.5);
+            break;
+	    }
+	}
+
+   return { r : parseInt(red), g : parseInt(green) , b : parseInt(blue) };
+}
+
+Rico.Color.RGBtoHSB = function(r, g, b) {
+
+   var hue;
+   var saturation;
+   var brightness;
+
+   var cmax = (r > g) ? r : g;
+   if (b > cmax)
+      cmax = b;
+
+   var cmin = (r < g) ? r : g;
+   if (b < cmin)
+      cmin = b;
+
+   brightness = cmax / 255.0;
+   if (cmax != 0)
+      saturation = (cmax - cmin)/cmax;
+   else
+      saturation = 0;
+
+   if (saturation == 0)
+      hue = 0;
+   else {
+      var redc   = (cmax - r)/(cmax - cmin);
+    	var greenc = (cmax - g)/(cmax - cmin);
+    	var bluec  = (cmax - b)/(cmax - cmin);
+
+    	if (r == cmax)
+    	   hue = bluec - greenc;
+    	else if (g == cmax)
+    	   hue = 2.0 + redc - bluec;
+      else
+    	   hue = 4.0 + greenc - redc;
+
+    	hue = hue / 6.0;
+    	if (hue < 0)
+    	   hue = hue + 1.0;
+   }
+
+   return { h : hue, s : saturation, b : brightness };
+}
+
+
+//-------------------- ricoCorner.js
+Rico.Corner = {
+
+   round: function(e, options) {
+      var e = $(e);
+      this._setOptions(options);
+
+      var color = this.options.color;
+      if ( this.options.color == "fromElement" )
+         color = this._background(e);
+
+      var bgColor = this.options.bgColor;
+      if ( this.options.bgColor == "fromParent" )
+         bgColor = this._background(e.offsetParent);
+
+      this._roundCornersImpl(e, color, bgColor);
+   },
+
+   _roundCornersImpl: function(e, color, bgColor) {
+      if(this.options.border)
+         this._renderBorder(e,bgColor);
+      if(this._isTopRounded())
+         this._roundTopCorners(e,color,bgColor);
+      if(this._isBottomRounded())
+         this._roundBottomCorners(e,color,bgColor);
+   },
+
+   _renderBorder: function(el,bgColor) {
+      var borderValue = "1px solid " + this._borderColor(bgColor);
+      var borderL = "border-left: "  + borderValue;
+      var borderR = "border-right: " + borderValue;
+      var style   = "style='" + borderL + ";" + borderR +  "'";
+      el.innerHTML = "<div " + style + ">" + el.innerHTML + "</div>"
+   },
+
+   _roundTopCorners: function(el, color, bgColor) {
+      var corner = this._createCorner(bgColor);
+      for(var i=0 ; i < this.options.numSlices ; i++ )
+         corner.appendChild(this._createCornerSlice(color,bgColor,i,"top"));
+      el.style.paddingTop = 0;
+      el.insertBefore(corner,el.firstChild);
+   },
+
+   _roundBottomCorners: function(el, color, bgColor) {
+      var corner = this._createCorner(bgColor);
+      for(var i=(this.options.numSlices-1) ; i >= 0 ; i-- )
+         corner.appendChild(this._createCornerSlice(color,bgColor,i,"bottom"));
+      el.style.paddingBottom = 0;
+      el.appendChild(corner);
+   },
+
+   _createCorner: function(bgColor) {
+      var corner = document.createElement("div");
+      corner.style.backgroundColor = (this._isTransparent() ? "transparent" : bgColor);
+      return corner;
+   },
+
+   _createCornerSlice: function(color,bgColor, n, position) {
+      var slice = document.createElement("span");
+
+      var inStyle = slice.style;
+      inStyle.backgroundColor = color;
+      inStyle.display  = "block";
+      inStyle.height   = "1px";
+      inStyle.overflow = "hidden";
+      inStyle.fontSize = "1px";
+
+      var borderColor = this._borderColor(color,bgColor);
+      if ( this.options.border && n == 0 ) {
+         inStyle.borderTopStyle    = "solid";
+         inStyle.borderTopWidth    = "1px";
+         inStyle.borderLeftWidth   = "0px";
+         inStyle.borderRightWidth  = "0px";
+         inStyle.borderBottomWidth = "0px";
+         inStyle.height            = "0px"; // assumes css compliant box model
+         inStyle.borderColor       = borderColor;
+      }
+      else if(borderColor) {
+         inStyle.borderColor = borderColor;
+         inStyle.borderStyle = "solid";
+         inStyle.borderWidth = "0px 1px";
+      }
+
+      if ( !this.options.compact && (n == (this.options.numSlices-1)) )
+         inStyle.height = "2px";
+
+      this._setMargin(slice, n, position);
+      this._setBorder(slice, n, position);
+      return slice;
+   },
+
+   _setOptions: function(options) {
+      this.options = {
+         corners : "all",
+         color   : "fromElement",
+         bgColor : "fromParent",
+         blend   : true,
+         border  : false,
+         compact : false
+      }
+      Object.extend(this.options, options || {});
+
+      this.options.numSlices = this.options.compact ? 2 : 4;
+      if ( this._isTransparent() )
+         this.options.blend = false;
+   },
+
+   _whichSideTop: function() {
+      if ( this._hasString(this.options.corners, "all", "top") )
+         return "";
+
+      if ( this.options.corners.indexOf("tl") >= 0 && this.options.corners.indexOf("tr") >= 0 )
+         return "";
+
+      if (this.options.corners.indexOf("tl") >= 0)
+         return "left";
+      else if (this.options.corners.indexOf("tr") >= 0)
+          return "right";
+      return "";
+   },
+
+   _whichSideBottom: function() {
+      if ( this._hasString(this.options.corners, "all", "bottom") )
+         return "";
+
+      if ( this.options.corners.indexOf("bl")>=0 && this.options.corners.indexOf("br")>=0 )
+         return "";
+
+      if(this.options.corners.indexOf("bl") >=0)
+         return "left";
+      else if(this.options.corners.indexOf("br")>=0)
+         return "right";
+      return "";
+   },
+
+   _borderColor : function(color,bgColor) {
+      if ( color == "transparent" )
+         return bgColor;
+      else if ( this.options.border )
+         return this.options.border;
+      else if ( this.options.blend )
+         return this._blend( bgColor, color );
+      else
+         return "";
+   },
+
+
+   _setMargin: function(el, n, corners) {
+      var marginSize = this._marginSize(n);
+      var whichSide = corners == "top" ? this._whichSideTop() : this._whichSideBottom();
+
+      if ( whichSide == "left" ) {
+         el.style.marginLeft = marginSize + "px"; el.style.marginRight = "0px";
+      }
+      else if ( whichSide == "right" ) {
+         el.style.marginRight = marginSize + "px"; el.style.marginLeft  = "0px";
+      }
+      else {
+         el.style.marginLeft = marginSize + "px"; el.style.marginRight = marginSize + "px";
+      }
+   },
+
+   _setBorder: function(el,n,corners) {
+      var borderSize = this._borderSize(n);
+      var whichSide = corners == "top" ? this._whichSideTop() : this._whichSideBottom();
+      if ( whichSide == "left" ) {
+         el.style.borderLeftWidth = borderSize + "px"; el.style.borderRightWidth = "0px";
+      }
+      else if ( whichSide == "right" ) {
+         el.style.borderRightWidth = borderSize + "px"; el.style.borderLeftWidth  = "0px";
+      }
+      else {
+         el.style.borderLeftWidth = borderSize + "px"; el.style.borderRightWidth = borderSize + "px";
+      }
+      if (this.options.border != false)
+        el.style.borderLeftWidth = borderSize + "px"; el.style.borderRightWidth = borderSize + "px";
+   },
+
+   _marginSize: function(n) {
+      if ( this._isTransparent() )
+         return 0;
+
+      var marginSizes          = [ 5, 3, 2, 1 ];
+      var blendedMarginSizes   = [ 3, 2, 1, 0 ];
+      var compactMarginSizes   = [ 2, 1 ];
+      var smBlendedMarginSizes = [ 1, 0 ];
+
+      if ( this.options.compact && this.options.blend )
+         return smBlendedMarginSizes[n];
+      else if ( this.options.compact )
+         return compactMarginSizes[n];
+      else if ( this.options.blend )
+         return blendedMarginSizes[n];
+      else
+         return marginSizes[n];
+   },
+
+   _borderSize: function(n) {
+      var transparentBorderSizes = [ 5, 3, 2, 1 ];
+      var blendedBorderSizes     = [ 2, 1, 1, 1 ];
+      var compactBorderSizes     = [ 1, 0 ];
+      var actualBorderSizes      = [ 0, 2, 0, 0 ];
+
+      if ( this.options.compact && (this.options.blend || this._isTransparent()) )
+         return 1;
+      else if ( this.options.compact )
+         return compactBorderSizes[n];
+      else if ( this.options.blend )
+         return blendedBorderSizes[n];
+      else if ( this.options.border )
+         return actualBorderSizes[n];
+      else if ( this._isTransparent() )
+         return transparentBorderSizes[n];
+      return 0;
+   },
+
+   _hasString: function(str) { for(var i=1 ; i<arguments.length ; i++) if (str.indexOf(arguments[i]) >= 0) return true; return false; },
+   _blend: function(c1, c2) { var cc1 = Rico.Color.createFromHex(c1); cc1.blend(Rico.Color.createFromHex(c2)); return cc1; },
+   _background: function(el) { try { return Rico.Color.createColorFromBackground(el).asHex(); } catch(err) { return "#ffffff"; } },
+   _isTransparent: function() { return this.options.color == "transparent"; },
+   _isTopRounded: function() { return this._hasString(this.options.corners, "all", "top", "tl", "tr"); },
+   _isBottomRounded: function() { return this._hasString(this.options.corners, "all", "bottom", "bl", "br"); },
+   _hasSingleTextChild: function(el) { return el.childNodes.length == 1 && el.childNodes[0].nodeType == 3; }
+}
+
+
+//-------------------- ricoDragAndDrop.js
+Rico.DragAndDrop = Class.create();
+
+Rico.DragAndDrop.prototype = {
+
+   initialize: function() {
+      this.dropZones                = new Array();
+      this.draggables               = new Array();
+      this.currentDragObjects       = new Array();
+      this.dragElement              = null;
+      this.lastSelectedDraggable    = null;
+      this.currentDragObjectVisible = false;
+      this.interestedInMotionEvents = false;
+      this._mouseDown = this._mouseDownHandler.bindAsEventListener(this);
+      this._mouseMove = this._mouseMoveHandler.bindAsEventListener(this);
+      this._mouseUp = this._mouseUpHandler.bindAsEventListener(this);
+   },
+
+   registerDropZone: function(aDropZone) {
+      this.dropZones[ this.dropZones.length ] = aDropZone;
+   },
+
+   deregisterDropZone: function(aDropZone) {
+      var newDropZones = new Array();
+      var j = 0;
+      for ( var i = 0 ; i < this.dropZones.length ; i++ ) {
+         if ( this.dropZones[i] != aDropZone )
+            newDropZones[j++] = this.dropZones[i];
+      }
+
+      this.dropZones = newDropZones;
+   },
+
+   clearDropZones: function() {
+      this.dropZones = new Array();
+   },
+
+   registerDraggable: function( aDraggable ) {
+      this.draggables[ this.draggables.length ] = aDraggable;
+      this._addMouseDownHandler( aDraggable );
+   },
+
+   clearSelection: function() {
+      for ( var i = 0 ; i < this.currentDragObjects.length ; i++ )
+         this.currentDragObjects[i].deselect();
+      this.currentDragObjects = new Array();
+      this.lastSelectedDraggable = null;
+   },
+
+   hasSelection: function() {
+      return this.currentDragObjects.length > 0;
+   },
+
+   setStartDragFromElement: function( e, mouseDownElement ) {
+      this.origPos = RicoUtil.toDocumentPosition(mouseDownElement);
+      this.startx = e.screenX - this.origPos.x
+      this.starty = e.screenY - this.origPos.y
+      //this.startComponentX = e.layerX ? e.layerX : e.offsetX;
+      //this.startComponentY = e.layerY ? e.layerY : e.offsetY;
+      //this.adjustedForDraggableSize = false;
+
+      this.interestedInMotionEvents = this.hasSelection();
+      this._terminateEvent(e);
+   },
+
+   updateSelection: function( draggable, extendSelection ) {
+      if ( ! extendSelection )
+         this.clearSelection();
+
+      if ( draggable.isSelected() ) {
+         this.currentDragObjects.removeItem(draggable);
+         draggable.deselect();
+         if ( draggable == this.lastSelectedDraggable )
+            this.lastSelectedDraggable = null;
+      }
+      else {
+         this.currentDragObjects[ this.currentDragObjects.length ] = draggable;
+         draggable.select();
+         this.lastSelectedDraggable = draggable;
+      }
+   },
+
+   _mouseDownHandler: function(e) {
+      if ( arguments.length == 0 )
+         e = event;
+
+      // if not button 1 ignore it...
+      var nsEvent = e.which != undefined;
+      if ( (nsEvent && e.which != 1) || (!nsEvent && e.button != 1))
+         return;
+
+      var eventTarget      = e.target ? e.target : e.srcElement;
+      var draggableObject  = eventTarget.draggable;
+
+      var candidate = eventTarget;
+      while (draggableObject == null && candidate.parentNode) {
+         candidate = candidate.parentNode;
+         draggableObject = candidate.draggable;
+      }
+   
+      if ( draggableObject == null )
+         return;
+
+      this.updateSelection( draggableObject, e.ctrlKey );
+
+      // clear the drop zones postion cache...
+      if ( this.hasSelection() )
+         for ( var i = 0 ; i < this.dropZones.length ; i++ )
+            this.dropZones[i].clearPositionCache();
+
+      this.setStartDragFromElement( e, draggableObject.getMouseDownHTMLElement() );
+   },
+
+
+   _mouseMoveHandler: function(e) {
+      var nsEvent = e.which != undefined;
+      if ( !this.interestedInMotionEvents ) {
+         //this._terminateEvent(e);
+         return;
+      }
+
+      if ( ! this.hasSelection() )
+         return;
+
+      if ( ! this.currentDragObjectVisible )
+         this._startDrag(e);
+
+      if ( !this.activatedDropZones )
+         this._activateRegisteredDropZones();
+
+      //if ( !this.adjustedForDraggableSize )
+      //   this._adjustForDraggableSize(e);
+
+      this._updateDraggableLocation(e);
+      this._updateDropZonesHover(e);
+
+      this._terminateEvent(e);
+   },
+
+   _makeDraggableObjectVisible: function(e)
+   {
+      if ( !this.hasSelection() )
+         return;
+
+      var dragElement;
+      if ( this.currentDragObjects.length > 1 )
+         dragElement = this.currentDragObjects[0].getMultiObjectDragGUI(this.currentDragObjects);
+      else
+         dragElement = this.currentDragObjects[0].getSingleObjectDragGUI();
+
+      // go ahead and absolute position it...
+      if ( RicoUtil.getElementsComputedStyle(dragElement, "position")  != "absolute" )
+         dragElement.style.position = "absolute";
+
+      // need to parent him into the document...
+      if ( dragElement.parentNode == null || dragElement.parentNode.nodeType == 11 )
+         document.body.appendChild(dragElement);
+
+      this.dragElement = dragElement;
+      this._updateDraggableLocation(e);
+
+      this.currentDragObjectVisible = true;
+   },
+
+   /**
+   _adjustForDraggableSize: function(e) {
+      var dragElementWidth  = this.dragElement.offsetWidth;
+      var dragElementHeight = this.dragElement.offsetHeight;
+      if ( this.startComponentX > dragElementWidth )
+         this.startx -= this.startComponentX - dragElementWidth + 2;
+      if ( e.offsetY ) {
+         if ( this.startComponentY > dragElementHeight )
+            this.starty -= this.startComponentY - dragElementHeight + 2;
+      }
+      this.adjustedForDraggableSize = true;
+   },
+   **/
+
+   _leftOffset: function(e) {
+	   return e.offsetX ? document.body.scrollLeft : 0
+	},
+
+   _topOffset: function(e) {
+	   return e.offsetY ? document.body.scrollTop:0
+	},
+
+		
+   _updateDraggableLocation: function(e) {
+      var dragObjectStyle = this.dragElement.style;
+      dragObjectStyle.left = (e.screenX + this._leftOffset(e) - this.startx) + "px"
+      dragObjectStyle.top  = (e.screenY + this._topOffset(e) - this.starty) + "px";
+   },
+
+   _updateDropZonesHover: function(e) {
+      var n = this.dropZones.length;
+      for ( var i = 0 ; i < n ; i++ ) {
+         if ( ! this._mousePointInDropZone( e, this.dropZones[i] ) )
+            this.dropZones[i].hideHover();
+      }
+
+      for ( var i = 0 ; i < n ; i++ ) {
+         if ( this._mousePointInDropZone( e, this.dropZones[i] ) ) {
+            if ( this.dropZones[i].canAccept(this.currentDragObjects) )
+               this.dropZones[i].showHover();
+         }
+      }
+   },
+
+   _startDrag: function(e) {
+      for ( var i = 0 ; i < this.currentDragObjects.length ; i++ )
+         this.currentDragObjects[i].startDrag();
+
+      this._makeDraggableObjectVisible(e);
+   },
+
+   _mouseUpHandler: function(e) {
+      if ( ! this.hasSelection() )
+         return;
+
+      var nsEvent = e.which != undefined;
+      if ( (nsEvent && e.which != 1) || (!nsEvent && e.button != 1))
+         return;
+
+      this.interestedInMotionEvents = false;
+
+      if ( this.dragElement == null ) {
+         this._terminateEvent(e);
+         return;
+      }
+
+      if ( this._placeDraggableInDropZone(e) )
+         this._completeDropOperation(e);
+      else {
+         this._terminateEvent(e);
+         new Rico.Effect.Position( this.dragElement,
+                              this.origPos.x,
+                              this.origPos.y,
+                              200,
+                              20,
+                              { complete : this._doCancelDragProcessing.bind(this) } );
+      }
+
+     Event.stopObserving(document.body, "mousemove", this._mouseMove);
+     Event.stopObserving(document.body, "mouseup",  this._mouseUp);
+   },
+
+   _retTrue: function () {
+      return true;
+   },
+
+   _completeDropOperation: function(e) {
+      if ( this.dragElement != this.currentDragObjects[0].getMouseDownHTMLElement() ) {
+         if ( this.dragElement.parentNode != null )
+            this.dragElement.parentNode.removeChild(this.dragElement);
+      }
+
+      this._deactivateRegisteredDropZones();
+      this._endDrag();
+      this.clearSelection();
+      this.dragElement = null;
+      this.currentDragObjectVisible = false;
+      this._terminateEvent(e);
+   },
+
+   _doCancelDragProcessing: function() {
+      this._cancelDrag();
+
+        if ( this.dragElement != this.currentDragObjects[0].getMouseDownHTMLElement() && this.dragElement)
+           if ( this.dragElement.parentNode != null )
+              this.dragElement.parentNode.removeChild(this.dragElement);
+
+
+      this._deactivateRegisteredDropZones();
+      this.dragElement = null;
+      this.currentDragObjectVisible = false;
+   },
+
+   _placeDraggableInDropZone: function(e) {
+      var foundDropZone = false;
+      var n = this.dropZones.length;
+      for ( var i = 0 ; i < n ; i++ ) {
+         if ( this._mousePointInDropZone( e, this.dropZones[i] ) ) {
+            if ( this.dropZones[i].canAccept(this.currentDragObjects) ) {
+               this.dropZones[i].hideHover();
+               this.dropZones[i].accept(this.currentDragObjects);
+               foundDropZone = true;
+               break;
+            }
+         }
+      }
+
+      return foundDropZone;
+   },
+
+   _cancelDrag: function() {
+      for ( var i = 0 ; i < this.currentDragObjects.length ; i++ )
+         this.currentDragObjects[i].cancelDrag();
+   },
+
+   _endDrag: function() {
+      for ( var i = 0 ; i < this.currentDragObjects.length ; i++ )
+         this.currentDragObjects[i].endDrag();
+   },
+
+   _mousePointInDropZone: function( e, dropZone ) {
+
+      var absoluteRect = dropZone.getAbsoluteRect();
+
+      return e.clientX  > absoluteRect.left + this._leftOffset(e) &&
+             e.clientX  < absoluteRect.right + this._leftOffset(e) &&
+             e.clientY  > absoluteRect.top + this._topOffset(e)   &&
+             e.clientY  < absoluteRect.bottom + this._topOffset(e);
+   },
+
+   _addMouseDownHandler: function( aDraggable )
+   {
+       htmlElement  = aDraggable.getMouseDownHTMLElement();
+      if ( htmlElement  != null ) { 
+         htmlElement.draggable = aDraggable;
+         Event.observe(htmlElement , "mousedown", this._onmousedown.bindAsEventListener(this));
+         Event.observe(htmlElement, "mousedown", this._mouseDown);
+      }
+   },
+
+   _activateRegisteredDropZones: function() {
+      var n = this.dropZones.length;
+      for ( var i = 0 ; i < n ; i++ ) {
+         var dropZone = this.dropZones[i];
+         if ( dropZone.canAccept(this.currentDragObjects) )
+            dropZone.activate();
+      }
+
+      this.activatedDropZones = true;
+   },
+
+   _deactivateRegisteredDropZones: function() {
+      var n = this.dropZones.length;
+      for ( var i = 0 ; i < n ; i++ )
+         this.dropZones[i].deactivate();
+      this.activatedDropZones = false;
+   },
+
+   _onmousedown: function () {
+     Event.observe(document.body, "mousemove", this._mouseMove);
+     Event.observe(document.body, "mouseup",  this._mouseUp);
+   },
+
+   _terminateEvent: function(e) {
+      if ( e.stopPropagation != undefined )
+         e.stopPropagation();
+      else if ( e.cancelBubble != undefined )
+         e.cancelBubble = true;
+
+      if ( e.preventDefault != undefined )
+         e.preventDefault();
+      else
+         e.returnValue = false;
+   },
+
+
+	   initializeEventHandlers: function() {
+	      if ( typeof document.implementation != "undefined" &&
+	         document.implementation.hasFeature("HTML",   "1.0") &&
+	         document.implementation.hasFeature("Events", "2.0") &&
+	         document.implementation.hasFeature("CSS",    "2.0") ) {
+	         document.addEventListener("mouseup",   this._mouseUpHandler.bindAsEventListener(this),  false);
+	         document.addEventListener("mousemove", this._mouseMoveHandler.bindAsEventListener(this), false);
+	      }
+	      else {
+	         document.attachEvent( "onmouseup",   this._mouseUpHandler.bindAsEventListener(this) );
+	         document.attachEvent( "onmousemove", this._mouseMoveHandler.bindAsEventListener(this) );
+	      }
+	   }
+	}
+
+	var dndMgr = new Rico.DragAndDrop();
+	dndMgr.initializeEventHandlers();
+
+
+//-------------------- ricoDraggable.js
+Rico.Draggable = Class.create();
+
+Rico.Draggable.prototype = {
+
+   initialize: function( type, htmlElement ) {
+      this.type          = type;
+      this.htmlElement   = $(htmlElement);
+      this.selected      = false;
+   },
+
+   /**
+    *   Returns the HTML element that should have a mouse down event
+    *   added to it in order to initiate a drag operation
+    *
+    **/
+   getMouseDownHTMLElement: function() {
+      return this.htmlElement;
+   },
+
+   select: function() {
+      this.selected = true;
+
+      if ( this.showingSelected )
+         return;
+
+      var htmlElement = this.getMouseDownHTMLElement();
+
+      var color = Rico.Color.createColorFromBackground(htmlElement);
+      color.isBright() ? color.darken(0.033) : color.brighten(0.033);
+
+      this.saveBackground = RicoUtil.getElementsComputedStyle(htmlElement, "backgroundColor", "background-color");
+      htmlElement.style.backgroundColor = color.asHex();
+      this.showingSelected = true;
+   },
+
+   deselect: function() {
+      this.selected = false;
+      if ( !this.showingSelected )
+         return;
+
+      var htmlElement = this.getMouseDownHTMLElement();
+
+      htmlElement.style.backgroundColor = this.saveBackground;
+      this.showingSelected = false;
+   },
+
+   isSelected: function() {
+      return this.selected;
+   },
+
+   startDrag: function() {
+   },
+
+   cancelDrag: function() {
+   },
+
+   endDrag: function() {
+   },
+
+   getSingleObjectDragGUI: function() {
+      return this.htmlElement;
+   },
+
+   getMultiObjectDragGUI: function( draggables ) {
+      return this.htmlElement;
+   },
+
+   getDroppedGUI: function() {
+      return this.htmlElement;
+   },
+
+   toString: function() {
+      return this.type + ":" + this.htmlElement + ":";
+   }
+
+}
+
+
+//-------------------- ricoDropzone.js
+Rico.Dropzone = Class.create();
+
+Rico.Dropzone.prototype = {
+
+   initialize: function( htmlElement ) {
+      this.htmlElement  = $(htmlElement);
+      this.absoluteRect = null;
+   },
+
+   getHTMLElement: function() {
+      return this.htmlElement;
+   },
+
+   clearPositionCache: function() {
+      this.absoluteRect = null;
+   },
+
+   getAbsoluteRect: function() {
+      if ( this.absoluteRect == null ) {
+         var htmlElement = this.getHTMLElement();
+         var pos = RicoUtil.toViewportPosition(htmlElement);
+
+         this.absoluteRect = {
+            top:    pos.y,
+            left:   pos.x,
+            bottom: pos.y + htmlElement.offsetHeight,
+            right:  pos.x + htmlElement.offsetWidth
+         };
+      }
+      return this.absoluteRect;
+   },
+
+   activate: function() {
+      var htmlElement = this.getHTMLElement();
+      if (htmlElement == null  || this.showingActive)
+         return;
+
+      this.showingActive = true;
+      this.saveBackgroundColor = htmlElement.style.backgroundColor;
+
+      var fallbackColor = "#ffea84";
+      var currentColor = Rico.Color.createColorFromBackground(htmlElement);
+      if ( currentColor == null )
+         htmlElement.style.backgroundColor = fallbackColor;
+      else {
+         currentColor.isBright() ? currentColor.darken(0.2) : currentColor.brighten(0.2);
+         htmlElement.style.backgroundColor = currentColor.asHex();
+      }
+   },
+
+   deactivate: function() {
+      var htmlElement = this.getHTMLElement();
+      if (htmlElement == null || !this.showingActive)
+         return;
+
+      htmlElement.style.backgroundColor = this.saveBackgroundColor;
+      this.showingActive = false;
+      this.saveBackgroundColor = null;
+   },
+
+   showHover: function() {
+      var htmlElement = this.getHTMLElement();
+      if ( htmlElement == null || this.showingHover )
+         return;
+
+      this.saveBorderWidth = htmlElement.style.borderWidth;
+      this.saveBorderStyle = htmlElement.style.borderStyle;
+      this.saveBorderColor = htmlElement.style.borderColor;
+
+      this.showingHover = true;
+      htmlElement.style.borderWidth = "1px";
+      htmlElement.style.borderStyle = "solid";
+      //htmlElement.style.borderColor = "#ff9900";
+      htmlElement.style.borderColor = "#ffff00";
+   },
+
+   hideHover: function() {
+      var htmlElement = this.getHTMLElement();
+      if ( htmlElement == null || !this.showingHover )
+         return;
+
+      htmlElement.style.borderWidth = this.saveBorderWidth;
+      htmlElement.style.borderStyle = this.saveBorderStyle;
+      htmlElement.style.borderColor = this.saveBorderColor;
+      this.showingHover = false;
+   },
+
+   canAccept: function(draggableObjects) {
+      return true;
+   },
+
+   accept: function(draggableObjects) {
+      var htmlElement = this.getHTMLElement();
+      if ( htmlElement == null )
+         return;
+
+      n = draggableObjects.length;
+      for ( var i = 0 ; i < n ; i++ )
+      {
+         var theGUI = draggableObjects[i].getDroppedGUI();
+         if ( RicoUtil.getElementsComputedStyle( theGUI, "position" ) == "absolute" )
+         {
+            theGUI.style.position = "static";
+            theGUI.style.top = "";
+            theGUI.style.top = "";
+         }
+         htmlElement.appendChild(theGUI);
+      }
+   }
+}
+
+
+//-------------------- ricoEffects.js
+
+/**
+  *  Use the Effect namespace for effects.  If using scriptaculous effects
+  *  this will already be defined, otherwise we'll just create an empty
+  *  object for it...
+ **/
+if ( window.Effect == undefined )
+   Rico.Effect = {};
+
+Rico.Effect.SizeAndPosition = Class.create();
+Rico.Effect.SizeAndPosition.prototype = {
+
+   initialize: function(element, x, y, w, h, duration, steps, options) {
+      this.element = $(element);
+      this.x = x;
+      this.y = y;
+      this.w = w;
+      this.h = h;
+      this.duration = duration;
+      this.steps    = steps;
+      this.options  = arguments[7] || {};
+
+      this.sizeAndPosition();
+   },
+
+   sizeAndPosition: function() {
+      if (this.isFinished()) {
+         if(this.options.complete) this.options.complete(this);
+         return;
+      }
+
+      if (this.timer)
+         clearTimeout(this.timer);
+
+      var stepDuration = Math.round(this.duration/this.steps) ;
+
+      // Get original values: x,y = top left corner;  w,h = width height
+      var currentX = this.element.offsetLeft;
+      var currentY = this.element.offsetTop;
+      var currentW = this.element.offsetWidth;
+      var currentH = this.element.offsetHeight;
+
+      // If values not set, or zero, we do not modify them, and take original as final as well
+      this.x = (this.x) ? this.x : currentX;
+      this.y = (this.y) ? this.y : currentY;
+      this.w = (this.w) ? this.w : currentW;
+      this.h = (this.h) ? this.h : currentH;
+
+      // how much do we need to modify our values for each step?
+      var difX = this.steps >  0 ? (this.x - currentX)/this.steps : 0;
+      var difY = this.steps >  0 ? (this.y - currentY)/this.steps : 0;
+      var difW = this.steps >  0 ? (this.w - currentW)/this.steps : 0;
+      var difH = this.steps >  0 ? (this.h - currentH)/this.steps : 0;
+
+      this.moveBy(difX, difY);
+      this.resizeBy(difW, difH);
+
+      this.duration -= stepDuration;
+      this.steps--;
+
+      this.timer = setTimeout(this.sizeAndPosition.bind(this), stepDuration);
+   },
+
+   isFinished: function() {
+      return this.steps <= 0;
+   },
+
+   moveBy: function( difX, difY ) {
+      var currentLeft = this.element.offsetLeft;
+      var currentTop  = this.element.offsetTop;
+      var intDifX     = parseInt(difX);
+      var intDifY     = parseInt(difY);
+
+      var style = this.element.style;
+      if ( intDifX != 0 )
+         style.left = (currentLeft + intDifX) + "px";
+      if ( intDifY != 0 )
+         style.top  = (currentTop + intDifY) + "px";
+   },
+
+   resizeBy: function( difW, difH ) {
+      var currentWidth  = this.element.offsetWidth;
+      var currentHeight = this.element.offsetHeight;
+      var intDifW       = parseInt(difW);
+      var intDifH       = parseInt(difH);
+
+      var style = this.element.style;
+      if ( intDifW != 0 )
+         style.width   = (currentWidth  + intDifW) + "px";
+      if ( intDifH != 0 )
+         style.height  = (currentHeight + intDifH) + "px";
+   }
+}
+
+Rico.Effect.Size = Class.create();
+Rico.Effect.Size.prototype = {
+
+   initialize: function(element, w, h, duration, steps, options) {
+      new Rico.Effect.SizeAndPosition(element, null, null, w, h, duration, steps, options);
+  }
+}
+
+Rico.Effect.Position = Class.create();
+Rico.Effect.Position.prototype = {
+
+   initialize: function(element, x, y, duration, steps, options) {
+      new Rico.Effect.SizeAndPosition(element, x, y, null, null, duration, steps, options);
+  }
+}
+
+Rico.Effect.Round = Class.create();
+Rico.Effect.Round.prototype = {
+
+   initialize: function(tagName, className, options) {
+      var elements = document.getElementsByTagAndClassName(tagName,className);
+      for ( var i = 0 ; i < elements.length ; i++ )
+         Rico.Corner.round( elements[i], options );
+   }
+};
+
+Rico.Effect.FadeTo = Class.create();
+Rico.Effect.FadeTo.prototype = {
+
+   initialize: function( element, opacity, duration, steps, options) {
+      this.element  = $(element);
+      this.opacity  = opacity;
+      this.duration = duration;
+      this.steps    = steps;
+      this.options  = arguments[4] || {};
+      this.fadeTo();
+   },
+
+   fadeTo: function() {
+      if (this.isFinished()) {
+         if(this.options.complete) this.options.complete(this);
+         return;
+      }
+
+      if (this.timer)
+         clearTimeout(this.timer);
+
+      var stepDuration = Math.round(this.duration/this.steps) ;
+      var currentOpacity = this.getElementOpacity();
+      var delta = this.steps > 0 ? (this.opacity - currentOpacity)/this.steps : 0;
+
+      this.changeOpacityBy(delta);
+      this.duration -= stepDuration;
+      this.steps--;
+
+      this.timer = setTimeout(this.fadeTo.bind(this), stepDuration);
+   },
+
+   changeOpacityBy: function(v) {
+      var currentOpacity = this.getElementOpacity();
+      var newOpacity = Math.max(0, Math.min(currentOpacity+v, 1));
+      this.element.ricoOpacity = newOpacity;
+
+      this.element.style.filter = "alpha(opacity:"+Math.round(newOpacity*100)+")";
+      this.element.style.opacity = newOpacity; /*//*/;
+   },
+
+   isFinished: function() {
+      return this.steps <= 0;
+   },
+
+   getElementOpacity: function() {
+      if ( this.element.ricoOpacity == undefined ) {
+         var opacity = RicoUtil.getElementsComputedStyle(this.element, 'opacity');
+         this.element.ricoOpacity = opacity != undefined ? opacity : 1.0;
+      }
+      return parseFloat(this.element.ricoOpacity);
+   }
+}
+
+Rico.Effect.AccordionSize = Class.create();
+
+Rico.Effect.AccordionSize.prototype = {
+
+   initialize: function(e1, e2, start, end, duration, steps, options) {
+      this.e1       = $(e1);
+      this.e2       = $(e2);
+      this.start    = start;
+      this.end      = end;
+      this.duration = duration;
+      this.steps    = steps;
+      this.options  = arguments[6] || {};
+
+      this.accordionSize();
+   },
+
+   accordionSize: function() {
+
+      if (this.isFinished()) {
+         // just in case there are round errors or such...
+         this.e1.style.height = this.start + "px";
+         this.e2.style.height = this.end + "px";
+
+         if(this.options.complete)
+            this.options.complete(this);
+         return;
+      }
+
+      if (this.timer)
+         clearTimeout(this.timer);
+
+      var stepDuration = Math.round(this.duration/this.steps) ;
+
+      var diff = this.steps > 0 ? (parseInt(this.e1.offsetHeight) - this.start)/this.steps : 0;
+      this.resizeBy(diff);
+
+      this.duration -= stepDuration;
+      this.steps--;
+
+      this.timer = setTimeout(this.accordionSize.bind(this), stepDuration);
+   },
+
+   isFinished: function() {
+      return this.steps <= 0;
+   },
+
+   resizeBy: function(diff) {
+      var h1Height = this.e1.offsetHeight;
+      var h2Height = this.e2.offsetHeight;
+      var intDiff = parseInt(diff);
+      if ( diff != 0 ) {
+         this.e1.style.height = (h1Height - intDiff) + "px";
+         this.e2.style.height = (h2Height + intDiff) + "px";
+      }
+   }
+
+};
+
+
+//-------------------- ricoLiveGrid.js
+// Rico.LiveGridMetaData -----------------------------------------------------
+
+Rico.LiveGridMetaData = Class.create();
+
+Rico.LiveGridMetaData.prototype = {
+
+   initialize: function( pageSize, totalRows, columnCount, options ) {
+      this.pageSize  = pageSize;
+      this.totalRows = totalRows;
+      this.setOptions(options);
+      this.ArrowHeight = 16;
+      this.columnCount = columnCount;
+   },
+
+   setOptions: function(options) {
+      this.options = {
+         largeBufferSize    : 7.0,   // 7 pages
+         nearLimitFactor    : 0.2    // 20% of buffer
+      };
+      Object.extend(this.options, options || {});
+   },
+
+   getPageSize: function() {
+      return this.pageSize;
+   },
+
+   getTotalRows: function() {
+      return this.totalRows;
+   },
+
+   setTotalRows: function(n) {
+      this.totalRows = n;
+   },
+
+   getLargeBufferSize: function() {
+      return parseInt(this.options.largeBufferSize * this.pageSize);
+   },
+
+   getLimitTolerance: function() {
+      return parseInt(this.getLargeBufferSize() * this.options.nearLimitFactor);
+   }
+};
+
+// Rico.LiveGridScroller -----------------------------------------------------
+
+Rico.LiveGridScroller = Class.create();
+
+Rico.LiveGridScroller.prototype = {
+
+   initialize: function(liveGrid, viewPort) {
+      this.isIE = navigator.userAgent.toLowerCase().indexOf("msie") >= 0;
+      this.liveGrid = liveGrid;
+      this.metaData = liveGrid.metaData;
+      this.createScrollBar();
+      this.scrollTimeout = null;
+      this.lastScrollPos = 0;
+      this.viewPort = viewPort;
+      this.rows = new Array();
+   },
+
+   isUnPlugged: function() {
+      return this.scrollerDiv.onscroll == null;
+   },
+
+   plugin: function() {
+      this.scrollerDiv.onscroll = this.handleScroll.bindAsEventListener(this);
+   },
+
+   unplug: function() {
+      this.scrollerDiv.onscroll = null;
+   },
+
+   sizeIEHeaderHack: function() {
+      if ( !this.isIE ) return;
+      var headerTable = $(this.liveGrid.tableId + "_header");
+      if ( headerTable )
+         headerTable.rows[0].cells[0].style.width =
+            (headerTable.rows[0].cells[0].offsetWidth + 1) + "px";
+   },
+
+   createScrollBar: function() {
+      var visibleHeight = this.liveGrid.viewPort.visibleHeight();
+      // create the outer div...
+      this.scrollerDiv  = document.createElement("div");
+      var scrollerStyle = this.scrollerDiv.style;
+      scrollerStyle.borderRight = this.liveGrid.options.scrollerBorderRight;
+      scrollerStyle.position    = "relative";
+      scrollerStyle.left        = this.isIE ? "-6px" : "-3px";
+      scrollerStyle.width       = "19px";
+      scrollerStyle.height      = visibleHeight + "px";
+      scrollerStyle.overflow    = "auto";
+
+      // create the inner div...
+      this.heightDiv = document.createElement("div");
+      this.heightDiv.style.width  = "1px";
+
+      this.heightDiv.style.height = parseInt(visibleHeight *
+                        this.metaData.getTotalRows()/this.metaData.getPageSize()) + "px" ;
+      this.scrollerDiv.appendChild(this.heightDiv);
+      this.scrollerDiv.onscroll = this.handleScroll.bindAsEventListener(this);
+
+     var table = this.liveGrid.table;
+     table.parentNode.parentNode.insertBefore( this.scrollerDiv, table.parentNode.nextSibling );
+  	  var eventName = this.isIE ? "mousewheel" : "DOMMouseScroll";
+	  Event.observe(table, eventName, 
+	                function(evt) {
+	                   if (evt.wheelDelta>=0 || evt.detail < 0) //wheel-up
+	                      this.scrollerDiv.scrollTop -= (2*this.viewPort.rowHeight);
+	                   else
+	                      this.scrollerDiv.scrollTop += (2*this.viewPort.rowHeight);
+	                   this.handleScroll(false);
+	                }.bindAsEventListener(this), 
+	                false);
+     },
+
+   updateSize: function() {
+      var table = this.liveGrid.table;
+      var visibleHeight = this.viewPort.visibleHeight();
+      this.heightDiv.style.height = parseInt(visibleHeight *
+                                  this.metaData.getTotalRows()/this.metaData.getPageSize()) + "px";
+   },
+
+   rowToPixel: function(rowOffset) {
+      return (rowOffset / this.metaData.getTotalRows()) * this.heightDiv.offsetHeight
+   },
+   
+   moveScroll: function(rowOffset) {
+      this.scrollerDiv.scrollTop = this.rowToPixel(rowOffset);
+      if ( this.metaData.options.onscroll )
+         this.metaData.options.onscroll( this.liveGrid, rowOffset );
+   },
+
+   handleScroll: function() {
+     if ( this.scrollTimeout )
+         clearTimeout( this.scrollTimeout );
+
+    var scrollDiff = this.lastScrollPos-this.scrollerDiv.scrollTop;
+    if (scrollDiff != 0.00) {
+       var r = this.scrollerDiv.scrollTop % this.viewPort.rowHeight;
+       if (r != 0) {
+          this.unplug();
+          if ( scrollDiff < 0 ) {
+             this.scrollerDiv.scrollTop += (this.viewPort.rowHeight-r);
+          } else {
+             this.scrollerDiv.scrollTop -= r;
+          }
+          this.plugin();
+       }
+    }
+    var contentOffset = parseInt(this.scrollerDiv.scrollTop / this.viewPort.rowHeight);
+    this.liveGrid.requestContentRefresh(contentOffset);
+    this.viewPort.scrollTo(this.scrollerDiv.scrollTop);
+
+    if ( this.metaData.options.onscroll )
+       this.metaData.options.onscroll( this.liveGrid, contentOffset );
+
+    this.scrollTimeout = setTimeout(this.scrollIdle.bind(this), 1200 );
+    this.lastScrollPos = this.scrollerDiv.scrollTop;
+
+   },
+
+   scrollIdle: function() {
+      if ( this.metaData.options.onscrollidle )
+         this.metaData.options.onscrollidle();
+   }
+};
+
+// Rico.LiveGridBuffer -----------------------------------------------------
+
+Rico.LiveGridBuffer = Class.create();
+
+Rico.LiveGridBuffer.prototype = {
+
+   initialize: function(metaData, viewPort) {
+      this.startPos = 0;
+      this.size     = 0;
+      this.metaData = metaData;
+      this.rows     = new Array();
+      this.updateInProgress = false;
+      this.viewPort = viewPort;
+      this.maxBufferSize = metaData.getLargeBufferSize() * 2;
+      this.maxFetchSize = metaData.getLargeBufferSize();
+      this.lastOffset = 0;
+   },
+
+   getBlankRow: function() {
+      if (!this.blankRow ) {
+         this.blankRow = new Array();
+         for ( var i=0; i < this.metaData.columnCount ; i++ ) 
+            this.blankRow[i] = "&nbsp;";
+     }
+     return this.blankRow;
+   },
+
+   loadRows: function(ajaxResponse) {
+      var rowsElement = ajaxResponse.getElementsByTagName('rows')[0];
+      this.updateUI = rowsElement.getAttribute("update_ui") == "true"
+      var newRows = new Array()
+      var trs = rowsElement.getElementsByTagName("tr");
+      for ( var i=0 ; i < trs.length; i++ ) {
+         var row = newRows[i] = new Array(); 
+         var cells = trs[i].getElementsByTagName("td");
+         for ( var j=0; j < cells.length ; j++ ) {
+            var cell = cells[j];
+            var convertSpaces = cell.getAttribute("convert_spaces") == "true";
+            var cellContent = RicoUtil.getContentAsString(cell);
+            row[j] = convertSpaces ? this.convertSpaces(cellContent) : cellContent;
+            if (!row[j]) 
+               row[j] = '&nbsp;';
+         }
+      }
+      return newRows;
+   },
+      
+   update: function(ajaxResponse, start) {
+     var newRows = this.loadRows(ajaxResponse);
+      if (this.rows.length == 0) { // initial load
+         this.rows = newRows;
+         this.size = this.rows.length;
+         this.startPos = start;
+         return;
+      }
+      if (start > this.startPos) { //appending
+         if (this.startPos + this.rows.length < start) {
+            this.rows =  newRows;
+            this.startPos = start;//
+         } else {
+              this.rows = this.rows.concat( newRows.slice(0, newRows.length));
+            if (this.rows.length > this.maxBufferSize) {
+               var fullSize = this.rows.length;
+               this.rows = this.rows.slice(this.rows.length - this.maxBufferSize, this.rows.length)
+               this.startPos = this.startPos +  (fullSize - this.rows.length);
+            }
+         }
+      } else { //prepending
+         if (start + newRows.length < this.startPos) {
+            this.rows =  newRows;
+         } else {
+            this.rows = newRows.slice(0, this.startPos).concat(this.rows);
+            if (this.rows.length > this.maxBufferSize) 
+               this.rows = this.rows.slice(0, this.maxBufferSize)
+         }
+         this.startPos =  start;
+      }
+      this.size = this.rows.length;
+   },
+   
+   clear: function() {
+      this.rows = new Array();
+      this.startPos = 0;
+      this.size = 0;
+   },
+
+   isOverlapping: function(start, size) {
+      return ((start < this.endPos()) && (this.startPos < start + size)) || (this.endPos() == 0)
+   },
+
+   isInRange: function(position) {
+      return (position >= this.startPos) && (position + this.metaData.getPageSize() <= this.endPos()); 
+             //&& this.size()  != 0;
+   },
+
+   isNearingTopLimit: function(position) {
+      return position - this.startPos < this.metaData.getLimitTolerance();
+   },
+
+   endPos: function() {
+      return this.startPos + this.rows.length;
+   },
+   
+   isNearingBottomLimit: function(position) {
+      return this.endPos() - (position + this.metaData.getPageSize()) < this.metaData.getLimitTolerance();
+   },
+
+   isAtTop: function() {
+      return this.startPos == 0;
+   },
+
+   isAtBottom: function() {
+      return this.endPos() == this.metaData.getTotalRows();
+   },
+
+   isNearingLimit: function(position) {
+      return ( !this.isAtTop()    && this.isNearingTopLimit(position)) ||
+             ( !this.isAtBottom() && this.isNearingBottomLimit(position) )
+   },
+
+   getFetchSize: function(offset) {
+      var adjustedOffset = this.getFetchOffset(offset);
+      var adjustedSize = 0;
+      if (adjustedOffset >= this.startPos) { //apending
+         var endFetchOffset = this.maxFetchSize  + adjustedOffset;
+         if (endFetchOffset > this.metaData.totalRows)
+            endFetchOffset = this.metaData.totalRows;
+         adjustedSize = endFetchOffset - adjustedOffset;  
+			if(adjustedOffset == 0 && adjustedSize < this.maxFetchSize){
+			   adjustedSize = this.maxFetchSize;
+			}
+      } else {//prepending
+         var adjustedSize = this.startPos - adjustedOffset;
+         if (adjustedSize > this.maxFetchSize)
+            adjustedSize = this.maxFetchSize;
+      }
+      return adjustedSize;
+   }, 
+
+   getFetchOffset: function(offset) {
+      var adjustedOffset = offset;
+      if (offset > this.startPos)  //apending
+         adjustedOffset = (offset > this.endPos()) ? offset :  this.endPos(); 
+      else { //prepending
+         if (offset + this.maxFetchSize >= this.startPos) {
+            var adjustedOffset = this.startPos - this.maxFetchSize;
+            if (adjustedOffset < 0)
+               adjustedOffset = 0;
+         }
+      }
+      this.lastOffset = adjustedOffset;
+      return adjustedOffset;
+   },
+
+   getRows: function(start, count) {
+      var begPos = start - this.startPos
+      var endPos = begPos + count
+
+      // er? need more data...
+      if ( endPos > this.size )
+         endPos = this.size
+
+      var results = new Array()
+      var index = 0;
+      for ( var i=begPos ; i < endPos; i++ ) {
+         results[index++] = this.rows[i]
+      }
+      return results
+   },
+
+   convertSpaces: function(s) {
+      return s.split(" ").join("&nbsp;");
+   }
+
+};
+
+
+//Rico.GridViewPort --------------------------------------------------
+Rico.GridViewPort = Class.create();
+
+Rico.GridViewPort.prototype = {
+
+   initialize: function(table, rowHeight, visibleRows, buffer, liveGrid) {
+      this.lastDisplayedStartPos = 0;
+      this.div = table.parentNode;
+      this.table = table
+      this.rowHeight = rowHeight;
+      this.div.style.height = this.rowHeight * visibleRows;
+      this.div.style.overflow = "hidden";
+      this.buffer = buffer;
+      this.liveGrid = liveGrid;
+      this.visibleRows = visibleRows + 1;
+      this.lastPixelOffset = 0;
+      this.startPos = 0;
+   },
+
+   populateRow: function(htmlRow, row) {
+      for (var j=0; j < row.length; j++) {
+         htmlRow.cells[j].innerHTML = row[j]
+      }
+   },
+   
+   bufferChanged: function() {
+      this.refreshContents( parseInt(this.lastPixelOffset / this.rowHeight));
+   },
+   
+   clearRows: function() {
+      if (!this.isBlank) {
+         this.liveGrid.table.className = this.liveGrid.options.loadingClass;
+         for (var i=0; i < this.visibleRows; i++)
+            this.populateRow(this.table.rows[i], this.buffer.getBlankRow());
+         this.isBlank = true;
+      }
+   },
+   
+   clearContents: function() {   
+      this.clearRows();
+      this.scrollTo(0);
+      this.startPos = 0;
+      this.lastStartPos = -1;   
+   },
+   
+   refreshContents: function(startPos) {
+      if (startPos == this.lastRowPos && !this.isPartialBlank && !this.isBlank) {
+         return;
+      }
+      if ((startPos + this.visibleRows < this.buffer.startPos)  
+          || (this.buffer.startPos + this.buffer.size < startPos) 
+          || (this.buffer.size == 0)) {
+         this.clearRows();
+         return;
+      }
+      this.isBlank = false;
+      var viewPrecedesBuffer = this.buffer.startPos > startPos
+      var contentStartPos = viewPrecedesBuffer ? this.buffer.startPos: startPos; 
+      var contentEndPos = (this.buffer.startPos + this.buffer.size < startPos + this.visibleRows) 
+                                 ? this.buffer.startPos + this.buffer.size
+                                 : startPos + this.visibleRows;
+      var rowSize = contentEndPos - contentStartPos;
+      var rows = this.buffer.getRows(contentStartPos, rowSize ); 
+      var blankSize = this.visibleRows - rowSize;
+      var blankOffset = viewPrecedesBuffer ? 0: rowSize;
+      var contentOffset = viewPrecedesBuffer ? blankSize: 0;
+
+      for (var i=0; i < rows.length; i++) {//initialize what we have
+        this.populateRow(this.table.rows[i + contentOffset], rows[i]);
+      }
+      for (var i=0; i < blankSize; i++) {// blank out the rest 
+        this.populateRow(this.table.rows[i + blankOffset], this.buffer.getBlankRow());
+      }
+      this.isPartialBlank = blankSize > 0;
+      this.lastRowPos = startPos;
+
+       this.liveGrid.table.className = this.liveGrid.options.tableClass;
+       // Check if user has set a onRefreshComplete function
+       var onRefreshComplete = this.liveGrid.options.onRefreshComplete;
+       if (onRefreshComplete != null)
+           onRefreshComplete();
+   },
+
+   scrollTo: function(pixelOffset) {      
+      if (this.lastPixelOffset == pixelOffset)
+         return;
+
+      this.refreshContents(parseInt(pixelOffset / this.rowHeight))
+      this.div.scrollTop = pixelOffset % this.rowHeight        
+      
+      this.lastPixelOffset = pixelOffset;
+   },
+   
+   visibleHeight: function() {
+      return parseInt(RicoUtil.getElementsComputedStyle(this.div, 'height'));
+   }
+
+};
+
+
+Rico.LiveGridRequest = Class.create();
+Rico.LiveGridRequest.prototype = {
+   initialize: function( requestOffset, options ) {
+      this.requestOffset = requestOffset;
+   }
+};
+
+// Rico.LiveGrid -----------------------------------------------------
+
+Rico.LiveGrid = Class.create();
+
+Rico.LiveGrid.prototype = {
+
+   initialize: function( tableId, visibleRows, totalRows, url, options, ajaxOptions ) {
+
+     this.options = {
+                tableClass:           $(tableId).className,
+                loadingClass:         $(tableId).className,
+                scrollerBorderRight: '1px solid #ababab',
+                bufferTimeout:        20000,
+                sortAscendImg:        'images/sort_asc.gif',
+                sortDescendImg:       'images/sort_desc.gif',
+                sortImageWidth:       9,
+                sortImageHeight:      5,
+                ajaxSortURLParms:     [],
+                onRefreshComplete:    null,
+                requestParameters:    null,
+                inlineStyles:         true
+                };
+      Object.extend(this.options, options || {});
+
+      this.ajaxOptions = {parameters: null};
+      Object.extend(this.ajaxOptions, ajaxOptions || {});
+
+      this.tableId     = tableId; 
+      this.table       = $(tableId);
+
+      this.addLiveGridHtml();
+
+      var columnCount  = this.table.rows[0].cells.length;
+      this.metaData    = new Rico.LiveGridMetaData(visibleRows, totalRows, columnCount, options);
+      this.buffer      = new Rico.LiveGridBuffer(this.metaData);
+
+      var rowCount = this.table.rows.length;
+      this.viewPort =  new Rico.GridViewPort(this.table, 
+                                            this.table.offsetHeight/rowCount,
+                                            visibleRows,
+                                            this.buffer, this);
+      this.scroller    = new Rico.LiveGridScroller(this,this.viewPort);
+      this.options.sortHandler = this.sortHandler.bind(this);
+
+      if ( $(tableId + '_header') )
+         this.sort = new Rico.LiveGridSort(tableId + '_header', this.options)
+
+      this.processingRequest = null;
+      this.unprocessedRequest = null;
+
+      this.initAjax(url);
+      if ( this.options.prefetchBuffer || this.options.prefetchOffset > 0) {
+         var offset = 0;
+         if (this.options.offset ) {
+            offset = this.options.offset;            
+            this.scroller.moveScroll(offset);
+            this.viewPort.scrollTo(this.scroller.rowToPixel(offset));            
+         }
+         if (this.options.sortCol) {
+             this.sortCol = options.sortCol;
+             this.sortDir = options.sortDir;
+         }
+         this.requestContentRefresh(offset);
+      }
+   },
+
+   addLiveGridHtml: function() {
+     // Check to see if need to create a header table.
+     if (this.table.getElementsByTagName("thead").length > 0){
+       // Create Table this.tableId+'_header'
+       var tableHeader = this.table.cloneNode(true);
+       tableHeader.setAttribute('id', this.tableId+'_header');
+       tableHeader.setAttribute('class', this.table.className+'_header');
+
+       // Clean up and insert
+       for( var i = 0; i < tableHeader.tBodies.length; i++ ) 
+       tableHeader.removeChild(tableHeader.tBodies[i]);
+       this.table.deleteTHead();
+       this.table.parentNode.insertBefore(tableHeader,this.table);
+     }
+
+    new Insertion.Before(this.table, "<div id='"+this.tableId+"_container'></div>");
+    this.table.previousSibling.appendChild(this.table);
+    new Insertion.Before(this.table,"<div id='"+this.tableId+"_viewport' style='float:left;'></div>");
+    this.table.previousSibling.appendChild(this.table);
+   },
+
+
+   resetContents: function() {
+      this.scroller.moveScroll(0);
+      this.buffer.clear();
+      this.viewPort.clearContents();
+   },
+   
+   sortHandler: function(column) {
+	   if(!column) return ;
+      this.sortCol = column.name;
+      this.sortDir = column.currentSort;
+
+      this.resetContents();
+      this.requestContentRefresh(0) 
+   },
+
+   adjustRowSize: function() {
+	  
+	},
+	
+   setTotalRows: function( newTotalRows ) {
+      this.resetContents();
+      this.metaData.setTotalRows(newTotalRows);
+      this.scroller.updateSize();
+   },
+
+   initAjax: function(url) {
+      ajaxEngine.registerRequest( this.tableId + '_request', url );
+      ajaxEngine.registerAjaxObject( this.tableId + '_updater', this );
+   },
+
+   invokeAjax: function() {
+   },
+
+   handleTimedOut: function() {
+      //server did not respond in 4 seconds... assume that there could have been
+      //an error or something, and allow requests to be processed again...
+      this.processingRequest = null;
+      this.processQueuedRequest();
+   },
+
+   fetchBuffer: function(offset) {
+      if ( this.buffer.isInRange(offset) &&
+         !this.buffer.isNearingLimit(offset)) {
+         return;
+         }
+      if (this.processingRequest) {
+          this.unprocessedRequest = new Rico.LiveGridRequest(offset);
+         return;
+      }
+      var bufferStartPos = this.buffer.getFetchOffset(offset);
+      this.processingRequest = new Rico.LiveGridRequest(offset);
+      this.processingRequest.bufferOffset = bufferStartPos;   
+      var fetchSize = this.buffer.getFetchSize(offset);
+      var partialLoaded = false;
+      
+      var queryString
+      if (this.options.requestParameters)
+         queryString = this._createQueryString(this.options.requestParameters, 0);
+
+        queryString = (queryString == null) ? '' : queryString+'&';
+        queryString  = queryString+'id='+this.tableId+'&page_size='+fetchSize+'&offset='+bufferStartPos;
+        if (this.sortCol)
+            queryString = queryString+'&sort_col='+escape(this.sortCol)+'&sort_dir='+this.sortDir;
+
+        this.ajaxOptions.parameters = queryString;
+
+       ajaxEngine.sendRequest( this.tableId + '_request', this.ajaxOptions );
+
+       this.timeoutHandler = setTimeout( this.handleTimedOut.bind(this), this.options.bufferTimeout);
+
+   },
+
+   setRequestParams: function() {
+      this.options.requestParameters = [];
+      for ( var i=0 ; i < arguments.length ; i++ )
+         this.options.requestParameters[i] = arguments[i];
+   },
+
+   requestContentRefresh: function(contentOffset) {
+      this.fetchBuffer(contentOffset);
+   },
+
+   ajaxUpdate: function(ajaxResponse) {
+      try {
+         clearTimeout( this.timeoutHandler );
+         this.buffer.update(ajaxResponse,this.processingRequest.bufferOffset);
+         this.viewPort.bufferChanged();
+      }
+      catch(err) {}
+      finally {this.processingRequest = null; }
+      this.processQueuedRequest();
+   },
+
+   _createQueryString: function( theArgs, offset ) {
+      var queryString = ""
+      if (!theArgs)
+          return queryString;
+
+      for ( var i = offset ; i < theArgs.length ; i++ ) {
+          if ( i != offset )
+            queryString += "&";
+
+          var anArg = theArgs[i];
+
+          if ( anArg.name != undefined && anArg.value != undefined ) {
+            queryString += anArg.name +  "=" + escape(anArg.value);
+          }
+          else {
+             var ePos  = anArg.indexOf('=');
+             var argName  = anArg.substring( 0, ePos );
+             var argValue = anArg.substring( ePos + 1 );
+             queryString += argName + "=" + escape(argValue);
+          }
+      }
+      return queryString;
+   },
+
+   processQueuedRequest: function() {
+      if (this.unprocessedRequest != null) {
+         this.requestContentRefresh(this.unprocessedRequest.requestOffset);
+         this.unprocessedRequest = null
+      }
+   }
+};
+
+
+//-------------------- ricoLiveGridSort.js
+Rico.LiveGridSort = Class.create();
+
+Rico.LiveGridSort.prototype = {
+
+   initialize: function(headerTableId, options) {
+      this.headerTableId = headerTableId;
+      this.headerTable   = $(headerTableId);
+      this.options = options;
+      this.setOptions();
+      this.applySortBehavior();
+
+      if ( this.options.sortCol ) {
+         this.setSortUI( this.options.sortCol, this.options.sortDir );
+      }
+   },
+
+   setSortUI: function( columnName, sortDirection ) {
+      var cols = this.options.columns;
+      for ( var i = 0 ; i < cols.length ; i++ ) {
+         if ( cols[i].name == columnName ) {
+            this.setColumnSort(i, sortDirection);
+            break;
+         }
+      }
+   },
+
+   setOptions: function() {
+      // preload the images...
+      new Image().src = this.options.sortAscendImg;
+      new Image().src = this.options.sortDescendImg;
+
+      this.sort = this.options.sortHandler;
+      if ( !this.options.columns )
+         this.options.columns = this.introspectForColumnInfo();
+      else {
+         // allow client to pass { columns: [ ["a", true], ["b", false] ] }
+         // and convert to an array of Rico.TableColumn objs...
+         this.options.columns = this.convertToTableColumns(this.options.columns);
+      }
+   },
+
+   applySortBehavior: function() {
+      var headerRow   = this.headerTable.rows[0];
+      var headerCells = headerRow.cells;
+      for ( var i = 0 ; i < headerCells.length ; i++ ) {
+         this.addSortBehaviorToColumn( i, headerCells[i] );
+      }
+   },
+
+   addSortBehaviorToColumn: function( n, cell ) {
+      if ( this.options.columns[n].isSortable() ) {
+         cell.id            = this.headerTableId + '_' + n;
+         cell.style.cursor  = 'pointer';
+         cell.onclick       = this.headerCellClicked.bindAsEventListener(this);
+         cell.innerHTML     = cell.innerHTML + '<span id="' + this.headerTableId + '_img_' + n + '">'
+                           + '&nbsp;&nbsp;&nbsp;</span>';
+      }
+   },
+
+   // event handler....
+   headerCellClicked: function(evt) {
+      var eventTarget = evt.target ? evt.target : evt.srcElement;
+      var cellId = eventTarget.id;
+      var columnNumber = parseInt(cellId.substring( cellId.lastIndexOf('_') + 1 ));
+      var sortedColumnIndex = this.getSortedColumnIndex();
+      if ( sortedColumnIndex != -1 ) {
+         if ( sortedColumnIndex != columnNumber ) {
+            this.removeColumnSort(sortedColumnIndex);
+            this.setColumnSort(columnNumber, Rico.TableColumn.SORT_ASC);
+         }
+         else
+            this.toggleColumnSort(sortedColumnIndex);
+      }
+      else
+         this.setColumnSort(columnNumber, Rico.TableColumn.SORT_ASC);
+
+      if (this.options.sortHandler) {
+         this.options.sortHandler(this.options.columns[columnNumber]);
+      }
+   },
+
+   removeColumnSort: function(n) {
+      this.options.columns[n].setUnsorted();
+      this.setSortImage(n);
+   },
+
+   setColumnSort: function(n, direction) {
+   	if(isNaN(n)) return ;
+      this.options.columns[n].setSorted(direction);
+      this.setSortImage(n);
+   },
+
+   toggleColumnSort: function(n) {
+      this.options.columns[n].toggleSort();
+      this.setSortImage(n);
+   },
+
+   setSortImage: function(n) {
+      var sortDirection = this.options.columns[n].getSortDirection();
+
+      var sortImageSpan = $( this.headerTableId + '_img_' + n );
+      if ( sortDirection == Rico.TableColumn.UNSORTED )
+         sortImageSpan.innerHTML = '&nbsp;&nbsp;';
+      else if ( sortDirection == Rico.TableColumn.SORT_ASC )
+         sortImageSpan.innerHTML = '&nbsp;&nbsp;<img width="'  + this.options.sortImageWidth    + '" ' +
+                                                     'height="'+ this.options.sortImageHeight   + '" ' +
+                                                     'src="'   + this.options.sortAscendImg + '"/>';
+      else if ( sortDirection == Rico.TableColumn.SORT_DESC )
+         sortImageSpan.innerHTML = '&nbsp;&nbsp;<img width="'  + this.options.sortImageWidth    + '" ' +
+                                                     'height="'+ this.options.sortImageHeight   + '" ' +
+                                                     'src="'   + this.options.sortDescendImg + '"/>';
+   },
+
+   getSortedColumnIndex: function() {
+      var cols = this.options.columns;
+      for ( var i = 0 ; i < cols.length ; i++ ) {
+         if ( cols[i].isSorted() )
+            return i;
+      }
+
+      return -1;
+   },
+
+   introspectForColumnInfo: function() {
+      var columns = new Array();
+      var headerRow   = this.headerTable.rows[0];
+      var headerCells = headerRow.cells;
+      for ( var i = 0 ; i < headerCells.length ; i++ )
+         columns.push( new Rico.TableColumn( this.deriveColumnNameFromCell(headerCells[i],i), true ) );
+      return columns;
+   },
+
+   convertToTableColumns: function(cols) {
+      var columns = new Array();
+      for ( var i = 0 ; i < cols.length ; i++ )
+         columns.push( new Rico.TableColumn( cols[i][0], cols[i][1] ) );
+      return columns;
+   },
+
+   deriveColumnNameFromCell: function(cell,columnNumber) {
+      var cellContent = cell.innerText != undefined ? cell.innerText : cell.textContent;
+      return cellContent ? cellContent.toLowerCase().split(' ').join('_') : "col_" + columnNumber;
+   }
+};
+
+Rico.TableColumn = Class.create();
+
+Rico.TableColumn.UNSORTED  = 0;
+Rico.TableColumn.SORT_ASC  = "ASC";
+Rico.TableColumn.SORT_DESC = "DESC";
+
+Rico.TableColumn.prototype = {
+   initialize: function(name, sortable) {
+      this.name        = name;
+      this.sortable    = sortable;
+      this.currentSort = Rico.TableColumn.UNSORTED;
+   },
+
+   isSortable: function() {
+      return this.sortable;
+   },
+
+   isSorted: function() {
+      return this.currentSort != Rico.TableColumn.UNSORTED;
+   },
+
+   getSortDirection: function() {
+      return this.currentSort;
+   },
+
+   toggleSort: function() {
+      if ( this.currentSort == Rico.TableColumn.UNSORTED || this.currentSort == Rico.TableColumn.SORT_DESC )
+         this.currentSort = Rico.TableColumn.SORT_ASC;
+      else if ( this.currentSort == Rico.TableColumn.SORT_ASC )
+         this.currentSort = Rico.TableColumn.SORT_DESC;
+   },
+
+   setUnsorted: function(direction) {
+      this.setSorted(Rico.TableColumn.UNSORTED);
+   },
+
+   setSorted: function(direction) {
+      // direction must by one of Rico.TableColumn.UNSORTED, .SORT_ASC, or .SORT_DESC...
+      this.currentSort = direction;
+   }
+
+};
+
+
+//-------------------- ricoUtil.js
+Rico.ArrayExtensions = new Array();
+
+if (Object.prototype.extend) {
+   // in prototype.js...
+   Rico.ArrayExtensions[ Rico.ArrayExtensions.length ] = Object.prototype.extend;
+}else{
+  Object.prototype.extend = function(object) {
+    return Object.extend.apply(this, [this, object]);
+  }
+  Rico.ArrayExtensions[ Rico.ArrayExtensions.length ] = Object.prototype.extend;
+}
+
+if (Array.prototype.push) {
+   // in prototype.js...
+   Rico.ArrayExtensions[ Rico.ArrayExtensions.length ] = Array.prototype.push;
+}
+
+if (!Array.prototype.remove) {
+   Array.prototype.remove = function(dx) {
+      if( isNaN(dx) || dx > this.length )
+         return false;
+      for( var i=0,n=0; i<this.length; i++ )
+         if( i != dx )
+            this[n++]=this[i];
+      this.length-=1;
+   };
+  Rico.ArrayExtensions[ Rico.ArrayExtensions.length ] = Array.prototype.remove;
+}
+
+if (!Array.prototype.removeItem) {
+   Array.prototype.removeItem = function(item) {
+      for ( var i = 0 ; i < this.length ; i++ )
+         if ( this[i] == item ) {
+            this.remove(i);
+            break;
+         }
+   };
+  Rico.ArrayExtensions[ Rico.ArrayExtensions.length ] = Array.prototype.removeItem;
+}
+
+if (!Array.prototype.indices) {
+   Array.prototype.indices = function() {
+      var indexArray = new Array();
+      for ( index in this ) {
+         var ignoreThis = false;
+         for ( var i = 0 ; i < Rico.ArrayExtensions.length ; i++ ) {
+            if ( this[index] == Rico.ArrayExtensions[i] ) {
+               ignoreThis = true;
+               break;
+            }
+         }
+         if ( !ignoreThis )
+            indexArray[ indexArray.length ] = index;
+      }
+      return indexArray;
+   }
+  Rico.ArrayExtensions[ Rico.ArrayExtensions.length ] = Array.prototype.indices;
+}
+
+  Rico.ArrayExtensions[ Rico.ArrayExtensions.length ] = Array.prototype.unique;
+  Rico.ArrayExtensions[ Rico.ArrayExtensions.length ] = Array.prototype.inArray;
+
+
+// Create the loadXML method and xml getter for Mozilla
+if ( window.DOMParser &&
+	  window.XMLSerializer &&
+	  window.Node && Node.prototype && Node.prototype.__defineGetter__ ) {
+
+   if (!Document.prototype.loadXML) {
+      Document.prototype.loadXML = function (s) {
+         var doc2 = (new DOMParser()).parseFromString(s, "text/xml");
+         while (this.hasChildNodes())
+            this.removeChild(this.lastChild);
+
+         for (var i = 0; i < doc2.childNodes.length; i++) {
+            this.appendChild(this.importNode(doc2.childNodes[i], true));
+         }
+      };
+	}
+
+	Document.prototype.__defineGetter__( "xml",
+	   function () {
+		   return (new XMLSerializer()).serializeToString(this);
+	   }
+	 );
+}
+
+document.getElementsByTagAndClassName = function(tagName, className) {
+  if ( tagName == null )
+     tagName = '*';
+
+  var children = document.getElementsByTagName(tagName) || document.all;
+  var elements = new Array();
+
+  if ( className == null )
+    return children;
+
+  for (var i = 0; i < children.length; i++) {
+    var child = children[i];
+    var classNames = child.className.split(' ');
+    for (var j = 0; j < classNames.length; j++) {
+      if (classNames[j] == className) {
+        elements.push(child);
+        break;
+      }
+    }
+  }
+
+  return elements;
+}
+
+var RicoUtil = {
+
+   getElementsComputedStyle: function ( htmlElement, cssProperty, mozillaEquivalentCSS) {
+      if ( arguments.length == 2 )
+         mozillaEquivalentCSS = cssProperty;
+
+      var el = $(htmlElement);
+      if ( el.currentStyle )
+         return el.currentStyle[cssProperty];
+      else
+         return document.defaultView.getComputedStyle(el, null).getPropertyValue(mozillaEquivalentCSS);
+   },
+
+   createXmlDocument : function() {
+      if (document.implementation && document.implementation.createDocument) {
+         var doc = document.implementation.createDocument("", "", null);
+
+         if (doc.readyState == null) {
+            doc.readyState = 1;
+            doc.addEventListener("load", function () {
+               doc.readyState = 4;
+               if (typeof doc.onreadystatechange == "function")
+                  doc.onreadystatechange();
+            }, false);
+         }
+
+         return doc;
+      }
+
+      if (window.ActiveXObject)
+          return Try.these(
+            function() { return new ActiveXObject('MSXML2.DomDocument')   },
+            function() { return new ActiveXObject('Microsoft.DomDocument')},
+            function() { return new ActiveXObject('MSXML.DomDocument')    },
+            function() { return new ActiveXObject('MSXML3.DomDocument')   }
+          ) || false;
+
+      return null;
+   },
+
+   getContentAsString: function( parentNode ) {
+      return parentNode.xml != undefined ? 
+         this._getContentAsStringIE(parentNode) :
+         this._getContentAsStringMozilla(parentNode);
+   },
+
+  _getContentAsStringIE: function(parentNode) {
+     var contentStr = "";
+     for ( var i = 0 ; i < parentNode.childNodes.length ; i++ ) {
+         var n = parentNode.childNodes[i];
+         if (n.nodeType == 4) {
+             contentStr += n.nodeValue;
+         }
+         else {
+           contentStr += n.xml;
+       }
+     }
+     return contentStr;
+  },
+
+  _getContentAsStringMozilla: function(parentNode) {
+     var xmlSerializer = new XMLSerializer();
+     var contentStr = "";
+     for ( var i = 0 ; i < parentNode.childNodes.length ; i++ ) {
+          var n = parentNode.childNodes[i];
+          if (n.nodeType == 4) { // CDATA node
+              contentStr += n.nodeValue;
+          }
+          else {
+            contentStr += xmlSerializer.serializeToString(n);
+        }
+     }
+     return contentStr;
+  },
+
+   toViewportPosition: function(element) {
+      return this._toAbsolute(element,true);
+   },
+
+   toDocumentPosition: function(element) {
+      return this._toAbsolute(element,false);
+   },
+
+   /**
+    *  Compute the elements position in terms of the window viewport
+    *  so that it can be compared to the position of the mouse (dnd)
+    *  This is additions of all the offsetTop,offsetLeft values up the
+    *  offsetParent hierarchy, ...taking into account any scrollTop,
+    *  scrollLeft values along the way...
+    *
+    * IE has a bug reporting a correct offsetLeft of elements within a
+    * a relatively positioned parent!!!
+    **/
+   _toAbsolute: function(element,accountForDocScroll) {
+
+      if ( navigator.userAgent.toLowerCase().indexOf("msie") == -1 )
+         return this._toAbsoluteMozilla(element,accountForDocScroll);
+
+      var x = 0;
+      var y = 0;
+      var parent = element;
+      while ( parent ) {
+
+         var borderXOffset = 0;
+         var borderYOffset = 0;
+         if ( parent != element ) {
+            var borderXOffset = parseInt(this.getElementsComputedStyle(parent, "borderLeftWidth" ));
+            var borderYOffset = parseInt(this.getElementsComputedStyle(parent, "borderTopWidth" ));
+            borderXOffset = isNaN(borderXOffset) ? 0 : borderXOffset;
+            borderYOffset = isNaN(borderYOffset) ? 0 : borderYOffset;
+         }
+
+         x += parent.offsetLeft - parent.scrollLeft + borderXOffset;
+         y += parent.offsetTop - parent.scrollTop + borderYOffset;
+         parent = parent.offsetParent;
+      }
+
+      if ( accountForDocScroll ) {
+         x -= this.docScrollLeft();
+         y -= this.docScrollTop();
+      }
+
+      return { x:x, y:y };
+   },
+
+   /**
+    *  Mozilla did not report all of the parents up the hierarchy via the
+    *  offsetParent property that IE did.  So for the calculation of the
+    *  offsets we use the offsetParent property, but for the calculation of
+    *  the scrollTop/scrollLeft adjustments we navigate up via the parentNode
+    *  property instead so as to get the scroll offsets...
+    *
+    **/
+   _toAbsoluteMozilla: function(element,accountForDocScroll) {
+      var x = 0;
+      var y = 0;
+      var parent = element;
+      while ( parent ) {
+         x += parent.offsetLeft;
+         y += parent.offsetTop;
+         parent = parent.offsetParent;
+      }
+
+      parent = element;
+      while ( parent &&
+              parent != document.body &&
+              parent != document.documentElement ) {
+         if ( parent.scrollLeft  )
+            x -= parent.scrollLeft;
+         if ( parent.scrollTop )
+            y -= parent.scrollTop;
+         parent = parent.parentNode;
+      }
+
+      if ( accountForDocScroll ) {
+         x -= this.docScrollLeft();
+         y -= this.docScrollTop();
+      }
+
+      return { x:x, y:y };
+   },
+
+   docScrollLeft: function() {
+      if ( window.pageXOffset )
+         return window.pageXOffset;
+      else if ( document.documentElement && document.documentElement.scrollLeft )
+         return document.documentElement.scrollLeft;
+      else if ( document.body )
+         return document.body.scrollLeft;
+      else
+         return 0;
+   },
+
+   docScrollTop: function() {
+      if ( window.pageYOffset )
+         return window.pageYOffset;
+      else if ( document.documentElement && document.documentElement.scrollTop )
+         return document.documentElement.scrollTop;
+      else if ( document.body )
+         return document.body.scrollTop;
+      else
+         return 0;
+   }
+
+};


More information about the Jifty-commit mailing list