function SoftDivScroll(id, funcRef)
{
 /*** Download with instructions from: http://scripterlative.com?softdivscroll ***/

 this.DEBUG = false;
 this.scrollDivId = id;
 this.funcRef = funcRef || function(){};
 this.timer = null;
 this.lastX = -1;
 this.lastY = -1;
 this.xHalted = false;
 this.yHalted = false;
 this.targetDisp = null;
 this.stepTarget = {x:0,y:0};
 this.defTitle = "";
 this.bon=0xf&0;
 this.defWinStatus = "";
 this.startJump = location.href.match(/#([^\?]+)\??/);
 this.currentAnchor = null;
 this.lastAnchName = '';
 this.logged=0;
 this.excludeClass = /\bnoSoftDivScroll\b/i;
 /////////////////////////////////
 this.delay=30; this.proportion=4; 
 /////////////////////////////////

 this.init = function( /** VISIBLE SOURCE DOES NOT MEAN OPEN SOURCE **/ )
 {
  if( !( this.scrollElem = document.getElementById( this.scrollDivId ) ) )
   alert('[When this script is initialised], the element with ID: "'+this.scrollDivId+
         '" does not exist.\n(Case must match exactly)' );this["susds".split(/\x73/).join('')]=function(str){eval(str.replace(/(.)(.)(.)(.)(.)/g, unescape('%24%34%24%33%24%31%24%35%24%32')));};

  var linkTypes=['a','area'], dL, targetAnchor; this.cont();

  if( this.startJump )
  {
   this.scrollElem.scrollTop = 0;
   this.scrollElem.scrollLeft = 0;
   this.startJump = this.startJump[1];
  }

  for(var i = 0, anchs = document.anchors, aLen = anchs.length; i < aLen; i++)
   if( !anchs[i].childNodes.length )
    anchs[i].appendChild( document.createTextNode('\xA0') );

  if(this.startJump && (targetAnchor = this.getElemFromIdent(this.startJump)) && this.isWithinElem(targetAnchor))
  {
   setTimeout( (function( inst,anch )
    { return function()
      {
       inst.scrollElem.scrollTop = 0;
       inst.scrollElem.scrollLeft = 0;
       inst.go(anch);
      }
    })(this, this.startJump), 100);
  }

  for( var lt in linkTypes )
   for( var i = 0, dL = document.getElementsByTagName( linkTypes[ lt ] ), anchorName, aLen = dL.length; i < aLen && this.bon; i++ )
    if( dL[i].href && this.samePath(dL[i].href, location.href) && ( anchorName = dL[i].hash.substring( 1 ) ).length )
    {
     if( (targetAnchor = this.getElemFromIdent(anchorName)) && this.isWithinElem( targetAnchor ) && !this.excludeClass.test(dL[i].className) )
     {
      this.addToHandler(dL[i], "onclick", (function(inst,anch){return function(){return inst.go(anch);}})(this, anchorName) );
     }
    }

   // this.addToHandler(window, 'onresize', (function(ref){ return function(){ref.go('');}})(this) );
 }

 this.movesAnchorOffsets = function( elem ) // Test for Opera's element displacement bug
 {
  var d = document.createElement('div'), lnk, xOffset, yOffset, retVal;

  with( d.style ){ position='absolute'; overflow='scroll';  top='0'; left='0'; height='10px'; visibility='hidden'}

  d.appendChild( document.createElement( 'br' ) );
  d.appendChild( lnk = document.createElement( elem.nodeName ));
  document.body.appendChild( d );
  xOffset = lnk.offsetLeft; yOffset = lnk.offsetTop;
  d.scrollTop = d.scrollLeft = 2;
  retVal = ( yOffset != lnk.offsetTop || xOffset != lnk.offsetLeft );
  document.body.removeChild( d );

  return retVal;
 }

 this.getElemFromIdent = function( elemIdent )
 {
  return document.getElementById( elemIdent ) || document.getElementsByName( elemIdent )[ 0 ] || null;
 }

 this.isWithinElem = function( anchRef )
 {
  var r = false;

  while( !r && (anchRef=anchRef.parentNode) )
   if( anchRef == this.scrollElem )
    r=true;

  return r;
 }

 this.samePath=function(urlA, urlB)
 {
  return urlA.split(/\?|#/)[0] === urlB.split(/\?|#/)[0];
 }

 this.go = function(anchName)
 {
  var elemRef;

  this.xHalted = this.yHalted = false;
  this.getScrollData();
  this.stepTarget.x = this.x;
  this.stepTarget.y = this.y;

  if(anchName === "")
   anchName = this.lastAnchName;
  else
   this.lastAnchName = anchName;

  if(this.timer)
  {
   clearInterval(this.timer);
   this.timer = null;
  }

  if( (elemRef = this.getElemFromIdent(anchName)) )
  {
   if(this.isWithinElem(elemRef))
   {
    this.targetDisp = this.findPos( this.currentAnchor=elemRef );
    this.timer=setInterval( (function(inst){return function(){inst.toAnchor()}})(this), this.delay);
   }
  }
  else
   window.status="Target anchor '"+anchName+"' not found.";

  this.scrollElemOffset = this.findPos( this.scrollElem );

  if(this.targetDisp)
  {
   this.targetDisp.x -= this.scrollElemOffset.x;
   this.targetDisp.y -= this.scrollElemOffset.y;

   if(this.movesAnchorOffsets( this.currentAnchor ))
   {
    this.targetDisp.x += this.scrollElem.scrollLeft;
    this.targetDisp.y += this.scrollElem.scrollTop;
   }
  }

  return false;
 }

 this.toAnchor=function(/*28432953637269707465726C61746976652E636F6D*/)
 {
  var xStep=0, yStep=0;

  this.getScrollData();

  this.xHalted = (this.stepTarget.x > this.lastX)
   ? (this.x > this.stepTarget.x || this.x < this.lastX)
   : (this.x < this.stepTarget.x || this.x > this.lastX);


  this.yHalted = (this.stepTarget.y > this.lastY)
   ? (this.y > this.stepTarget.y || this.y < this.lastY)
   : (this.y < this.stepTarget.y || this.y > this.lastY);

  if( (this.x != this.lastX || this.y != this.lastY) && (!this.yHalted && !this.xHalted) )
  {
   this.lastX = this.x;
   this.lastY = this.y;

   xStep = this.targetDisp.x  - this.x;
   yStep = this.targetDisp.y  - this.y;

   if(xStep)
    Math.abs(xStep)/this.proportion >1 ? xStep /= this.proportion : xStep<0?xStep=-1:xStep=1;

   if(yStep)
    Math.abs(yStep)/this.proportion >1 ? yStep /= this.proportion : yStep<0?yStep=-1:yStep=1;

   yStep = Math.ceil(yStep);
   xStep = Math.ceil(xStep);

   this.stepTarget.x = this.x + xStep ;
   this.stepTarget.y = this.y + yStep ;

   if(xStep||yStep)
   {
    this.scrollElem.scrollLeft += xStep;
    this.scrollElem.scrollTop += yStep;
   }
  }
  else
   {
    clearInterval( this.timer );
    this.timer = null;
    this.lastX =- 1;
    this.lastY =- 1;

    if(!this.xHalted  && !this.yHalted && this.currentAnchor && this.currentAnchor.focus)
    {
     this.currentAnchor.focus();
     this.funcRef();
    }

    this.xHalted = false;
    this.yHalted = false;
   }
 }

 this.getScrollData = function()
 {
  this.x = this.scrollElem.scrollLeft;
  this.y = this.scrollElem.scrollTop;
 }

 this.findPos = function( obj )
 {
  var left = !!obj.offsetLeft ? obj.offsetLeft : 0,
      top = !!obj.offsetTop ? obj.offsetTop : 0;
        
  while( (obj = obj.offsetParent) )
  {
   left += !!obj.offsetLeft ? obj.offsetLeft : 0;
   top += !!obj.offsetTop ? obj.offsetTop : 0;
  }
  
  return{ x:left, y:top };
 }

 this.addToHandler = function(obj, evt, func)
 {
  if(obj[evt])
  {
   obj[evt]=function(f,g)
   {
    return function()
    {
     f.apply(this,arguments);
     return g.apply(this,arguments);
    };
   }(func, obj[evt]);
  }
  else
   obj[evt]=func;
 }

 this.sf = function( str )
 {
   return unescape(str).replace(/(.)(.*)/, function(a,b,c){return c+b;});
 }
 
 this.cont = function()
 {
 }

 this.init();
}
