/******************************************************************************
 *  SiteBar 3 - The Bookmark Server for Personal and Team Use.                *
 *  Copyright (C) 2003-2006  Ondrej Brablc <http://brablc.com/mailto?o>       *
 *                                                                            *
 *  This program is free software; you can redistribute it and/or modify      *
 *  it under the terms of the GNU General Public License as published by      *
 *  the Free Software Foundation; either version 2 of the License, or         *
 *  (at your option) any later version.                                       *
 *                                                                            *
 *  This program is distributed in the hope that it will be useful,           *
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of            *
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the             *
 *  GNU General Public License for more details.                              *
 *                                                                            *
 *  You should have received a copy of the GNU General Public License         *
 *  along with this program; if not, write to the Free Software               *
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA *
 ******************************************************************************/

/*** Global variables *********************************************************/
var de = document.documentElement;
var db = document.body;
// Skin directory
var SB_gSkinDir = null;
// Pop-up window preferences
var SB_gWinPrefs = null;
  	
// Base directory
var SB_gAbsBaseUrl = null;
var obj = new Object();
// Image holder to fix problems with cache
var images = document.getElementsByTagName('img');
var img = new Image();
var SB_gImageHolder = Array();

// Currently selected context menu
var SB_gCtxMenu = null;

// Semaphore for ignoring bubbling of events using timers
var SB_gIgnore = 0;

// Timer for hiding context menu
var SB_gHideTimer = null;

// Object reference of the right clicked object
var SB_gTargetID = null;

// ID to be copied or moved
var SB_gSourceID = null;

// ID of the dragged object
var SB_gDraggedID = null;

// Object to show tool tip
var SB_gToolTipObj = null;
var SB_gToolTipTop = null;
var SB_gToolTipLeft = null;
var SB_gCoordUnit = '' || 'px';

// Saved color
var SB_gDraggingStyleBG = null;
var SB_gDraggingStyleFG = null;
var SB_gDraggingStyleCR = null;

// Is source node? If not it is link.
var SB_gSourceTypeIsNode = null;

// Global variable to focus already opened window
var SB_gCmdWin = null;
var SB_gHelpWin = null;

// Should external window be used?
var SB_gAutoReload = true;

// In place commands
var SB_gInPlaceCommands = new Array();

// Previous opened parent - optimization
var SB_gPrevParent = null;

var divs = document.getElementsByTagName('div');
var SB_gState = null;
var ohttp = null;
var url = document.URL;
var links = document.getElementsByTagName('a');
// Dragging style
var SB_gDragIconCSS = null;

// Filter state
var SB_gFilterActive = false;

var SB_gHighlighted = new Array();
var SB_gHidden = Array();

var SB_gToolTipTimer = null;

/*** Autoload *****************************************************************/

function SB_getJSData(label)
{
    var obj = document.getElementById(label);
    if (obj)
    {
        //alert('Javascript data for ' + label + ' not found!');
        return obj.innerHTML;
    }
    //return obj.innerHTML;
}

function SB_getAbsBaseUrl()
{
    if (SB_gAbsBaseUrl == null)
    {
        SB_gAbsBaseUrl = SB_getJSData('sb_absBaseUrl');
    }

    return SB_gAbsBaseUrl;
}

function SB_getCookie(name, defaultValue)
{
    var index = document.cookie.indexOf(name + '=');
    if (index == -1)
    {
        return defaultValue;
    }
    index = document.cookie.indexOf('=', index) + 1; // first character
    var endstr = document.cookie.indexOf(';', index);

    if (endstr == -1)
    {
        endstr = document.cookie.length; // last character
    }
    return unescape(document.cookie.substr(index, endstr));
}

SB_gState = SB_getCookie('SB3NODES','!');

/*** Toolbar functions ********************************************************/

function SB_buttonDown(btn, event)
{
    if (btn == document.getElementById('btnFilter') && SB_gFilterActive && !event) return;
    //btn.className = 'pressed';
}

function SB_buttonUp(btn, event)
{
    if (btn == document.getElementById('btnFilter') && SB_gFilterActive && !event) return;
    //btn.className = 'raised';
}

function SB_buttonOver(btn, event)
{
    SB_toolTip(btn,event);
    if (btn == document.getElementById('btnFilter') && SB_gFilterActive && !event) return;

}

function SB_buttonOut(btn, event)
{
    SB_toolTipHide(btn,event);
    if (btn == document.getElementById('btnFilter') && SB_gFilterActive && !event) return;

}

function SB_storeSearch()
{
    var searchText = document.getElementById('fldSearch').value;
    document.cookie = 'SB3SEARCH='+encodeURIComponent(searchText);
}

function SB_storePosition()
{
    document.cookie = 'SB3TOP='+SB_getTop();
    document.cookie = 'SB3LEFT='+SB_getLeft();
}

function SB_hasClass(obj, className)
{
    return obj.className.indexOf(className)!=-1;
}

/* Add remove class name to the div */
function SB_class(obj, className, add)
{
    var startPos = obj.className.indexOf(className);

    if (add)
    {
        // We already have the class
        if (startPos != -1)
        {
            return;
        }

        obj.className += ' ' + className;
    }
    else
    {
        // We do not have it
        if (startPos == -1)
        {
            return;
        }

        var oldClass = obj.className;

        obj.className = obj.className.substr(0,startPos);

        if (obj.className.length>startPos+className.length)
        {
            obj.className+=oldClass.substr(startPos+className.length);
        }
    }
}

function SB_unfilter()
{
    if (!SB_gFilterActive) return;
    SB_gFilterActive = false;

    for (var i=0; i<SB_gHidden.length; i++)
    {
        SB_gHidden[i].style.display = 'block';
    }

    SB_gHidden = new Array();

    SB_buttonOut(document.getElementById('btnFilter'));
    document.getElementById('fldSearch').focus();
}

/* Add remove class name to the link */
function SB_highlight(linkObj, highlight)
{
    var className;

    if (!SB_hasClass(linkObj, className) && highlight)
    {
        className = 'highlight';SB_gHighlighted[SB_gHighlighted.length] = linkObj;
        SB_class(linkObj, className, highlight);
        linkObj.onmouseover=function(){if(linkObj.className=='acl highlight') linkObj.className='acl'; if(linkObj.className=='al highlight') linkObj.className='al'; if(linkObj.className=='an highlight') linkObj.className='an'; SB_toolTip(linkObj);}
        linkObj.onmouseout=function(){if(linkObj.className=='acl highlight') linkObj.className='acl'; if(linkObj.className=='al') linkObj.className='al highlight'; if(linkObj.className=='an') linkObj.className='an highlight'; SB_toolTipHide(linkObj);}		

    }
}

/* Filter links with matching name or URL */
function SB_filter(icon)
{
    var btnFilter = document.getElementById('btnFilter');

    if (SB_gFilterActive)
    {
        SB_unfilter();
        if (icon) return;
    }

    for (var i=0; i<SB_gHighlighted.length; i++)
    {
        SB_highlight(SB_gHighlighted[i], false);
    }

    SB_gHighlighted = new Array();

    var fld  = document.getElementById('fldSearch');
    var text = fld.value;
    if (text.length==0) return;

    SB_gFilterActive = true;
    SB_buttonDown(btnFilter, true);

    var type = SB_getJSData('sb_defaultSearch');
    SB_gPrevParent = null;

    // Check search pattern
    var reST = new RegExp('/^(url|desc|name|all):(.*)$/');
    if (text.match(reST))
    {
        type = RegExp.$1;

        // If we have pattern then use it
        if (type == 'url' || type == 'desc' || type == 'name' || type == 'all')
        {
            text = RegExp.$2;
        }
    }

    var re = new RegExp(text,'i')

    for (i = 0; i<divs.length; i++)
    {
        if (divs[i].className == 'node')
        {
            var nodeAnchor = document.getElementById('a'+divs[i].id);
            if (SB_getLinkName(nodeAnchor).search(re)!=-1)
            {
                SB_highlight(nodeAnchor, true);
                divs[i].style.display = 'block';
                SB_openParents(divs[i].parentNode.parentNode);
            }
            else
            {
                divs[i].style.display = 'none';
                SB_gHidden[SB_gHidden.length] = divs[i];
            }
        }
    }

    for (i = 0; i<links.length; i++)
    {
        var name = SB_getLinkName(links[i]);
        url = links[i].getAttribute('href');
        var desc = links[i].getAttribute('x_title');
        if (!desc)
        {
            links[i].getAttribute('title');
        }

        var parentDIV = links[i].parentNode.parentNode;

        // Ignore everything but links in tree
        if (parentDIV.className.indexOf('link')==-1) continue;

        var subject = '';

        if (type=='url' || type=='all') subject += url;
        if (type=='name' || type=='all') subject += name;
        if (type=='desc' || type=='all') subject += desc;

        if (subject.search(re)!=-1)
        {
            SB_openParents(parentDIV.parentNode.parentNode);
            SB_highlight(links[i], true);
        }
    }

    for (i = 0; i<divs.length; i++)
    {
        if (divs[i].className == 'node')
        {
            nodeAnchor = document.getElementById('a'+divs[i].id);
            // Folder is not matching
            if (SB_getLinkName(nodeAnchor).search(re)==-1)
            {
                var children = document.getElementById('c'+divs[i].id).childNodes;

                for (var j = 0; j < children.length; j++)
                {
                    if (children[j].className && children[j].className == 'link')
                    {
                        if (SB_hasClass(document.getElementById('a'+children[j].id), 'highlight'))
                        {
                            continue;
                        }
                        children[j].style.display = 'none';
                        SB_gHidden[SB_gHidden.length] = children[j];
                    }
                }
            }
        }
    }

    fld.select();
    fld.focus();
}

/* For search functions: opens all parent folders */
function SB_openParents(parentNode)
{
    if (SB_gPrevParent == parentNode)
    {
        return;
    }

    SB_gPrevParent = parentNode;

    var obj = parentNode;
    while (obj && obj.getAttribute('x_level') != null && obj.getAttribute('x_level') != '') // For Opera
    {
        obj.style.display = 'block';
        SB_node(false, obj, true);
        obj = obj.parentNode.parentNode;
    }
}

/* For search functions: returns name of the link (ignores leading tags) */
function SB_getLinkName(linkTag)
{
    if (linkTag.innerHTML.match('/.*>(.*)/'))
    {
        return RegExp.$1;
    }
    else
    {
        return linkTag.innerHTML;
    }
}

function SB_defaultSearch(target, tool)
{
    if (tool == 'filter')
    {
        SB_filter();
        return;
    }
    SB_storeSearch();
    window.open('search.php' + (tool=='web'?'?web=1':''), target);
}

/* Reload sitebar keeping images in cache */
function SB_reloadPageWorker(cancelled, all)
{
    SB_onUnload();
    url = 'index.php?reload=' + (all?'all':'yes') + (!cancelled?'&uniq=' + (new Date()).valueOf():'') + SB_appendPersistentParams();
    location=url+location.hash;
}

function SB_reloadPage()
{
    SB_reloadPageWorker();
}

/* Reload with hidden folders and all roots */
function SB_reloadAll()
{
    SB_reloadPageWorker(false, true);
}

/* Collapse all nodes */
function SB_collapseAll()
{
    if (SB_gState.length == 0 || SB_gState == '!')
    {
        SB_expandAll();
        return;
    }

    var level;
    var div;

    for (var i=0; i<divs.length; i++)
    {
        div = divs[i];
        level = div.getAttribute('x_level');

        if (level != null && level != '') // '' for Opera
        {
            SB_node(null, div, false, true);
        }
    }

    SB_gState = '!';
    SB_saveCookie(SB_gState);
}

/* Expand all nodes */
function SB_expandAll()
{
    var level;
    var div;

    for (var i=0; i<divs.length; i++)
    {
        div = divs[i];
        level = div.getAttribute('x_level');

        if (level != null && level != '') // '' for Opera
        {
            SB_node(null, div, true);
        }
    }

}

/*** Drag & Drop **************************************************************/

function SB_nodeDrag(event, obj, nid)
{
    var e = event || window.event; 
    if(this.parentNode.parentNode.className == 'node') nid = this.parentNode.parentNode.getAttribute('id').substr(1);
    if (e && (e.button == 2 || e.which == 2 || SB_gDraggedID != null))
    {
        return false;
    }
    //if(SB_isOpera()){return '';}
    SB_menuOff();
    SB_toolTipHide();
    //SB_changeStyleForDragging(true);
    SB_gSourceID = nid;
    SB_gSourceTypeIsNode = true;
    SB_gDraggedID = SB_gSourceID;
    if( e.preventDefault ) { e.preventDefault(); }
    e.returnValue = false;
    if( e.stopPropagation ) { e.stopPropagation(); }
    e.cancelBubble = true;
    return false;
}

function SB_linkDrag(event, obj, lid)
{
    var e = event || window.event; 
    if(this.parentNode.parentNode.className == 'link') lid = this.parentNode.parentNode.getAttribute('id').substr(1);
    if (e && (e.button == 2 || e.which == 2 || SB_gDraggedID != null))
    {
        return false;
    }
    //if(SB_isOpera()){return '';}
    SB_menuOff();
    SB_toolTipHide();
    //SB_changeStyleForDragging(true);
    SB_gSourceID = lid;
    SB_gSourceTypeIsNode = false;
    SB_gDraggedID = SB_gSourceID;
    if( e.preventDefault ) { e.preventDefault(); }
    e.returnValue = false;
    if( e.stopPropagation ) { e.stopPropagation(); }
    e.cancelBubble = true;
    return false;
}

function SB_cancelDragging()
{
    if (SB_gDraggedID != null)
    {
        SB_gDraggedID = null;
        //SB_changeStyleForDragging(false);
    }
}

function SB_nodeDrop(event, obj, nid, lid)
{
    var e = event || window.event; 
    if(this.parentNode.parentNode.className=='node') nid = this.parentNode.parentNode.getAttribute('id').substr(1);
    else if(this.parentNode.parentNode.className=='link') lid = this.parentNode.parentNode.getAttribute('id').substr(1);

    if (SB_gDraggedID == nid || (!SB_gSourceTypeIsNode && lid && SB_gDraggedID == lid))
    {
        return true;
    }

    if (e && (e.button == 2 || e.which == 2 || SB_gDraggedID == null))
    {
        return false;
    }
    //if(SB_isOpera()){return '';}
    SB_stopIt(e);
    SB_gDraggedID = SB_gSourceID;
    SB_commandWindow('Paste', nid?nid:lid);
    SB_cancelDragging();
    if( e.preventDefault ) { e.preventDefault(); }
    e.returnValue = false;
    if( e.stopPropagation ) { e.stopPropagation(); }
    e.cancelBubble = true;
    return false;
}

/*** Image preloading *********************************************************
 * Preload images - necessary for Internet Explorer otherwise
 * some image is always somehow missing.
 * Does not harm any other browser.
*/
/*------------------------------------------------------------------------------------
http://warpspire.com/tipsresources/interface-scripting/image-preloading-revisited 
	Preloader
	A very simple image preloader object
  
 	Usage:
 	
    Preloader.add(path);
    Preloader.onFinish(func);
    Preloader.load();
    
      path: 		A string or array of strings of image paths to preload
      func:     A function or array of functions to be called after images are loaded

      load():   Start the preloader
      
------------------------------------------------------------------------------------*/

var Preloader = {
  callbacks: [],
  images: [],
  loadedImages: [],
  imagesLoaded: 0,
  add: function(image){
    if (typeof image == 'string') this.images.push(image);
    if (typeof image == 'array' || typeof image == 'srcElement' || typeof image == 'target'){
      for (var i=0; i< image.length; i++){
        this.images.push(image[i]);
      }
    }
  },
  onFinish: function(func){
    if (typeof func == 'function') this.callbacks.push(func);
    if (typeof func == 'array' || typeof func == 'srcElement' || typeof func == 'target'){
      for (var i=0; i< func.length; i++){
        this.callbacks.push(func[i]);
      }
    }
  },
  load: function(){
    for(var i=0; i<this.images.length; i++){
      this.loadedImages[i] = new Image();
      this.loadedImages[i].onload = function(){ Preloader.checkFinished.apply(Preloader) }
      this.loadedImages[i].src = this.images[i];
    }
  },
  checkFinished: function(){
    this.imagesLoaded++;
    if (this.imagesLoaded == this.images.length) this.fireFinish();
  },
  fireFinish: function(){
    for (var i=0; i<this.callbacks.length; i++){
      this.callbacks[i]();
    }
    this.images = [];
    this.loadedImages = [];
    this.imagesLoaded = 0;
    this.callbacks = [];
  }
}
 

function SB_imgPath(SB_gImageHolder)
{
    if (SB_gSkinDir == null || SB_gSkinDir == 'undefined')
    {
        SB_gSkinDir = SB_getJSData('sb_skinDir');
        SB_gImageHolder = Array(
        'collapse',
        'connect',
        'empty',
        'feed',
        'join',
        'join_last',
        'link',
        'link_private',
        'link_wrong_favicon',
        'menu',
        'minus',
        'minus_last',
        'node',
        'node_open',
        'plus',
        'plus_last',
        'reload',
        'reload_all',
        'root',
        'root_deleted',
        'root_plus'
    );    
	}
    return SB_gSkinDir + SB_gImageHolder + '.png';
}

/* On error handler for images: Wrong Favicon */
function SB_WFI()
{
    SB_gImageHolder = 'link_wrong_favicon';
}

function SB_preloadImages(SB_gImageHolder,func)
{
   SB_imgPath(SB_gImageHolder);


    Preloader.add(SB_gImageHolder);
    Preloader.onFinish(func);
    Preloader.load();
        //SB_gImageHolder[SB_gImageHolder.length] = images.push(path);
        img.onerror = SB_WFI;
    return SB_gImageHolder;
}

/*** Commander functions ******************************************************/

function SB_initCommander()
{
    document.cookie = 'SB3COOKIE=1';

    if (document.getElementById('focused'))
    {
        setTimeout('document.getElementById("focused").focus();',10);
    }

    if (window && !window.closed)
    {
        window.focus();
    }
}

/* When a menu should be shown on link when using Ctrl+click */
function SB_isOpera()
{
    return window.opera && window.print;
}
/*
function SB_generalTimeout()
{
    setTimeout('SB_generalTimeout();',1000);
}

function SB_onScroll()
{
    var toolbar = document.getElementById('toolbar');

    if (toolbar)
    {
        var logo = document.getElementById('logo');
        var toolbarPlace = document.getElementById('toolbarPlace');

        var top = SB_getTop();

        if (logo && logo.offsetTop+logo.offsetHeight>top)
        {
            top = logo.offsetTop+logo.offsetHeight;
        }

        if (toolbar.offsetTop != top)
        {
            toolbar.style.top = top+'px';
            toolbar.style.left = '1px';
            toolbar.style.position = 'absolute';
            toolbarPlace.style.display = 'block';
        }
    }

    setTimeout('SB_generalTimeout();',10);
}
window.onscroll = SB_onScroll;
*/

function SB_restorePosition()
{
    var iTop = parseInt(SB_getCookie('SB3TOP',-1),10);
    var iLeft = parseInt(SB_getCookie('SB3LEFT',-1),10);

    if (iTop!=-1)
    {
        window.scroll(iLeft,iTop);
    }
}

function SB_initPage(inPlaceCommands)
{
    SB_gInPlaceCommands = inPlaceCommands;
    var sb_main = document.getElementById('sb_main');
    if(sb_main && sb_main != null)
    {
        //SB_storePosition();
        sb_main.style.display = 'block';
    }

//@ONDREJ: we need to reload a page for a correct use of hashes on nodes, correct positioning and cookies
    url = 'index.php';
    if (this.location.href.indexOf(url) == -1) location.replace(url);

    if(document.cookie != -1) SB_restorePosition();
    else SB_storePosition();
    //setTimeout('SB_generalTimeout();',1000);
}
function SB_onLoad()
{
    if (SB_isOpera())
    {
        SB_restorePosition();
    }

}

/*** Tree collapsing/expanding ************************************************/
/**
 * When a div is clicked this event becomes all its parent, however, the
 * the innermost is the first. We increase ignore semaphore and schedule
 * its zeroing after 10 milliseconds. Any subsequent call of stopIt will
 * return false before it is zeroied.
 */
function SB_stopIt(event)
{
    // If event not filled then user initiated action which should
    // not be stopped.
    if (!event) return false;
    SB_gIgnore++;
    if (SB_gIgnore>1) return true;
    setTimeout('SB_renewIt();',10);
    return false;
}

/* Renew the event - for Opera Ctrl+click. */
function SB_renewIt()
{
    SB_gIgnore = 0;
}

/**
 * If the base is not '_content' it must be changed to '_main', what is most likely
 * Internet Explorer and works in Opera.
 */
function SB_isGecko()
{
    return window.content && window.sidebar && window.sidebar.addPanel;
}

/* Save state of certain node */
function SB_saveState(id, state)
{
    SB_gState = (state?'Y':'N')+id.substr(1)+':'+SB_gState;
    SB_saveCookie(SB_gState);
}

/* Save global state cookie */
function SB_saveCookie(value)
{
    var expires = new Date(new Date().getTime()+1000*60*60*24*7).toGMTString();
    document.cookie = 'SB3NODES='+value+'; expires=' + expires;
}

/* Toggle display of any div referenced as object */
function SB_toggleDiv(obj, show)
{
    if (show != null)
    {
        obj.style.display = (show?'block':'none');
        return show;
    }

    if (obj.style.display == '')
    {
        if (SB_hasClass(obj,'childrenExpanded'))
        {
            obj.style.display = 'block';
        }
        if (SB_hasClass(obj,'childrenCollapsed'))
        {
            obj.style.display = 'none';
        }
    }

    obj.style.display = (obj.style.display == 'block'?'none':'block');
    return (obj.style.display == 'block');
}

/* Activated on click on node (folder). Changes + and - sign according to current state. */
function SB_node(event, obj, show, noSaveState)
{
    if (SB_stopIt(event)) return false;

    SB_menuOff();
    SB_cancelDragging();
/*
    if (event)
    {
        if (event.ctrlKey && SB_isOpera())
        {
            SB_renewIt(event);
            SB_menuOn(event, obj);
            return false;
        }
    }
*/
    var simg = document.getElementById('is' + obj.id);
    var nimg = document.getElementById('in' + obj.id);
    var children = document.getElementById('c' + obj.id);
    var root = (obj.getAttribute('x_level')=='1');
    var opened = SB_toggleDiv(children, show);

    if (!noSaveState)
    {
        SB_saveState(obj.id, opened);
    }

    if (root)
    {
        var deleted = (obj.getAttribute('x_acl').indexOf('*')==-1);
        links = children.getElementsByTagName('a');
        nimg.src = SB_imgPath((opened || !links.length?'root'+(deleted?'_deleted':''):'root_plus'));
    }
    else if (simg)
    {
        var last = (simg.src.indexOf('_last.png')>-1);
        simg.src = SB_imgPath((opened?'minus':'plus') + (last?'_last':''));
        nimg.src = SB_imgPath('node' + (opened?'_open':''));
    }
    return true;
}
/*http://blogs.msdn.com/ie/archive/2006/06/08/619507.aspx*/
//An XMLHTTPRequest tip
function SB_xmlHttpGet()
{
    var nhttp = null;

    if (window.ActiveXObject)
    {
        try
        {
            nhttp = new ActiveXObject('Msxml2.XMLHTTP');
        }
        catch(e)
        {
            nhttp = new ActiveXObject('Microsoft.XMLHTTP');
        }
    }
    if(!nhttp && typeof XMLHttpRequest!="undefined")
    {
        nhttp = new XMLHttpRequest();
    }

    return nhttp;
}

function SB_xmlHttpReady()
{
    return ohttp.readyState == 4 && (ohttp.status == 304 || ohttp.status == 302 || ohttp.status == 200);
}

function SB_xmlHttpSend(ohttp, url)
{
    ohttp.open('GET', url, true);

    if (window.XMLHttpRequest)
    {
        ohttp.send(null?null:'');
    }
    // branch for IE/Windows ActiveX version
    else if (window.ActiveXObject)
    {
        ohttp.send();
    }
}

function SB_nodeReload(event, obj)
{
    if (SB_node(event, obj))
    {
        var children = document.getElementById('c' + obj.id);

        // There were 2 mutually excluding conditionals here before.
        if (children.className == 'childrenCollapsed')
        {
            children.className  = 'childrenExpanded';
            ohttp = SB_xmlHttpGet();

            // We have old browser
            if (!ohttp)
            {
                SB_reloadPage();
                //return;
            }

            var level = obj.getAttribute('x_level');
            if (!level)
            {
                level = 1;
            }

            children.innerHTML  = '';

            for (var i=0; i<level; i++)
            {
                children.innerHTML += '&nbsp;&nbsp;&nbsp;&nbsp;';
            }

            children.innerHTML += '<span id="sb_label_loading"><a href="#a'+obj.id+'" class="ajax">' +SB_getJSData('sb_label_loading') + '</a></span>';

            // Yes, this is an AJAX style of doing things <img src="'+SB_getJSData('sb_skinDir')+'progress.gif" alt="">
            ohttp.onreadystatechange = function()
            {
                if (SB_xmlHttpReady())
                {
                    var hdrIdx = ohttp.responseText.indexOf("\r");
                    var nid = ohttp.responseText.substr(1,hdrIdx);

                    //var children = document.getElementById('cn' + nid);
                    children.innerHTML = ohttp.responseText.substr('cn'+nid);

/*                  Opera 8.5 does not support responseXML at all and the others with diffs.

                    var xmlRoot = http.responseXML.getElementsByTagName('root').item(0);
                    var xmlData = http.responseXML.getElementsByTagName('data').item(0);

                    if (xmlRoot && xmlData)
                    {
                        var strRoot = window.ActiveXObject?xmlRoot.text:xmlRoot.textContent;
                        var strData = window.ActiveXObject?xmlData.firstChild.text:xmlData.textContent;

                        var children = document.getElementById('cn' + strRoot);
                        children.innerHTML = strData;
                    }
*/
                }
            }

            var acl = obj.getAttribute('x_acl');
            url = 'index.php?w=sitebar_ajax'+
                           '&call=loadfolder'+
                           '&nid='+obj.id.substr(1)+
                           '&level='+level+
                           '&acl='+acl +
                           SB_appendPersistentParams();
            SB_xmlHttpSend(ohttp, url);
        }
    }
}
/* Ctrl+ Left Click in Opera substitutes right click. */
function SB_link(event,obj)
{
    SB_cancelDragging();

    if (event && event.ctrlKey && SB_isOpera())
    {
        SB_menuOn(event, obj);
        return false;
    }
    else
    {
        SB_stopIt(event);
        return true;
    }
}

/*** Context menu functionality ***********************************************/

function SB_getCoordTop(event)
{
    var e = event;
    if (!e)
    {
        e = window.event;
    }

    var ycoord;

    if (!e || ( typeof( e.pageY ) != 'number' && typeof( e.clientY ) != 'number' ) )
    {
        return[0];
    }

    if (typeof( e.pageY ) == 'number' )
    {
        SB_gCoordUnit = 'px';
        ycoord = e.pageY;
    }
    else
    {
        ycoord = e.clientY;
        if (!( ( window.navigator.userAgent.indexOf( 'Opera' ) + 1 ) || ( window.ScriptEngine && ScriptEngine().indexOf( 'InScript' ) + 1 ) || window.navigator.vendor == 'KDE' ) )
        {
            if (de && de.scrollTop)
            {
                ycoord += de.scrollTop;
            }
            else if (db && db.scrollTop)
            {
                ycoord += db.scrollTop;
            }
        }
    }
    return ycoord-1;
}

function SB_getCoordLeft(event)
{
    var e = event;
    if (!e )
    {
        e = window.event;
    }

    var xcoord;
    if (!e || ( typeof( e.pageX ) != 'number' && typeof( e.clientX ) != 'number' ) )
    {
        return[0];
    }

    if (typeof( e.pageX ) == 'number' )
    {
        SB_gCoordUnit = 'px';
        xcoord = e.pageX;
    }
    else
    {
        SB_gCoordUnit = '';
        xcoord = e.clientX;
        if (!( ( window.navigator.userAgent.indexOf( 'Opera' ) + 1 ) || ( window.ScriptEngine && ScriptEngine().indexOf( 'InScript' ) + 1 ) || window.navigator.vendor == 'KDE' ) )
        {
            if (de && de.scrollLeft)
            {
                xcoord += de.scrollLeft;
            }
            else if (db && db.scrollLeft)
            {
                xcoord += db.scrollLeft;
            }
        }
    }
    return xcoord-1;
}

function SB_getTop()
{
    var topOffset = document.documentElement.scrollTop;
    if (!topOffset)
    {
        topOffset = document.body.scrollTop;
    }
    return topOffset;
}

function SB_getLeft()
{
    var leftOffset = document.documentElement.scrollLeft;
    if (!leftOffset)
    {
        leftOffset = document.body.scrollLeft;
    }
    return leftOffset;
}

/* Called on right click on nodes or items */
function SB_menuOn(event, obj)
{
    var e = event || window.event; 

    if (SB_stopIt(e)) return false;
    SB_cancelDragging();
    SB_stopMenuHider();
    obj = links || images;
    obj.id = this.parentNode.parentNode.getAttribute('id');
    // Store reference in the global variable
    SB_gTargetID = obj.id;

    var menuDIV = (SB_gTargetID.charAt(0)=='n'?'node':'link');
    SB_gCtxMenu = document.getElementById(menuDIV+'CtxMenu');

    if (menuDIV=='node')
    {
        document.cookie = 'SB3CTXROOT='+this.parentNode.parentNode.id.substr(1);

        // Mark folder as opened
        SB_saveState(this.parentNode.parentNode.id, true);
    }
    SB_toolTipHide();
    // Hide the other context menus
    SB_hideMenus(SB_gCtxMenu);

    SB_gCtxMenu.style.top = SB_getCoordTop(e) + SB_gCoordUnit;
    SB_gCtxMenu.style.left = SB_getCoordLeft(e) + SB_gCoordUnit;
    SB_gCtxMenu.style.display = 'block';
    if (SB_isOpera() && this.obj==links && event && !event.ctrlKey)
    {
        if(this.parentNode.parentNode.className == 'node') {SB_renewIt(event); return true;}
        else if(this.parentNode.parentNode.className == 'link'){SB_stopIt(event); return true;}
        return false;
    }

    // Get ACL for node
    var nodeACL = this.parentNode.parentNode.getAttribute('x_acl');

    // Set initial state of all items in the context menu
    for (var i=0;;i++)
    {
        var menuItem = document.getElementById(menuDIV+'menuItem'+i);
        /*if (menuItem)
        {
             //menuItem.createAttribute('x_acl');
			 menuItem.setAttribute('x_acl','');
			 //menuItem.createAttribute('x_cmd');
             menuItem.setAttribute('x_cmd','');
        }*/
        if (!menuItem) break;

        // If not separator then set off or disable
        if (SB_hasClass(menuItem,'separator'))
        {
            continue;
        }

        var commandACL = menuItem.getAttribute('x_acl');

        if (!commandACL)
        {
            continue;
        }

        var commandSPEC = menuItem.getAttribute('x_cmd');

        var arr = commandACL.split('_');
        var disabled = false;

        if (arr.length>1)
        {
            commandACL = arr[0];
            commandSPEC = arr[1];
        }

        // Each command might require some rights, for each letter
        // in the command ACL there must be a letter in the node
        // otherwise the command is disabled
        for (var j=0; j<commandACL.length; j++)
        {
            if (nodeACL.indexOf(commandACL.charAt(j))==-1)
            {
                disabled = true;
                break;
            }
        }

        if (!disabled && commandSPEC)
        {
            switch (commandSPEC)
            {
                case 'c':
                    disabled = !SB_gTargetID;
                    break;
            }
        }

        SB_class(menuItem,'disabled', disabled);
        //SB_class(menuItem,'active', false);
    }
    return false;
}

function SB_showOptional(menuItem, menuDIV)
{
    // Set initial state of all items in the context menu
    for (var i=0;;i++)
    {
        menuItem = document.getElementById(menuDIV+'menuItem'+i);
        if (!menuItem) break;
        menuItem.style.display = 'block';
        menuItem.parentNode.style.display = 'block';
    }
}

function SB_stopMenuHider()
{
    if (SB_gHideTimer)
    {
        clearTimeout(SB_gHideTimer);
        SB_gHideTimer = null;
    }
}

/* When the item is left this is called to show parent menu. */
function SB_menuOff()
{
    SB_gCtxMenu = null;
    SB_hideMenus(SB_gCtxMenu);
    SB_stopMenuHider();
}

/* Hide all context menus, ignore the one passed as object reference */
function SB_hideMenus(menu)
{
    var menus = Array('node','link');
    for (var i=0; i<menus.length; i++)
    {
        menu = document.getElementById(menus[i]+'CtxMenu');
        if (menu)
        {
            menu.style.display = 'none';
        }
    }
}

/* Activated on mouseover on the item in context menu */
function SB_itemOn(menuItem)
{
    // And its hiding was scheduled
    SB_stopMenuHider();

    // Display menu
    menuItem.parentNode.style.display = 'block';

    //SB_toggleItem(menuItem, true);
    if (SB_hasClass(menuItem,'disabled'))
    {
        return;
    }
}

/* Activated on mouse off */
function SB_itemOff(menuItem)
{
    SB_stopMenuHider();
    SB_gHideTimer = setTimeout('SB_menuOff();', 1000);
    //SB_toggleItem(menuItem, false);
    if (SB_hasClass(menuItem,'disabled'))
    {
        return;
    }
}

/* Activated on click on the context menu item */
function SB_itemDo(menuItem, func)
{
    if (SB_hasClass(menuItem,'disabled') || menuItem.getAttribute('x_cmd') == null)
    {
        return;
    }

    SB_menuOff();
    var nid = null;
    var lid = null;
    var id  = null;

    if (SB_gTargetID)
    {
        id = SB_gTargetID.substr(1);
        if (SB_gTargetID.charAt(0) == 'n')
        {
            nid = id;
        }
        else
        {
            lid = id;
        }
        //SB_gTargetID = null;
    }

    if (func)
    {
        eval(func+'(id)');
    }
    else
    {
        SB_commandWindow(menuItem.getAttribute('x_cmd'), nid, lid);
    }
}

function SB_itemDoAlt(menuItem, func)
{
    if (SB_hasClass(menuItem,'disabled') || menuItem.getAttribute('x_cmd') == null)
    {
        return;
    }

    SB_menuOff();
    var nid = null;
    var lid = null;
    var id  = null;

    if (SB_gTargetID)
    {
        id = SB_gTargetID.id.substr(1);
        if (SB_gTargetID.id.charAt(0)=='n')
        {
            nid = id;
        }
        else
        {
            lid = id;
        }
        //SB_gTargetID = null;
    }

    if (func)
    {
        eval(func+'(id)');
    }
    else
    {
        SB_commandWindow(menuItem.getAttribute('x_cmd'), nid, lid);
    }
}

function SB_toolTip(source, event)
{
    var e = event || window.event; 
    SB_gToolTipObj = source;
    SB_gToolTipTop = SB_getCoordTop(e);
    SB_gToolTipLeft = SB_getCoordLeft(e);
    SB_gToolTipTimer = setTimeout('SB_toolTipShow();',1000);
    return false;
}

function SB_toolTipHide()
{
    if (SB_gToolTipTimer)
    {
        clearTimeout(SB_gToolTipTimer);
        SB_gToolTipTimer = null;
    }
    SB_gToolTipObj = null;
    var toolTipObj = document.getElementById('toolTip');
    if (toolTipObj)
    {
        toolTipObj.style.display = 'none';
    }
    //return false;
}

function SB_toolTipShow()
{
    if (SB_gCtxMenu)
    {
        SB_toolTipHide();
        return;
    }
    SB_gCoordUnit = '' || 'px';
    if (SB_gToolTipObj)
    {
        var toolTipObj = document.getElementById('toolTip');

        if (!toolTipObj || toolTipObj.style.display == 'block')
        {
            return;
        }
        var text = SB_gToolTipObj.getAttribute('x_title');

        if (!text || !text.length)
        {
            return;
        }

        var maxLen = 20;
        var curLen = 0;

        if (text.indexOf(' ')==-1)
        {
            maxLen = text.length;
        }
        else
        {
            for (var i=0; i<text.length; i++)
            {
                curLen = text.indexOf(' ',i);
                if ((curLen-i)>maxLen)
                {
                    maxLen = (curLen-i);
                }
            }
        }

        var width = maxLen*7; // Magic number

        var iTop = 0;
        var iLeft = 0;

        if (0 && SB_gToolTipObj.className=='raised')
        {
		    if(SB_isGecko() && SB_gToolTipObj.offsetParent) {iTop = SB_gToolTipObj.offsetTop+20; iLeft = SB_gToolTipLeft-width+5;}
		    else {iTop = SB_gToolTipTop+15; iLeft = SB_gToolTipLeft-width;}

            if (iLetf<0) iLeft = 0;
        }
        else
        {
		    if(SB_isGecko() && SB_gToolTipObj.offsetParent) {iTop = SB_gToolTipObj.offsetTop+30; iLeft = Math.floor(SB_gToolTipLeft/20)+5;}
		    else {iTop = SB_gToolTipTop+22; iLeft = Math.floor(SB_gToolTipLeft/20);}
        }

        var punct = new Array('.','(',')',':',';','#');
        images = new Array('dot','brace_left','brace_right','colon','semicolon','hash');
        var save  = '';

        for (var i=0; i<text.length; i++)
        {
            var skip = false;
            for (var j=0; j<punct.length && !skip; j++)
            {
                if (text.charAt(i) == punct[j])
                {
                    save += '<img class="char" src="skins/punct_'+images[j]+'.png" alt="">';
                    skip = true;
                }
            }
            if (!skip)
            {
                save += text.charAt(i);
            }
        }

        toolTipObj.innerHTML = save;
        toolTipObj.style.display = 'block';
        toolTipObj.style.top = iTop + SB_gCoordUnit;
        toolTipObj.style.left = iLeft + SB_gCoordUnit;
        toolTipObj.style.width = width+SB_gCoordUnit;
        if(SB_isOpera()) toolTipObj.parentNode.onmouseover='return false';//for Opera <9.0
    }
}

/* Called on node Mark as Default command */
function SB_markDefault(nid)
{
    ohttp = SB_xmlHttpGet();

    // We have old browser
    if (!ohttp)
    {
        alert('Sorry, your browser does not support AJAX!');
        return;
    }

    url = 'command.php?command=Mark%20as%20Default&do=1&nid_acl=' + nid + SB_appendPersistentParams();
    SB_xmlHttpSend(ohttp, url);
}

/* Called on node Copy command */
function SB_nodeCopy(nid)
{
    SB_gSourceID = nid;
    SB_gSourceTypeIsNode = true;
}

/* Called on node Hide command */
function SB_nodeHide(nid)
{
    var nodeObj = document.getElementById('n'+nid);
    nodeObj.style.display = 'none';
    SB_commandWindow('Hide Folder', nid, null);
}

/* Called on link Copy command */
function SB_linkCopy(lid)
{
    SB_gSourceID = lid;
    SB_gSourceTypeIsNode = false;
}

function SB_appendPersistentParams()
{
    url = '';

    var sParam = location.search;
    var persistentParams = new Array('target','mode','w');

    if (sParam && sParam.length && sParam.split)
    {
        var aParam = sParam.substr(1).split('&');

        for (var i=0; i<aParam.length; i++)
        {
            var aPair = aParam[i].split('=');
            if (aPair[0] == 'reload') continue;
            if (aPair[0] == 'uniq') continue;

            for (var j=0; j<persistentParams.length; j++)
            {
                if (persistentParams[j] == aPair[0])
                {
                    url += '&' + aParam[i];
                }
            }
        }
    }

    return url;
}

/* Open control window */

function SB_commandWindow(command, nid, lid)
{
    url = 'command.php?command='+command+(nid?'&nid_acl='+nid:'')+(lid?'&lid_acl='+lid:'')+(SB_gSourceID?'&sid='+SB_gSourceID+'&stype='+(SB_gSourceTypeIsNode?'1':'0'):'');

    url += SB_appendPersistentParams();

    var inPlaceCommands = false;
    for (var i=0; i<SB_gInPlaceCommands.length; i++)
    {
        if (command == SB_gInPlaceCommands[i])
        {
            inPlaceCommands = true;
            break;
        }
    }

    if (SB_getJSData('sb_externCommander')==1 && !inPlaceCommands)
    {
var w = window, d = document, cp = d.characterSet?d.characterSet:d.charset, sX, sY, sW, sH, opW, pW, opH, pH, nwO, nwW, nwH, nwX, nwY;
SB_gCmdWin = null;
sW = screen.availWidth;sH=screen.availHeight;
opW = w.outerWidth || de.offsetWidth || db.offsetWidth;
opH = w.outerHeight || de.offsetHeight || db.offsetHeight;
pW = w.innerWidth || de.clientWidth || db.clientWidth;
pH = w.innerHeight || de.clientHeight || db.clientHeight;
sX = sW-opW+4+w.screenX; sY = opH-pH-3+w.screenY;
nwW = 192; nwH = pH;
if(SB_isOpera()){nwX = (sW-nwW)/2+nwW; nwY = screen.height-sH+4;}
else{nwX = sW-nwW-22; nwY = sY?sY:w.screenTop+3;};
nwO='width='+nwW+',height='+nwH+',left='+nwX+',top='+nwY+',toolbar=1,location=1,resizable=1,scrollbars=1,status=1,dependent=1';

        if (SB_gCmdWin == null || SB_gCmdWin.closed)
        {
            SB_gCmdWin = w.open(url,'sitebar_gCmdWin',nwO);
            SB_gCmdWin.blur(); SB_gCmdWin.resizeTo(nwW,nwH);
            if(SB_isGecko()){SB_gCmdWin.moveTo(nwX,nwY-26);}
            else {SB_gCmdWin.moveTo(nwX,nwY);}
            SB_gCmdWin.focus();
            //SB_gSourceID = null;
        }
        else {SB_gCmdWin.location.href = url; SB_gCmdWin.focus();}
        //SB_gSourceID = null;
    }
    else
    {
         SB_onUnload(); location.href = url; 
    }
    //return false;
}
/*
function bookmarklet()
{
url='command.php?command=Add%20Link&url='+escape(location)+'&name='+escape(d.title)+(cp?'&cp='+cp:'');
if(SB_gCmdWin == null || SB_gCmdWin.closed){SB_gCmdWin = open(url,'sitebar_gCmdWin',nwO);
SB_gCmdWin.resizeTo(nwW,pH);
if(SB_isGecko()){SB_gCmdWin.moveTo(nwX,nwY-24)}
else{SB_gCmdWin.moveTo(nwX,nwY);}}else{SB_gCmdWin.location=url;SB_gCmdWin.focus();}
}
*/
function SB_openHelp(url)
{
    var nwO = 'resizable,location,toolbar,scrollbars,status';
    SB_gHelpWin = open(url,'sitebar_gHelpWin',nwO);
    SB_gHelpWin.focus();
}

function SB_showMore()
{
    document.getElementById('showMore').style.display="block";
    document.getElementById('showLess').style.display="none";
    document.getElementById('optionalFields').style.display="none";
}

function SB_showLess()
{
    document.getElementById('showMore').style.display="none";
    document.getElementById('showLess').style.display="block";
    document.getElementById('optionalFields').style.display="block";
}

function SB_showShareGroup(gid)
{
    for (var i=0; i<2; i++)
    {
        var ch = i==0?'a':'b';
        var el = document.getElementById('group'+gid+ch);
        if (el)
        {
            el.style.visibility = 'visible';
        }
    }
}

function SB_memberSelector(id, show)
{
    document.getElementById(id+"_l").style.display=show?"none":"block";
    document.getElementById(id+"_s").style.display=!show?"none":"block";

    if (show)
    {
        document.getElementById(id+"_v").focus();
        document.getElementById(id+"_v").className=document.getElementById(id+"_v").value;
    }
}

function SB_onMemberSelectorChange(id)
{
    document.getElementById(id+"_r").className=document.getElementById(id+"_v").value;
    document.getElementById(id+"_v").className=document.getElementById(id+"_v").value;
}

function SB_onMemberSelectorBlur(id)
{
    SB_memberSelector(id, false);
}

/*
 * (c)2006 Dean Edwards/Matthias Miller/John Resig
 * Special thanks to Dan Webb's domready.js Prototype extension
 * and Simon Willison's addLoadEvent
 * For more info, see:
 * http://dean.edwards.name/weblog/2006/06/again/
 * http://www.vivabit.com/bollocks/2006/06/21/a-dom-ready-extension-for-prototype
 * http://simon.incutio.com/archive/2004/05/26/addLoadEvent
 * 
 * Thrown together by Jesse Skinner (http://www.thefutureoftheweb.com/)
 *
 * To use: call addDOMLoadEvent one or more times with functions, ie:
 *
 *    function something() {
 *       // do something
 *    }
 *    addDOMLoadEvent(something);
 *
 *    addDOMLoadEvent(function() {
 *        // do other stuff
 *    });
 *
 */
 
function addDOMLoadEvent(func) {
   if (!window.__load_events) {
      var init = function () {
          // quit if this function has already been called
          if (arguments.callee.done) return;
      
          // flag this function so we don't do the same thing twice
          arguments.callee.done = true;
      
          // kill the timer
          if (window.__load_timer) {
              clearInterval(window.__load_timer);
              window.__load_timer = null;
          }
          
          // execute each function in the stack in the order they were added
          for (var i=0;i < window.__load_events.length;i++) {
              window.__load_events[i]();
          }
          window.__load_events = null;
      };
   
      // for Mozilla/Opera9
      if (document.addEventListener) {
          document.addEventListener("DOMContentLoaded", init, false);
      }
      
      // for Internet Explorer
      /*@cc_on @*/
      /*@if (@_win32)
          document.write('<scr'+'ipt type="text/javascript" id="__ie_onload" defer src="javascript:void(0);"><\/scr'+'ipt>');
          var script = document.getElementById("__ie_onload");
          script.onreadystatechange = function() {
              if (this.readyState == "complete") {
                  init(); // call the onload handler
              }
          };
      /*@end @*/
      
      // for Safari
      if (/WebKit/i.test(navigator.userAgent)) { // sniff
          window.__load_timer = setInterval(function() {
              if (/loaded|complete/.test(document.readyState)) {
                  init(); // call the onload handler
              }
          }, 10);
      }
      // for other browsers
      window.onload = init;
      // create event function stack
      window.__load_events = [];
   }
   // add function to event stack
   window.__load_events.push(func);
   //SB_imgPath(SB_gImageHolder);
   SB_preloadImages(SB_gImageHolder,func);
}
addDOMLoadEvent(SB_imgPath, SB_preloadImages);

addDOMLoadEvent(function () { 
/*http://groups.google.com/group/behaviour/browse_thread/thread/1aa9f56df99aaeba/314d641ef34cd864?lnk=st&q=%22var+Behaviour+%3D+%7B%22&rnum=7#314d641ef34cd864*/
function attachEH(obj, e, func) 
{ 
        if(obj.attachEvent) obj.attachEvent('on'+e,func); 
        else  obj.addEventListener(e, func, false); 
/* Event capture explained
* http://dev.opera.com/articles/view/event-capture-explained/
*/
} 

function detachEH(obj, e, func) 
{ 
        if(obj.detachEvent) obj.detachEvent('on'+e,func); 
        else  obj.removeEventListener(e, func, false); 
} 

var Behaviour = { 
        list: {}, 
        handle : function (e) { 
                if (!e) e = window.event; 
                var n = e.srcElement || e.target; 
                while(n && document.domain) { 
                        try { Behaviour.list[e.type+'__'+n.className](n) } catch (err) {}; 
                        try { Behaviour.list[ e.type+'_'+n.id](n) } catch (err) {}; 
                        if (n.last) { n.last = null; break; } 
                        n = n.parentNode; 
                } 
        }, 
        start : function () { 
                //start handlers, here you can attach what ever event handlers you need 
                var d = db || de; 
                attachEH( d, 'load', Behaviour.handle ); 
                attachEH( d, 'error', Behaviour.handle ); 
                attachEH( d, 'mousemove', Behaviour.handle ); 
                attachEH( d, 'mouseover', Behaviour.handle ); 
                attachEH( d, 'mouseout', Behaviour.handle ); 
                attachEH( d, 'mousedown', Behaviour.handle ); 
                attachEH( d, 'mouseup', Behaviour.handle ); 
                attachEH( d, 'click', Behaviour.handle ); 
                attachEH( d, 'keydown', Behaviour.handle ); 
                attachEH( d, 'keypress', Behaviour.handle ); 
                attachEH( d, 'keyup', Behaviour.handle ); 
                attachEH( d, 'contextmenu', Behaviour.handle ); 
                attachEH( d, 'focus', Behaviour.handle ); 
                attachEH( d, 'blur', Behaviour.handle ); 
                attachEH( d, 'dragstart', Behaviour.handle ); 
                attachEH( d, 'dragend', Behaviour.handle ); 
                attachEH( d, 'drop', Behaviour.handle ); 
        }, 
        end : function () { 
                //end handlers, here you can detach what ever event handlers you need 
                var d = db || de; 
                detachEH( d, 'mousemove', Behaviour.handle ); 
                detachEH( d, 'mouseover', Behaviour.handle ); 
                detachEH( d, 'mouseout', Behaviour.handle ); 
                detachEH( d, 'mousedown', Behaviour.handle ); 
                detachEH( d, 'mouseup', Behaviour.handle ); 
                detachEH( d, 'click', Behaviour.handle ); 
                detachEH( d, 'keydown', Behaviour.handle ); 
                detachEH( d, 'keypress', Behaviour.handle ); 
                detachEH( d, 'keyup', Behaviour.handle ); 
                detachEH( d, 'contextmenu', Behaviour.handle ); 
                detachEH( d, 'focus', Behaviour.handle ); 
                detachEH( d, 'blur', Behaviour.handle ); 
                detachEH( d, 'dragstart', Behaviour.handle ); 
        }
}; 

/* usually we start event handlers when document.body is loaded */ 
Behaviour.start(); 
//Behaviour.end(); 
/* examples */ 
/* command hash name syntax:   <event>_<id> or <event>__<className>  */ 
Behaviour.list = { 
//element with class "foo" 2 "underscore"
load__siteBar:function(n){ SB_preloadImages(SB_gImageHolder,func); n.last = true; }, 
load__siteBarCmdWin:function(n){ SB_preloadImages(SB_gImageHolder,func); n.last = true; }, 
load__favicon:function(n){ SB_preloadImages(SB_gImageHolder,func); n.last = true; }, 
mouseup__siteBar:function(n){ SB_cancelDragging(); n.last = true; }, 
mouseover__acl:function(n){ SB_toolTip(n); n.last = true; }, 
mouseout__acl:function(n){ SB_toolTipHide(n); n.last = true; }, 
mouseover__al:function(n){ SB_toolTip(n); n.last = true; }, 
mouseout__al:function(n){ SB_toolTipHide(n); n.last = true; }, 
mouseover__an:function(n){ SB_toolTip(n); n.last = true; }, 
mouseout__an:function(n){ SB_toolTipHide(n); n.last = true; }, 
mouseover__dead:function(n){ SB_toolTip(n); n.last = true; }, 
mouseout__dead:function(n){ SB_toolTipHide(n); n.last = true; }, 
mouseover__private:function(n){ SB_toolTip(n); n.last = true; }, 
mouseout__private:function(n){ SB_toolTipHide(n); n.last = true; }, 
//
mousedown__acl:function(n){ if(!SB_isOpera()){ n.oncontextmenu = SB_menuOn; n.ondragstart?n.ondragstart:n.onmousedown = SB_nodeDrag;}; n.last = true; }, 
mousedown__an:function(n){ if(!SB_isOpera()){ n.oncontextmenu = SB_menuOn; n.ondragstart?n.ondragstart:n.onmousedown = SB_nodeDrag;}; n.last = true; }, 
mousedown__al:function(n){ if(!SB_isOpera()){ n.oncontextmenu = SB_menuOn; n.ondragstart?n.ondragstart:n.onmousedown = SB_linkDrag;}; n.last = true; }, 
mousedown__dead:function(n){ if(!SB_isOpera()){ n.oncontextmenu = SB_menuOn; n.ondragstart?n.ondragstart:n.onmousedown = SB_linkDrag;}; n.last = true; }, 
mousedown__private:function(n){ if(!SB_isOpera()){ n.oncontextmenu = SB_menuOn; n.ondragstart?n.ondragstart:n.onmousedown = SB_linkDrag;}; n.last = true; }, 
//
mouseup__acl:function(n){ if(!SB_isOpera()){ n.ondragend?n.ondragend:n.onmouseup = SB_nodeDrop; n.last = true }}, 
mouseup__an:function(n){ if(!SB_isOpera()){ n.ondragend?n.ondragend:n.onmouseup = SB_nodeDrop; n.last = true }}, 
mouseup__al:function(n){ if(!SB_isOpera()){ n.ondragend?n.ondragend:n.onmouseup = SB_nodeDrop; n.last = true }}, 
mouseup__dead:function(n){ if(!SB_isOpera()){ n.ondragend?n.ondragend:n.onmouseup = SB_nodeDrop; n.last = true }}, 
mouseup__private:function(n){ if(!SB_isOpera()){ n.ondragend?n.ondragend:n.onmouseup = SB_nodeDrop; n.last = true }}, 
//
mouseup__loader:function(n){ if(!SB_isOpera()){ n.lastChild.ondrop?n.lastChild.ondrop:n.lastChild.onmouseup = SB_nodeDrop; n.last = true }}, 
keypress__acl:function(n){ if(SB_isOpera() && event && event.ctrlKey){ n.onclick = SB_menuOn; n.last = true; }}, 
keypress__an:function(n){ if(SB_isOpera() && event && event.ctrlKey){ n.onclick = SB_menuOn; n.last = true; }}, 
keypress__al:function(n){ if(SB_isOpera() && event && event.ctrlKey){ n.onclick = SB_menuOn; n.last = true; }}, 
keypress__dead:function(n){ if(SB_isOpera() && event && event.ctrlKey){ n.onclick = SB_menuOn; n.last = true; }}, 
keypress__private:function(n){ if(SB_isOpera() && event && event.ctrlKey){ n.onclick = SB_menuOn; n.last = true; }}, 
//
mouseover__item:function(n){ n.className = 'activeItem'; SB_itemOn(n); n.last = true; }, 
mouseout__activeItem:function(n){ n.className='item'; SB_itemOff(n); n.last = true; }, 
mouseover__optional:function(n){ n.className = 'actopt'; SB_itemOn(n); n.last = true; }, 
mouseout__actopt:function(n){ n.className = "optional"; SB_itemOff(n); n.last = true; }, 
mouseup__actopt:function(n){ if(n.parentNode.id=='nodeCtxMenu'){if(n.getAttribute('x_cmd')=='Mark as Default') SB_itemDo(n,'SB_markDefault'); else SB_itemDo(n);}; n.last = true; }, 
mouseup__activeItem:function(n){ if(n.parentNode.id=='linkCtxMenu'){if(n.getAttribute('x_cmd')=='Copy Bookmark') SB_itemDo(n,'SB_linkCopy'); else SB_itemDo(n);} if(n.parentNode.id=='nodeCtxMenu'){if(n.getAttribute('x_cmd')=='Copy') SB_itemDo(n,'SB_nodeCopy'); else SB_itemDo(n);} if(n.parentNode.id=='userCtxMenu'){if(n.getAttribute('x_cmd')) SB_itemDo(n);}; n.last = true }, 
mouseover__more:function(n){ n.className = 'less'; SB_showOptional(n,'node'); n.last = true; }, 
//
mousedown__nmenu:function(n){ n.parentNode.className=''; n.onmouseup=SB_menuOn; n.last = true; }, 
click__nmenu:function(n){ n.parentNode.className='loader'; n.last = true; }, 
mousedown__lmenu:function(n){ n.onmouseup=SB_menuOn; n.last = true; }, 
//
mousedown__raised:function(n){ n.className = 'pressed'; SB_buttonDown(n); n.last = true; }, 
mouseup__pressed:function(n){ n.className = 'raised'; SB_buttonUp(n); n.last = true; }, 
mouseover__btn:function(n){n.className = 'raised'; SB_buttonOver(n); n.last = true; }, 
mouseout__raised:function(n){n.className = 'btn'; SB_buttonOut(n); n.last = true; }, 
mouseover__check:function(n){ SB_toolTip(n); n.last = true; }, 
mouseout__check:function(n){ SB_toolTipHide(n); n.last = true; }, 
//
//keydown_fldSearch:function(n){ SB_storeSearch(this);  if((event && event.keyCode && event.keyCode==13) || (event && event.which && event.which==13)) SB_defaultSearch(SB_getJSData('sb_baseTarget'),SB_getJSData('sb_defaultSearchTool')); n.last = true; }, 
click__loader:function(n){ SB_nodeReload(n, n.parentNode) || SB_getJSData('sb_loader'); location.hash='#an'+n.parentNode.id.substr(1); SB_preloadImages(SB_gImageHolder,func); n.last = true; }, 
//
//element with id "foo"  1 "underscore"
click_reloader:function(n){ if(window.opener) window.opener.location.reload(true); window.close(); n.last = true; }, 
click_closer:function(n){ window.close(); n.last = true; }, 
click_history:function(n){ history.go(-1); n.last = true; }, 
click_btnFilter:function(n){ SB_filter(true); n.last = true; }, 
click_btnBack:function(n){ history.go(-1); n.last = true; }, 
click_btnForward:function(n){ history.go(1); n.last = true; }, 
click_showMore:function(n){ n.className = 'showLess'; SB_showLess(n); n.last = true; }, 
click_showLess:function(n){ n.className = 'showMore'; SB_showMore(n); n.last = true; }, 
click_btnCollapse:function(n){ SB_collapseAll(n); n.last = true; }, 
click_btnReloadAll:function(n){ SB_reloadAll(n); n.last = true; }, 
click_btnReload:function(n){ SB_reloadPage(n); n.last = true; } 
}
});
/* Unload all events */
function SB_onUnload(func)
{
    SB_preloadImages(SB_gImageHolder,func);
    var sb_main = document.getElementById('sb_main');
    if(sb_main && sb_main != null)
    {
         SB_storePosition();
        sb_main.style.display = 'none';
    }
}

if (window.addEventListener) {

        window.addEventListener('beforeunload', SB_onUnload, false);
}
else if (window.attachEvent) {

        window.attachEvent('onbeforeunload', SB_onUnload);
}
else window.onbeforeunload=SB_onUnload;

//Special Operators:this Operator
//http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Operators:Special_Operators:this_Operator#Method_binding
//The distinction between methods and functions is made only when they are called: 
//method calls pass the "parent object" as this, 
//while function calls pass the global object as this.
