(function(b){
    b.jScrollPane={
        active:[]
    };
    
    b.fn.jScrollPane=function(c){
        c=b.extend({},b.fn.jScrollPane.defaults,c);
        var l=function(){
            return false
            };
            
        return this.each(function(){
            var d=b(this),Q=this,R=0,k,f,o,u=c.topCapHeight,g;
            if(b(this).parent().is(".jScrollPaneContainer")){
                g=b(this).parent();
                R=c.maintainPosition?d.position().top:0;
                var h=b(this).parent();
                k=h.innerWidth();
                f=h.outerHeight();
                b(">.jScrollPaneTrack, >.jScrollArrowUp, >.jScrollArrowDown, >.jScrollCap",h).remove();
                d.css({
                    top:0
                })
                }else{
                d.data("originalStyleTag", d.attr("style"));
                d.css("overflow","hidden");
                this.originalPadding=d.css("paddingTop")+" "+d.css("paddingRight")+" "+d.css("paddingBottom")+" "+d.css("paddingLeft");
                this.originalSidePaddingTotal=(parseInt(d.css("paddingLeft"))||0)+(parseInt(d.css("paddingRight"))||0);
                k=d.innerWidth();
                f=d.innerHeight();
                g=b("<div></div>").attr({
                    className:"jScrollPaneContainer"
                }).css({
                    height:f+"px",
                    width:k+"px"
                    });
                c.enableKeyboardNavigation&&g.attr("tabindex",c.tabIndex);
                d.wrap(g);
                g=d.parent();
                b(document).bind("emchange", function(){
                    d.jScrollPane(c)
                    })
                }
                o=f;
            if(c.reinitialiseOnImageLoad){
                var v=b.data(Q,"jScrollPaneImagesToLoad")||b("img",d),S=[];
                v.length&&v.each(function(a,e){
                    b(this).bind("load readystatechange",function(){
                        if(b.inArray(a,S)==-1){
                            S.push(e);
                            v=b.grep(v,function(p){
                                return p!=e
                                });
                            b.data(Q,"jScrollPaneImagesToLoad",v);
                            var i=b.extend(c,{
                                reinitialiseOnImageLoad:false
                            });
                            d.jScrollPane(i)
                            }
                        }).each(function(){
                    if(this.complete||this.complete===undefined)this.src=this.src
                        })
                })
            }
            h={
            height:"auto",
            width:k-c.scrollbarWidth- c.scrollbarMargin-this.originalSidePaddingTotal+"px"
            };
            
        if(c.scrollbarOnLeft)h.paddingLeft=c.scrollbarMargin+c.scrollbarWidth+"px";else h.paddingRight=c.scrollbarMargin+"px";
            d.css(h);
            var w=d.outerHeight(),A=f/w;
            h=A<0.99;
            g[h?"addClass":"removeClass"]("jScrollPaneScrollable");
            if(h){
            g.append(b("<div></div>").addClass("jScrollCap jScrollCapTop").css({
                height:c.topCapHeight
                }),b("<div></div>").attr({
                className:"jScrollPaneTrack"
            }).css({
                width:c.scrollbarWidth+"px"
                }).append(b("<div></div>").attr({
                className:"jScrollPaneDrag"
            }).css({
                width:c.scrollbarWidth+ "px"
                }).append(b("<div></div>").attr({
                className:"jScrollPaneDragTop"
            }).css({
                width:c.scrollbarWidth+"px"
                }),b("<div></div>").attr({
                className:"jScrollPaneDragBottom"
            }).css({
                width:c.scrollbarWidth+"px"
                }))),b("<div></div>").addClass("jScrollCap jScrollCapBottom").css({
                height:c.bottomCapHeight
                }));
            k=b(">.jScrollPaneTrack",g);
            var B=b(">.jScrollPaneTrack .jScrollPaneDrag",g),x,q=[],r,s=function(){
                if(r>4||r%4==0)m(j+x*L);
                r++
            };
            
            c.enableKeyboardNavigation&&g.bind("keydown.jscrollpane",function(a){
                switch(a.keyCode){
                    case 38:
                        x= -1;
                        r=0;
                        s();
                        q[q.length]=setInterval(s,100);
                        return false;
                    case 40:
                        x=1;
                        r=0;
                        s();
                        q[q.length]=setInterval(s,100);
                        return false;
                    case 33:case 34:
                        return false;default:
                }
            }).bind("keyup.jscrollpane",function(a){
            if(a.keyCode==38||a.keyCode==40){
                for(a=0;a<q.length;a++)clearInterval(q[a]);
                return false
                }
            });
        if(c.showArrows){
            var C,T,U=function(){
                b("html").unbind("mouseup",U);
                C.removeClass("jScrollActiveArrowButton");
                clearInterval(T)
                },V=function(){
                b("html").bind("mouseup",U);
                C.addClass("jScrollActiveArrowButton");
                r=0;
                s();
                T=setInterval(s,100)
                };
                
            g.append(b("<a></a>").attr({
                href:"javascript:;",
                className:"jScrollArrowUp",
                tabindex:-1
            }).css({
                width:c.scrollbarWidth+"px",
                top:c.topCapHeight+"px"
                }).html("Scroll up").bind("mousedown",function(){
                C=b(this);
                x=-1;
                V();
                this.blur();
                return false
                }).bind("click",l),b("<a></a>").attr({
                href:"javascript:;",
                className:"jScrollArrowDown",
                tabindex:-1
            }).css({
                width:c.scrollbarWidth+"px",
                bottom:c.bottomCapHeight+"px"
                }).html("Scroll down").bind("mousedown",function(){
                C=b(this);
                x=1;
                V();
                this.blur();
                return false
                }).bind("click",l));
            var M=b(">.jScrollArrowUp",g),W=b(">.jScrollArrowDown",g)
            }
            if(c.arrowSize){
            o=f-c.arrowSize-c.arrowSize;
            u+=c.arrowSize
            }else if(M){
            h=M.height();
            c.arrowSize=h;
            o=f-h-W.height();
            u+=h
            }
            o-=c.topCapHeight+c.bottomCapHeight;
        k.css({
            height:o+"px",
            top:u+"px"
            });
        var N=b(this).css({
            position:"absolute",
            overflow:"visible"
        }),y,n,L,j=0,D=A*f/2,E=function(a,e){
            var i=e=="X"?"Left":"Top";
            return a["page"+e]||a["client"+e]+(document.documentElement["scroll"+i]||document.body["scroll"+i])||0
            }, F=function(){
            return false
            },H=function(){
            G();
            y=B.offset(false);
            y.top-=j;
            n=o-B[0].offsetHeight;
            L=2*c.wheelSpeed*n/w
            },X=function(){
            b("html").unbind("mouseup",X).unbind("mousemove",Y);
            D=A*f/2;
            b.browser.msie&&b("html").unbind("dragstart",F).unbind("selectstart",F)
            },m=function(a){
            g.scrollTop(0);
            j=a=a<0?0:a>n?n:a;
            B.css({
                top:a+"px"
                });
            var e=a/n;
            d.data("jScrollPanePosition",(f-w)*-e);
            N.css({
                top:(f-w)*e+"px"
                });
            d.trigger("scroll");
            if(c.showArrows){
                M[a==0?"addClass":"removeClass"]("disabled");
                W[a==n?"addClass": "removeClass"]("disabled")
                }
            },Y=function(a){
        m(E(a,"Y")-y.top-D)
        };
        
    u=Math.max(Math.min(A*(f-c.arrowSize*2),c.dragMaxHeight),c.dragMinHeight);
    B.css({
        height:u+"px"
        }).bind("mousedown",function(a){
        H();
        D=E(a,"Y")-j-y.top;
        b("html").bind("mouseup",X).bind("mousemove",Y);
        b.browser.msie&&b("html").bind("dragstart",F).bind("selectstart",F);
        return false
        });
    var Z,I,$,aa=function(){
        if(I>8||I%4==0)m(j-(j-$)/2);
        I++
    },ba=function(){
        clearInterval(Z);
        b("html").unbind("mouseup",ba).unbind("mousemove",O)
        },O=function(a){
        $= E(a,"Y")-y.top-D
        };
        
    k.bind("mousedown",function(a){
        H();
        O(a);
        I=0;
        b("html").bind("mouseup",ba).bind("mousemove",O);
        Z=setInterval(aa,100);
        aa();
        return false
        });
    g.bind("mousewheel",function(a,e){
        e=e||(a.wheelDelta?a.wheelDelta/120:a.detail?-a.detail/3:0);
        H();
        G();
        a=j;
        m(j-e*L);
        return a==j
        });
    var J,P;
    function da(){
        var a=(J-j)/c.animateStep;
        if(a>1||a<-1)m(j+a);
        else{
            m(J);
            G()
            }
        }
    var G=function(){
    if(P){
        clearInterval(P);
        delete J
        }
    },t=function(a,e){
    if(typeof a=="string"){
        try{
            $e=b(a,d)
            }catch(i){
            return
        }
        if(!$e.length)return;
        a=$e.offset().top-d.offset().top
        }
        G();
    var p=w-f;
    a=a>p?p:a;
    d.data("jScrollPaneMaxScroll",p);
    a=a/p*n;
    if(e||!c.animateTo)m(a);
    else{
        g.scrollTop(0);
        J=a;
        P=setInterval(da,c.animateInterval)
        }
    };

d[0].scrollTo=t;
d[0].scrollBy=function(a){
    var e=-parseInt(N.css("top"))||0;
    t(e+a)
    };
    
H();
t(-R,true);
b("*",this).bind("focus",function(){
    for(var a=b(this),e=0;a[0]!=d[0];){
        e+=a.position().top;
        a=a.offsetParent()
        }
        a=-parseInt(N.css("top"))||0;
    var i=a+f;
    if(!(e>a&&e<i)){
        i=e-c.scrollbarMargin;
        if(e>a)i+=b(this).height()+15+c.scrollbarMargin- f;
        t(i)
        }
    });
if(c.observeHash){
    if(location.hash&&location.hash.length>1)setTimeout(function(){
        t(location.hash)
        },b.browser.safari?100:0);
    b(document).bind("click",function(a){
        $target=b(a.target);
        if($target.is("a")){
            var e=$target.attr("href");
            if(e&&e.substr(0,1)=="#"&&e.length>1)setTimeout(function(){
                t(e,!c.animateToInternalLinks)
                },b.browser.safari?100:0)
            }
            })
}
function ea(){
    b(document).bind("mousemove.jScrollPaneDragging",fa);
    b(document).bind("mouseup.jScrollPaneDragging",ga)
    }
    var K,z;
function ha(){
    direction= K<0?-1:1;
    d[0].scrollBy(K/2)
    }
    function ca(){
    if(z){
        clearInterval(z);
        z=undefined
        }
    }
function fa(a){
    var e=d.parent().offset().top,i=e+f;
    a=E(a,"Y");
    K=a<e?a-e:a>i?a-i:0;
    if(K==0)ca();else z||(z=setInterval(ha,100))
        }
        function ga(){
    b(document).unbind("mousemove.jScrollPaneDragging").unbind("mouseup.jScrollPaneDragging");
    ca()
    }
    g.bind("mousedown.jScrollPane",ea);
b.jScrollPane.active.push(d[0])
}else{
    d.css({
        height:f+"px",
        width:k-this.originalSidePaddingTotal+"px",
        padding:this.originalPadding
        });
    d[0].scrollTo=d[0].scrollBy= function(){};
    
    d.parent().unbind("mousewheel").unbind("mousedown.jScrollPane").unbind("keydown.jscrollpane").unbind("keyup.jscrollpane")
    }
})
};

b.fn.jScrollPaneRemove=function(){
    b(this).each(function(){
        $this=b(this);
        var c=$this.parent();
        if(c.is(".jScrollPaneContainer")){
            $this.css({
                top:"",
                height:"",
                width:"",
                padding:"",
                overflow:"",
                position:""
            });
            $this.attr("style",$this.data("originalStyleTag"));
            c.after($this).remove()
            }
        })
};

b.fn.jScrollPane.defaults={
    scrollbarWidth:10,
    scrollbarMargin:5,
    wheelSpeed:18,
    showArrows:false, 
    arrowSize:0,
    animateTo:false,
    dragMinHeight:1,
    dragMaxHeight:99999,
    animateInterval:100,
    animateStep:3,
    maintainPosition:true,
    scrollbarOnLeft:false,
    reinitialiseOnImageLoad:false,
    tabIndex:0,
    enableKeyboardNavigation:true,
    animateToInternalLinks:false,
    topCapHeight:0,
    bottomCapHeight:0,
    observeHash:true
};

b(window).bind("unload",function(){
    for(var c=b.jScrollPane.active,l=0;l<c.length;l++)c[l].scrollTo=c[l].scrollBy=null
        })
})(jQuery);
