Array.prototype.ln=function() {return this.length}
with (String)
{
  prototype.sb=function(s,e) {return this.substring(s,e)}
  prototype.io=function(s)   {return this.indexOf(s)}
  prototype.ln=function()    {return this.length}
}


var b_IE    = 0;
var b_IE5   = 0;
var b_IE6   = 0;
var b_IEPC  = 0;
var b_IEMAC = 0;
var b_NS    = 0;
var b_NS4   = 0;
var b_OP    = 0;
var b_MZ    = 0;
var b_DOM   = 0;
var b_MAC   = 0;
var b_IEComp= 0;
var b_SAF   = 0;
var b_VER   = 0;
var d_o     = document;
var _un     = 'undefined';

dm_getBrowser();


//##############################################################################
var addedScripts = [];
if (typeof(dmWorkPath)==_un) var dmWorkPath = '';

function dm_addScript(fname)
// Includes additional script files
{
  for (var i=0; i<addedScripts.ln(); i++) if (addedScripts[i]==fname) return;
  addedScripts[addedScripts.ln()] = fname;
  d_o.write('<scr'+'ipt src="'+dmWorkPath+fname+'" type="text/javascript"></scr'+'ipt>');
}

dm_addScript((b_NS4 ? 'dmenu_fore.js' : 'dmenu_addition.js'));
//##############################################################################

// Create style for special <DIV id="dmlinks"> where menu links are placed (for search engines)
d_o.write('<style>#dmlinks{position:absolute;left:-10000px;display:none}</style>');


var dUnits = 'px';                               // units
var docElement;                                  // Document object variable depending on <!DOCTYPE> tag. Used as document.body object.
var fdocElement;                                 // Document object variable in a frame depending on <!DOCTYPE> tag. Used as document.body object of a frame.
var userLoadFunc = null;                         // Variable to remember user's onLoad event
var assignFloating = 0;
var assignMoving   = 0;

var dm_menu   = [];                              // Main menu object
var isLoaded  = 0;                               // Are submenus loaded
var regexp_m  = /dm([0-9]+)m([0-9]+)/;           // Mask to extact indexes from menu id
var regexp_i  = /dm([0-9]+)m([0-9]+)i([0-9]+)/;  // Mask to extact indexes from item id


var curMenu =
{
  ind  : 0,    	        // index of current processed menu
  smInd: 0,         	  // index of current processed submenus
  itInd: 0,   		      // index of current processed item
  smVar: null,          // current submenu variable
  itVar: null,          // current item variable
  curPressedIt: -1,     // current pressed item index
  statusStr   : ''      // text in status bar
}


var moveRec =
{
  isMoving   : 0,       // if the menu is in a moving process
  prepareSmID: '',
  cX      : 0,          // capturing X coord
  cY      : 0,          // capturing Y coord
  smObj   : 0,          // current movable submenu object
  smVar   : null        // current movable submenu variable
}


var toggleRec =
{
   pressedSelf    : false,   // script sets pressed item, not user
   changeStyleOnly: false    // change item style only
}


var keyMode =
{
  isEnabled : false,         // keystokes are activated
  menu      : null,          // menu object
  rsmVar    : null,          // root submenu variable
  ritVar    : null,          // root items variable
  smVar     : null,          // submenu variable
  itVar     : null           // item variable
}


// Cross-frame mode ############################################################
var cfEnabled      = 0;
var cfFsetID       = '';
var cfMFrameInd    = 0;
var cfSFrameInd    = 1;
var cfOrientation  = 0;
var cfType         = 1;  // values: 1 - standard cross-fame mode
                         //         3 - standard cross-fame mode + submenus resize main frame when subframe isn't accessible (IE only)
var oldFsetSizes;        // variable ro remember frames dimensions in frameset (rows/cols attributes of frameset)
//##############################################################################


function dm_getBrowser()
// Detects client's browser
{
  var nv = navigator;
  var a  = nv.userAgent;
  var n  = nv.appName;
  var v  = nv.appVersion;
  var ns = 'Netscape';
  var gk = 'Gecko';
  var pf = function(r) {return parseFloat(r)}
  b_MAC  = v.io("Mac") >= 0;
  b_DOM  = d_o.getElementById?1:0;

  // Safari detect
  if ((parseInt(nv.productSub)>=20020000) && (nv.vendor.io('Apple Computer') != -1) && (nv.product==gk))
  {
      b_NS  = 1;
      b_VER = 6;
      b_SAF = 1;
      return;
  }
  
  // Konqueror detect
  if (n.toLowerCase()=='konqueror')
  {
      isMZ  = 1;
      isVER = 1.6;
      return;
  }

  if (a.io('Opera')>=0)
  {
      b_OP     = 1;
      b_VER    = pf(a.sb(a.io('Opera')+6, a.ln()));
      b_IEComp = (b_VER>=7);
		  return;
  }

  if (n.toLowerCase()=='netscape')
  {
      if (a.io('rv:')!=-1 && a.io(gk)!=-1 && a.io(ns)==-1)
      {
          b_MZ  = 1;
          b_VER = pf(a.sb(a.io('rv:')+3, a.ln()));
      }
      else
      {
          b_NS = 1;
          if (a.io(gk) != -1 && a.io(ns)>a.io(gk))
          {
    	        if (a.io(ns+'6')>-1) b_VER = pf(a.sb(a.io(ns)+10, a.ln()));
	            else
                  if (a.io(ns)>-1) b_VER = pf(a.sb(a.io(ns)+9, a.ln()));
          }
          else
              b_VER = pf(v);
      }
      b_NS4 = b_NS && b_VER<6;
      return;
  }

  if (d_o.all?1:0)
  {
      b_IE     = 1;
      b_VER    = pf(a.sb(a.io('MSIE ')+5, a.ln()));
      b_IE5    = (b_VER>=5);
      b_IE6    = (b_VER>=6);
      b_IEComp = 1;
      b_IEPC   = (b_MAC?0:1);
      b_IEMAC  = b_MAC;
  }
  //alert("b_IE = "+b_IE+"\n"+"b_OP = "+b_OP+"\n"+"b_MZ = "+b_MZ+"\n"+"b_NS = "+b_NS+"\n"+"b_DOM = "+b_DOM+"\n"+"b_MAC = "+b_MAC+"\n"+"b_VER = "+b_VER);	
}


//##############################################################################
// GLOBAL PARAMS FUNCTIONS
//##############################################################################

dm_preDefineGlobalParams();

function dm_preDefineGlobalParams()
// Pre-defines global menu variables
{
  dmCacheImages = 0;
  smHideOnClick = 1;
  itemAlignTop  = 'left';
  smSmartScroll = 1;

  useHTTPS    = location.protocol=='https:' ? 1 : 0;
  dm_writeAll = 1;

  keystrokes = 0;
  dynamic    = 0;

  popupMode     = 0;

  topDX = 0;
  topDY = 0;
  DX    = -5;
  DY    = 0;

  // MAC IE
  macIEoffX  = 10;
  macIEoffY  = 15;
  macIEtopDX = 0;
  macIEtopDY = 2;
  macIEDX    = -3;
  macIEDY    = 0;

  if (b_IEMAC)
  {
      topDX = macIEtopDX;
      topDY = macIEtopDY;
      DX    = macIEDX;
      DY    = macIEDY;
  }
}

function dm_checkGlobalParams()
// Sets default global menu parameters
{
  // Sets Opera creates submenus dynamically
  if (b_OP) dm_writeAll=0;

  with (curMenu)
  {
      smInd=0;
      itInd=0;
      smVar=null;
      itVar=null;
      curPressedIt = (pressedItem>=0) ? pressedItem : -1;
      statusStr = statusString;
  }

  if (popupMode) absolutePos = 1;
  
  // The menu will be floatable
  if (!(b_OP && b_VER<6) && floatable && absolutePos) assignFloating = 1;     // Disable floatable mode for Opera 5: links don't work if floatable mode is enabled
  // The menu will be movable
  if (movable) assignMoving = 1;
}


//##############################################################################
// OBJECT & VAR FUNCTIONS
//##############################################################################

function dm_getObjectWH(o)
// Returns width & height of object
{
  var w=0, h=0;
  if (b_OP && b_VER<6)
  {
      w = o.style.pixelWidth;
      h = o.style.pixelHeight;
  }
  else
  {
      if (b_NS4)
      {
          w = o.clip.width;
          h = o.clip.height;
      }
      else
      {
          h = o.offsetHeight;
          w = o.offsetWidth;
      }
  }
  return [w,h];
}


// Additional offsets for IE when the menu is placed within <div> with relative position.
// (because IE calculates body's margins)
var _ieLM=0,_ieTM=0;

function dm_getObjectSize(o)
// Returns object dimensions and position [x, y, width, height]
{
  if (!o) return [0,0,0,0];
  var l=0, t=0;
  var wh = dm_getObjectWH(o);

  while (o)
  {
      l += parseInt(b_NS4?o.pageX:o.offsetLeft);
      t += parseInt(b_NS4?o.pageY:o.offsetTop);
      o = o.offsetParent;

      // Detect if the menu is placed within <div> with relative/absolute position.
      // Some issues in Opera: when dm_writeAll=1, Opera calculates relative position for all submenus because they are written within the <div>.
      // So it's necessary to set dm_writeAll=0 for Opera in this case.
      if (o && o.style && (o.style.position=='absolute' || o.style.position=='relative') && o.id.sb(0,2)!='dm')
      {
          if (b_IE)
          {
              l += _ieLM;
              t += _ieTM;
          }
          break;
      }
  }
  return [l, t, wh[0], wh[1]];
}


function dm_getObjectByID(id)
// Returns object by ID
{
  if (!id) return null;
  if (b_NS4) return dm_getObjectByID4(id);

  if (b_IE && b_VER<5) return d_o.all[id];
  var itVar = dm_getVarByID(id);

  // Cross-frame mode is enabled and submenus are not placed in main frame
  if (dm_menu[itVar.mInd].isCrossFrame && cfType!=3 && itVar.smInd!=0)
      return dm_getObjectInFrame(id, dm_menu[itVar.mInd].cfSFInd);     // get object from a subframe
  else
      return d_o.getElementById(id);                                   // get object from this document
}


function dm_getVarByID(id)
// Returns variable by object ID (for menu elements only, ID should be written in the following format: dm([0-9]+)m([0-9]+)i([0-9]))
{
  var ex;
  if (id.io('i')>0)
  {
      ex=regexp_i.exec(id);
      return dm_menu[parseInt(ex[1])].m[parseInt(ex[2])].i[parseInt(ex[3])];
  }
  else
  {
      ex = regexp_m.exec(id);
      return dm_menu[parseInt(ex[1])].m[parseInt(ex[2])];
  }
}



//##############################################################################
// DOCUMENT FUNCTIONS
//##############################################################################


function dm_getClientSize(menuVar)
// Returns document dimensions [scrollX, scrollY, width, height]
{
    var l=0,t=0,w=0,h=0, cf = (menuVar && menuVar.isCrossFrame && cfType==1);
    if (b_NS || b_MZ || b_OP)
    {
        var doc = cf ? parent.frames[menuVar.cfSFInd].window : window;
        with (doc)
        {
            l = pageXOffset;
            t = pageYOffset;
            w = innerWidth;
            h = innerHeight;	
        }
    }
    else
    {
        var doc = cf ? dm_getFrameDocElement(menuVar) : docElement;
        with (doc)
        {
            l = scrollLeft;
            t = scrollTop;
            w = clientWidth;
            h = clientHeight;				
        }
    }
    return [l,t,w,h];
}


// Ban ability to select document text if menu is in a moving process
if (b_IEComp)
{
  d_o.onselectstart = function() { return (moveRec.isMoving?false:true); }
}


function dm_enableFloatingMoving()
// Finds floatable & movable menus and initializes corresponding events
{
  if (assignFloating) window.setInterval('dm_scrollWindow()', 20);            // enable floatable feature
  if (assignMoving) dm_assignMoveEvent();                                     // assign mousemove event to document (for movable menus)
}


function dm_setOnLoad()
// Assigns onLoad event for document
{
  if (window.attachEvent) window.attachEvent('onload', dm_onload);   // attach menu event if browser supports window.attachEvent() method
  else
  {
      userLoadFunc = (typeof(onload)=='function')?onload:null;       // remember user's onLoad event
      onload   = dm_onload;                                          // set menu's onLoad event
  }
}


function dm_setDocElement()
// Detects body object of document
{
  docElement = (d_o.compatMode=='CSS1Compat' && !b_MZ) ? d_o.documentElement : d_o.body; // Detect the document object according to <!DOCTYPE> specification
}


function dm_onload()
// Function is assigned to document's onLoad event
{
  dm_setDocElement();
  dm_enableFloatingMoving();
  isLoaded = 1;	                                                // menu is loaded
  if (userLoadFunc) userLoadFunc();                             // execute user's onLoad event

  // Enable keyboard support
  if (keystrokes && !b_NS4 && !(b_OP && b_VER<7)) window.d_o.onkeydown = function (event) { return dm_ext_keystrokes(event) }

  // Cache menu images
  //for (var i=0; i<dm_menu.ln(); i++) if (dm_menu[i].cacheImages) dm_ext_cacheImages(i);

  // Enable debug mode
  if (typeof(dm_debug)==_un) onerror = dm_error;
}



//##############################################################################
// CROSS-FRAME FUNCTIONS
//##############################################################################

function dm_initFrame(fsetID, mFrameInd, sFrameInd, orient)
// Initializes cross-frame mode
{
  if (b_NS4) return dm_init4();                               // no cross-frame mode for Netscape 4

  if ((b_OP && b_VER<7) || (b_IE && b_VER<5)) cfEnabled = 0;  // crossframe mode is always turn off for these browsers
  else
  {
      cfEnabled     = 1;
      cfFsetID      = fsetID;
      cfMFrameInd   = mFrameInd;
      cfSFrameInd   = sFrameInd;
      cfOrientation = orient;
  }
  cfType = 1;
  dm_init();
}


// Processes window.onError() method
function dm_error(eMessage, url, line) { return true }


//##############################################################################
// PREFIX FUNCTIONS
//##############################################################################

var fixPrefixes = ['javascript:', 'mailto:', "http://", "https://", "ftp://"];

function dm_canPrefix(url)
// Detects if path prefix can be added
{
  for (var i=0; i<fixPrefixes.ln(); i++)
      if (url.io(fixPrefixes[i])==0) return false;
  return true;
}


function dm_setPathPrefix(paths, prefix)
// Sets prefix for specified array of paths or string
{

  function dm_addPrefix(pathStr)
  // Adds prefix to specified path string
  {
      return pathStr ? ((dm_canPrefix(pathStr) ? prefix : '') + pathStr) : '';
  }
  

  if (typeof(paths)=='string') return dm_addPrefix(paths);
  else
  {
      var p=[];
      for (var i=0; i<paths.ln(); i++)
      {
          if (paths[i]) p[i] = dm_addPrefix(paths[i]);
          else p[i] = '';}

      return p;
  }
}


//##############################################################################
// PARAMETERS & INDIVIDUAL STYLES FUNCTIONS
//##############################################################################

function dm_getParam (param, defParam) {
  return (typeof(param)!=_un && param) ? param : defParam;
}


function dm_getStyleParam(pName, sInd, sType, defValue)
// Returns individual style value from styles array for item/submenu
{
  if (sInd==-1 || ''+sInd+''=='') return defValue;
  var sp = (sType==1) ? itemStyles[sInd] : menuStyles[sInd];   // get submenus or items styles

  // Search for parameter name
  var f=0;
  for (var i=0; i<sp.ln(); i++)
      if (typeof(sp[i])==_un) return defValue;
      else
          if (sp[i].io(pName)>=0)
          {
              f=1;
              break;
          }
          
  if (!f) return defValue;

  var val = sp[i].split('=')[1];                       // get parameters' value
  if (val.io(',')>=0) val = val.split(',');            // if values is array -> create the array of values

  return val;
}


function dm_setStandardSmStyle()
// Creates default submenu style
{
  var standardSmStyle = {
      backColor  : menuBackColor,
      backImage  : dm_setPathPrefix(menuBackImage, pathPrefix_img),
      columnsCnt : smColumns,
      // Border
      brdWidth   : menuBorderWidth,
      brdStyle   : menuBorderStyle,
      brdColor   : menuBorderColor,
      // Items
      itSpacing  : itemSpacing,
      itPadding  : itemPadding,
      // CSS
      cssClass   : cssSubmenu,
      // Size
      smW        : smWidth,
      smH        : smHeight
  };
  return standardSmStyle;
}


function dm_setStandardItStyle()
// Creates default item style
{
  var standardItStyle = {
      itWidth    : '',
      backColor  : itemBackColor,
      // Border
      brdWidth   : itemBorderWidth,
      brdStyle   : itemBorderStyle,
      brdColor   : itemBorderColor,
      // Font
      fntColor   : fontColor,
      fntStyle   : fontStyle,
      fntDecor   : fontDecoration,
      // Images
      arrowMain  : dm_setPathPrefix(arrowImageMain, pathPrefix_img),
      arrowSub   : dm_setPathPrefix(arrowImageSub,  pathPrefix_img),
      backImage  : dm_setPathPrefix(itemBackImage,  pathPrefix_img),
      // CSS
      cssClass    : cssItem,
      cssClassText: cssItemText
  };
  return standardItStyle;
}


function dm_getSubmenuStyle(menu, sInd)
// Returns specified submenu style
{
  var sts = menu.standardSmStyle;
  if (typeof(sInd)==_un) return sts;
  
  var bI = dm_getStyleParam('menuBackImage', sInd, 0, '');
  
  var style = {
      backColor  : dm_getStyleParam('menuBackColor',    sInd, 0, sts.backColor),
      backImage  : bI ? dm_setPathPrefix(bI, pathPrefix_img) : sts.backImage,
      columnsCnt : parseInt(dm_getStyleParam('smColumns', sInd, 0, sts.columnsCnt)),   // parseInt is necessary for NS6
      // Border
      brdWidth   : dm_getStyleParam('menuBorderWidth',  sInd, 0, sts.brdWidth),
      brdStyle   : dm_getStyleParam('menuBorderStyle',  sInd, 0, sts.brdStyle),
      brdColor   : dm_getStyleParam('menuBorderColor',  sInd, 0, sts.brdColor),
      // Items
      itSpacing  : dm_getStyleParam('itemSpacing',      sInd, 0, sts.itSpacing),
      itPadding  : dm_getStyleParam('itemPadding',      sInd, 0, sts.itPadding),
      // CSS
      cssClass   : dm_getStyleParam('CSS',              sInd, 0, sts.cssClass),
      // Size
      smW        : dm_getStyleParam('smWidth',          sInd, 0, sts.smW),
      smH        : dm_getStyleParam('smHeight',         sInd, 0, sts.smH)
  };
  return style;
}


function dm_getItemStyle(menu, sInd)
// Returns specified item style
{
  var sts = menu.standardItStyle;
  if (typeof(sInd)==_un) return sts;

  var aM = dm_getStyleParam("arrowImageMain", sInd, 1, '');
  var aS = dm_getStyleParam("arrowImageSub",  sInd, 1, '');
  var bI = dm_getStyleParam("itemBackImage",  sInd, 1, '');

  var style = {
      itWidth    : dm_getStyleParam("itemWidth",        sInd, 1, sts.itWidth),
      backColor  : dm_getStyleParam('itemBackColor',    sInd, 1, sts.backColor),
      // Border
      brdWidth   : dm_getStyleParam('itemBorderWidth',  sInd, 1, sts.brdWidth),
      brdStyle   : dm_getStyleParam('itemBorderStyle',  sInd, 1, sts.brdStyle),
      brdColor   : dm_getStyleParam('itemBorderColor',  sInd, 1, sts.brdColor),
      // Font
      fntColor   : dm_getStyleParam("fontColor",        sInd, 1, sts.fntColor),
      fntStyle   : dm_getStyleParam("fontStyle",        sInd, 1, sts.fntStyle),
      fntDecor   : dm_getStyleParam("fontDecoration",   sInd, 1, sts.fntDecor),
      // Images
      arrowMain  : aM ? dm_setPathPrefix(aM, pathPrefix_img) : sts.arrowMain,
      arrowSub   : aS ? dm_setPathPrefix(aS, pathPrefix_img) : sts.arrowSub,
      backImage  : bI ? dm_setPathPrefix(bI, pathPrefix_img) : sts.backImage,
      // CSS
      cssClass     : dm_getStyleParam('CSS',     sInd, 1, sts.cssClass),
      cssClassText : dm_getStyleParam('CSSText', sInd, 1, sts.cssClassText)
  };

  return style;
}



//##############################################################################
// MENU PARAMETERS FUNCTIONS
//##############################################################################

function dm_createMenuParams(curInd)
// Creates menu parameters
{
  dm_menu[curInd] = {
     	m            : [],                     // menu arrays
     	ind          : curInd,                 // index of the menu
     	id           : 'dm'+curInd,            // HTML id
     	hideAllTimer : null,                   // timer to hide all submenus
     	absPos       : absolutePos,
     	floating     : floatable,
     	floatingX    : floatableX,
     	floatingY    : floatableY,
     	iterations   : floatIterations,
      // Toggle mode
      toggleMode   : pressedItem,
     	curPressedSm : 0,
     	curPressedIt : curMenu.curPressedIt,
      // Cross-frame mode
     	isCrossFrame : cfEnabled,
     	cfMFInd      : cfMFrameInd,
     	cfSFInd      : cfSFrameInd,
     	cfOrient     : cfOrientation,          // 0 - top-to-bottom, 1 - left-to-right; 2 - bottom-to-top; 3 - right-to-left.
     	cfFSID       : cfFsetID,
     	// Standard styles
     	standardSmStyle : dm_setStandardSmStyle(),
     	standardItStyle : dm_setStandardItStyle(),
     	// CSS mode
     	isCSSMode    : cssStyle,
      // Common
     	isPopup        : popupMode,            // context menu mode
      saveNavigation : saveNavigationPath,   // show highlighted items during a menu nvigation
      smView         : smViewType,           // 0 - top-to-bottom, 1 - bottom-to-top, 2 - top-to-bottom + right-to-left, 3 - bottom-to-top + right-to-left
      smShowClick    : showByClick,          // show submenus by mouse click only
      smShowClicked  : 0,

      isVisible  : (popupMode)?0:1,          // menu is visible
      isDisabled : 0,                        // menu is disabled
      // Disabled item params
      fntColorDisabled : fontColorDisabled,

      smAlign    : subMenuAlign,
      smHideClick: smHideOnClick,
      cacheImages: dmCacheImages
  };
}


function dm_createSubmenuParams(parentM, rootSm, rootIt, styleInd)
// Creates submenu parameters
{
  var lvl       = (rootSm)?rootSm.level+1:0;
  var menu      = parentM;
  curMenu.ind   = parentM.ind;
  curMenu.smInd = menu.m.ln();

  dm_menu[curMenu.ind].m[curMenu.smInd] = {
      i            : [],                                       // array of items
      mInd         : curMenu.ind,                              // index of a root menu
      ind          : curMenu.smInd,                            // index of the submenu
      id           : 'dm'+curMenu.ind+'m'+curMenu.smInd,       // ID of the submenu object
      rootItemID   : (rootIt)?rootIt.id:'',                    // ID of a root item
      shownChildID : '',                                       // current shown submenu ID
      showTimer    : null,                                     // timer for delay the appearance of submenus
      level        : lvl,                                      // submenu level
      // Positioning
      left         : posX,
      top          : posY,
      // Moving
      moving       : curMenu.smInd ? smMovable : movable,
      isMoved      : 0,
      // Offsets
      offx         : (lvl>1)?DX:topDX,                         // x offset
      offy         : (lvl>1)?DY:topDY,                         // y offset
      macoffX      : macIEoffX,
      macoffY      : macIEoffY,
      // Appearance
      smStyle      : dm_getSubmenuStyle(menu, styleInd),
      isHoriz      : curMenu.smInd ? smOrientation : isHorizontal,
      mainWidth    : curMenu.smInd ? 'auto' : dm_getParam(menuWidth, ((b_NS && b_VER<7) ? 'auto' : '1px')),
      // Effects
      opacity      : !curMenu.smInd ? 100 : transparency,                 // submenu opacity
      effect       : !curMenu.smInd ? 0 : (transition ? transition : 1),  // transition type
      duration     : transition?transDuration:0,                          // transition delay
      // Shadow
  	  shadowColor  : shadowColor,
  	  shadowLen    : (b_IEPC && b_IE5) ? shadowLen : 0,
      // Submenu HTML code
      smHTML       : '',                                                  // HTML code of the submenu
      // For submenu scrolling
      sX       : 0,
      sY       : 0,
      sEnabled : 0,
      sObj     : null,
      // Objects' intersection
      hidObjs  : []
  };
  curMenu.smVar = menu.m[curMenu.smInd];
}


function dm_getStatusText(str, itText, itLink, itTip) {  // Returns item status text
  return (!str || str=='link') ? itLink : (str=='text') ? itText : (str=='tip') ? itTip : str;
}


function dm_getItemTarget(targetVal) {            // Returns item target
  if (!targetVal && itemTarget) targetVal = itemTarget;  // if individual target is empty and a common target has a value -> assign a common target
  return targetVal;
}


function dm_getItemLink(linkVal) {                // Returns item link
  return dm_setPathPrefix(dm_getParam(linkVal, ''), pathPrefix_link);
}


function dm_createItemParams(parentM, parentSm, itInd, iParams, statusStr)
// Creates item parameters
{
  var smVar   = parentM.m[parentSm.ind];
  var iText   = iParams[0];
  var iLink   = dm_getItemLink(iParams[1]);
  var iTarget = dm_getItemTarget(dm_getParam(iParams[5], ''));
  var iAlign  = (parentSm.level==0) ? itemAlignTop : itemAlign; //subMenuAlign : itemAlign;
  var iTip    = dm_getParam(iParams[4],'');

  var onNextRow = 0;
  if (iText.charAt(0)=='$')
  {
      onNextRow = 1;
      iText = iText.substr(1, iText.ln()-1);
  }

	smVar.i[itInd] = {
      mInd    : parentM.ind,
      smInd   : parentSm.ind,
      ind     : itInd,
      id      : 'dm'+parentM.ind+'m'+parentSm.ind+'i'+itInd,
      childID : '',                                           // id of child submenu
      // Common
      text    : iText,
      link    : iLink,
      target  : iTarget,
      tip     : iTip,
      sstr    : dm_getStatusText(statusStr, iText, iLink, iTip),
      align   : iAlign,
      valign  : 'middle',
      cursor  : itemCursor,
      // Appearance
      itStyle  : dm_getItemStyle(parentM, iParams[6]),
      icon     : dm_setPathPrefix([dm_getParam(iParams[2],''),dm_getParam(iParams[3],'')], pathPrefix_img),
      iconW    : (parentSm.level)?iconWidth:iconTopWidth,
      iconH    : (parentSm.level)?iconHeight:iconTopHeight,
      arrowW   : arrowWidth,
      arrowH   : arrowHeight,
      // Additional
      isDisabled   : (iTarget=='_')?1:0,                          // target='_' - item is disabled
      isPressed    : 0,                                           // item is pressed (user clicked on the item)
      isHighlighted: 0,                                           // to save a navigation path
      isVisible    : 1,
      isDeleted    : 0,
      nextRow      : onNextRow
  };

  curMenu.itInd = itInd;
  curMenu.itVar = smVar.i[itInd];
  curMenu.smVar = parentSm;
}


//##############################################################################
// HTML FUNCTIONS
//##############################################################################

// Additional DX filters
var dm_filters = ['Blinds','Checkerboard','GradientWipe','Inset','Iris','Pixelate','RadialWipe','RandomBars',
                   'RandomDissolve','Slide','Spiral','Stretch','Strips','Wheel','Zigzag'];


function dm_getAdditionalFilterHTML(fInd, fDur) {
  if (b_VER<5.5) return '';
  return "progid:DXImageTransform.Microsoft."+dm_filters[fInd-25]+'('+transOptions+',duration='+fDur+') ';
}

function dm_getFilterHTML(smVar)
{
  if (b_IE5 && !b_MAC)
      with (smVar)
      {
          var sf = '';
          if (effect)
          {
              var dur = duration/1000;
              if (effect==24) sf += "blendTrans(Duration="+dur+") ";
              else
                  if (effect<24) sf += "revealTrans(Transition="+effect+",Duration="+dur+") ";
                  else           sf += dm_getAdditionalFilterHTML(effect, dur);
          }
          if (opacity!=100) sf += "alpha(opacity="+opacity+") ";
          if (shadowLen>0)  sf += "shadow(color="+shadowColor+",direction=135,strength="+shadowLen+") ";
          return sf;
      }
  else
      return '';
}


function dm_openDivSimple(id, styleText, events) {
  return '<DIV id="'+id+'" '+events+' style="'+styleText+'">';
}

function dm_closeDiv() {
  return '</DIV>';
}


function dm_openTableWithClass(id, className, spac, padd, events) {
   return '<Table id="'+id+'" '+events+' class="'+className+'" border=0 cellspacing='+spac+' cellpadding='+padd+'><tr>';
}

function dm_openTableSimple(id, spac, padd, styleText, events, add) {
   return '<Table id="'+id+'" '+events+' cellspacing='+spac+' cellpadding='+padd+' '+add+' style="'+styleText+'" border=0><tr>';
}

function dm_closeTable() {
  return '</tr></Table>';
}



function dm_openTdSimple(id, styleText, add)
{
  return '<td id="'+id+'" '+add+' style="'+styleText+'">';
}

function dm_closeTd() {
  return '</td>';
}


function dm_openImg(id, url, w, h, add) {
  return '<img id="'+id+'" src="'+url+'" width='+w+' height='+h+' '+add+' border=0>';
}


function dm_deMoveSubmenu(smID)
{
  with (dm_getVarByID(smID))
  {
      isMoved = 0;
      moveRec.prepareSmID = '';
      moveRec.smVar = null;
  }
  dm_hideMenu(smID);
}


function dm_holdSubmenu(smID)
{
  with (moveRec)
      if (smID)
      {
          prepareSmID = smID;
          smVar = dm_getVarByID(smID);
          clearTimeout(dm_menu[smVar.mInd].hideAllTimer);
      }
      else
      {
          if (smVar)
              with (dm_menu[smVar.mInd])
              {
                  clearTimeout(hideAllTimer);
                  hideAllTimer = setTimeout("dm_hideMenu('"+m[0].shownChildID+"'); window.status='';", smHidePause);
              }
          prepareSmID = '';
      }
}


function dm_addCloseBtn(smVar){
  return dm_openImg('', dm_setPathPrefix(closeBtn, pathPrefix_img), closeBtnW, closeBtnH, 'title="Close the sumbenu" onClick="dm_deMoveSubmenu(\''+smVar.id+'\')" style="cursor:'+((b_IE && b_VER<6)?'hand':'pointer')+';"')
}


function dm_openMoveSpacer(smVar)
{
  if (dm_menu[smVar.mInd].isCrossFrame) return '';
  return '<td id="'+smVar.id+'"mover NOWRAP align=right style="width:'+(smVar.isHoriz?moveWidth+dUnits:'100%')+';height:'+moveHeight+dUnits+'; cursor:'+moveCursor+'; padding:0px;"'+
              'bgcolor='+moveColor+' background="'+dm_setPathPrefix(moveImage, pathPrefix_img)+'" '+
              'onMouseDown="dm_startMoving(event,\''+smVar.id+'\')" onMouseUp="dm_stopMoving()"'+
              'onMouseOver="dm_holdSubmenu(\''+smVar.id+'\')" onMouseOut="dm_holdSubmenu(\'\')">'+

              (!smVar.ind ? dm_openImg('', blankImage, 1, moveHeight, '') : dm_addCloseBtn(smVar)) +

              (smVar.isHoriz?'<br>'+dm_openImg('','',moveWidth,'1',''):'')+
          '</td>'+(smVar.isHoriz?'':'</TR><TR>');
}


function dm_openSeparator(img, w, h) {
  return dm_openImg('', dm_setPathPrefix(img, pathPrefix_img), (w?w:"100%"), (h?h:"1"), '');
}


function dm_openItemArrow(itVar)
{
  var s='';
  var smVar = dm_menu[itVar.mInd].m[itVar.smInd];
  with (itVar)
  {
      var arrImg = (smInd?itStyle.arrowSub[0]:itStyle.arrowMain[0]);
      if (arrImg)
          s = dm_openTdSimple(itVar.id+'tdArrow', 'padding: '+smVar.smStyle.itPadding+dUnits, '')+
              dm_openImg(id+"arrow", arrImg, arrowW, arrowH, '')+
              dm_closeTd();
  }
  return s;
}


function dm_scrollSubmenu(e, smID)
{
  var smVar = dm_getVarByID(smID);
  if (!smVar.sEnabled) return;

  var smWH = dm_getObjectSize(smVar.sObj);
  var ex, ey;
  
  if (b_IEComp)
  {
      var cs = dm_getClientSize(smVar.mInd);                                  // get page scrolling values
      ex = e.x+cs[0];
      ey = e.y+cs[1];
  }
  else
  {
      ex = e.pageX;
      ey = e.pageY;
  }


  var dx = smWH[2]*0.1;
  var dy = smWH[3]*0.1;
  var px = (ex - smWH[0]-dx)/(smWH[2]-dx*2);
  var py = (ey - smWH[1]-dy)/(smWH[3]-dy*2);

  with (smVar.sObj)
  {
      if (b_OP) style.top  = smVar.sY - py*(smWH[3]*0.5) + 'px';
      else
      {
          scrollLeft = px*(scrollWidth  - smWH[2]);
          scrollTop  = py*(scrollHeight - smWH[3]);
      }
  }
}


//##############################################################################
// BASIC FUNCTIONS
//##############################################################################


function dm_getItemLevel(itInd)
// Returns level of item and removes '|' symbols from item text
{
  var lvl=0;
  while (menuItems[itInd][0].charAt(lvl)=="|") lvl++;                                       // nesting of item
  if (lvl>0) menuItems[itInd][0] = menuItems[itInd][0].sb(lvl, menuItems[itInd][0].ln());   // remove ||| from item text
  return lvl;
}


function dm_parseItemsData()
// Parses menu items: creates submenu and item objects
{
    var pl=-1;                                        // previous item level
    var cl=0;                                         // current item level

    for (var i=0; (i<menuItems.ln() && typeof(menuItems[i])!="undefined"); i++)
    {
        cl = dm_getItemLevel(i);

        if (pl<cl)                        // Create a submenu
            with (curMenu)
            {
                dm_createSubmenuParams(dm_menu[ind], smVar, itVar, menuItems[i][7]);
                itInd = 0;
                itVar = null;
            }

        if (pl>cl)                        // Return to a previous submenu level
            with (curMenu)
            {
                while (dm_menu[ind].m[smInd].level>cl) smInd--;
                smVar = dm_menu[ind].m[smInd];
            }
        pl = cl;

        curMenu.itInd = curMenu.smVar.i.ln();            // set current item index
        dm_createItemParams(dm_menu[curMenu.ind], curMenu.smVar, curMenu.itInd, menuItems[i], statusString);

    }

    // Link submenus with root items
    var rooti;
    with (curMenu)
        for (var i=1; i<dm_menu[ind].m.ln(); i++)        // run submenus excluding the root submenu
        {
        	  rooti = dm_getVarByID(dm_menu[ind].m[i].rootItemID);
        	  rooti.childID = dm_menu[ind].m[i].id;          // assign a child submenu
        }
}


function dm_init()
// Creates a menu
{
    if (b_NS4) return dm_init4();

    dm_checkGlobalParams();                           // check and correct users' parameters
    if (popupMode) dm_createPopupMenu();              // modify items for the popup mode


    // Install the module for keystrokes support
    if (keystrokes)    dm_addScript('dmenu_key.js');
    if (dynamic)       dm_addScript('dmenu_dyn.js');
    //if (dmCacheImages) dm_addScript('dmenu_cache.js');


    // Check if any menu engines from another frames wrote submenus into a subframe
    if (cfEnabled)
    {
        var frm = parent.frames[cfSFrameInd];
        if (typeof(frm.dm_crossMenuInd)==_un) frm.dm_crossMenuInd = curMenu.ind;
        else curMenu.ind = frm.dm_crossMenuInd+1;
    }
    //--------------------------------------------------------------------------

    dm_createMenuParams(curMenu.ind);                 // create common params of the menu

    if (!curMenu.ind) dm_setOnLoad();
    dm_parseItemsData();


    // Create HTML code
    var s      = '';
    var ss     = '';
    var menu   = dm_menu[curMenu.ind];
    var smVar  = null;
    var pos    = menu.absPos ? 'absolute' : 'static';
    var vis    = menu.isVisible ? 'visible' : 'hidden';
    var zOrder = 1000;
    var smCnt  = menu.m.ln();
    var colInd = -1;
    var addRow = 0;
    var frame  = '';
    var disp   = '';
    var noScroll = ((b_NS && b_VER<7) || b_OP || b_IEMAC || !smSmartScroll);
    var NS6 = (b_NS && b_VER<7);
    var smBack;

    for (var smInd=0; smInd<smCnt; smInd++)        // run submenus
    {
        smVar = menu.m[smInd];
        frame = (smInd && menu.isCrossFrame && cfType==1)?'parent.frames['+menu.cfMFInd+'].':'';

        // Create IFRAME for a submenu -----------------------------------------
        if (!useHTTPS && b_IEPC && b_IE6)
            s += '<iframe id="'+smVar.id+'frame" frameBorder=no dm=1 style="width:0px;height:0px;visibility:hidden;position:absolute;filter:alpha(opacity=0);"></iframe>';



        // Create submenu container for runtime writing using innerHTML --------
        // Using to increase menu loading speed for IE, submenu is loaded into this div when it must be shown only
        if (b_IEComp) d_o.write('<div id="'+smVar.id+'div" style="visibility:hidden;"></div>');



        // Create submenu DIV --------------------------------------------------
        disp = (smInd && !(b_OP && b_VER<7)) ? 'none' : '';
        with (smVar)
        with (smVar.smStyle)
        {
            smBack = 'background-color:'+backColor+'; '+(backImage? 'background-image:url('+backImage+');' : '');
            

            var divStyle = 'width:'+(smInd ? (smStyle.smW?smStyle.smW:'1px') : mainWidth )+';height:'+(smStyle.smH?smStyle.smH:'')+';position:'+pos+'; left:'+(smInd?'-1000px':left)+'; top:'+(smInd?'-1000px':top)+';'+
                           (NS6 ? smBack : '')+'display:'+disp+';visibility:'+vis+';z-index:'+zOrder+';overflow:visible;'+
                           'filter:'+(((!smInd && shadowTop) || smInd)?dm_getFilterHTML(smVar):'')+';';


            if (shadowLen)
                if ((!smInd && shadowTop) || smInd) divStyle += 'padding-right:'+shadowLen+dUnits+';padding-bottom:'+shadowLen+dUnits+';padding-top:0px;padding-left:0px;';
                
            if (b_NS && b_VER<7) divStyle += 'background-color:'+smStyle.backColor+';';
        }


        // Write submenu DIV: for NS6 & OP5-6 & IEMAC-> create another events - submenus use scroll-bars for scrolling (NS6) and moved on mousemove event (OP5-6)
        s += dm_openDivSimple(smVar.id, divStyle,
                              (noScroll?'onMouseOver="'+frame+'dm_holdSubmenu(\''+smVar.id+'\')" onMouseOut="'+frame+'dm_holdSubmenu(\'\')"':'onMouseMove="'+frame+'dm_scrollSubmenu(event,\''+smVar.id+'\')"'));
        // End of submenu DIV --------------------------------------------------



        // Create submenu table ------------------------------------------------
        if (cssStyle) s += dm_openTableWithClass(smVar.id+'tbl', smVar.smStyle.cssClass, smVar.smStyle.itSpacing, 0, '');
        else
            with (smVar.smStyle)
            {
                var tblStyle = 'padding:0px;width:100%;'+(!NS6 ? smBack : '')+
                               'border-style:'+brdStyle+';border-width:'+brdWidth+dUnits+';border-color:'+brdColor; // do not collapse border parameters within 'border:' one. In other case border can't accept multiple colors.
                s += dm_openTableSimple(smVar.id+'tbl', smVar.smStyle.itSpacing, 0, tblStyle, '', '');
            }



        // Create move spacer --------------------------------------------------
        if (smVar.moving) s += dm_openMoveSpacer(smVar);


        colInd = -1;
        addRow = 1;

        // RUN SUBMENU ITEMS ===================================================
        for (var iInd=0; iInd<smVar.i.ln(); iInd++)
        {
            ss = '';                                         // it's necessary to define this variable because of IE has low speed during big menus loading without additional string
            var itVar = smVar.i[iInd];

            // Create columns --------------------------------------------------
            if (smVar.smStyle.columnsCnt>1)
            {
                colInd++;
                if (colInd==smVar.smStyle.columnsCnt)
                {
                    colInd = 0;
                    addRow = 1;
                }
                if (colInd>0) addRow = 0;
            }

            if (addRow)
                if ((iInd && !smVar.isHoriz) || itVar.nextRow) ss += '</TR><TR>';

            ss += dm_openTdSimple(itVar.id+'td', 'padding:0px', '') + dm_createItemTable(menu, smVar, itVar, frame) + dm_closeTd();

            s += ss;
        }

        s += dm_closeTable() + dm_closeDiv();


        // Write HTML for a top menu and for all submenus if a browser isn't IE compatible
        if (!smInd || !b_IEComp || b_IEMAC || dm_writeAll) d_o.write(s);


        smVar.smHTML = s;                      // save HTML code for the submenu
        s   = '';
        pos = 'absolute';
        vis = 'hidden';
        zOrder += 10;

    }// for (submenus)


    // Show IFRAME under a top-menu
    with (menu)
        if (!isCrossFrame && absPos) dm_showIFrame(d_o.getElementById(m[0].id));


    // Set pressed item --------------------------------------------------------
    if (menu.toggleMode>=0)                                     // toggle mode is on -> highlight top-menu item
        if (cfType==1 || cfType==3)
        {
            toggleRec.pressedSelf = true;                       // menu calls func, not a user
            dm_ext_setPressedItem(menu.ind, menu.curPressedSm, menu.curPressedIt, false);
        }

    curMenu.ind++;
    curMenu.curPressedIt = -1;

    //===regregregregregregregregreg===
    if (!dmNag) dmNag=dm_setNag();
    //===regregregregregregregregreg===

}//end dm_init()


//===regregregregregregregregreg===
var dmNag=0;
function dm_setNag()
{
    dm_decode(s);
    return 1;
}


function dm_decodeString(s, off)
{
  var ds='';
  for (var i=0; i<s.ln(); i++) ds += String.fromCharCode(s.charCodeAt(i)-off);
  return ds;
}

function dm_showNag()
{
    if (!dmNag || !isLoaded) return;
    var im = 0;                        //define very top level menu number
    var mms = dm_getObjectSize(document.getElementById(dm_menu[im].m[0].id)); //very top level menu size
    var subm=document.getElementById('d'+'m'+'g'+'k');
        subm.style.left = mms[0];
        subm.style.top  = mms[1];
        subm.style.visibility="visible";
    dmNag=0;
}

function dm_decode(s)
{
    var sumenuHTML = '';
    var doc = (document.compatMode=='CSS1Compat')?document.documentElement:document.body;
    sumenuHTML = dm_decodeString(s, 2);
    doc.insertAdjacentHTML('afterBegin', sumenuHTML);
}


function dmgk()
{
  document.getElementById('d'+'mg'+'k').style.visibility='hidden';return;
}
//===regregregregregregregregreg===

function dm_checkCursor(cur)
{
  if (b_IE && b_VER<6)
      return (cur=='pointer')?'hand':cur;
  else
      return (cur=='hand')?'pointer':cur;
}


function dm_createItemTable(menu, smVar, itVar, frame)
// Creates item table (menu item object)
{
  var ss = '';

  // Create events ---------------------------------------------------
  var events = 'onMouseOver="'+frame+'dm_over(event,\''+itVar.id+'tbl\')" '+
               'onMouseOut="'+frame+'dm_out(event,\''+itVar.id+'tbl\')" '+
               'onClick="'+frame+'dm_click(event,\''+itVar.id+'tbl\');"';

  if (menu.isCSSMode) ss += dm_openTableWithClass(itVar.id+'tbl', itVar.itStyle.cssClass[0], 0, 0, 'title="'+itVar.tip+'" '+events);
  else
  {
      with (itVar.itStyle)
          var tblStyle = 'padding:0px; width:'+(itWidth?itWidth:'100%')+'; cursor:'+dm_checkCursor(itVar.cursor)+
                         ';background-color:'+backColor[0]+'; ' + (backImage[0]? 'background-image:url('+backImage[0]+');' : '') +
                         'border-color:'+brdColor[0]+'; border-style:'+brdStyle[0]+'; border-width:'+brdWidth+dUnits+';';

      ss += dm_openTableSimple(itVar.id+'tbl', 0, 0, tblStyle, events, 'title="'+itVar.tip+'"');
  }


  // Create item cells ===============================================
  if (itVar.text=="-")                       // item is separator
  {
      ss += dm_openTdSimple(itVar.id+'tdText', 'text-align:'+separatorAlignment, '');
      if (itVar.smInd>0) ss += dm_openSeparator(separatorImage,  separatorWidth,  separatorHeight);
      else               ss += dm_openSeparator(separatorVImage, separatorVWidth, separatorVHeight);
      ss += dm_closeTd();
  }
  else
  {
      // Create item arrow-image -------------------------------------
      if (menu.smView>=2 && itVar.childID) ss += dm_openItemArrow(itVar, 0);

      // Create item icon --------------------------------------------
      if (itVar.icon[0]) ss += dm_openTdSimple(itVar.id+'tdIcon', 'padding: '+smVar.smStyle.itPadding+dUnits, '') +
                               dm_openImg(itVar.id+"icon", itVar.icon[0], itVar.iconW, itVar.iconH, '')+
                               dm_closeTd();


      // Create item text --------------------------------------------
      if (itVar.text)
      {

          var textStyle='', textCSS='';
          var textAdd = (noWrap?' NOWRAP ':'');
          var textStyle = ''
          
          with (itVar.itStyle)
              if (menu.isCSSMode) textCSS = 'class='+cssClassText[0];
              else                textStyle += 'padding:'+smVar.smStyle.itPadding+dUnits+';width:100%;text-align:'+itVar.align+';font:'+fntStyle+';color:'+(itVar.isDisabled?menu.fntColorDisabled:fntColor[0])+'; text-decoration:'+fntDecor[0]+';';

          ss += dm_openTdSimple(itVar.id+'tdText', textStyle, textAdd+textCSS)+
                itVar.text+
                dm_closeTd();
      }


      // Create item arrow-image -------------------------------------
      if (menu.smView<2 && itVar.childID) ss += dm_openItemArrow(itVar, 0);
  }

  return ss+dm_closeTable();
}


//##############################################################################
// ITEMS FUNCTIONS
//##############################################################################


function dm_changeItemStyle(it, over)
// Changes item appearance
{
  over = (it.isHighlighted?1:over);
  if (b_NS4) return dm_changeItemStyle4(it, over);
  var itObj = dm_getObjectByID(it.id+'tbl');
  if (!itObj) return;

  with (it.itStyle)
  {
      if (dm_menu[it.mInd].isCSSMode) itObj.className = cssClass[over];
      else
      {
          var is = itObj.style;
          is.borderWidth = brdWidth;
          if (backColor[over]) is.backgroundColor = backColor[over];
          if (brdColor[over])  is.borderColor     = brdColor[over];
          if (brdStyle[over])  is.borderStyle     = brdStyle[over];
          if (backImage[over]) is.backgroundImage = 'url('+backImage[over]+')';
      }

      var textObj=dm_getObjectByID(it.id+'tdText');

      if (textObj && dm_menu[it.mInd].isCSSMode) textObj.className = cssClassText[over];
      else
          if (textObj)                   // check for a popup mode: a top submenu doesn't have any objects
              with (textObj.style)
              {
                  if (it.isDisabled) color = dm_menu[it.mInd].fntColorDisabled;
                  else
                      if (fntColor[over]) color = fntColor[over];
                  if (fntDecor[over]) textDecoration = fntDecor[over];
              }
  }

  with (it)
  {
      if (icon[over]) dm_getObjectByID(id+'icon').src = icon[over];

      var arr = (smInd?itStyle.arrowSub[over]:itStyle.arrowMain[over]);
      if (childID && arr) dm_getObjectByID(id+'arrow').src = arr;
  }
}


var _d_rID='';

function dm_over(e, id)
// Items' mouse over event
{
    //===regregregregregregregregreg===
    dm_showNag();
    //===regregregregregregregregreg===

    if (keyMode.isEnabled) dm_disableKeyMode();

    var itVar = dm_getVarByID(id);
    var menu  = dm_menu[itVar.mInd];

    // Change status bar text
    window.status = itVar.sstr;                                            // it's necessary to specify window object for Mozilla browsers


    // Check if item should change its appearance
    if (!itVar.isDisabled && itVar.text!='-' && !itVar.isPressed) dm_changeItemStyle(itVar, 1);


    // Check if user should click on item to show submenu
    if (menu.smShowClick && !menu.smShowClicked && !itVar.smInd) return;   // if the item is a top-menu item and showByClick-mode is enabled -> return


    var itObj = dm_getObjectByID(id);
    if (b_IE && e.fromElement && itObj.contains(e.fromElement)) return;    // eliminate flickering

    var smVar = menu.m[itVar.smInd];
    _d_rID = smVar.rootItemID;
    

    // Timers ------------------------------------------------------------------
    if (menu.hideAllTimer)
    {
        clearTimeout(menu.hideAllTimer);    menu.hideAllTimer = null;
    }
    if (smVar.showTimer)
    {
        clearTimeout(smVar.showTimer);      smVar.showTimer = null;
    }
    //--------------------------------------------------------------------------


    //if (!itVar.isDisabled && itVar.childID) smVar.showTimer = setTimeout("dm_showMenu('"+itVar.childID+"')", smShowPause);

    var showSmID = (!itVar.isDisabled && itVar.childID) ? itVar.childID : '';
    var hideSmID = (smVar.shownChildID && smVar.shownChildID!=itVar.childID) ? smVar.shownChildID : '';


    if (menu.isCrossFrame && cfType==1)
        if (!dm_isFrameAccessible(smVar.id, menu.cfSFInd)) hideSmID = '';  // if subframe is NOT accessible -> do not hide submenu therein

    smVar.showTimer = setTimeout('dm_waitForSubmenu("'+hideSmID+'","'+showSmID+'")', smShowPause);
}


function dm_waitForSubmenu(hideSmID, showSmID)
{
  dm_hideMenu(hideSmID);
  if (showSmID) dm_showMenu(showSmID);
}



function dm_out(e, id)
// Items' mouse over event
{
    var itObj = dm_getObjectByID(id);
    if (b_IE && e.toElement && itObj.contains(e.toElement)) return;       // eliminate flickering

    var itVar  = dm_getVarByID(id);
    var menu   = dm_menu[itVar.mInd];


    var smRVar = menu.m[0]                                                // get the top-menu var
    var smVar  = menu.m[itVar.smInd];

    if (smRVar.shownChildID)
        if (_d_rID!=itVar.id && !(menu.smShowClick && !menu.smShowClicked))
            menu.hideAllTimer = setTimeout("dm_hideMenu('"+smRVar.shownChildID+"');window.status='';", smHidePause);

    if (smVar.showTimer)
    {
       clearTimeout(smVar.showTimer);    smVar.showTimer = null;
    }

    if (itVar.isDisabled) return;
    if (itVar.text!='-' && !itVar.isPressed) dm_changeItemStyle(itVar, 0);
}


function dm_click(e, id)
// Items' mouse click event
{
    var itVar = dm_getVarByID(id);
    if (itVar.isDisabled || itVar.text=='-') return;
    var menu  = dm_menu[itVar.mInd];

    // showByClick-mode is enabled ---------------------------------------------
    if (!itVar.smInd && menu.smShowClick && !menu.smShowClicked && itVar.childID)
    {
        menu.smShowClicked = 1;
        dm_over(e, id);
        return;
    }
    //--------------------------------------------------------------------------

    if (itVar.link!='' && menu.toggleMode>-2 && !itVar.isPressed) dm_ext_setPressedItem(menu.ind, itVar.smInd, itVar.ind, true);  // toggle mode is on, set pressed item
    if (itVar.isDisabled || !itVar.link) return;

    var smRVar = menu.m[0];                                       // get the top-menu var
    if (menu.shownChildID) dm_hideMenu(menu.shownChildID);


    if (menu.hideAllTimer)
    {
        clearTimeout(menu.hideAllTimer);   menu.hideAllTimer = null;
    }

    dm_openItemLink(menu, itVar);
}


function dm_openItemLink(menu, itVar)
{
  if (itVar.isDisabled || !itVar.link) return;
  with (itVar)
  {
      if (!link) return;

      // Hide all submenus on item click
      if (menu.smHideClick)
      {
          moveRec.prepareSmID = '';                       // clear captured submenu ID
          dm_hideMenu(menu.m[0].shownChildID);            // hide submenu
      }

      // execute JavaScript
 	    if (link.toLowerCase().io('javascript:')==0) eval(link.sb(11, link.ln()));
	    else
      {
          if (!target || target=='_self')
          {
              if (menu.isCrossFrame && (cfType==1 || cfType==3))
                  parent.frames[menu.cfSFInd].location.href = link;     // if item was clicked in subframe -> open link in subframe
              else
                  location.href = link;
          }
          else
              open(link, target);
      }
  }
}



//##############################################################################
// SUBMENU FUNCTIONS
//##############################################################################

function dm_showIFrame(smObj)
// Shows IFRAME object under the submenu
{
  if (!useHTTPS && b_IEPC && b_IE6)
      with (dm_getObjectByID(smObj.id+'frame').style)
      {
          left   = smObj.style.left;
          top    = smObj.style.top;
          width  = smObj.offsetWidth  + 'px';
          height = smObj.offsetHeight + 'px';
          visibility = 'visible';
      }
}


function dm_writeSubmenuHTML(smVar)
// Check a submenu object on a page and writes submenus' HTML if it doesn't exist (fast speed for IE, other browsers work with large menus well)
{
  var smObj=dm_getObjectByID(smVar.id);
  if (smObj) return smObj;

//      docElement.insertAdjacentHTML('beforeEnd', smVar.smHTML);
  d_o.getElementById(smVar.id+'div').innerHTML = smVar.smHTML;
  var m=dm_menu[smVar.mInd];
  if (m.curPressedSm==smVar.ind) dm_changeItemStyle(smVar.i[m.curPressedIt], 1);

  return dm_getObjectByID(smVar.id);
}


function dm_showMenu(id)
// Shows specified submenu according to a root item position and the cross-frame mode
{
    if (!docElement) dm_setDocElement();
    if (b_NS4) return dm_showMenu4(id);

    var smVar = dm_getVarByID(id);
    var menu  = dm_menu[smVar.mInd];
    var smObj = null;
    var canFilter = (b_IEPC && b_VER>=5.5 && smVar.duration)?1:0;

    // Hide submenus for all menus on a page excluding current menu
    for (var i=0; i<dm_menu.ln(); i++) if (i!=menu.ind) dm_hideSubmenus(i);
    

    // CREATE THE SUBMENUS AND GET THE SUBMENU OBJECT ==========================
    if (menu.isCrossFrame)                                       // Crossframe mode
    {
        if (!dm_isFrameAccessible(id, menu.cfSFInd))            // if a page was loaded into a subframe from another domain
        {
            if (!(smObj=dm_getObjectByID(id)))                  // there are no submenus in a top frame yet -> create them
            {
                if (b_IEComp) docElement.insertAdjacentHTML("beforeEnd", dm_getSubmenusHTML(menu));
                else          docElement.innerHTML += dm_getSubmenusHTML(menu);

                smObj = dm_getObjectByID(id);
                if (menu.toggleMode>=0 && menu.curPressedIt!=-1) dm_setCrossPressedItem(menu);
            }
        }
        else                                                     // a page was loaded into a subframe from the same domain
        {
            if (!(smObj=dm_createCrossHTML(menu, id))) return;
            // Toggle mode is on and some item was pressed -> highlight this item
            if (menu.toggleMode>=0 && menu.curPressedIt!=-1) dm_setCrossPressedItem(menu);
        }
    }
    else
        if (!(smObj=dm_writeSubmenuHTML(smVar))) return;
    //==========================================================================


    if (typeof(smObj.style.display)!=_un) smObj.style.display = 'block';            // define display property before determine the submenu position and sizes
    var smXY = dm_getSubmenuXY(smVar);
    var it   = dm_getVarByID(smVar.rootItemID);


    // SET SUBMENU COORDINATES =================================================
    if (menu.isCrossFrame && cfType==1 && smVar.level==1)           // Crossframe mode
    {
        var mfSize = dm_getClientSize(null);                       // scroll offset of a main frame
        var sfSize = dm_getClientSize(menu);                       // scroll offset of a subframe
        var l=0, t=0;
        var smSize = dm_getObjectSize(dm_getObjectByID(id+'tbl'));
        var w=smSize[2], h=smSize[3];
        var frame = parent.frames[menu.cfSFInd];

        if (menu.cfOrient==1)           //#### vertical frame orientation ####
        {
            var dy = mfSize[1];
            if (b_IE || b_OP) dy += frame.window.screenTop - window.screenTop;
            switch (menu.smView)
            {
                case 0: case 1: l = sfSize[0]-smVar.offx;
                break;

                case 2: case 3: l = sfSize[2]+sfSize[0]-smSize[2]-smVar.offx;
                break;
            }
            t = smXY[1] + sfSize[1] - dy;
        }
        else                           //#### horizontal frame orientation ####
        {
            var dx = mfSize[0];
            if (b_IE || b_OP) dx += frame.window.screenLeft - window.screenLeft;
            l = smXY[0] + sfSize[0] - dx;

            switch (menu.smView)
            {
                case 0: case 2: t = sfSize[1] + smVar.offy;
                break;

                case 1: case 3: t = sfSize[3]+sfSize[1]-smSize[3] - smVar.offy;
                break;
            }
        }

        // Check submenu position with page bounds
        if (l+w > sfSize[0]+sfSize[2]) l = sfSize[0]+sfSize[2] - w;
        if (t+h > sfSize[1]+sfSize[3]) t = sfSize[1]+sfSize[3] - h;
        if (l < sfSize[0]) l = sfSize[0];
        if (t < sfSize[1]) t = sfSize[1];

        with (smObj.style)
        {
            left = l+'px';
            top  = t+'px';
        }
    }
    else              // No crossframe mode OR crossframe mode is on and subframe has a content from another domain
    {
        with (smObj.style)
        {
            left = smXY[0] + ((b_OP && b_VER<6)?'':'px');
            top  = smXY[1] + ((b_OP && b_VER<6)?'':'px');
        }


        // Frame resizing ------------------------------------------------------
        if (cfType==3 && b_IEPC && b_VER>=5)
        {
            with (parent.d_o.getElementById(menu.cfFSID))    // get frame's sizes from frameset COLS/ROWS attribute
                if (menu.cfOrient==1) var fsSizes = cols;
                else                  var fsSizes = rows;

            if (!oldFsetSizes) oldFsetSizes = fsSizes;
            var fsSizes3 = dm_extractFramesetSizes(fsSizes, menu.cfMFInd);   // divide the string with sizes (extract the size of a top frame)
            var docSize  = dm_getClientSize(menu);                           // get document size
            var smSize   = dm_getObjectSize(dm_getObjectByID(id+'tbl'));    // get submenu size

            with (parent.d_o.getElementById(menu.cfFSID))
                switch (menu.cfOrient)
                {
                  // left-to-right frame orientation
                  case 0:  if (smSize[1]+smSize[3] > docSize[3]) rows = fsSizes3[0] + (smSize[1]+smSize[3]+2) + fsSizes3[2]; // resize a top frame
                  break;
                  // top-to-bottom frame orientation
                  case 1:  if (smSize[0]+smSize[2] > docSize[2]) cols = fsSizes3[0] + (smSize[0]+smSize[2]+2) + fsSizes3[2]; // resize a top frame
                  break;
                  // right-to-left frame orientation
                  case 3:
                  break;
                  // bottom-to-top frame orientation
                  case 4:
                  break;
                }


        }
        //---------------------------------------------------------------------
    }


    // Highlight selected item -------------------------------------------------
    menu.m[it.smInd].shownChildID = id;
    it.isHighlighted = menu.saveNavigation;

    with (smObj.style)
    {
        width  = smXY[2] + 'px';
        height = smXY[3] + 'px';

        // Set submenu scrolling parameters
        with (smVar)
        {
            sX = smXY[0];
            sY = smXY[1];
            sEnabled = 1;
            sObj = smObj;
        }

        // Set submenu container (div) overflow property
        if (smXY[4])
        {
            if (b_IEMAC)
            {
                height = smXY[3]-20 + 'px';               // decrease submenu size for MAC IE for bottom scrollbar
                overflow = 'auto';
            }
            else
            {
                if ((b_NS && b_VER<7) || b_OP) overflow = 'auto';
                else
                {
                   if (smSmartScroll) overflow = 'hidden';
                   else
                      if (b_IE6)
                      {
                          overflow  = 'visible';
                          overflowY = 'scroll';
                      }
                      else
                          overflow  = 'auto';
                }

                if (b_OP)
                width = smObj.offsetWidth+17;       // increase submenu width in Opera for right scrollbar
            }


            smObj.scrollTop=0;
            smObj.scrollLeft=0;
        }
        else
        {
            overflow  = 'visible';
            smVar.sEnabled = (b_OP && smXY[4])?1:0;
        }


        dm_showIFrame(smObj);

        // Show the submenu
        if (visibility!='visible')
        {
            if (canFilter)
                with (fl=smObj.filters[0])
                {
                    enabled = 1;
                    if (status!=0) stop();
                    apply();
                }
            visibility = 'visible';
            if (canFilter) fl.play();
        }
    }


    // Objects intersection
    dm_checkSubmenuIntersection(smVar, smXY);
}


function dm_dehighlightRootItem(menu, smVar)
{
  if (menu.saveNavigation)
  {
      var ritVar = dm_getVarByID(smVar.rootItemID);
      ritVar.isHighlighted = 0;

      // if root item isn't pressed and it's not a very top item when popup-mode is on (because popup menu hasn't top-item object on a page)
      //if (!ritVar.isPressed && !(menu.isPopup && !ritVar.smInd)) dm_changeItemStyle(ritVar, 0);

      if (!ritVar.isPressed) dm_changeItemStyle(ritVar, 0);
  }
}

function dm_hideMenu(id)
{
    if (!id) return;
    if (b_NS4) return dm_hideMenu4(id);

    var smObj = dm_getObjectByID(id);
    if (!smObj) return;

    var smVar = dm_getVarByID(id);
    var menu  = dm_menu[smVar.mInd];


    if (smVar.isMoved && !moveRec.isMoving)
    {
        with (smObj.style)
        {
            left = smVar.left + 'px';
            top  = smVar.top  + 'px';
        }
        dm_showIFrame(smObj);
    }


    // Hide all visible submenus
    if (smVar.shownChildID) dm_hideMenu(smVar.shownChildID);
    smVar.shownChildID = '';


    // Dehighlight root item
    dm_dehighlightRootItem(menu, smVar);


    if (smVar.showTimer)
    {
        clearTimeout(smVar.showTimer);   smVar.showTimer = null;
    }


    // Hide submenu
    if (!smVar.isMoved && moveRec.prepareSmID!=smVar.id)
    {
        with (smObj.style)
        {
            if (typeof(display)!=_un) display = 'none';
            visibility = 'hidden';
            left = '-1000px';
            top  = '-1000px';
        }
        if (b_IEPC && b_IE6 && !useHTTPS) dm_getObjectByID(id+'frame').style.visibility = 'hidden';  // Hide IFRAME on IE for PC
    }


    // Restore frame size for cross-frame mode
    if (smVar.level==1 && cfType==3 && oldFsetSizes)
    {
        with (parent.d_o.getElementById(menu.cfFSID))
              if (menu.cfOrient) cols = oldFsetSizes;
              else               rows = oldFsetSizes;
        oldFsetSizes = null;                                                    // clear saved sizes for frames
    }


    // Show submenus on click: if all submenus were hidden -> enable "need-to-click"
    if (menu.smShowClick && menu.hideAllTimer) menu.smShowClicked = 0;


    // Show hidden objects on page
    dm_showIntersectedObjects(smVar);
}


function dm_getSubmenuXY(smVar)
// Returns submenu coords and dimensions: [x, y, width, height, resize]
{
    var menu     = dm_menu[smVar.mInd];
    var smObj    = dm_getObjectByID(smVar.id);

    if (b_NS4) var smSize = dm_getObjectSize(smObj, 0);
    else       var smSize = dm_getObjectSize(dm_getObjectByID(smObj.id+'tbl'));


    var ritVar   = dm_getVarByID(smVar.rootItemID);
    var rsmVar   = menu.m[ritVar.smInd];

    var ritObj   = dm_getObjectByID(ritVar.id+(b_NS4?'':'tbl'));
    var ritSize  = dm_getObjectSize(ritObj);
    var rsmObj   = dm_getObjectByID(rsmVar.id);


    var docSize  = dm_getClientSize(menu);
    var x=0, y=0, w=0, h=0, resize=0;

    switch (menu.smView)
    {
        case 1: case 3: y = ritSize[1] + ((rsmVar.ind || !rsmVar.isHoriz)?ritSize[3]:0) - smSize[3]  - smVar.offy;
        break;
        case 0: case 2: y = ritSize[1] + (rsmVar.isHoriz?ritSize[3]:0) + smVar.offy;
        break;
    }

    if (rsmVar.isHoriz)
    {
        if (menu.smAlign == 'right' /*ritVar.align=='right'*/) x = ritSize[0] + ritSize[2] - smSize[2] - smVar.offx;
        else
            if (menu.smAlign == 'center' /*ritVar.align=='center'*/) x = parseInt(ritSize[0] + (ritSize[2] - smSize[2])/2);
            else                        x = ritSize[0] + smVar.offx;
    }
    else
        switch (menu.smView)
        {
            case 0: case 1: x = ritSize[0] + ritSize[2] + smVar.offx;
            break;
            case 2: case 3: x = ritSize[0] - (!rsmVar.isHoriz?smSize[2]:0) - smVar.offx;
            break;
        }

    docSize[2] += docSize[0];
    docSize[3] += docSize[1];


    // Set submenu size
    with (smVar.smStyle)
    {
        w = (smW?parseInt(smW):smSize[2]) + smVar.shadowLen;
        h = (smH?parseInt(smH):smSize[3]) + smVar.shadowLen;
    }

    // Correct submenu position ------------------------------------------------
    if (!menu.isCrossFrame || (smVar.level>1 && cfType!=3))
    {
        // Correct position according to a scrolling of parent submenu
        if (typeof(rsmObj.scrollLeft)!=_un)
        {
            x -= rsmObj.scrollLeft;
            y -= rsmObj.scrollTop;
        }


        // Check document bounds, correct submenu position
        if (x+w > docSize[2]) x = docSize[2] - w;
        if (x < docSize[0])   x = docSize[0];

        if (y+h > docSize[3] && docSize[3]-y<200) y = docSize[3] - h;
        if (y < docSize[1])   y = docSize[1];


        // Check document bounds once again and set new submenu size
        if (x+w > docSize[2]) w = (docSize[2]-x);
        if (y+h > docSize[3]) h = (docSize[3]-y);


        // Check if submenu must be scrollable
        if (w<smSize[2] || h<smSize[3]) resize=1;


        // Check size for Netscape 6
        if (b_NS && b_VER<7)
        {
            if (resize) w += 14;
            if (rsmVar.sEnabled) x+= 14;
        }
    }


    if (b_IEMAC)
    {
        x += smVar.macoffX;
        y += smVar.macoffY;
    }
    //--------------------------------------------------------------------------

    return[x,y,w,h,resize];
}



//##############################################################################
// EXTERNAL FUNCTIONS
//##############################################################################


function dm_ext_setPressedItem(mInd, smInd, itInd, recursion)
// Sets current pressed item
{
  if (b_NS4) return;
  var menu = dm_menu[mInd];

  // If function doesn't call itself and pressed item exists
  with (menu)
  {
      if (!toggleRec.pressedSelf && menu.curPressedIt!=-1)
      {
          toggleRec.pressedSelf = true;
          dm_ext_setPressedItem(mInd, curPressedSm, curPressedIt, recursion);   // unpress pressed item
          if (curPressedSm==smInd && curPressedIt==itInd)
          {
              curPressedSm = 0;
              curPressedIt = -1;
              return;
          }
      }

      if (!toggleRec.pressedSelf)    // if func doesn't call itself -> set new pressed indexes
      {
          curPressedSm = smInd;
          curPressedIt = itInd;
      }
      else
          toggleRec.pressedSelf = false;
  }

  var itVar = dm_getVarByID('dm'+mInd+'m'+smInd+'i'+itInd);
  with (toggleRec)
  {
      if (!changeStyleOnly) itVar.isPressed = !itVar.isPressed;
      changeStyleOnly = false;
  }


  dm_changeItemStyle(itVar, (itVar.isPressed?1:0));


  // If recursion is enabled and submenu isn't a root menu
  if (recursion && smInd>0)
  {
      var smVar = menu.m[smInd];
      var ritVar;
      for (var j=smVar.level; j>0; j--)
      {
          ritVar = dm_getVarByID(smVar.rootItemID)
          dm_changeItemStyle(ritVar, (itVar.isPressed?1:0));
          ritVar.isPressed = itVar.isPressed;
          smVar = menu.m[ritVar.smInd];             // get next parent submenu
      }
  }
}

function dm_hideSubmenus(mInd)
{
    clearInterval(dm_menu[mInd].hideAllTimer);
    dm_hideMenu(dm_menu[mInd].m[0].shownChildID);
}

// External function
// Do not move it into dmenu_dyn.js file, it's used in dmenu_key.js
function dm_ext_hideAllSubmenus(mInd) {
    dm_hideSubmenus(mInd);
}

