

if (typeof(XMLHttpRequest) == "undefined") {
 XMLHttpRequest = function () {
   var msxmls = ["MSXML3", "MSXML2", "Microsoft"];
   for (var i=0; i < msxmls.length; i++) {
 try {
   return new ActiveXObject(msxmls[i]+".XMLHTTP");
 } catch (e) { }
   }
   throw new Error("No XML component installed");
 }
}



function LiveBlog( pThreadId, pNewestAtBottom, pTime, pUserId, pAllowedToEdit, pDisplayLanguage,  pRootElement, pWidth )
{
    if( pNewestAtBottom == null )
    {
        pNewestAtBottom = true;
    }
    
    if( pTime == null ) 
    {
        pTime = ( new Date() ).toUTCString();
    }

    if( pWidth == null )
    {
        this.Width = 600;
    }
    else
    {
        this.Width = pWidth;
    }
    
    
    
    this.UserId = pUserId;
    this.NewestAtBottom = pNewestAtBottom;
    this.Time = pTime;
    
    if( ( pThreadId + "").match( /^[0-9]+$/ ) )
    {
        this.ThreadId = pThreadId;
        this.ThreadKey = "";
    }
    else
    {
        this.ThreadId = "";
        this.ThreadKey = pThreadId;
    }
    
    if( pRootElement == null )
    {
        this.PostsList = document.getElementById("Posts");
    }
    else
    {
        this.PostsList = pRootElement;
    }
    
    
    
    
    
    
    this.IsCrossDomain = false;
    if( ! ( document.location + "" ).match( /(http:\/\/www\.scribblelive.com\/|http:\/\/scribblelive.com\/|http:\/\/stage.scribblelive.com\/|http:\/\/localhost)/i ) )
    {
        this.IsCrossDomain = true;
    }

    this.AllowedToEdit = ( pAllowedToEdit == true );
    
    this.FadeColor_Start = "#0099CC";
    this.FadeColor_End = "#ffffff";
    
    this.NumPolls = 0;
    
    this.CurrentVisitors = 0;
    
    this.DisplayLanguage = pDisplayLanguage;
    
    if( this.DisplayLanguage )
    {
        this.TranslateAllPosts();
    }
    
    LiveBlog.StoreInstance( this );
    
    
}

LiveBlog.prototype.TranslateAllPosts = function( pDisplayLanguage )
{
    if( ! pDisplayLanguage )
    {
        if( ! this.DisplayLanguage )
        {
            return;
        }
        else
        {
            pDisplayLanguage = this.DisplayLanguage;
        }
    }
    else
    {
        this.DisplayLanguage = pDisplayLanguage;
    }

    var ExistingPosts = this.PostsList.getElementsByTagName("div");
    
    for( var i = 0; i < ExistingPosts.length; i++ )
    {
        var CurrentPostContent = ExistingPosts[i];
        
        if( CurrentPostContent.className.match( "Content" ) 
            && ! CurrentPostContent.innerHTML.match( "<img" ) 
            && ! CurrentPostContent.innerHTML.match( "<embed" ) 
            )
        {
            this.TranslateContent( CurrentPostContent.innerHTML, CurrentPostContent );
        }
    }
}

LiveBlog.StoreInstance = function( pLiveBlog )
{
    if( LiveBlog.__instances == null )
    {
        LiveBlog.__instances = new Array();
    }
    
    var HashKey;
    
    if( pLiveBlog.ThreadId != "" )
    {
        HashKey = "" + pLiveBlog.ThreadId;
    }
    else if( pLiveBlog.ThreadKey != "" )
    {
        HashKey = pLiveBlog.ThreadKey;
    }
    else
    {
        HashKey = "0";
    }   
    
    if( LiveBlog.__instances[HashKey] == null )
    {
        LiveBlog.__instance = pLiveBlog;
        LiveBlog.__instances[HashKey] = pLiveBlog;
        return true;
    }
    else
    {
        return false;
    }
}

LiveBlog.GetInstance = function( pThreadId )
{
    if( LiveBlog.__instances == null )
    {
        return null;
    }
    else if( pThreadId == null )
    {
        return LiveBlog.__instance;
    }
    else
    {
        return LiveBlog.__instances[""+pThreadId];
    }
    
}


LiveBlog.DestroyElement = function( pElement )
{
    pElement.parentNode.removeChild( pElement );
    
    return false;
}

LiveBlog.Ping = function( pThreadId, pResponseObject )
{
    var _LiveBlog = LiveBlog.GetInstance( pThreadId );
    
    if( _LiveBlog == null )
    {
        return;
    }
    
    _LiveBlog.PollForNew_Handler( pResponseObject );
    
    var Scripts = document.getElementsByTagName("script");
    for( var i = 0; i < Scripts.length; i++ )
    {
        if( ( Scripts[i].src + "" ).match( /\/Poll\.aspx\?/i ) )
        {
            LiveBlog.DestroyElement( Scripts[i] );
            break;
        }
    }
    
    setTimeout( function() { _LiveBlog.PollForNew( _LiveBlog.Time ); }, 5000 );   
}

LiveBlog.prototype.PollForNew_Handler = function( pResponseObject )
{

    var ResponseObject = pResponseObject;
	
    var CurrentTime = ResponseObject.Time;
    this.Time = CurrentTime;
    
    if( ResponseObject.CurrentVisitors && ResponseObject.CurrentVisitors != this.CurrentVisitors )
    {
        this.CurrentVisitors = ResponseObject.CurrentVisitors;
        var ems = document.getElementsByTagName( "em" );
        
        for( var i = 0; i < ems.length; i++ )
        {
            if( ems[i].className == "CurrentVisitors" )
            {
                ems[i].innerHTML = ( this.CurrentVisitors == "1" ? "" : "(" + this.CurrentVisitors + " watchers)" );
            }
        }
    }
	
    var Actions = ResponseObject.Actions;
	
    var AutoScroll = false;
	
    if( ! this.IsCrossDomain && Actions.length > 0 && this.NewestAtBottom )
    {
        AutoScroll = ( ( LiveBlog.YPosition() + 50 ) >= LiveBlog.PageHeight() )
    }
    
    try
    {
        if( ! this.UserId )
        {
            this.UserId = -1;
        }
    }
    catch( err )
    {
        this.UserId = -1;
    }


    for( var i = 0; i < Actions.length; i++ )
    {
        switch( Actions[i].Action )
        {
            case "New":
                // It was not a post by current user
                if( 
                    document.getElementById("LiveBlog_Post" + Actions[i].Id) == null 
                )
                {
                
                    if( ! Actions[i].IsComment )
                    {
                
                        this.AttachNewPost( Actions[i] );
                        
                        this.FadeIn( "LiveBlog_Post" + Actions[i].Id );
                        
                        this.SetLastPostTime( LiveBlog.ConvertServerTimeToLocalTimeFriendlyString( Actions[i].Date ) );
                    }
                    else
                    {
                        this.AttachNewComment( Actions[i] );
                        
                        this.FadeIn( "LiveBlog_Post" + Actions[i].Id );
                    }
         
                }
                break;
            case "Update":
                
                if( Actions[i].CreatorId != this.UserId && document.getElementById("LiveBlog_Post" + Actions[i].Id ) ) 
                {
                    document.getElementById("LiveBlog_Post" + Actions[i].Id ).firstChild.innerHTML = this.TranslateContent( Actions[i].Content, document.getElementById("LiveBlog_Post" + Actions[i].Id ).firstChild );
                    document.getElementById("LiveBlog_Post" + Actions[i].Id ).lastChild.innerHTML = "edited by <em>" + Actions[i].CreatorName + "</em> at " + LiveBlog.ConvertServerTimeToLocalTimeFriendlyString( Actions[i].Date );
                    if( this.AllowedToEdit )
                    {
                        document.getElementById("LiveBlog_Post" + Actions[i].Id ).lastChild.innerHTML += "  <a href='#' class='Edit' onClick='return Edit(" + Actions[i].Id + ", this)'>edit</a> <a href='#' onClick='return Delete(" + Actions[i].Id + ")'>delete</a>";
                    }
                    
                    this.FadeIn( "LiveBlog_Post" + Actions[i].Id );
                }
                break;
            case "Delete":
                if( document.getElementById("LiveBlog_Post" + Actions[i].Id ) )
                {
                    var ULElement = document.getElementById("LiveBlog_Post" + Actions[i].Id ).parentNode;
                    ULElement.removeChild(
                        document.getElementById("LiveBlog_Post" + Actions[i].Id )
                        );
                    ULElement.innerHTML += "";
                }
                break;
            case "Invite":
                if( this.UserId > 0 && Actions[i].InviteUserId == this.UserId + "" )
                {
                    if( confirm( "You have been invited to join this live event as a writer.\nClick OK to load the writer interface immediately, or just reload when you have a chance." ) )
                    {
                        document.location.reload();
                    }
                    
                }
                break;
        }
	            
    }
	
    if( Actions.length > 0 && AutoScroll )
    {
        LiveBlog.ScrollToBottom();
    }
}


LiveBlog.prototype.PollForNew = function( Since )
{


    if( Since == null )
    {
        Since = this.Time;
    }
    
    var _LiveBlog = this;
    
    if( ! this.NewestAtBottom && LiveBlog.YPosition() > LiveBlog.findPosY( this.PostsList ) + 100 )
    {
	    setTimeout( function() { _LiveBlog.PollForNew( Since ); }, 2000 );
	    return;
	}
    
    if( this.IsCrossDomain )
    {
        var PollScript = document.createElement("script");
        PollScript.src = "http://www.scribblelive.com/Poll.aspx?threadid=" + this.ThreadId + "&threadkey=" + this.ThreadKey + "&since=" + encodeURI( Since ) + "&crossdomain=1"  + ( this.NumPolls++ <= 0 ? "&rand=" + Math.round( 10000000 * Math.random() ) : "" );
        PollScript.type = "text/javascript";
		document.getElementsByTagName("head")[0].appendChild( PollScript );
    }
    else
    {

	    var req = new XMLHttpRequest();
        req.open("GET", "/Poll.aspx?threadid=" + this.ThreadId + "&threadkey=" + this.ThreadKey + "&since=" + encodeURI( Since ) + "&crossdomain=0" + ( this.NumPolls++ <= 0 ? "&rand=" + Math.round( 10000000 * Math.random() ) : "" ), true );
        
        req.onreadystatechange = function()
            {
                if( req.readyState == 4 )
                {
                
                    if( req.status == 200 )
                    {
                    
					    if( req.responseText != "" )
					    {
					        _LiveBlog.PollForNew_Handler( eval("(" +  req.responseText + ")" ) );
                        
                            setTimeout( function() { _LiveBlog.PollForNew( _LiveBlog.Time ); }, 5000 );
					    }
                    }
                    else
                    {
					    setTimeout( function() { _LiveBlog.PollForNew( _LiveBlog.Time ); }, 10000 );
                    }
                }
            };
        
        req.send( null );
    }
}

LiveBlog.prototype.ConnectNewPost = function( Item )
{
    if( this.NewestAtBottom || ! this.PostsList.firstChild )
    {
        this.PostsList.appendChild( Item );
    }
    else
    {
        for( var i = 0; i < this.PostsList.childNodes.length && i < 3; i++ )
        {
            if( this.PostsList.childNodes[i].className )
            {
                this.PostsList.childNodes[i].className = this.PostsList.childNodes[i].className.replace( "First", "" );
            }
        }
        
        Item.className += " First";
    
        this.PostsList.insertBefore( Item, this.PostsList.firstChild );
    }
    
}

LiveBlog.prototype.AttachNewComment = function( PostInfo )
{
    var NewItem = document.createElement("li");
	NewItem.id = "LiveBlog_Post" + PostInfo.Id;
    NewItem.className = "Comment";
    
    var ContentElement = document.createElement( "div" );
	ContentElement.className = "Content";
	ContentElement.innerHTML = this.TranslateContent( PostInfo.Content, ContentElement );
	
    
	    
    var MetaElement = document.createElement("div" );
    MetaElement.className = "Meta";
    
    MetaElement.innerHTML = "<em>" + PostInfo.CreatorName + "</em><br />" + LiveBlog.ConvertServerTimeToLocalTimeFriendlyString( PostInfo.Date ) + "";
    
    
    if( this.AllowedToEdit )
	{
	    MetaElement.innerHTML += " <a href='#' onClick='return InviteWriter(" + PostInfo.CreatorId + ")'>invite</a> <a href='#' onClick='return Delete(" + PostInfo.Id + ")'>delete</a>";
	}
	
	if(  PostInfo.CreatorThumbnail )
    {
        NewItem.className += " Thumbnail";
        ContentElement.style.backgroundImage = "url(" + PostInfo.CreatorThumbnail + ")";
    }
    
    
    NewItem.appendChild( MetaElement );
    NewItem.appendChild( ContentElement );
    
    
    
    
    this.ConnectNewPost( NewItem );

}

LiveBlog.prototype.AttachNewPost = function( PostInfo )
{
	var NewItem = document.createElement("li");
	var PostType;
	try
	{
	    PostType = PostInfo.Type;
	}
	catch( Error )
	{
	    PostType = 1;
	}
	
	
	   
	
    NewItem.id = "LiveBlog_Post" + PostInfo.Id;
    NewItem.className = "";
    NewItem.style.backgroundColor = this.FadeColor_Start;
    //NewItem.style.display = "none";
    
    if( PostType == 2 )
	{
	    var ImageContent = PostInfo.Content;
	    
	    switch( this.Width )
	    {
	        case 300:
	            ImageContent = ImageContent.replace( /\.(jpe?g|png|gif)$/, "_300.$1" );
	            break;
	        case 300:
	            ImageContent = ImageContent.replace( /\.(jpe?g|png|gif)$/, "_400.$1" );
	            break;
	    }
	    
	        if( PostInfo.CreatorThumbnail )
	        {
	            NewItem.className += " Thumbnail";
	        }
	        NewItem.innerHTML = "<div class='Content' " + ( PostInfo.CreatorThumbnail ? "style='background-image:url(" + PostInfo.CreatorThumbnail + ")'" : "" ) + "><img src='" + ImageContent + "' onload='LiveBlog.NewContentImageLoaded(this)'/></div><div class='Meta'>by <em>" + PostInfo.CreatorName + "</em> at " + LiveBlog.ConvertServerTimeToLocalTimeFriendlyString( PostInfo.Date ) + "</div>";
	}
	else
	{
	    var ContentElement = document.createElement( "div" );
	    ContentElement.className = "Content";
	   
	    if( PostInfo.Content.match( /<object/ ) )
	    {
	        switch( this.Width )
	        {
	            case 300:
	                ContentElement.innerHTML = LiveBlog.ResizeObjectEmbed( PostInfo.Content, 300, 250 );
	                break;
	            case 400:
	                ContentElement.innerHTML = LiveBlog.ResizeObjectEmbed( PostInfo.Content, 400, 334 );
	                break;
	            default:
	                ContentElement.innerHTML = PostInfo.Content;
	                break;
	        }
	    }
	    else
	    {
	        ContentElement.innerHTML = this.TranslateContent( PostInfo.Content, ContentElement );
	    }
	    
	    if( PostInfo.CreatorThumbnail )
	    {
	        NewItem.className += " Thumbnail";
	        ContentElement.style.backgroundImage = "url(" + PostInfo.CreatorThumbnail + ")";
	    }
	    
	    
	    NewItem.appendChild( ContentElement );
	    
	    var MetaElement = document.createElement("div" );
	    MetaElement.className = "Meta";
	    
	    MetaElement.innerHTML += "by <em>" + PostInfo.CreatorName + "</em> at " + LiveBlog.ConvertServerTimeToLocalTimeFriendlyString( PostInfo.Date ) + "";
	    
	    NewItem.appendChild( MetaElement );
	    
	    if( this.AllowedToEdit && !PostInfo.Content.match( /<object/ ) )
	    {
	        NewItem.firstChild.onmousedown = Wiki.ClickRegion;
	    }
        
	}
	
	if( this.AllowedToEdit )
	{
	    NewItem.lastChild.innerHTML += "  ";
	    
	    if( PostType != 2 )
	    {
	        NewItem.lastChild.innerHTML += "<a href='#' onClick='return Edit(" + PostInfo.Id + ", this)' class='Edit'>edit</a>";
	    }
	    
	    NewItem.lastChild.innerHTML += "<a href='#' onClick='return Delete(" + PostInfo.Id + ")'>delete</a>";
	}
	
    this.ConnectNewPost( NewItem );
}

LiveBlog.prototype.TranslateContent = function( pContent, pElement )
{
    if( this.DisplayLanguage 
        && ! this.AllowedToEdit 
        && ! pContent.match( "<embed" )
        )
    {
        var TranslatedText = "<em>" + pContent + "</em>";
        
        var ResultElement = pElement;
    
        google.language.translate( pContent, "", this.DisplayLanguage, function(result) {
          if (!result.error) {
            ResultElement.innerHTML = result.translation;
          }
          else
          {
            ResultElement.innerHTML = ResultElement.innerHTML.replace( /^<em>/, "" );
            ResultElement.innerHTML = ResultElement.innerHTML.replace( /<\/em>$/, "" );
            
          }
        });
        
        return TranslatedText;
    }
    else
    {
        return pContent;
    }
}


LiveBlog.PageHeight = function()
{
  var y, h;
  if(window.innerHeight && window.scrollMaxY)
    y = window.innerHeight + window.scrollMaxY;
  else if(document.body.scrollHeight)
    y = document.body.scrollHeight;
  else y = document.body.offsetHeight;
  if(window.innerHeight) h = window.innerHeight;
  else if(document.documentElement && document.documentElement.clientHeight)
    h = document.documentElement.clientHeight;
  else if(document.body) h = document.body.clientHeight;
  return ((y > h) ? y + 20 - h : false); 
}


LiveBlog.YPosition = function()
{
    if (document.body && document.body.scrollTop)
      return document.body.scrollTop;
    if (document.documentElement && document.documentElement.scrollTop)
      return document.documentElement.scrollTop;
    if (window.pageYOffset)
      return window.pageYOffset;
    return 0;
}

LiveBlog.findPosX = function(obj)
{
    var curleft = 0;
    if(obj.offsetParent)
        while(1) 
        {
          curleft += obj.offsetLeft;
          if(!obj.offsetParent)
            break;
          obj = obj.offsetParent;
        }
    else if(obj.x)
        curleft += obj.x;
    return curleft;
}

LiveBlog.findPosY = function(obj)
{
    var curtop = 0;
    if(obj.offsetParent)
        while(1)
        {
          curtop += obj.offsetTop;
          if(!obj.offsetParent)
            break;
          obj = obj.offsetParent;
        }
    else if(obj.y)
        curtop += obj.y;
    return curtop;
}

LiveBlog.NewContentImageLoaded = function( NewImage )
{
    if( ( LiveBlog.YPosition() + 50 + NewImage.clientHeight ) >= LiveBlog.PageHeight() )
    {
        if( LiveBlog.GetInstance().NewestAtBottom )
        {
            LiveBlog.ScrollToBottom();
        }
    }
}

LiveBlog.ScrollToBottom = function()
{
    try
    {
        clearInterval( LiveBlog.ScrollInterval );
    }
    catch( Error ) {}
    
    LiveBlog.LastPosition = LiveBlog.YPosition();
    
    LiveBlog.ScrollInterval = setInterval('LiveBlog.Scroll_Handler(LiveBlog.YPosition()+25)',100);
}

LiveBlog.Scroll_Handler = function( DestinationY )
{
    var PositionDiffFromLastScroll = DestinationY - LiveBlog.LastPosition;
    
    if( 
        LiveBlog.YPosition() + 20 >= LiveBlog.PageHeight()
        || PositionDiffFromLastScroll < 25
    )
    {
        clearInterval( LiveBlog.ScrollInterval );
    }
    else
    {
        window.scrollTo( 0, DestinationY );
        LiveBlog.LastPosition = DestinationY;
    }
}

LiveBlog.ConvertServerTimeToLocalTime = function( ServerTime )
{
    var CurrentUTCServerTime = new Date( ServerTime );
    
    return new Date( CurrentUTCServerTime.getTime() - ( new Date() ).getTimezoneOffset() * 60000 );
    
}

LiveBlog.ConvertServerTimeToLocalTimeFriendlyString = function( ServerTime )
{
    var LocalTime = LiveBlog.ConvertServerTimeToLocalTime( ServerTime );
    
    
    var MidnightToday = new Date();
    MidnightToday.setHours( 0 );
    MidnightToday.setMinutes( 0 );
    MidnightToday.setSeconds( 0 );
    
    var Minutes = LocalTime.getMinutes();
    Minutes = ( Minutes < 10 ? "0" + Minutes : Minutes );
    
    var Hours = ( LocalTime.getHours() % 12 );
    Hours = ( Hours == 0 ? "12" : Hours );
    
    var MidnightYesterday = MidnightToday.getTime() - 1000 * 60 * 60 * 24;
    MidnightYesterday = ( new Date() ).setTime( MidnightYesterday );
    
    
    if( LocalTime > MidnightToday )
    {
        return Hours + ":" + Minutes + " " + ( LocalTime.getHours() < 12 ? "AM" : "PM" );
    }
    else if( LocalTime > MidnightYesterday )
    {
        return Hours + ":" + Minutes + " " + ( LocalTime.getHours() < 12 ? "AM" : "PM" ) + " yesterday";
    }
    else
    {
        return LocalTime.toLocaleString();
    }
}

LiveBlog.prototype.SetLastPostTime = function( pTime )
{
    if( document.getElementById("LastPostTimeHolder") )
    {
        document.getElementById("LastPostTimeHolder").innerHTML = pTime;
    }
}


LiveBlog.ResizeObjectEmbed = function( Html, Width, Height )
{
    Html = Html.replace( /width='([0-9]+)'/g, "width='" + Width + "'" );
    Html = Html.replace( /height='([0-9]+)'/g, "height='" + Height + "'" );

    return Html;
}


LiveBlog.prototype.FadeIn = function( pWho )
{
    //Effect.Grow(pWho, {duration:0.5,direction:'top-left'} );
    Fat.fade_element( pWho, 15, 1000, this.FadeColor_Start, this.FadeColor_End );
}

LiveBlog.prototype.TwitterPing = function( pTweets, pSearchQuery )
{
    var Tweets = pTweets.results;
    
    if( pSearchQuery != null )
    {
        this.TwitterSearchQuery = pSearchQuery;
    }
    else if( this.TwitterSearchQuery == null )
    {
        this.TwitterSearchQuery = "scribblelive";
    }

    var CurrentTweet;
    var LastId = -1;
    var HtmlContent;
    
    for( var i = Tweets.length - 1; i >= 0; i-- )
    {
        HtmlContent = Tweets[i].text;
        HtmlContent = HtmlContent.replace( /(http:\/\/[\w\.\/\?]+)/gi, "<a href='$1'>$1</a>" );
        HtmlContent = HtmlContent.replace( /@(\w+)/g, "<a href='http://twitter.com/$1'>@$1</a>" );
    
        CurrentTweet = new Object();
        CurrentTweet.Content = HtmlContent + " <em>via</em> <a href='http://twitter.com/" + Tweets[i].from_user + "'>twitter</a>";
        CurrentTweet.CreatorName = Tweets[i].from_user;
        CurrentTweet.Id = "tweet" + Tweets[i].id;
        CurrentTweet.Type = 1;
        CurrentTweet.Date = new Date( ( new Date( Date.parse( Tweets[i].created_at ) ) ).getTime() + ( new Date() ).getTimezoneOffset() * 60000 );
        CurrentTweet.CreatorThumbnail = Tweets[i].profile_image_url;
        
        LastId = Tweets[i].id;
    
        this.AttachNewPost( CurrentTweet );
        this.FadeIn( "LiveBlog_Post" + CurrentTweet.Id );        
        this.SetLastPostTime( LiveBlog.ConvertServerTimeToLocalTimeFriendlyString( CurrentTweet.Date ) );
    }
    
    if( LastId == -1 )
    {
        LastId = pTweets.since_id;
    }
    
    setTimeout( function() {
        var PollScript = document.createElement("script");
        PollScript.src = "http://search.twitter.com/search.json?q=" + escape( LiveBlog.GetInstance().TwitterSearchQuery ) + "&callback=LiveBlog.GetInstance().TwitterPing&rpp=4&since_id=" + LastId + "&rand=" + Math.round( 10000000 * Math.random() );
        PollScript.type = "text/javascript";
        PollScript.defer = "defer";
	    document.getElementsByTagName("head")[0].appendChild( PollScript );
	    
	    }, 5000 );
}





var Fat = {
	make_hex : function (r,g,b) 
	{
		r = r.toString(16); if (r.length == 1) r = '0' + r;
		g = g.toString(16); if (g.length == 1) g = '0' + g;
		b = b.toString(16); if (b.length == 1) b = '0' + b;
		return "#" + r + g + b;
	},
	fade_all : function ()
	{
		var a = document.getElementsByTagName("*");
		for (var i = 0; i < a.length; i++) 
		{
			var o = a[i];
			var r = /fade-?(\w{3,6})?/.exec(o.className);
			if (r)
			{
				if (!r[1]) r[1] = "";
				if (o.id) Fat.fade_element(o.id,null,null,"#"+r[1]);
			}
		}
	},
	fade_element : function (id, fps, duration, from, to) 
	{
		if (!fps) fps = 30;
		if (!duration) duration = 3000;
		if (!from || from=="#") from = "#FFFF33";
		if (!to) to = this.get_bgcolor(id);
		
		var frames = Math.round(fps * (duration / 1000));
		var interval = duration / frames;
		var delay = interval;
		var frame = 0;
		
		if (from.length < 7) from += from.substr(1,3);
		if (to.length < 7) to += to.substr(1,3);
		
		var rf = parseInt(from.substr(1,2),16);
		var gf = parseInt(from.substr(3,2),16);
		var bf = parseInt(from.substr(5,2),16);
		var rt = parseInt(to.substr(1,2),16);
		var gt = parseInt(to.substr(3,2),16);
		var bt = parseInt(to.substr(5,2),16);
		
		var r,g,b,h;
		while (frame < frames)
		{
			r = Math.floor(rf * ((frames-frame)/frames) + rt * (frame/frames));
			g = Math.floor(gf * ((frames-frame)/frames) + gt * (frame/frames));
			b = Math.floor(bf * ((frames-frame)/frames) + bt * (frame/frames));
			h = this.make_hex(r,g,b);
		
			setTimeout("Fat.set_bgcolor('"+id+"','"+h+"')", delay);

			frame++;
			delay = interval * frame; 
		}
		setTimeout("Fat.set_bgcolor('"+id+"','"+to+"')", delay);
	},
	set_bgcolor : function (id, c)
	{
		var o = document.getElementById(id);
		o.style.backgroundColor = c;
	},
	get_bgcolor : function (id)
	{
		var o = document.getElementById(id);
		while(o)
		{
			var c;
			if (window.getComputedStyle) c = window.getComputedStyle(o,null).getPropertyValue("background-color");
			if (o.currentStyle) c = o.currentStyle.backgroundColor;
			if ((c != "" && c != "transparent") || o.tagName == "BODY") { break; }
			o = o.parentNode;
		}
		if (c == undefined || c == "" || c == "transparent") c = "#FFFFFF";
		var rgb = c.match(/rgb\s*\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*\)/);
		if (rgb) c = this.make_hex(parseInt(rgb[1]),parseInt(rgb[2]),parseInt(rgb[3]));
		return c;
	}
}