﻿
/***************************************************************
jQuery默认方法  ============

inArray:  返回参数在数组中的索引,没找到是返回0。
          eg:  $.inArray("young", arr);
each:     遍历一个数组或对象属性
          eg:  $.each(obj,function(key,value){})
               当obj为数组时，key为索引值;当为对象时,key为对象属性值
extend:   用一个或多个对象扩展第一个对象
          eg:  $.extend( target, object1, [objectN] ) 
grep:     用过滤函数对数值进行过滤
          eg:  $.grep([5,6,9], function(n, i){})
          n,i分别对应值和相应位置索引
map:      对数值用相应函数重新转换
          eg:  $.map([5,6,9], function(n, i){})
          n,i分别对应值和相应位置索引
makeArray:将类似数值的对象转化为者真实的数组
          eg:  var arr = jQuery.makeArray($(".div"));
trim:     移除字符串两端的空格


***************************************************************
扩展方法  ============               
----------------------------------------------------------------------------------------
chk:      检查传入的对象或值是否存在。
          return true或false
---------------------------------------------------------------
defined:  检测传入的对象或值是否定义过
          return true或false
---------------------------------------------------------------
pick:     如果传入的参数被定义返回第一个对象,否则返回第二个.
          eg: $.pick(obj, {name:"Young.Jiang"});
---------------------------------------------------------------
random:   返回介于两个值之间的整数
---------------------------------------------------------------
toInt,toFloat:    将第一个参数转化为整数或浮点数,当无法转化，返回默认值,
          para: v-需转化的值; def，默认值，未定义是为0;
---------------------------------------------------------------
gmp:      get mouse positon的缩写,获取鼠标事件的位置
          return { x:x坐标值 , y:y坐标值 }
---------------------------------------------------------------
url:      url设置
          eg: var url="http://www.holygrace.cn/index.htm?fx=drag";
          var urlpara=$.url(url); alert(urlpara.fx)  //返回"drag"; urlpara为{pageName:"index.htm",fx:"drag"}
          urlpara=$url(url,"fx"); alert(urlpara)     //相当于"drag"
          var newurl=$.url(url,"fx","dialog"); //newurl为:"http://www.holygrace.cn/index.htm?fx=dialog";
          newurl=$.url(url,{pageName:"test.aspx",fx:"star",lg:"cn"}); //newurl为:"http://www.holygrace.cn/test.aspx?fx=dialog&lg=cn";
---------------------------------------------------------------
cookie:   cookie的设置和读取
          eg: $.cookie('name', 'value');
          $.cookie('name','value',{expires: 7, path:'/', domain:'www.holygrace.cn',secure: true});
          $.cookie('the_cookie', null); //删除

*/

jQuery.extend({
    chk: function (obj) {
        return !!(obj || obj === 0);
    },
    defined: function (obj) {
        return (obj != undefined);
    },
    pick: function () {
        for (var i = 0, l = arguments.length; i < l; i++) {
            if ($.defined(arguments[i])) return arguments[i];
        }
        return null;
    },
    random: function (min, max) {
        return Math.floor(Math.random() * (max - min + 1) + min);
    },
    parseNum: function (type, v, def) {
        var r = (type == "float") ? parseFloat(v) : parseInt(v);
        return isNaN(r) ? ($.defined(def) ? def : 0) : r;
    },
    toInt: function (v, def) {
        return $.parseNum("int", v, def);
    },
    toFloat: function (v, def) {
        return $.parseNum("float", v, def);
    },
    id: function (id) {
        return document.getElementById(id);
    },
    gmp: function (e) {
        var posx = 0;
        var posy = 0;
        if (!e) { var e = window.event; }
        if (e.pageX || e.pageY) {
            posx = e.pageX;
            posy = e.pageY;
        }
        else if (e.clientX || e.clientY) {
            posx = e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft;
            posy = e.clientY + document.body.scrollTop + document.documentElement.scrollTop;
        };
        return { 'x': posx, 'y': posy };
    },
    url: function (url) {
        var urls = url.split("?");
        var paths = urls[0].split("/");
        var pageName = paths[paths.length - 1];
        var querys = new Object();
        querys.pageName = pageName;
        var arg = arguments;
        if (url.indexOf("?") != -1) {
            $.each(urls[1].split("&"), function (i, n) {
                var v = n.split("=");
                querys[v[0]] = v[1];
            })
        }
        function urlToString() {
            url = urls[0] + "?";
            $.each(querys, function (i, n) {
                url = i != "pageName" ? url + i + "=" + n + "&" : url.replace(pageName, n);
            });
            return url.substr(0, url.length - 1);
        }
        if (!$.defined(arg[1])) {
            return querys;
        }
        if (typeof arg[1] == "object") {
            $.extend(querys, arg[1]);
            return urlToString();
        }
        if (typeof arg[1] == "string") {
            if ($.defined(arg[2])) {
                querys[arg[1]] = arg[2];
                return urlToString();
            }
            else {
                return querys[arg[1]]
            }
        }
    },
    GetMousePosition: function (e) {
        var posx = 0;
        var posy = 0;

        if (!e) {
            var e = window.event;
        }

        if (e.pageX || e.pageY) {
            posx = e.pageX;
            posy = e.pageY;
        }
        else if (e.clientX || e.clientY) {
            posx = e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft;
            posy = e.clientY + document.body.scrollTop + document.documentElement.scrollTop;
        };
        return { 'x': posx, 'y': posy };
    },
    cookie: function (name, value, options) {
        if (typeof value != 'undefined') {
            options = options || {};
            if (value === null) {
                value = '';
                options.expires = -1;
            }
            var expires = '';
            if (options.expires && (typeof options.expires == 'number' || options.expires.toUTCString)) {
                var date;
                if (typeof options.expires == 'number') {
                    date = new Date();
                    date.setTime(date.getTime() + (options.expires * 24 * 60 * 60 * 1000));
                } else {
                    date = options.expires;
                }
                expires = '; expires=' + date.toUTCString();
            }
            var path = options.path ? '; path=' + options.path : '';
            var domain = options.domain ? '; domain=' + options.domain : '';
            var secure = options.secure ? '; secure' : '';
            document.cookie = [name, '=', encodeURIComponent(value), expires, path, domain, secure].join('');
            //document.cookie = [name, '=', value, expires, path, domain, secure].join('');
        } else {
            var cookieValue = null;
            if (document.cookie && document.cookie != '') {
                var cookies = document.cookie.split(';');
                for (var i = 0; i < cookies.length; i++) {
                    var cookie = jQuery.trim(cookies[i]);
                    if (cookie.substring(0, name.length + 1) == (name + '=')) {
                        cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
                        break;
                    }
                }
            }
            return cookieValue;
        }
    }
});


jQuery.fn.outerHTML = function (s) {
    return (s) 
? this.before(s).remove() 
: $($('<div></div>').html(this.clone())).html();    
};

// Opacity ：设置透明度
jQuery.fn.extend({
    Opacity : function(value){
        return this.each(function(){
            if(value!=null)
            {
                if ( $.browser.msie ){
                    this.style.filter = "alpha(opacity = "+value+")";
                }
                else{
                    this.style.MozOpacity = $.toInt(value)/100;
                }
            }
        })
    }
});


jQuery.fn.extend({Drag:function(options){
    options=$.extend({handle:"",range:""},options);
    var isMouseDown=false;
    var dragObj=null;
    var dragHandle=null;
    var lastMouseX;
    var lastMouseY;
    var lastElemTop;
    var lastElemLeft;
    function updatePosition(e){
      var pos=$.GetMousePosition(e);
      var spanX=(pos.x-lastMouseX);
      var spanY=(pos.y-lastMouseY);
      var top=lastElemTop+spanY;
      var left=lastElemLeft+spanX;
      if(options.range==""){
        dragObj.css({top:top,left:left});
      }else {
        var range=$("#"+options.range);
        var rangeBottom=$.toInt(range.css("height"))-$.toInt(dragObj.css("height"))-$.toInt(dragObj.css("borderTopWidth"),true)-$.toInt(dragObj.css("borderBottomWidth"),true);
        var rangeRight=$.toInt(range.css("width"))-$.toInt(dragObj.css("width"))-$.toInt(dragObj.css("borderLeftWidth"),true)-$.toInt(dragObj.css("borderRightWidth"),true);
        if(top>0&&top<rangeBottom){
          dragObj.css("top",top);
        }else {
          dragObj.css("top",top>0?rangeBottom:0);
        }
        if(left>0&&left<rangeRight){
          dragObj.css("left",left);
        }else {
          dragObj.css("left",left>0?rangeRight:0);
        }
      }
    }
    $(document).mousemove(function(e){
      if(isMouseDown){
        updatePosition(e);
        return false;
      }
    });
    $(document).mouseup(function(e){
      if(isMouseDown){
        isMouseDown=false;
        return false;
      }
    });
    return this.each(function(){
      var dragDom=this;
      dragHandle=(options.handle==""?$(this):$(options.handle));
      dragHandle.css("cursor","move");
      dragHandle.mousedown(function(e){
        dragObj=$(dragDom);
        dragObj.css("position","absolute");
        isMouseDown=true;
        var pos=$.GetMousePosition(e);
        lastMouseX=pos.x;
        lastMouseY=pos.y;
        lastElemTop=dragDom.offsetTop;
        lastElemLeft=dragDom.offsetLeft;
        updatePosition(e);
      });
    });
  }});
  
(function ($) {
    var m = {
            '\b': '\\b',
            '\t': '\\t',
            '\n': '\\n',
            '\f': '\\f',
            '\r': '\\r',
            '"' : '\\"',
            '\\': '\\\\'
        },
        s = {
            'array': function (x) {
                var a = ['['], b, f, i, l = x.length, v;
                for (i = 0; i < l; i += 1) {
                    v = x[i];
                    f = s[typeof v];
                    if (f) {
                        v = f(v);
                        if (typeof v == 'string') {
                            if (b) {
                                a[a.length] = ',';
                            }
                            a[a.length] = v;
                            b = true;
                        }
                    }
                }
                a[a.length] = ']';
                return a.join('');
            },
            'boolean': function (x) {
                return String(x);
            },
            'null': function (x) {
                return "null";
            },
            'number': function (x) {
                return isFinite(x) ? String(x) : 'null';
            },
            'object': function (x) {
                if (x) {
                    if (x instanceof Array) {
                        return s.array(x);
                    }
                    var a = ['{'], b, f, i, v;
                    for (i in x) {
                        v = x[i];
                        f = s[typeof v];
                        if (f) {
                            v = f(v);
                            if (typeof v == 'string') {
                                if (b) {
                                    a[a.length] = ',';
                                }
                                a.push(s.string(i), ':', v);
                                b = true;
                            }
                        }
                    }
                    a[a.length] = '}';
                    return a.join('');
                }
                return 'null';
            },
            'string': function (x) {
                if (/["\\\x00-\x1f]/.test(x)) {
                    x = x.replace(/([\x00-\x1f\\"])/g, function(a, b) {
                        var c = m[b];
                        if (c) {
                            return c;
                        }
                        c = b.charCodeAt();
                        return '\\u00' +
                            Math.floor(c / 16).toString(16) +
                            (c % 16).toString(16);
                    });
                }
                return '"' + x + '"';
            }
        };

	$.toJSON = function(v) {
		var f = isNaN(v) ? s[typeof v] : s['number'];
		if (f) return f(v);
	};
	
	$.parseJSON = function(v, safe) {
		if (safe === undefined) safe = $.parseJSON.safe;
		if (safe && !/^("(\\.|[^"\\\n\r])*?"|[,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t])+?$/.test(v))
			return undefined;
		return eval('('+v+')');
	};
	
	$.parseJSON.safe = false;

})(jQuery);

  AjaxService=function(url,async,callback,errorCallback,dataType,pars){
    $.ajax({
      data:pars,
      url: url,
      type: "POST",
      async:async,
      dataType:dataType,
      contentType: "application/json;utf-8",
      cache: false,
      success: function(json){
        callback(json);
      },
      error:function(xml,status){
        if(status=='error'){
            try{
            errorCallback(xml.statusText);
            }catch(e){}
        }else{
            errorCallback(status);
        }
      },
      beforeSend:function(xml){
        if(!pars)  xml.setRequestHeader("Content-Type", "application/json;utf-8")
      }
    });
};

renderDate=function(value){
   return eval("new " + value.substr(1,value.length-2)).format('yyyy-MM-dd');
};

Date.prototype.format = function(format)
{
var o = {
"M+" : this.getMonth()+1, //month
"d+" : this.getDate(),    //day
"h+" : this.getHours(),   //hour
"m+" : this.getMinutes(), //minute
"s+" : this.getSeconds(), //second
"q+" : Math.floor((this.getMonth()+3)/3),  //quarter
"S" : this.getMilliseconds() //millisecond
}
if(/(y+)/.test(format)) format=format.replace(RegExp.$1,
(this.getFullYear()+"").substr(4 - RegExp.$1.length));
for(var k in o)if(new RegExp("("+ k +")").test(format))
format = format.replace(RegExp.$1,
RegExp.$1.length==1 ? o[k] :
("00"+ o[k]).substr((""+ o[k]).length));
return format;
};



var _st = window.setTimeout;
window.setTimeout = function(fRef, mDelay) {

	if (typeof fRef == 'function') {
		var argu = Array.prototype.slice.call(arguments, 2);
		var f = (function() {
			fRef.apply(null, argu);
		});
		return _st(f, mDelay);
	}
	return _st(fRef, mDelay);

};

jQuery.extend({
			init_slide : function(firstname, secondname, imagewidth,
					imageheight,showtitle, playtime,
					clickable, titlecolor,mytarget) {

				if (!mytarget) {
					mytarget = '_blank';
				}
				if (!playtime) {
					playtime = 6000;
				}
				if (!titlecolor){
					titlecolor='#fff';
				}

				var timer, myend, myfirst, myfirstlink, myfirstsrc;
				myfirst = $('#' + firstname + ' img:eq(0)').clone();
				myfirstlink = $(myfirst).attr('rel');
				myfirstsrc = $(myfirst).attr('src');
				var myImage = new Image();
				myImage.src = $(myfirst).attr('src');

				var mylink = new Array();
				var chk, mysrc, myrel, mytitle, mycover;
				$('#' + secondname)
						.append('<div class=myslide style="width:'
								+ imagewidth
								+ 'px;height:'
								+ imageheight
								+ 'px"><div id='
								+ secondname
								+ 'show class=slideshowbg" ></div><div class="slidelink" id='
								+ secondname
								+ 'link align=center valign=top></div></div>'
								+ '<div class=slidetitle style="width:'+ imagewidth+'px;background-color:'+titlecolor+'" id=' + secondname + 'linktitle ></div>');

				$('#' + firstname + ' img').each(function(e) {
					var f = e + 1;
					chk = $(this).attr('title');
					myrel = $(this).attr('rel');
					mysrc = $(this).attr('src');
					if (chk) {
						mytitle = chk;
					}
					if (chk === undefined) {
						mytitle = $(this).attr("src");
						mytitle = mytitle.replace(new RegExp(/\.*\w*\//g), "");
					}
					mylink[e] = '<span rel=\"' + mysrc + '\" link=\"' + myrel
							+ '\" title=\"' + mytitle + '\" no=\"' + f + '\" >'
							+ f + '</span>';

				});
				if (!clickable) {
					$('#' + secondname + 'link').hide();
				}

				if (!showtitle) {
					$('#' + secondname + 'linktitle').hide();
				}
				
				$('#' + secondname + 'link').html(mylink.join(""));
				$('#' + secondname + 'link span').addClass("link_nor");
				$('#' + secondname + 'link span:eq(0)').addClass("link_act");

				$('#' + secondname + 'link span').click(function() {
					var mm = $(this).attr('rel');
					var nn = this.title;
					var kk = $(this).attr('link');
					var mynowplaying = $(this).text();

					mynowplaying = parseInt(mynowplaying, 10);
					clearTimeout(timer);
					timer = setTimeout(function(){
					q=mynowplaying;
					if (!q) {
						q = 1;
					}
					myend = $('#' + secondname + 'link span').size() - 1;
					if (q > myend) {
						q = 0;
					}
					$('#' + secondname + 'link span').eq(q).click();
					q = q + 1;
					}, playtime);
					$('#' + secondname + 'link span').removeClass("link_act");
					$(this).addClass("link_act");
					$('#' + secondname + 'show').html('<a href=' + kk
							+ ' target=' + mytarget + ' ><img border="0" src=' + mm
							+ ' style="display:none"></a>');

					$('#' + secondname + 'show img').fadeIn('slow');
					$('#' + secondname + 'linktitle').html('<a href=' + kk
							+ ' target=' + mytarget + ' >'+nn+'</a>');
					$('#' + secondname + 'show img').hover(function() {
						clearTimeout(timer);
						$(this).fadeTo("slow", 0.8);
						}, function() {
							$(this).fadeTo("slow", 1);
							myend = $('#' + secondname + 'link span').size();
							if (mynowplaying > myend) {
								mynowplaying = 0;
							}
							clearTimeout(timer);
							timer = setTimeout(function(){
							q=mynowplaying;
							if (!q) {
								q = 1;
							}
							myend = $('#' + secondname + 'link span').size() - 1;
							if (q > myend) {
								q = 0;
							}
							$('#' + secondname + 'link span').eq(q).click();
							q = q + 1;

							}, 100);
						});

				});

				$('#' + secondname + 'link span').eq(0).click();

			}
		});



 /* Licensed under the MIT License:
 * http://www.opensource.org/licenses/mit-license.php
 *
 *
 * Parameter
 * @animate     : 显示动画，其中"bounceout","elasout","backin"等特效需要easing library,默认为无效果
 * @maskColor   : 遮罩层的颜色,默认为#000000
 * @maskOpacity : 遮罩层透明度,默认为5
 * @left @top   : 对话框显示时的位置,默认为正中间
 * @draggable   : 是否可以拖拽
 * @dragHandle  : 拖拽助手,详情见HG.Drag,当draggable为true是有效
 * @dragRange   : 拖拽范围,详情见HG.Drag,当draggable为true是有效
 * @close       : 触发关闭事件的对象，jquery选择器
 *
 * Event
 * CloseDialog()  : 出发关闭对话框事件
 *
 *  Example:
 *  $("#dialog").Dialog();
 *       
 *  $("#dialog").Dialog({
 *       animate     : "bounceout",
 *       draggable   : true,
 *       dragHandle  : "#dialogtitle",
 *       close       : "#close"
 *  });
 *
 * $("#dialog").CloseDialog();
 */


jQuery.fn.extend({
    Dialog : function(options){
        options = $.extend({
            animate     : "",   //推荐： "bounceout","elasout","backin"
            showmask    : true,
            maskColor   : "#000000",            
            maskOpacity : "5",
            left        : "",
            right       : "",
            top         : "",
            draggable   : false,
            dragHandle  : "",
            bodyHandle  : "",
            footHandle  : "",
            dragRange   : "",
            minimize    : "",
            minimizecallback : "",
            restore     : "",
            restorecallback : "",
            close: "",
            closecallback:"",
            state       : "max",
            aferRun     : ""
         },options);	
        
        return this.each(function(){
			var dialog=$(this);
			if (options.showmask){
			    $("body").append("<div id='dialogmask'><div>");
			    $('#dialogmask').css({
                    position   : "absolute",
                    top:"0px",
                    left:"0px",
                    width:$(window).width()+"px",
                    height:$("body").height()+"px",
                    zIndex: "999",
                    background:options.maskColor
			    });
			    $('#dialogmask').Opacity(options.maskOpacity);
			}
			 
			//show
			var toLeft=(options.left=="")?(($(window).width()-dialog.width())/2):options.left;
			var toTop=(options.top=="")?(($(window).height()-dialog.height())/3):options.top;
			 
			if(options.animate=="")
			{
			    dialog.css({
			        position   : "absolute",
			        top        : (toTop+document.documentElement.scrollTop)+"px",
			        zIndex      : "1000"
			    });
			    if (options.right)
    				dialog.css("right",options.right+"px");			    
			    else
				    dialog.css("left",toLeft+"px");			    
			    dialog.show('',options.aferRun)
			}
			else
			{
                dialog.css({
			        position   : "absolute",
			        top        : "0px",
			        zIndex      : "1000"
			    });
			    if (options.right)
    				dialog.css("right",options.right+"px");			    
			    else
				    dialog.css("left",toLeft+"px");			    
			    dialog.slideDown(200);
			    dialog.animate(
			        {top: (toTop+document.documentElement.scrollTop)+"px"},
			        { easing : options.animate ,
			          duration : 800
			        }
			     );
			}
			            
            //drag
            if(options.draggable)
            {
                dialog.Drag({
                    handle : options.dragHandle,
                    range  : options.dragRange
                })
            }
			
			//close
			if(options.close!="")
			{
			    $(options.close).click(function(){
			        dialog.CloseDialog(options.showmask,options.closecallback);
			        $(this).unbind("click");
			    })

			}


			
			//minimize
			if(options.minimize!="")
			{
			    $(options.minimize).click(function(){
			        toTop=dialog.MinDialog(dialog,options.bodyHandle,options.footHandle,options.minimize,options.restore,options.minimizecallback);
			    })			    
			}
			
			
			//restore
			if(options.restore!="")
			{
			    $(options.restore).hide();       

			    $(options.restore).click(function(){
			        toTop=dialog.restoreDialog(dialog,options.bodyHandle,options.footHandle,options.minimize,options.restore,options.restorecallback);
			    })			    
			}
			
			if(options.state=="min")
			{
			    $(options.minimize).click();
			}
			
			
			var flowtime;
			//scroll
			$(window).scroll(function(){			   			    
                if(flowtime) clearInterval(flowtime);
                flowtime = setInterval(function(){
                                        dialog.css({
                                            top:(toTop+ $(this).scrollTop())+"px"
                                        });
                                        clearInterval(flowtime);
                                       }
                                        ,100);
			})			
        })
    },


    CloseDialog: function (showmask, callback) {
        if (typeof callback == 'function') {
            callback();
        }
        return this.each(function(){
            $(this).slideUp(100,function(){                
                if (showmask){
                 $('#dialogmask').remove();
                }                
            })
        });
    },
    
    MinDialog:function(dialog,bodyHandle,footHandle,minimize,restore,callback){
       dialog.saveViewState(dialog);
       $(minimize).hide();
       $(restore).show();       
       $(bodyHandle).hide();
       $(footHandle).hide();
       dialog.css("width","150px");
       dialog.css("right","2px");              
       dialog.css("left","auto");
       dialog.css("top",($(window).height()-dialog.height()+$(window).scrollTop()-2)+"px");
       if (typeof callback == 'function')
       {
        callback();
       }
       return ($(window).height()-dialog.height()-2);              
    },
    
    restoreDialog:function(dialog,bodyHandle,footHandle,minimize,restore,callback){
       $(minimize).show();
       $(restore).hide();       
       $(bodyHandle).show();
       $(footHandle).show();
       dialog.css("width",dialog.lastwidth+"px");
       dialog.css("left",dialog.lastleft+"px");
       dialog.css("top",dialog.lasttop+$(window).scrollTop()+"px");
       //dialog.css("top",(($(window).height()-dialog.height())/3));
       if (typeof callback == 'function')
       {
        callback();
       }

       return dialog.lasttop;              
    },
        
    saveViewState:function(dialog){
       dialog.lasttop=parseInt(dialog.css("top"))-$(window).scrollTop();
       dialog.lastleft=parseInt(dialog.css("left"));
       dialog.lastwidth=parseInt(dialog.css("width"));
       
    },
    
    DialogRange:function(){
        return this.each(function(){ 
            $(this).width($(window).width()-3);
            $(this).height($(window).height()-8);
        });
    }
});


// jQuery Easing v1.3 - http://gsgd.co.uk/sandbox/jquery/easing/
jQuery.easing['jswing'] = jQuery.easing['swing'];

jQuery.extend(jQuery.easing,
{
def: 'easeOutQuad',
swing: function (x, t, b, c, d) {
//alert(jQuery.easing.default);
return jQuery.easing[jQuery.easing.def](x, t, b, c, d);
},
easeInQuad: function (x, t, b, c, d) {
return c * (t /= d) * t + b;
},
easeOutQuad: function (x, t, b, c, d) {
return -c * (t /= d) * (t - 2) + b;
},
easeInOutQuad: function (x, t, b, c, d) {
if ((t /= d / 2) < 1) return c / 2 * t * t + b;
return -c / 2 * ((--t) * (t - 2) - 1) + b;
},
easeInCubic: function (x, t, b, c, d) {
return c * (t /= d) * t * t + b;
},
easeOutCubic: function (x, t, b, c, d) {
return c * ((t = t / d - 1) * t * t + 1) + b;
},
easeInOutCubic: function (x, t, b, c, d) {
if ((t /= d / 2) < 1) return c / 2 * t * t * t + b;
return c / 2 * ((t -= 2) * t * t + 2) + b;
},
easeInQuart: function (x, t, b, c, d) {
return c * (t /= d) * t * t * t + b;
},
easeOutQuart: function (x, t, b, c, d) {
return -c * ((t = t / d - 1) * t * t * t - 1) + b;
},
easeInOutQuart: function (x, t, b, c, d) {
if ((t /= d / 2) < 1) return c / 2 * t * t * t * t + b;
return -c / 2 * ((t -= 2) * t * t * t - 2) + b;
},
easeInQuint: function (x, t, b, c, d) {
return c * (t /= d) * t * t * t * t + b;
},
easeOutQuint: function (x, t, b, c, d) {
return c * ((t = t / d - 1) * t * t * t * t + 1) + b;
},
easeInOutQuint: function (x, t, b, c, d) {
if ((t /= d / 2) < 1) return c / 2 * t * t * t * t * t + b;
return c / 2 * ((t -= 2) * t * t * t * t + 2) + b;
},
easeInSine: function (x, t, b, c, d) {
return -c * Math.cos(t / d * (Math.PI / 2)) + c + b;
},
easeOutSine: function (x, t, b, c, d) {
return c * Math.sin(t / d * (Math.PI / 2)) + b;
},
easeInOutSine: function (x, t, b, c, d) {
return -c / 2 * (Math.cos(Math.PI * t / d) - 1) + b;
},
easeInExpo: function (x, t, b, c, d) {
return (t == 0) ? b : c * Math.pow(2, 10 * (t / d - 1)) + b;
},
easeOutExpo: function (x, t, b, c, d) {
return (t == d) ? b + c : c * (-Math.pow(2, -10 * t / d) + 1) + b;
},
easeInOutExpo: function (x, t, b, c, d) {
if (t == 0) return b;
if (t == d) return b + c;
if ((t /= d / 2) < 1) return c / 2 * Math.pow(2, 10 * (t - 1)) + b;
return c / 2 * (-Math.pow(2, -10 * --t) + 2) + b;
},
easeInCirc: function (x, t, b, c, d) {
return -c * (Math.sqrt(1 - (t /= d) * t) - 1) + b;
},
easeOutCirc: function (x, t, b, c, d) {
return c * Math.sqrt(1 - (t = t / d - 1) * t) + b;
},
easeInOutCirc: function (x, t, b, c, d) {
if ((t /= d / 2) < 1) return -c / 2 * (Math.sqrt(1 - t * t) - 1) + b;
return c / 2 * (Math.sqrt(1 - (t -= 2) * t) + 1) + b;
},
easeInElastic: function (x, t, b, c, d) {
var s = 1.70158; var p = 0; var a = c;
if (t == 0) return b; if ((t /= d) == 1) return b + c; if (!p) p = d * .3;
if (a < Math.abs(c)) { a = c; var s = p / 4; }
else var s = p / (2 * Math.PI) * Math.asin(c / a);
return -(a * Math.pow(2, 10 * (t -= 1)) * Math.sin((t * d - s) * (2 * Math.PI) / p)) + b;
},
easeOutElastic: function (x, t, b, c, d) {
var s = 1.70158; var p = 0; var a = c;
if (t == 0) return b; if ((t /= d) == 1) return b + c; if (!p) p = d * .3;
if (a < Math.abs(c)) { a = c; var s = p / 4; }
else var s = p / (2 * Math.PI) * Math.asin(c / a);
return a * Math.pow(2, -10 * t) * Math.sin((t * d - s) * (2 * Math.PI) / p) + c + b;
},
easeInOutElastic: function (x, t, b, c, d) {
var s = 1.70158; var p = 0; var a = c;
if (t == 0) return b; if ((t /= d / 2) == 2) return b + c; if (!p) p = d * (.3 * 1.5);
if (a < Math.abs(c)) { a = c; var s = p / 4; }
else var s = p / (2 * Math.PI) * Math.asin(c / a);
if (t < 1) return -.5 * (a * Math.pow(2, 10 * (t -= 1)) * Math.sin((t * d - s) * (2 * Math.PI) / p)) + b;
return a * Math.pow(2, -10 * (t -= 1)) * Math.sin((t * d - s) * (2 * Math.PI) / p) * .5 + c + b;
},
easeInBack: function (x, t, b, c, d, s) {
if (s == undefined) s = 1.70158;
return c * (t /= d) * t * ((s + 1) * t - s) + b;
},
easeOutBack: function (x, t, b, c, d, s) {
if (s == undefined) s = 1.70158;
return c * ((t = t / d - 1) * t * ((s + 1) * t + s) + 1) + b;
},
easeInOutBack: function (x, t, b, c, d, s) {
if (s == undefined) s = 1.70158;
if ((t /= d / 2) < 1) return c / 2 * (t * t * (((s *= (1.525)) + 1) * t - s)) + b;
return c / 2 * ((t -= 2) * t * (((s *= (1.525)) + 1) * t + s) + 2) + b;
},
easeInBounce: function (x, t, b, c, d) {
return c - jQuery.easing.easeOutBounce(x, d - t, 0, c, d) + b;
},
easeOutBounce: function (x, t, b, c, d) {
if ((t /= d) < (1 / 2.75)) {
return c * (7.5625 * t * t) + b;
} else if (t < (2 / 2.75)) {
return c * (7.5625 * (t -= (1.5 / 2.75)) * t + .75) + b;
} else if (t < (2.5 / 2.75)) {
return c * (7.5625 * (t -= (2.25 / 2.75)) * t + .9375) + b;
} else {
return c * (7.5625 * (t -= (2.625 / 2.75)) * t + .984375) + b;
}
},
easeInOutBounce: function (x, t, b, c, d) {
if (t < d / 2) return jQuery.easing.easeInBounce(x, t * 2, 0, c, d) * .5 + b;
return jQuery.easing.easeOutBounce(x, t * 2 - d, 0, c, d) * .5 + c * .5 + b;
}
});



/*! idTabs v3.0 ~ Sean Catchpole - Copyright 2010 MIT/GPL */
; (function ($) {

    /* Changes for 3.0
    - return removed (it was depreciated)
    - passing arguments changed (id,s,e)
    - refresh of code speed and accuracy
    - items now object instead of id's
    - multiple tabs can now point to same id
    - removed autoloading jQuery
    - added item classes support
    - toggle visibility
    - update or remove idTabs
    - grouped areas
    - extend idTabs
    */

    /* Options (in any order):

    start (number|string)
    Index number of default tab. ex: $(...).idTabs(0)
    String of id of default tab. ex: $(...).idTabs("#tab1")
    default: class "selected" or index 0
    Passing -1 or null will force it to not select a default tab

    change (boolean)
    True - Url will change. ex: $(...).idTabs(true)
    False - Url will not change. ex: $(...).idTabs(false)
    default: false

    click (function)
    Function will be called when a tab is clicked. ex: $(...).idTabs(function(id,s){...})
    If the function returns false, idTabs will not take any action,
    otherwise idTabs will show/hide the content (as usual).
    The function is passed three variables:
    The id of the element to be shown
    The settings object which has the following additional items:
    area     - the original area $(area).idTabs();
    tabarea  - the current tab area used to find tabs
    tabs     - a jQuery list of tabs
    items    - a jQuery list of the elements the tabs point to
    tab(id)  - a helper function to find a tab with id
    item(id) - a helper function to find an item with id
    The event object that triggered idTabs

    selected (string)
    Class to use for selected. ex: $(...).idTabs(".current")
    default: ".selected"

    event (string)
    Event to trigger idTabs on. ex: $(...).idTabs("!mouseover")
    default: "!click"
    To bind multiple events, call idTabs multiple times
    ex: $(...).idTabs("!click").idTabs("!focus")

    toggle (boolean)
    True - Toggle visibility of tab content. ex: $(...).idTabs("!true")
    False - Ignore clicks on tabs already selected. ex: $(...).idTabs("!false")
    default: false

    grouped (boolean)
    True - Groups all tabs in area together. ex: $(...).idTabs(":grouped")
    False - jQuery selector is seperated into tab areas. ex: $(...).idTabs(":!grouped")
    default: false

    update (boolean)
    True - Rebinds idTabs ex: $(...).idTabs(":update");
    False - Cancels update ex: $(...).idTabs(":!update");

    remove (boolean)
    True - Removes idTabs ex: $(...).idTabs(":remove");
    False - Cancels removal ex: $(...).idTabs(":!remove");

    */

    // Helper functions
    var idTabs, //shortcut
undefined,  //speed up
href = function (e) { return $(e).attr("href"); },
type = function (o) { //reliable
    return o === null && "Null"
      || o === undefined && "Undefined"
      || ({}).toString.call(o).slice(8, -1);
};

    $.fn.idTabs = function () {
        var s = idTabs.args.apply(this, arguments),
  action = s.update && "update" || s.remove && "remove" || "bind";
        s.area = this; //save context
        idTabs[action](s);
        return this; //chainable
    };

    idTabs = $.idTabs = function (tabarea, options, data) {
        // Settings
        var e, tabs, items, test = $(), meta = $.metadata ? $(tabarea).metadata() : {}, //metadata
  s = { tab: idTabs.tab, item: idTabs.item }; //helpers
        s = $.extend(s, idTabs.settings, meta, options || {}); //settings
        s.tabarea = $(tabarea); //save context
        s.data = data || "idTabs" + +new Date; //save expando

        // Play nice
        $.each({ selected: '.', event: '!', start: '#' }, function (n, c) {
            if (type(s[n]) == "String" && s[n].indexOf(c) == 0)
                s[n] = s[n].substr(1);
        }); //removes type characters
        if (s.start === null) s.start = -1; //no tab selected

        // Find tabs
        items = []; //save elements
        s.tabs = tabs = $("a[href^=#]", tabarea); //save tabs
        tabs.each(function () { //add items
            test = s.item(href(this));
            if (test.length) items = items.concat(test.get());
        });
        s.items = $(items).hide(); //hide items

        // Save Settings
        e = "idTabs." + s.event;
        data = s.tabarea.data("idTabs") || {};
        data[e] = s;
        s.tabarea.data("idTabs", data);

        // Bind idTabs
        tabs.trigger(e).data(s.data, s)
      .bind(e, { s: s }, function () { //wrapper function due to jQuery bug
          return idTabs.unbind.apply(this, arguments);
      })
      .bind(s.event, { s: s }, idTabs.find);

        // Select default tab
        type(s.start) == "Number" && (s.start < 0 || (test = tabs.eq(s.start)).length)
  || type(s.start) == "String" && (test = tabs.filter("a[href=#" + s.start + "]")).length
  || (test = tabs.filter('.' + s.selected).removeClass(s.selected)).length
  || (s.start === undefined && (test = tabs.eq(0)).length);
        if (test.length) test.trigger(s.event);

        return s; //return current settings (be creative)
    };

    // Parse arguments into settings
    idTabs.args = function () {
        var a, i = 0, s = {}, args = arguments,
        // Handle string flags .!:
  str = function (_, a) {
      if (a.indexOf('.') == 0) s.selected = a;
      else if (a.indexOf('!') == 0)
          if (/^!(true|false)$/i.test(a)) s.toggle = /^!true$/i.test(a);
          else s.event = a;
      else if (a.indexOf(':') == 0) {
          a = a.substr(1).toLowerCase();
          if (a.indexOf('!') == 0) s[a.substr(1)] = false;
          else s[a] = true;
      } else if (a) s.start = a;
  };
        // Loop through arguments matching options
        while (i < args.length) {
            a = args[i++];
            switch (type(a)) {
                case "Object": $.extend(s, a); break;
                case "Boolean": s.change = a; break;
                case "Number": s.start = a; break;
                case "Function": s.click = a; break;
                case "Null": s.start = a; break;
                case "String": $.each(a.split(/\s+/g), str);
                default: break;
            }
        }
        return s; //settings object
    };

    // Bind idTabs
    idTabs.bind = function (s) {
        if (!s) return;
        var data = "idTabs" + +new Date; //instance expando
        if (s.grouped) $.idTabs(s.area, s, data);
        else s.area.each(function () { $.idTabs(this, s, data); });
    };

    // Rebind idTabs
    idTabs.update = function (s) {
        if (!s) return;
        s.update = false;
        var self, data, n, e = s.event;
        e = (e + "").indexOf('!') == 0 && e.substr(1) || e;
        e = e ? "idTabs." + e : "";
        return s.area.each(function () {
            self = $(this);
            data = self.data("idTabs");
            if (!data) return;
            if (e) {
                n = $.extend({}, data[e], s);
                idTabs.remove(data[e])
                idTabs(n.tabarea, n, n.data);
            } else for (e in data) {
                if (!Object.hasOwnProperty.call(data, e)) continue;
                n = $.extend({}, data[e], s);
                idTabs.remove(data[e]);
                idTabs(n.tabarea, n, n.data);
            }
        });
    };

    // Unbind idTabs
    idTabs.remove = function (s) {
        if (!s) return;
        var data, tabs, e = s.event;
        e = (e + "").indexOf('!') == 0 && e.substr(1) || e;
        e = "idTabs" + (e ? "." + e : "");
        return s.area.each(function () {
            data = $(this).data("idTabs");
            delete data["idTabs." + s.event];
            $(this).data("idTabs", data);
            tabs = s.tabs || $("a[href^=#]", this); //save tabs
            if (!tabs.length && $(this).is("a[href^=#]")) tabs = $(this);
            tabs.trigger(e);
        });
    };

    // Find tabs
    idTabs.find = function (e) {
        // Save self since clicked tab may not be the first tab in the tabarea
        var self = this, ret = false, s = e.data.s;
        // Find first tab within each tabset
        $("a[href=" + href(this) + "]:first", s.area).each(function () {
            var t = $(this).data(s.data); //tab's settings
            if (t) ret = idTabs.showtab.call(t.tabarea == s.tabarea ? self : this, t, e) || ret;
        });
        return ret;
    };

    // Show tab
    idTabs.showtab = function (s, e) {
        if (!s || !s.toggle && $(this).is('.' + s.selected))
            return s && s.change; //return if already selected
        var id = href(this); //find id
        if (s.click && s.click.call(this, id, s, e) == false) return s.change; //call custom func
        if (s.toggle && $(this).is('.' + s.selected)) id = null; //hide items
        return idTabs.show.call(this, id, s, e); //call default func
    };

    // Show item
    idTabs.show = function (id, s) {
        s.tabs.removeClass(s.selected); //clear tabs
        s.tab(id).addClass(s.selected); //select tab(s)
        s.items.hide(); //hide all items
        s.item(id).show(); //show item(s)
        return s.change; //option for changing url
    };

    // Unbind idTabs
    idTabs.unbind = function (e) {
        var s = e.data.s;
        $(this).removeData(s.data)
  .unbind("idTabs." + s.event);
        return false;
    };

    // Extend idTabs
    idTabs.extend = function () {
        var args = arguments;
        return function () {
            [ ].push.apply(args, arguments);
            this.idTabs.apply(this, args);
        };
    };

    // Matching tabs
    idTabs.tab = function (id) {
        if (!id) return $([]);
        return $("a[href=" + id + "]", this.tabarea);
    };

    // Matching items
    idTabs.item = function (id) {
        if (!id) return $([]);
        var item = $(id);
        return item.length ? item : $('.' + id.substr(1));
    };

    // Defaults
    idTabs.settings = {
        start: undefined,
        change: false,
        click: null,
        selected: ".selected",
        event: "!click",
        toggle: false,
        grouped: false
    };

    // Version
    idTabs.version = "3.0";

    // Auto-run
    $(function () { $(".idTabs").idTabs(); });

})(jQuery);



jQuery.fn.rater = function(url, options , callback)
{
	var settings = {
		url			: url ,
		maxvalue	: 3 ,
		curvalue	: 0 ,
		//title		: null ,
		enabled		: true
	};
	
	if(options) { jQuery.extend(settings, options); };
	jQuery.extend(settings, {cancel: (settings.maxvalue > 1) ? true : false});
	
	var container = jQuery(this);
	jQuery.extend(container, { averageRating: settings.curvalue, url: settings.url });

	var starWidth	= 25;
	var raterWidth	= settings.maxvalue * starWidth;
	var curvalueWidth	= settings.curvalue * starWidth;
	
	var title	= '';
	if (typeof settings.title == 'object' && typeof settings.title[settings.curvalue] == 'string') {
		title	= settings.title[settings.curvalue];
	} else {
		title	= settings.curvalue+'/'+settings.maxvalue;
	}
	
	var ratingParent	= '<ul class="rating" style="width:'+raterWidth+'px" title="'+title+'">';
	container.html(ratingParent);
	
	var listItems	= '<li class="current" style="width:'+curvalueWidth+'px"></li>';
	
	if (settings.enabled){
		for (var i = 1;i <= settings.maxvalue;i++) {
			
			if (typeof settings.title == 'object' && typeof settings.title[i] == 'string') {
				title	= settings.title[i];
			} else {
				title	= i+'/'+settings.maxvalue;
			}
			listItems	+= '<li class="star" style="width:'+i * starWidth+'px;z-index:'+(settings.maxvalue-i+1)+'" title="'+title+'"></li>';
		}
	}
	
	container.find('.rating').html(listItems);
	container.find('.rating').find('.star').hover(function() {
		container.find('.rating').find('.current').hide();
		this.className	= 'star_hover';
	} , function() {
		container.find('.rating').find('.current').show();
		this.className	= 'star';
	});
	
	container.find('.rating').find('.star').click(function() {
		var value	= settings.maxvalue - $(this).css('z-index') + 1;
		container.find('.rating').find('.current').width(starWidth * value);
		if (url) {
			$.post(url , {value:value} , function(response) {
				if (typeof callback == 'function') {
					callback(container , value , response);	
				}
			});
			return;
		}
		
		if (typeof callback == 'function') {
			callback(container , value);
			return ;
		}
		
	});
};

/*
 * jQuery corner plugin
 *
 * version 1.92 (12/18/2007)
 *
 * Dual licensed under the MIT and GPL licenses:
 *   http://www.opensource.org/licenses/mit-license.php
 *   http://www.gnu.org/licenses/gpl.html
 */

/**
 * The corner() method provides a simple way of styling DOM elements.  
 *
 * corner() takes a single string argument:  $().corner("effect corners width")
 *
 *   effect:  The name of the effect to apply, such as round or bevel. 
 *            If you don't specify an effect, rounding is used.
 *
 *   corners: The corners can be one or more of top, bottom, tr, tl, br, or bl. 
 *            By default, all four corners are adorned. 
 *
 *   width:   The width specifies the width of the effect; in the case of rounded corners this 
 *            will be the radius of the width. 
 *            Specify this value using the px suffix such as 10px, and yes it must be pixels.
 *
 * For more details see: http://methvin.com/jquery/jq-corner.html
 * For a full demo see:  http://malsup.com/jquery/corner/
 *
 *
 * @example $('.adorn').corner();
 * @desc Create round, 10px corners 
 *
 * @example $('.adorn').corner("25px");
 * @desc Create round, 25px corners 
 *
 * @example $('.adorn').corner("notch bottom");
 * @desc Create notched, 10px corners on bottom only
 *
 * @example $('.adorn').corner("tr dog 25px");
 * @desc Create dogeared, 25px corner on the top-right corner only
 *
 * @example $('.adorn').corner("round 8px").parent().css('padding', '4px').corner("round 10px");
 * @desc Create a rounded border effect by styling both the element and its parent
 * 
 * @name corner
 * @type jQuery
 * @param String options Options which control the corner style
 * @cat Plugins/Corner
 * @return jQuery
 * @author Dave Methvin (dave.methvin@gmail.com)
 * @author Mike Alsup (malsup@gmail.com)
 */
(function($) { 

$.fn.corner = function(o) {
    var ie6 = $.browser.msie && /MSIE 6.0/.test(navigator.userAgent);
    function sz(el, p) { return parseInt($.css(el,p))||0; };
    function hex2(s) {
        var s = parseInt(s).toString(16);
        return ( s.length < 2 ) ? '0'+s : s;
    };
    function gpc(node) {
        for ( ; node && node.nodeName.toLowerCase() != 'html'; node = node.parentNode ) {
            var v = $.css(node,'backgroundColor');
            if ( v.indexOf('rgb') >= 0 ) { 
                if ($.browser.safari && v == 'rgba(0, 0, 0, 0)')
                    continue;
                var rgb = v.match(/\d+/g); 
                return '#'+ hex2(rgb[0]) + hex2(rgb[1]) + hex2(rgb[2]);
            }
            if ( v && v != 'transparent' )
                return v;
        }
        return '#ffffff';
    };
    function getW(i) {
        switch(fx) {
        case 'round':  return Math.round(width*(1-Math.cos(Math.asin(i/width))));
        case 'cool':   return Math.round(width*(1+Math.cos(Math.asin(i/width))));
        case 'sharp':  return Math.round(width*(1-Math.cos(Math.acos(i/width))));
        case 'bite':   return Math.round(width*(Math.cos(Math.asin((width-i-1)/width))));
        case 'slide':  return Math.round(width*(Math.atan2(i,width/i)));
        case 'jut':    return Math.round(width*(Math.atan2(width,(width-i-1))));
        case 'curl':   return Math.round(width*(Math.atan(i)));
        case 'tear':   return Math.round(width*(Math.cos(i)));
        case 'wicked': return Math.round(width*(Math.tan(i)));
        case 'long':   return Math.round(width*(Math.sqrt(i)));
        case 'sculpt': return Math.round(width*(Math.log((width-i-1),width)));
        case 'dog':    return (i&1) ? (i+1) : width;
        case 'dog2':   return (i&2) ? (i+1) : width;
        case 'dog3':   return (i&3) ? (i+1) : width;
        case 'fray':   return (i%2)*width;
        case 'notch':  return width; 
        case 'bevel':  return i+1;
        }
    };
    o = (o||"").toLowerCase();
    var keep = /keep/.test(o);                       // keep borders?
    var cc = ((o.match(/cc:(#[0-9a-f]+)/)||[])[1]);  // corner color
    var sc = ((o.match(/sc:(#[0-9a-f]+)/)||[])[1]);  // strip color
    var width = parseInt((o.match(/(\d+)px/)||[])[1]) || 10; // corner width
    var re = /round|bevel|notch|bite|cool|sharp|slide|jut|curl|tear|fray|wicked|sculpt|long|dog3|dog2|dog/;
    var fx = ((o.match(re)||['round'])[0]);
    var edges = { T:0, B:1 };
    var opts = {
        TL:  /top|tl/.test(o),       TR:  /top|tr/.test(o),
        BL:  /bottom|bl/.test(o),    BR:  /bottom|br/.test(o)
    };
    if ( !opts.TL && !opts.TR && !opts.BL && !opts.BR )
        opts = { TL:1, TR:1, BL:1, BR:1 };
    var strip = document.createElement('div');
    strip.style.overflow = 'hidden';
    strip.style.height = '1px';
    strip.style.backgroundColor = sc || 'transparent';
    strip.style.borderStyle = 'solid';
    return this.each(function(index){
        var pad = {
            T: parseInt($.css(this,'paddingTop'))||0,     R: parseInt($.css(this,'paddingRight'))||0,
            B: parseInt($.css(this,'paddingBottom'))||0,  L: parseInt($.css(this,'paddingLeft'))||0
        };

        if ($.browser.msie) this.style.zoom = 1; // force 'hasLayout' in IE
        if (!keep) this.style.border = 'none';
        strip.style.borderColor = cc || gpc(this.parentNode);
        var cssHeight = $.curCSS(this, 'height');

        for (var j in edges) {
            var bot = edges[j];
            // only add stips if needed
            if ((bot && (opts.BL || opts.BR)) || (!bot && (opts.TL || opts.TR))) {
                strip.style.borderStyle = 'none '+(opts[j+'R']?'solid':'none')+' none '+(opts[j+'L']?'solid':'none');
                var d = document.createElement('div');
                $(d).addClass('jquery-corner');
                var ds = d.style;

                bot ? this.appendChild(d) : this.insertBefore(d, this.firstChild);

                if (bot && cssHeight != 'auto') {
                    if ($.css(this,'position') == 'static')
                        this.style.position = 'relative';
                    ds.position = 'absolute';
                    ds.bottom = ds.left = ds.padding = ds.margin = '0';
                    if ($.browser.msie)
                        ds.setExpression('width', 'this.parentNode.offsetWidth');
                    else
                        ds.width = '100%';
                }
                else if (!bot && $.browser.msie) {
                    if ($.css(this,'position') == 'static')
                        this.style.position = 'relative';
                    ds.position = 'absolute';
                    ds.top = ds.left = ds.right = ds.padding = ds.margin = '0';
                    
                    // fix ie6 problem when blocked element has a border width
                    var bw = 0;
                    if (ie6 || !$.boxModel)
                        bw = sz(this,'borderLeftWidth') + sz(this,'borderRightWidth');
                    ie6 ? ds.setExpression('width', 'this.parentNode.offsetWidth - '+bw+'+ "px"') : ds.width = '100%';
                }
                else {
                    ds.margin = !bot ? '-'+pad.T+'px -'+pad.R+'px '+(pad.T-width)+'px -'+pad.L+'px' : 
                                        (pad.B-width)+'px -'+pad.R+'px -'+pad.B+'px -'+pad.L+'px';                
                }

                for (var i=0; i < width; i++) {
                    var w = Math.max(0,getW(i));
                    var e = strip.cloneNode(false);
                    e.style.borderWidth = '0 '+(opts[j+'R']?w:0)+'px 0 '+(opts[j+'L']?w:0)+'px';
                    bot ? d.appendChild(e) : d.insertBefore(e, d.firstChild);
                }
            }
        }
    });
};

$.fn.uncorner = function(o) { return $('.jquery-corner', this).remove(); };
    
})(jQuery);


/* Copyright (c) 2007 Paul Bakaus (paul.bakaus@googlemail.com) and Brandon Aaron (brandon.aaron@gmail.com || http://brandonaaron.net)
 * Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php)
 * and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses.
 *
 * $LastChangedDate: 2007-08-17 13:14:11 -0500 (Fri, 17 Aug 2007) $
 * $Rev: 2759 $
 *
 * Version: 1.1.2
 *
 * Requires: jQuery 1.1.3+
 */

(function($){

// store a copy of the core height and width methods
var height = $.fn.height,
    width  = $.fn.width;

$.fn.extend({
	/**
	 * If used on document, returns the document's height (innerHeight).
	 * If used on window, returns the viewport's (window) height.
	 * See core docs on height() to see what happens when used on an element.
	 *
	 * @example $("#testdiv").height()
	 * @result 200
	 *
	 * @example $(document).height()
	 * @result 800
	 *
	 * @example $(window).height()
	 * @result 400
	 *
	 * @name height
	 * @type Number
	 * @cat Plugins/Dimensions
	 */
	height: function() {
		if ( !this[0] ) error();
		if ( this[0] == window )
			if ( $.browser.opera || ($.browser.safari && parseInt($.browser.version) > 520) )
				return self.innerHeight - (($(document).height() > self.innerHeight) ? getScrollbarWidth() : 0);
			else if ( $.browser.safari )
				return self.innerHeight;
			else
                return $.boxModel && document.documentElement.clientHeight || document.body.clientHeight;
		
		if ( this[0] == document ) 
			return Math.max( ($.boxModel && document.documentElement.scrollHeight || document.body.scrollHeight), document.body.offsetHeight );
		
		return height.apply(this, arguments);
	},
	
	/**
	 * If used on document, returns the document's width (innerWidth).
	 * If used on window, returns the viewport's (window) width.
	 * See core docs on width() to see what happens when used on an element.
	 *
	 * @example $("#testdiv").width()
	 * @result 200
	 *
	 * @example $(document).width()
	 * @result 800
	 *
	 * @example $(window).width()
	 * @result 400
	 *
	 * @name width
	 * @type Number
	 * @cat Plugins/Dimensions
	 */
	width: function() {
		if (!this[0]) error();
		if ( this[0] == window )
			if ( $.browser.opera || ($.browser.safari && parseInt($.browser.version) > 520) )
				return self.innerWidth - (($(document).width() > self.innerWidth) ? getScrollbarWidth() : 0);
			else if ( $.browser.safari )
				return self.innerWidth;
			else
                return $.boxModel && document.documentElement.clientWidth || document.body.clientWidth;

		if ( this[0] == document )
			if ($.browser.mozilla) {
				// mozilla reports scrollWidth and offsetWidth as the same
				var scrollLeft = self.pageXOffset;
				self.scrollTo(99999999, self.pageYOffset);
				var scrollWidth = self.pageXOffset;
				self.scrollTo(scrollLeft, self.pageYOffset);
				return document.body.offsetWidth + scrollWidth;
			}
			else 
				return Math.max( (($.boxModel && !$.browser.safari) && document.documentElement.scrollWidth || document.body.scrollWidth), document.body.offsetWidth );

		return width.apply(this, arguments);
	},
	
	/**
	 * Gets the inner height (excludes the border and includes the padding) for the first matched element.
	 * If used on document, returns the document's height (innerHeight).
	 * If used on window, returns the viewport's (window) height.
	 *
	 * @example $("#testdiv").innerHeight()
	 * @result 210
	 *
	 * @name innerHeight
	 * @type Number
	 * @cat Plugins/Dimensions
	 */
	innerHeight: function() {
		if (!this[0]) error();
		return this[0] == window || this[0] == document ?
			this.height() :
			this.is(':visible') ?
				this[0].offsetHeight - num(this, 'borderTopWidth') - num(this, 'borderBottomWidth') :
				this.height() + num(this, 'paddingTop') + num(this, 'paddingBottom');
	},
	
	/**
	 * Gets the inner width (excludes the border and includes the padding) for the first matched element.
	 * If used on document, returns the document's width (innerWidth).
	 * If used on window, returns the viewport's (window) width.
	 *
	 * @example $("#testdiv").innerWidth()
	 * @result 210
	 *
	 * @name innerWidth
	 * @type Number
	 * @cat Plugins/Dimensions
	 */
	innerWidth: function() {
		if (!this[0]) error();
		return this[0] == window || this[0] == document ?
			this.width() :
			this.is(':visible') ?
				this[0].offsetWidth - num(this, 'borderLeftWidth') - num(this, 'borderRightWidth') :
				this.width() + num(this, 'paddingLeft') + num(this, 'paddingRight');
	},
	
	/**
	 * Gets the outer height (includes the border and padding) for the first matched element.
	 * If used on document, returns the document's height (innerHeight).
	 * If used on window, returns the viewport's (window) height.
	 *
	 * The margin can be included in the calculation by passing an options map with margin
	 * set to true.
	 *
	 * @example $("#testdiv").outerHeight()
	 * @result 220
	 *
	 * @example $("#testdiv").outerHeight({ margin: true })
	 * @result 240
	 *
	 * @name outerHeight
	 * @type Number
	 * @param Map options Optional settings to configure the way the outer height is calculated.
	 * @cat Plugins/Dimensions
	 */
	outerHeight: function(options) {
		if (!this[0]) error();
		options = $.extend({ margin: false }, options || {});
		return this[0] == window || this[0] == document ?
			this.height() :
			this.is(':visible') ?
				this[0].offsetHeight + (options.margin ? (num(this, 'marginTop') + num(this, 'marginBottom')) : 0) :
				this.height() 
					+ num(this,'borderTopWidth') + num(this, 'borderBottomWidth') 
					+ num(this, 'paddingTop') + num(this, 'paddingBottom')
					+ (options.margin ? (num(this, 'marginTop') + num(this, 'marginBottom')) : 0);
	},
	
	/**
	 * Gets the outer width (including the border and padding) for the first matched element.
	 * If used on document, returns the document's width (innerWidth).
	 * If used on window, returns the viewport's (window) width.
	 *
	 * The margin can be included in the calculation by passing an options map with margin
	 * set to true.
	 *
	 * @example $("#testdiv").outerWidth()
	 * @result 1000
	 *
	 * @example $("#testdiv").outerWidth({ margin: true })
	 * @result 1020
	 * 
	 * @name outerHeight
	 * @type Number
	 * @param Map options Optional settings to configure the way the outer width is calculated.
	 * @cat Plugins/Dimensions
	 */
	outerWidth: function(options) {
		if (!this[0]) error();
		options = $.extend({ margin: false }, options || {});
		return this[0] == window || this[0] == document ?
			this.width() :
			this.is(':visible') ?
				this[0].offsetWidth + (options.margin ? (num(this, 'marginLeft') + num(this, 'marginRight')) : 0) :
				this.width() 
					+ num(this, 'borderLeftWidth') + num(this, 'borderRightWidth') 
					+ num(this, 'paddingLeft') + num(this, 'paddingRight')
					+ (options.margin ? (num(this, 'marginLeft') + num(this, 'marginRight')) : 0);
	},
	
	/**
	 * Gets how many pixels the user has scrolled to the right (scrollLeft).
	 * Works on containers with overflow: auto and window/document.
	 *
	 * @example $(window).scrollLeft()
	 * @result 100
	 *
	 * @example $(document).scrollLeft()
	 * @result 100
	 * 
	 * @example $("#testdiv").scrollLeft()
	 * @result 100
	 *
	 * @name scrollLeft
	 * @type Number
	 * @cat Plugins/Dimensions
	 */
	/**
	 * Sets the scrollLeft property for each element and continues the chain.
	 * Works on containers with overflow: auto and window/document.
	 *
	 * @example $(window).scrollLeft(100).scrollLeft()
	 * @result 100
	 * 
	 * @example $(document).scrollLeft(100).scrollLeft()
	 * @result 100
	 *
	 * @example $("#testdiv").scrollLeft(100).scrollLeft()
	 * @result 100
	 *
	 * @name scrollLeft
	 * @param Number value A positive number representing the desired scrollLeft.
	 * @type jQuery
	 * @cat Plugins/Dimensions
	 */
	scrollLeft: function(val) {
		if (!this[0]) error();
		if ( val != undefined )
			// set the scroll left
			return this.each(function() {
				if (this == window || this == document)
					window.scrollTo( val, $(window).scrollTop() );
				else
					this.scrollLeft = val;
			});
		
		// return the scroll left offest in pixels
		if ( this[0] == window || this[0] == document )
			return self.pageXOffset ||
				$.boxModel && document.documentElement.scrollLeft ||
				document.body.scrollLeft;
				
		return this[0].scrollLeft;
	},
	
	/**
	 * Gets how many pixels the user has scrolled to the bottom (scrollTop).
	 * Works on containers with overflow: auto and window/document.
	 *
	 * @example $(window).scrollTop()
	 * @result 100
	 *
	 * @example $(document).scrollTop()
	 * @result 100
	 * 
	 * @example $("#testdiv").scrollTop()
	 * @result 100
	 *
	 * @name scrollTop
	 * @type Number
	 * @cat Plugins/Dimensions
	 */
	/**
	 * Sets the scrollTop property for each element and continues the chain.
	 * Works on containers with overflow: auto and window/document.
	 *
	 * @example $(window).scrollTop(100).scrollTop()
	 * @result 100
	 * 
	 * @example $(document).scrollTop(100).scrollTop()
	 * @result 100
	 *
	 * @example $("#testdiv").scrollTop(100).scrollTop()
	 * @result 100
	 *
	 * @name scrollTop
	 * @param Number value A positive number representing the desired scrollTop.
	 * @type jQuery
	 * @cat Plugins/Dimensions
	 */
	scrollTop: function(val) {
		if (!this[0]) error();
		if ( val != undefined )
			// set the scroll top
			return this.each(function() {
				if (this == window || this == document)
					window.scrollTo( $(window).scrollLeft(), val );
				else
					this.scrollTop = val;
			});
		
		// return the scroll top offset in pixels
		if ( this[0] == window || this[0] == document )
			return self.pageYOffset ||
				$.boxModel && document.documentElement.scrollTop ||
				document.body.scrollTop;

		return this[0].scrollTop;
	},
	
	/** 
	 * Gets the top and left positioned offset in pixels.
	 * The positioned offset is the offset between a positioned
	 * parent and the element itself.
	 *
	 * For accurate calculations make sure to use pixel values for margins, borders and padding.
	 *
	 * @example $("#testdiv").position()
	 * @result { top: 100, left: 100 }
	 *
	 * @example var position = {};
	 * $("#testdiv").position(position)
	 * @result position = { top: 100, left: 100 }
	 * 
	 * @name position
	 * @param Object returnObject Optional An object to store the return value in, so as not to break the chain. If passed in the
	 *                            chain will not be broken and the result will be assigned to this object.
	 * @type Object
	 * @cat Plugins/Dimensions
	 */
	position: function(returnObject) {
		return this.offset({ margin: false, scroll: false, relativeTo: this.offsetParent() }, returnObject);
	},
	
	/**
	 * Gets the location of the element in pixels from the top left corner of the viewport.
	 * The offset method takes an optional map of key value pairs to configure the way
	 * the offset is calculated. Here are the different options.
	 *
	 * (Boolean) margin - Should the margin of the element be included in the calculations? True by default.
	 * (Boolean) border - Should the border of the element be included in the calculations? False by default. 
	 * (Boolean) padding - Should the padding of the element be included in the calculations? False by default. 
	 * (Boolean) scroll - Should the scroll offsets of the parent elements be included in the calculations? True by default.
	 *                    When true it adds the total scroll offsets of all parents to the total offset and also adds two
	 *                    properties to the returned object, scrollTop and scrollLeft.
	 * (Boolean) lite - When true it will use the offsetLite method instead of the full-blown, slower offset method. False by default.
	 *                  Only use this when margins, borders and padding calculations don't matter.
	 * (HTML Element) relativeTo - This should be a parent of the element and should have position (like absolute or relative).
	 *                             It will retreive the offset relative to this parent element. By default it is the body element.
	 *
	 * Also an object can be passed as the second paramater to
	 * catch the value of the return and continue the chain.
	 *
	 * For accurate calculations make sure to use pixel values for margins, borders and padding.
	 * 
	 * Known issues:
	 *  - Issue: A div positioned relative or static without any content before it and its parent will report an offsetTop of 0 in Safari
	 *    Workaround: Place content before the relative div ... and set height and width to 0 and overflow to hidden
	 *
	 * @example $("#testdiv").offset()
	 * @result { top: 100, left: 100, scrollTop: 10, scrollLeft: 10 }
	 *
	 * @example $("#testdiv").offset({ scroll: false })
	 * @result { top: 90, left: 90 }
	 *
	 * @example var offset = {}
	 * $("#testdiv").offset({ scroll: false }, offset)
	 * @result offset = { top: 90, left: 90 }
	 *
	 * @name offset
	 * @param Map options Optional settings to configure the way the offset is calculated.
	 * @param Object returnObject An object to store the return value in, so as not to break the chain. If passed in the
	 *                            chain will not be broken and the result will be assigned to this object.
	 * @type Object
	 * @cat Plugins/Dimensions
	 */
	offset: function(options, returnObject) {
		if (!this[0]) error();
		var x = 0, y = 0, sl = 0, st = 0,
		    elem = this[0], parent = this[0], op, parPos, elemPos = $.css(elem, 'position'),
		    mo = $.browser.mozilla, ie = $.browser.msie, oa = $.browser.opera,
		    sf = $.browser.safari, sf3 = $.browser.safari && parseInt($.browser.version) > 520,
		    absparent = false, relparent = false, 
		    options = $.extend({ margin: true, border: false, padding: false, scroll: true, lite: false, relativeTo: document.body }, options || {});
		
		// Use offsetLite if lite option is true
		if (options.lite) return this.offsetLite(options, returnObject);
		// Get the HTMLElement if relativeTo is a jquery collection
		if (options.relativeTo.jquery) options.relativeTo = options.relativeTo[0];
		
		if (elem.tagName == 'BODY') {
			// Safari 2 is the only one to get offsetLeft and offsetTop properties of the body "correct"
			// Except they all mess up when the body is positioned absolute or relative
			x = elem.offsetLeft;
			y = elem.offsetTop;
			// Mozilla ignores margin and subtracts border from body element
			if (mo) {
				x += num(elem, 'marginLeft') + (num(elem, 'borderLeftWidth')*2);
				y += num(elem, 'marginTop')  + (num(elem, 'borderTopWidth') *2);
			} else
			// Opera ignores margin
			if (oa) {
				x += num(elem, 'marginLeft');
				y += num(elem, 'marginTop');
			} else
			// IE does not add the border in Standards Mode
			if ((ie && jQuery.boxModel)) {
				x += num(elem, 'borderLeftWidth');
				y += num(elem, 'borderTopWidth');
			} else
			// Safari 3 doesn't not include border or margin
			if (sf3) {
				x += num(elem, 'marginLeft') + num(elem, 'borderLeftWidth');
				y += num(elem, 'marginTop')  + num(elem, 'borderTopWidth');
			}
		} else {
			do {
				parPos = $.css(parent, 'position');
			
				x += parent.offsetLeft;
				y += parent.offsetTop;

				// Mozilla and IE do not add the border
				// Mozilla adds the border for table cells
				if ((mo && !parent.tagName.match(/^t[d|h]$/i)) || ie || sf3) {
					// add borders to offset
					x += num(parent, 'borderLeftWidth');
					y += num(parent, 'borderTopWidth');

					// Mozilla does not include the border on body if an element isn't positioned absolute and is without an absolute parent
					if (mo && parPos == 'absolute') absparent = true;
					// IE does not include the border on the body if an element is position static and without an absolute or relative parent
					if (ie && parPos == 'relative') relparent = true;
				}

				op = parent.offsetParent || document.body;
				if (options.scroll || mo) {
					do {
						if (options.scroll) {
							// get scroll offsets
							sl += parent.scrollLeft;
							st += parent.scrollTop;
						}
						
						// Opera sometimes incorrectly reports scroll offset for elements with display set to table-row or inline
						if (oa && ($.css(parent, 'display') || '').match(/table-row|inline/)) {
							sl = sl - ((parent.scrollLeft == parent.offsetLeft) ? parent.scrollLeft : 0);
							st = st - ((parent.scrollTop == parent.offsetTop) ? parent.scrollTop : 0);
						}
				
						// Mozilla does not add the border for a parent that has overflow set to anything but visible
						if (mo && parent != elem && $.css(parent, 'overflow') != 'visible') {
							x += num(parent, 'borderLeftWidth');
							y += num(parent, 'borderTopWidth');
						}
				
						parent = parent.parentNode;
					} while (parent != op);
				}
				parent = op;
				
				// exit the loop if we are at the relativeTo option but not if it is the body or html tag
				if (parent == options.relativeTo && !(parent.tagName == 'BODY' || parent.tagName == 'HTML'))  {
					// Mozilla does not add the border for a parent that has overflow set to anything but visible
					if (mo && parent != elem && $.css(parent, 'overflow') != 'visible') {
						x += num(parent, 'borderLeftWidth');
						y += num(parent, 'borderTopWidth');
					}
					// Safari 2 and opera includes border on positioned parents
					if ( ((sf && !sf3) || oa) && parPos != 'static' ) {
						x -= num(op, 'borderLeftWidth');
						y -= num(op, 'borderTopWidth');
					}
					break;
				}
				if (parent.tagName == 'BODY' || parent.tagName == 'HTML') {
					// Safari 2 and IE Standards Mode doesn't add the body margin for elments positioned with static or relative
					if (((sf && !sf3) || (ie && $.boxModel)) && elemPos != 'absolute' && elemPos != 'fixed') {
						x += num(parent, 'marginLeft');
						y += num(parent, 'marginTop');
					}
					// Safari 3 does not include the border on body
					// Mozilla does not include the border on body if an element isn't positioned absolute and is without an absolute parent
					// IE does not include the border on the body if an element is positioned static and without an absolute or relative parent
					if ( sf3 || (mo && !absparent && elemPos != 'fixed') || 
					     (ie && elemPos == 'static' && !relparent) ) {
						x += num(parent, 'borderLeftWidth');
						y += num(parent, 'borderTopWidth');
					}
					break; // Exit the loop
				}
			} while (parent);
		}

		var returnValue = handleOffsetReturn(elem, options, x, y, sl, st);

		if (returnObject) { $.extend(returnObject, returnValue); return this; }
		else              { return returnValue; }
	},
	
	/**
	 * Gets the location of the element in pixels from the top left corner of the viewport.
	 * This method is much faster than offset but not as accurate when borders and margins are
	 * on the element and/or its parents. This method can be invoked
	 * by setting the lite option to true in the offset method.
	 * The offsetLite method takes an optional map of key value pairs to configure the way
	 * the offset is calculated. Here are the different options.
	 *
	 * (Boolean) margin - Should the margin of the element be included in the calculations? True by default.
	 * (Boolean) border - Should the border of the element be included in the calculations? False by default. 
	 * (Boolean) padding - Should the padding of the element be included in the calcuations? False by default. 
	 * (Boolean) scroll - Sould the scroll offsets of the parent elements be included int he calculations? True by default.
	 *                    When true it adds the total scroll offsets of all parents to the total offset and also adds two
	 *                    properties to the returned object, scrollTop and scrollLeft.
	 * (HTML Element) relativeTo - This should be a parent of the element and should have position (like absolute or relative).
	 *                             It will retreive the offset relative to this parent element. By default it is the body element.
	 *
	 * @name offsetLite
	 * @param Map options Optional settings to configure the way the offset is calculated.
	 * @param Object returnObject An object to store the return value in, so as not to break the chain. If passed in the
	 *                            chain will not be broken and the result will be assigned to this object.
	 * @type Object
	 * @cat Plugins/Dimensions
	 */
	offsetLite: function(options, returnObject) {
		if (!this[0]) error();
		var x = 0, y = 0, sl = 0, st = 0, parent = this[0], offsetParent, 
		    options = $.extend({ margin: true, border: false, padding: false, scroll: true, relativeTo: document.body }, options || {});
				
		// Get the HTMLElement if relativeTo is a jquery collection
		if (options.relativeTo.jquery) options.relativeTo = options.relativeTo[0];
		
		do {
			x += parent.offsetLeft;
			y += parent.offsetTop;

			offsetParent = parent.offsetParent || document.body;
			if (options.scroll) {
				// get scroll offsets
				do {
					sl += parent.scrollLeft;
					st += parent.scrollTop;
					parent = parent.parentNode;
				} while(parent != offsetParent);
			}
			parent = offsetParent;
		} while (parent && parent.tagName != 'BODY' && parent.tagName != 'HTML' && parent != options.relativeTo);

		var returnValue = handleOffsetReturn(this[0], options, x, y, sl, st);

		if (returnObject) { $.extend(returnObject, returnValue); return this; }
		else              { return returnValue; }
	},
	
	/**
	 * Returns a jQuery collection with the positioned parent of 
	 * the first matched element. This is the first parent of 
	 * the element that has position (as in relative or absolute).
	 *
	 * @name offsetParent
	 * @type jQuery
	 * @cat Plugins/Dimensions
	 */
	offsetParent: function() {
		if (!this[0]) error();
		var offsetParent = this[0].offsetParent;
		while ( offsetParent && (offsetParent.tagName != 'BODY' && $.css(offsetParent, 'position') == 'static') )
			offsetParent = offsetParent.offsetParent;
		return $(offsetParent);
	}
});

/**
 * Throws an error message when no elements are in the jQuery collection
 * @private
 */
var error = function() {
	throw "Dimensions: jQuery collection is empty";
};

/**
 * Handles converting a CSS Style into an Integer.
 * @private
 */
var num = function(el, prop) {
	return parseInt($.css(el.jquery?el[0]:el,prop))||0;
};

/**
 * Handles the return value of the offset and offsetLite methods.
 * @private
 */
var handleOffsetReturn = function(elem, options, x, y, sl, st) {
	if ( !options.margin ) {
		x -= num(elem, 'marginLeft');
		y -= num(elem, 'marginTop');
	}

	// Safari and Opera do not add the border for the element
	if ( options.border && (($.browser.safari && parseInt($.browser.version) < 520) || $.browser.opera) ) {
		x += num(elem, 'borderLeftWidth');
		y += num(elem, 'borderTopWidth');
	} else if ( !options.border && !(($.browser.safari && parseInt($.browser.version) < 520) || $.browser.opera) ) {
		x -= num(elem, 'borderLeftWidth');
		y -= num(elem, 'borderTopWidth');
	}

	if ( options.padding ) {
		x += num(elem, 'paddingLeft');
		y += num(elem, 'paddingTop');
	}
	
	// do not include scroll offset on the element ... opera sometimes reports scroll offset as actual offset
	if ( options.scroll && (!$.browser.opera || elem.offsetLeft != elem.scrollLeft && elem.offsetTop != elem.scrollLeft) ) {
		sl -= elem.scrollLeft;
		st -= elem.scrollTop;
	}

	return options.scroll ? { top: y - st, left: x - sl, scrollTop:  st, scrollLeft: sl }
	                      : { top: y, left: x };
};

/**
 * Gets the width of the OS scrollbar
 * @private
 */
var scrollbarWidth = 0;
var getScrollbarWidth = function() {
	if (!scrollbarWidth) {
		var testEl = $('<div>')
				.css({
					width: 100,
					height: 100,
					overflow: 'auto',
					position: 'absolute',
					top: -1000,
					left: -1000
				})
				.appendTo('body');
		scrollbarWidth = 100 - testEl
			.append('<div>')
			.find('div')
				.css({
					width: '100%',
					height: 200
				})
				.width();
		testEl.remove();
	}
	return scrollbarWidth;
};

})(jQuery);




/* Copyright (c) 2006 Brandon Aaron (http://brandonaaron.net)
 * Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php) 
 * and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses.
 *
 * $LastChangedDate: 2007-06-19 20:23:36 -0500 (Tue, 19 Jun 2007) $
 * $Rev: 2110 $
 *
 * Version 2.1
 */

(function($){

/**
 * The bgiframe is chainable and applies the iframe hack to get 
 * around zIndex issues in IE6. It will only apply itself in IE 
 * and adds a class to the iframe called 'bgiframe'. The iframe
 * is appeneded as the first child of the matched element(s) 
 * with a tabIndex and zIndex of -1.
 * 
 * By default the plugin will take borders, sized with pixel units,
 * into account. If a different unit is used for the border's width,
 * then you will need to use the top and left settings as explained below.
 *
 * NOTICE: This plugin has been reported to cause perfromance problems
 * when used on elements that change properties (like width, height and
 * opacity) a lot in IE6. Most of these problems have been caused by 
 * the expressions used to calculate the elements width, height and 
 * borders. Some have reported it is due to the opacity filter. All 
 * these settings can be changed if needed as explained below.
 *
 * @example $('div').bgiframe();
 * @before <div><p>Paragraph</p></div>
 * @result <div><iframe class="bgiframe".../><p>Paragraph</p></div>
 *
 * @param Map settings Optional settings to configure the iframe.
 * @option String|Number top The iframe must be offset to the top
 * 		by the width of the top border. This should be a negative 
 *      number representing the border-top-width. If a number is 
 * 		is used here, pixels will be assumed. Otherwise, be sure
 *		to specify a unit. An expression could also be used. 
 * 		By default the value is "auto" which will use an expression 
 * 		to get the border-top-width if it is in pixels.
 * @option String|Number left The iframe must be offset to the left
 * 		by the width of the left border. This should be a negative 
 *      number representing the border-left-width. If a number is 
 * 		is used here, pixels will be assumed. Otherwise, be sure
 *		to specify a unit. An expression could also be used. 
 * 		By default the value is "auto" which will use an expression 
 * 		to get the border-left-width if it is in pixels.
 * @option String|Number width This is the width of the iframe. If
 *		a number is used here, pixels will be assume. Otherwise, be sure
 * 		to specify a unit. An experssion could also be used.
 *		By default the value is "auto" which will use an experssion
 * 		to get the offsetWidth.
 * @option String|Number height This is the height of the iframe. If
 *		a number is used here, pixels will be assume. Otherwise, be sure
 * 		to specify a unit. An experssion could also be used.
 *		By default the value is "auto" which will use an experssion
 * 		to get the offsetHeight.
 * @option Boolean opacity This is a boolean representing whether or not
 * 		to use opacity. If set to true, the opacity of 0 is applied. If
 *		set to false, the opacity filter is not applied. Default: true.
 * @option String src This setting is provided so that one could change 
 *		the src of the iframe to whatever they need.
 *		Default: "javascript:false;"
 *
 * @name bgiframe
 * @type jQuery
 * @cat Plugins/bgiframe
 * @author Brandon Aaron (brandon.aaron@gmail.com || http://brandonaaron.net)
 */
$.fn.bgIframe = $.fn.bgiframe = function(s) {
    // This is only for IE6
    if ($.browser.msie) {
        s = $.extend({
            top: 'auto', // auto == .currentStyle.borderTopWidth
            left: 'auto', // auto == .currentStyle.borderLeftWidth
            width: 'auto', // auto == offsetWidth
            height: 'auto', // auto == offsetHeight
            opacity: true,
            src: 'javascript:false;'
        }, s || {});
        var prop = function(n) { return n && n.constructor == Number ? n + 'px' : n; },
		    html = '<iframe class="bgiframe"frameborder="0"tabindex="-1"src="' + s.src + '"' +
		               'style="display:block;position:absolute;z-index:-1;' +
			               (s.opacity !== false ? 'filter:Alpha(Opacity=\'0\');' : '') +
					       'top:' + (s.top == 'auto' ? 'expression(((parseInt(this.parentNode.currentStyle.borderTopWidth)||0)*-1)+\'px\')' : prop(s.top)) + ';' +
					       'left:' + (s.left == 'auto' ? 'expression(((parseInt(this.parentNode.currentStyle.borderLeftWidth)||0)*-1)+\'px\')' : prop(s.left)) + ';' +
					       'width:' + (s.width == 'auto' ? 'expression(this.parentNode.offsetWidth+\'px\')' : prop(s.width)) + ';' +
					       'height:' + (s.height == 'auto' ? 'expression(this.parentNode.offsetHeight+\'px\')' : prop(s.height)) + ';' +
					'"/>';
        return this.each(function() {
            if ($('> iframe.bgiframe', this).length == 0)
                this.insertBefore(document.createElement(html), this.firstChild);
        });
    }
    return this;
};

})(jQuery);


/**
* jTemplates 0.7.8 (http://jtemplates.tpython.com)
* Copyright (c) 2007-2009 Tomasz Gloc (http://www.tpython.com)
* 
* Dual licensed under the MIT (MIT-LICENSE.txt)
* and/or GPL (GPL-LICENSE.txt) licenses.
*
* Id: $Id: jquery-jtemplates_uncompressed.js 177 2009-04-02 17:36:36Z tom $
*/

/**
* @fileOverview Template engine in JavaScript.
* @name jTemplates
* @author Tomasz Gloc
* @date $Date: 2009-04-02 19:36:36 +0200 (Cz, 02 kwi 2009) $
*/


if (window.jQuery && !window.jQuery.createTemplate) {
    (function (jQuery) {

        /**
        * [abstract]
        * @name BaseNode
        * @class Abstract node. [abstract]
        */

        /**
        * Process node and get the html string. [abstract]
        * @name get
        * @function
        * @param {object} d data
        * @param {object} param parameters
        * @param {Element} element a HTML element
        * @param {Number} deep
        * @return {String}
        * @memberOf BaseNode
        */

        /**
        * [abstract]
        * @name BaseArray
        * @augments BaseNode
        * @class Abstract array/collection. [abstract]
        */

        /**
        * Add node 'e' to array.
        * @name push
        * @function
        * @param {BaseNode} e a node
        * @memberOf BaseArray
        */

        /**
        * See (http://jquery.com/).
        * @name jQuery
        * @class jQuery Library (http://jquery.com/)
        */

        /**
        * See (http://jquery.com/)
        * @name fn
        * @class jQuery Library (http://jquery.com/)
        * @memberOf jQuery
        */


        /**
        * Create new template from string s.
        * @name Template
        * @class A template or multitemplate.
        * @param {string} s A template string (like: "Text: {$T.txt}.").
        * @param {array} [includes] Array of included templates.
        * @param {object} [settings] Settings.
        * @config {boolean} [disallow_functions] Do not allow use function in data (default: true).
        * @config {boolean} [filter_data] Enable filter data using escapeHTML (default: true).
        * @config {boolean} [filter_params] Enable filter parameters using escapeHTML (default: false).
        * @config {boolean} [runnable_functions] Automatically run function (from data) inside {} [default: false].
        * @config {boolean} [clone_data] Clone input data [default: true]
        * @config {boolean} [clone_params] Clone input parameters [default: true]
        * @config {Function} [f_cloneData] Function using to data cloning
        * @config {Function} [f_escapeString] Function using to escape strings
        * @augments BaseNode
        */
        var Template = function (s, includes, settings) {
            this._tree = [];
            this._param = {};
            this._includes = null;
            this._templates = {};
            this._templates_code = {};

            this.settings = jQuery.extend({
                disallow_functions: false,
                filter_data: true,
                filter_params: false,
                runnable_functions: false,
                clone_data: true,
                clone_params: true
            }, settings);

            this.f_cloneData = (this.settings.f_cloneData !== undefined) ? (this.settings.f_cloneData) : (TemplateUtils.cloneData);
            this.f_escapeString = (this.settings.f_escapeString !== undefined) ? (this.settings.f_escapeString) : (TemplateUtils.escapeHTML);

            this.splitTemplates(s, includes);

            if (s) {
                this.setTemplate(this._templates_code['MAIN'], includes, this.settings);
            }

            this._templates_code = null;
        };

        /**
        * jTemplates version
        * @type string
        */
        Template.prototype.version = '0.7.8';

        /**
        * Debug mode (all errors are on), default: on
        * @type Boolean
        */
        Template.DEBUG_MODE = true;

        /**
        * Split multitemplate into multiple templates.
        * @param {string} s A template string (like: "Text: {$T.txt}.").
        * @param {array} includes Array of included templates.
        */
        Template.prototype.splitTemplates = function (s, includes) {
            var reg = /\{#template *(\w*?)( .*)*\}/g;
            var iter, tname, se;
            var lastIndex = null;

            var _template_settings = [];

            while ((iter = reg.exec(s)) != null) {
                lastIndex = reg.lastIndex;
                tname = iter[1];
                se = s.indexOf('{#/template ' + tname + '}', lastIndex);
                if (se == -1) {
                    throw new Error('jTemplates: Template "' + tname + '" is not closed.');
                }
                this._templates_code[tname] = s.substring(lastIndex, se);
                _template_settings[tname] = TemplateUtils.optionToObject(iter[2]);
            }
            if (lastIndex === null) {
                this._templates_code['MAIN'] = s;
                return;
            }

            for (var i in this._templates_code) {
                if (i != 'MAIN') {
                    this._templates[i] = new Template();
                }
            }
            for (var i in this._templates_code) {
                if (i != 'MAIN') {
                    this._templates[i].setTemplate(this._templates_code[i], jQuery.extend({}, includes || {}, this._templates || {}), jQuery.extend({}, this.settings, _template_settings[i]));
                    this._templates_code[i] = null;
                }
            }
        };

        /**
        * Parse template. (should be template, not multitemplate).
        * @param {string} s A template string (like: "Text: {$T.txt}.").
        * @param {array} includes Array of included templates.
        */
        Template.prototype.setTemplate = function (s, includes, settings) {
            if (s == undefined) {
                this._tree.push(new TextNode('', 1, this));
                return;
            }
            s = s.replace(/[\n\r]/g, '');
            s = s.replace(/\{\*.*?\*\}/g, '');
            this._includes = jQuery.extend({}, this._templates || {}, includes || {});
            this.settings = new Object(settings);
            var node = this._tree;
            var op = s.match(/\{#.*?\}/g);
            var ss = 0, se = 0;
            var e;
            var literalMode = 0;
            var elseif_level = 0;

            for (var i = 0, l = (op) ? (op.length) : (0); i < l; ++i) {
                var this_op = op[i];

                if (literalMode) {
                    se = s.indexOf('{#/literal}');
                    if (se == -1) {
                        throw new Error("jTemplates: No end of literal.");
                    }
                    if (se > ss) {
                        node.push(new TextNode(s.substring(ss, se), 1, this));
                    }
                    ss = se + 11;
                    literalMode = 0;
                    i = jQuery.inArray('{#/literal}', op);
                    continue;
                }
                se = s.indexOf(this_op, ss);
                if (se > ss) {
                    node.push(new TextNode(s.substring(ss, se), literalMode, this));
                }
                var ppp = this_op.match(/\{#([\w\/]+).*?\}/);
                var op_ = RegExp.$1;
                switch (op_) {
                    case 'elseif':
                        ++elseif_level;
                        node.switchToElse();
                        //no break
                    case 'if':
                        e = new opIF(this_op, node);
                        node.push(e);
                        node = e;
                        break;
                    case 'else':
                        node.switchToElse();
                        break;
                    case '/if':
                        while (elseif_level) {
                            node = node.getParent();
                            --elseif_level;
                        }
                        //no break
                    case '/for':
                    case '/foreach':
                        node = node.getParent();
                        break;
                    case 'foreach':
                        e = new opFOREACH(this_op, node, this);
                        node.push(e);
                        node = e;
                        break;
                    case 'for':
                        e = opFORFactory(this_op, node, this);
                        node.push(e);
                        node = e;
                        break;
                    case 'continue':
                    case 'break':
                        node.push(new JTException(op_));
                        break;
                    case 'include':
                        node.push(new Include(this_op, this._includes));
                        break;
                    case 'param':
                        node.push(new UserParam(this_op));
                        break;
                    case 'cycle':
                        node.push(new Cycle(this_op));
                        break;
                    case 'ldelim':
                        node.push(new TextNode('{', 1, this));
                        break;
                    case 'rdelim':
                        node.push(new TextNode('}', 1, this));
                        break;
                    case 'literal':
                        literalMode = 1;
                        break;
                    case '/literal':
                        if (Template.DEBUG_MODE) {
                            throw new Error("jTemplates: Missing begin of literal.");
                        }
                        break;
                    default:
                        if (Template.DEBUG_MODE) {
                            throw new Error('jTemplates: unknown tag: ' + op_ + '.');
                        }
                }

                ss = se + this_op.length;
            }

            if (s.length > ss) {
                node.push(new TextNode(s.substr(ss), literalMode, this));
            }
        };

        /**
        * Process template and get the html string.
        * @param {object} d data
        * @param {object} param parameters
        * @param {Element} element a HTML element
        * @param {Number} deep
        * @return {String}
        */
        Template.prototype.get = function (d, param, element, deep) {
            ++deep;

            var $T = d, _param1, _param2;

            if (this.settings.clone_data) {
                $T = this.f_cloneData(d, { escapeData: (this.settings.filter_data && deep == 1), noFunc: this.settings.disallow_functions }, this.f_escapeString);
            }

            if (!this.settings.clone_params) {
                _param1 = this._param;
                _param2 = param;
            } else {
                _param1 = this.f_cloneData(this._param, { escapeData: (this.settings.filter_params), noFunc: false }, this.f_escapeString);
                _param2 = this.f_cloneData(param, { escapeData: (this.settings.filter_params && deep == 1), noFunc: false }, this.f_escapeString);
            }
            var $P = jQuery.extend({}, _param1, _param2);

            var $Q = (element != undefined) ? (element) : ({});
            $Q.version = this.version;

            var ret = '';
            for (var i = 0, l = this._tree.length; i < l; ++i) {
                ret += this._tree[i].get($T, $P, $Q, deep);
            }

            --deep;
            return ret;
        };

        /**
        * Set to parameter 'name' value 'value'.
        * @param {string} name
        * @param {object} value
        */
        Template.prototype.setParam = function (name, value) {
            this._param[name] = value;
        };


        /**
        * Template utilities.
        * @namespace Template utilities.
        */
        TemplateUtils = function () {
        };

        /**
        * Replace chars &, >, <, ", ' with html entities.
        * To disable function set settings: filter_data=false, filter_params=false
        * @param {string} string
        * @return {string}
        * @static
        * @memberOf TemplateUtils
        */
        TemplateUtils.escapeHTML = function (txt) {
            return txt.replace(/&/g, '&amp;').replace(/>/g, '&gt;').replace(/</g, '&lt;').replace(/"/g, '&quot;').replace(/'/g, '&#39;');
        };

        /**
        * Make a copy od data 'd'. It also filters data (depend on 'filter').
        * @param {object} d input data
        * @param {object} filter a filters
        * @config {boolean} [escapeData] Use escapeHTML on every string.
        * @config {boolean} [noFunc] Do not allow to use function (throws exception).
        * @param {Function} f_escapeString function using to filter string (usually: TemplateUtils.escapeHTML)
        * @return {object} output data (filtered)
        * @static
        * @memberOf TemplateUtils
        */
        TemplateUtils.cloneData = function (d, filter, f_escapeString) {
            if (d == null) {
                return d;
            }
            switch (d.constructor) {
                case Object:
                    var o = {};
                    for (var i in d) {
                        o[i] = TemplateUtils.cloneData(d[i], filter, f_escapeString);
                    }
                    if (!filter.noFunc) {
                        if (d.hasOwnProperty("toString"))
                            o.toString = d.toString;
                    }
                    return o;
                case Array:
                    var o = [];
                    for (var i = 0, l = d.length; i < l; ++i) {
                        o[i] = TemplateUtils.cloneData(d[i], filter, f_escapeString);
                    }
                    return o;
                case String:
                    return (filter.escapeData) ? (f_escapeString(d)) : (d);
                case Function:
                    if (filter.noFunc) {
                        if (Template.DEBUG_MODE)
                            throw new Error("jTemplates: Functions are not allowed.");
                        else
                            return undefined;
                    }
                    //no break
                default:
                    return d;
            }
        };

        /**
        * Convert text-based option string to Object
        * @param {string} optionText text-based option string
        * @return {Object}
        * @static
        * @memberOf TemplateUtils
        */
        TemplateUtils.optionToObject = function (optionText) {
            if (optionText === null || optionText === undefined) {
                return {};
            }

            var o = optionText.split(/[= ]/);
            if (o[0] === '') {
                o.shift();
            }

            var obj = {};
            for (var i = 0, l = o.length; i < l; i += 2) {
                obj[o[i]] = o[i + 1];
            }

            return obj;
        };


        /**
        * Create a new text node.
        * @name TextNode
        * @class All text (block {..}) between control's block "{#..}".
        * @param {string} val text string
        * @param {boolean} literalMode When enable (true) template does not process blocks {..}.
        * @param {Template} Template object
        * @augments BaseNode
        */
        var TextNode = function (val, literalMode, template) {
            this._value = val;
            this._literalMode = literalMode;
            this._template = template;
        };

        /**
        * Get the html string for a text node.
        * @param {object} d data
        * @param {object} param parameters
        * @param {Element} element a HTML element
        * @param {Number} deep
        * @return {String}
        */
        TextNode.prototype.get = function (d, param, element, deep) {
            var __t = this._value;
            if (!this._literalMode) {
                var __template = this._template;
                var $T = d;
                var $P = param;
                var $Q = element;
                __t = __t.replace(/\{(.*?)\}/g, function (__0, __1) {
                    try {
                        var __tmp = eval(__1);
                        if (typeof __tmp == 'function') {
                            if (__template.settings.disallow_functions || !__template.settings.runnable_functions) {
                                return '';
                            } else {
                                __tmp = __tmp($T, $P, $Q);
                            }
                        }
                        return (__tmp === undefined) ? ("") : (String(__tmp));
                    } catch (e) {
                        if (Template.DEBUG_MODE) {
                            if (e instanceof JTException)
                                e.type = "subtemplate";
                            throw e;
                        }
                        return "";
                    }
                });
            }
            return __t;
        };

        /**
        * Create a new conditional node.
        * @name opIF
        * @class A class represent: {#if}.
        * @param {string} oper content of operator {#..}
        * @param {object} par parent node
        * @augments BaseArray
        */
        var opIF = function (oper, par) {
            this._parent = par;
            oper.match(/\{#(?:else)*if (.*?)\}/);
            this._cond = RegExp.$1;
            this._onTrue = [];
            this._onFalse = [];
            this._currentState = this._onTrue;
        };

        /**
        * Add node 'e' to array.
        * @param {BaseNode} e a node
        */
        opIF.prototype.push = function (e) {
            this._currentState.push(e);
        };

        /**
        * Get a parent node.
        * @return {BaseNode}
        */
        opIF.prototype.getParent = function () {
            return this._parent;
        };

        /**
        * Switch from collection onTrue to onFalse.
        */
        opIF.prototype.switchToElse = function () {
            this._currentState = this._onFalse;
        };

        /**
        * Process node depend on conditional and get the html string.
        * @param {object} d data
        * @param {object} param parameters
        * @param {Element} element a HTML element
        * @param {Number} deep
        * @return {String}
        */
        opIF.prototype.get = function (d, param, element, deep) {
            var $T = d;
            var $P = param;
            var $Q = element;
            var ret = '';

            try {
                var tab = (eval(this._cond)) ? (this._onTrue) : (this._onFalse);
                for (var i = 0, l = tab.length; i < l; ++i) {
                    ret += tab[i].get(d, param, element, deep);
                }
            } catch (e) {
                if (Template.DEBUG_MODE || (e instanceof JTException))
                    throw e;
            }
            return ret;
        };

        /**
        * Handler for a tag 'FOR'. Create new and return relative opFOREACH object.
        * @name opFORFactory
        * @class Handler for a tag 'FOR'. Create new and return relative opFOREACH object.
        * @param {string} oper content of operator {#..}
        * @param {object} par parent node
        * @param {Template} template a pointer to Template object
        * @return {opFOREACH}
        */
        opFORFactory = function (oper, par, template) {
            if (oper.match(/\{#for (\w+?) *= *(\S+?) +to +(\S+?) *(?:step=(\S+?))*\}/)) {
                oper = '{#foreach opFORFactory.funcIterator as ' + RegExp.$1 + ' begin=' + (RegExp.$2 || 0) + ' end=' + (RegExp.$3 || -1) + ' step=' + (RegExp.$4 || 1) + ' extData=$T}';
                return new opFOREACH(oper, par, template);
            } else {
                throw new Error('jTemplates: Operator failed "find": ' + oper);
            }
        };

        /**
        * Function returns inputs data (using internal with opFORFactory)
        * @param {object} i any data
        * @return {object} any data (equal parameter 'i')
        * @private
        * @static
        */
        opFORFactory.funcIterator = function (i) {
            return i;
        };

        /**
        * Create a new loop node.
        * @name opFOREACH
        * @class A class represent: {#foreach}.
        * @param {string} oper content of operator {#..}
        * @param {object} par parent node
        * @param {Template} template a pointer to Template object
        * @augments BaseArray
        */
        var opFOREACH = function (oper, par, template) {
            this._parent = par;
            this._template = template;
            oper.match(/\{#foreach (.+?) as (\w+?)( .+)*\}/);
            this._arg = RegExp.$1;
            this._name = RegExp.$2;
            this._option = RegExp.$3 || null;
            this._option = TemplateUtils.optionToObject(this._option);

            this._onTrue = [];
            this._onFalse = [];
            this._currentState = this._onTrue;
        };

        /**
        * Add node 'e' to array.
        * @param {BaseNode} e
        */
        opFOREACH.prototype.push = function (e) {
            this._currentState.push(e);
        };

        /**
        * Get a parent node.
        * @return {BaseNode}
        */
        opFOREACH.prototype.getParent = function () {
            return this._parent;
        };

        /**
        * Switch from collection onTrue to onFalse.
        */
        opFOREACH.prototype.switchToElse = function () {
            this._currentState = this._onFalse;
        };

        /**
        * Process loop and get the html string.
        * @param {object} d data
        * @param {object} param parameters
        * @param {Element} element a HTML element
        * @param {Number} deep
        * @return {String}
        */
        opFOREACH.prototype.get = function (d, param, element, deep) {
            try {
                var $T = d;
                var $P = param;
                var $Q = element;
                var fcount = eval(this._arg); //array of elements in foreach
                var key = []; //only for objects
                var mode = typeof fcount;
                if (mode == 'object') {
                    var arr = [];
                    jQuery.each(fcount, function (k, v) {
                        key.push(k);
                        arr.push(v);
                    });
                    fcount = arr;
                }
                var extData = (this._option.extData !== undefined) ? (eval(this._option.extData)) : (($T != null) ? ($T) : ({}));
                var s = Number(eval(this._option.begin) || 0), e; //start, end
                var step = Number(eval(this._option.step) || 1);
                if (mode != 'function') {
                    e = fcount.length;
                } else {
                    if (this._option.end === undefined || this._option.end === null) {
                        e = Number.MAX_VALUE;
                    } else {
                        e = Number(eval(this._option.end)) + ((step > 0) ? (1) : (-1));
                    }
                }
                var ret = ''; //returned string
                var i, l; //iterators

                if (this._option.count) {
                    var tmp = s + Number(eval(this._option.count));
                    e = (tmp > e) ? (e) : (tmp);
                }
                if ((e > s && step > 0) || (e < s && step < 0)) {
                    var iteration = 0;
                    var _total = (mode != 'function') ? (Math.ceil((e - s) / step)) : undefined;
                    var ckey, cval; //current key, current value
                    for (; ((step > 0) ? (s < e) : (s > e)); s += step, ++iteration) {
                        ckey = key[s];
                        if (mode != 'function') {
                            cval = fcount[s];
                        } else {
                            cval = fcount(s);
                            if (cval === undefined || cval === null) {
                                break;
                            }
                        }
                        if ((typeof cval == 'function') && (this._template.settings.disallow_functions || !this._template.settings.runnable_functions)) {
                            continue;
                        }
                        if ((mode == 'object') && (ckey in Object)) {
                            continue;
                        }
                        var prevValue = extData[this._name];
                        extData[this._name] = cval;
                        extData[this._name + '$index'] = s;
                        extData[this._name + '$iteration'] = iteration;
                        extData[this._name + '$first'] = (iteration == 0);
                        extData[this._name + '$last'] = (s + step >= e);
                        extData[this._name + '$total'] = _total;
                        extData[this._name + '$key'] = (ckey !== undefined && ckey.constructor == String) ? (this._template.f_escapeString(ckey)) : (ckey);
                        extData[this._name + '$typeof'] = typeof cval;
                        for (i = 0, l = this._onTrue.length; i < l; ++i) {
                            try {
                                ret += this._onTrue[i].get(extData, param, element, deep);
                            } catch (ex) {
                                if (ex instanceof JTException) {
                                    switch (ex.type) {
                                        case 'continue':
                                            i = l;
                                            break;
                                        case 'break':
                                            i = l;
                                            s = e;
                                            break;
                                        default:
                                            throw e;
                                    }
                                } else {
                                    throw e;
                                }
                            }
                        }
                        delete extData[this._name + '$index'];
                        delete extData[this._name + '$iteration'];
                        delete extData[this._name + '$first'];
                        delete extData[this._name + '$last'];
                        delete extData[this._name + '$total'];
                        delete extData[this._name + '$key'];
                        delete extData[this._name + '$typeof'];
                        delete extData[this._name];
                        extData[this._name] = prevValue;
                    }
                } else {
                    for (i = 0, l = this._onFalse.length; i < l; ++i) {
                        ret += this._onFalse[i].get($T, param, element, deep);
                    }
                }
                return ret;
            } catch (e) {
                if (Template.DEBUG_MODE || (e instanceof JTException))
                    throw e;
                return "";
            }
        };

        /**
        * Template-control exceptions
        * @name JTException
        * @class A class used internals for a template-control exceptions
        * @param type {string} Type of exception
        * @augments Error
        * @augments BaseNode
        */
        var JTException = function (type) {
            this.type = type;
        };
        JTException.prototype = Error;

        /**
        * Throw a template-control exception
        * @throws It throws itself
        */
        JTException.prototype.get = function (d) {
            throw this;
        };

        /**
        * Create a new entry for included template.
        * @name Include
        * @class A class represent: {#include}.
        * @param {string} oper content of operator {#..}
        * @param {array} includes
        * @augments BaseNode
        */
        var Include = function (oper, includes) {
            oper.match(/\{#include (.*?)(?: root=(.*?))?\}/);
            this._template = includes[RegExp.$1];
            if (this._template == undefined) {
                if (Template.DEBUG_MODE)
                    throw new Error('jTemplates: Cannot find include: ' + RegExp.$1);
            }
            this._root = RegExp.$2;
        };

        /**
        * Run method get on included template.
        * @param {object} d data
        * @param {object} param parameters
        * @param {Element} element a HTML element
        * @param {Number} deep
        * @return {String}
        */
        Include.prototype.get = function (d, param, element, deep) {
            var $T = d;
            var $P = param;
            try {
                return this._template.get(eval(this._root), param, element, deep);
            } catch (e) {
                if (Template.DEBUG_MODE || (e instanceof JTException))
                    throw e;
            }
            return '';
        };

        /**
        * Create new node for {#param}.
        * @name UserParam
        * @class A class represent: {#param}.
        * @param {string} oper content of operator {#..}
        * @augments BaseNode
        */
        var UserParam = function (oper) {
            oper.match(/\{#param name=(\w*?) value=(.*?)\}/);
            this._name = RegExp.$1;
            this._value = RegExp.$2;
        };

        /**
        * Return value of selected parameter.
        * @param {object} d data
        * @param {object} param parameters
        * @param {Element} element a HTML element
        * @param {Number} deep
        * @return {String} empty string
        */
        UserParam.prototype.get = function (d, param, element, deep) {
            var $T = d;
            var $P = param;
            var $Q = element;

            try {
                param[this._name] = eval(this._value);
            } catch (e) {
                if (Template.DEBUG_MODE || (e instanceof JTException))
                    throw e;
                param[this._name] = undefined;
            }
            return '';
        };

        /**
        * Create a new cycle node.
        * @name Cycle
        * @class A class represent: {#cycle}.
        * @param {string} oper content of operator {#..}
        * @augments BaseNode
        */
        var Cycle = function (oper) {
            oper.match(/\{#cycle values=(.*?)\}/);
            this._values = eval(RegExp.$1);
            this._length = this._values.length;
            if (this._length <= 0) {
                throw new Error('jTemplates: cycle has no elements');
            }
            this._index = 0;
            this._lastSessionID = -1;
        };

        /**
        * Do a step on cycle and return value.
        * @param {object} d data
        * @param {object} param parameters
        * @param {Element} element a HTML element
        * @param {Number} deep
        * @return {String}
        */
        Cycle.prototype.get = function (d, param, element, deep) {
            var sid = jQuery.data(element, 'jTemplateSID');
            if (sid != this._lastSessionID) {
                this._lastSessionID = sid;
                this._index = 0;
            }
            var i = this._index++ % this._length;
            return this._values[i];
        };


        /**
        * Add a Template to HTML Elements.
        * @param {Template/string} s a Template or a template string
        * @param {array} [includes] Array of included templates.
        * @param {object} [settings] Settings (see Template)
        * @return {jQuery} chainable jQuery class
        * @memberOf jQuery.fn
        */
        jQuery.fn.setTemplate = function (s, includes, settings) {
            if (s.constructor === Template) {
                return jQuery(this).each(function () {
                    jQuery.data(this, 'jTemplate', s);
                    jQuery.data(this, 'jTemplateSID', 0);
                });
            } else {
                return jQuery(this).each(function () {
                    jQuery.data(this, 'jTemplate', new Template(s, includes, settings));
                    jQuery.data(this, 'jTemplateSID', 0);
                });
            }
        };

        /**
        * Add a Template (from URL) to HTML Elements.
        * @param {string} url_ URL to template
        * @param {array} [includes] Array of included templates.
        * @param {object} [settings] Settings (see Template)
        * @return {jQuery} chainable jQuery class
        * @memberOf jQuery.fn
        */
        jQuery.fn.setTemplateURL = function (url_, includes, settings) {
            var s = jQuery.ajax({
                url: url_,
                async: false
            }).responseText;

            return jQuery(this).setTemplate(s, includes, settings);
        };

        /**
        * Create a Template from element's content.
        * @param {string} elementName an ID of element
        * @param {array} [includes] Array of included templates.
        * @param {object} [settings] Settings (see Template)
        * @return {jQuery} chainable jQuery class
        * @memberOf jQuery.fn
        */
        jQuery.fn.setTemplateElement = function (elementName, includes, settings) {
            var s = jQuery('#' + elementName).val();
            if (s == null) {
                s = jQuery('#' + elementName).html();
                s = s.replace(/&lt;/g, "<").replace(/&gt;/g, ">");
            }

            s = jQuery.trim(s);
            s = s.replace(/^<\!\[CDATA\[([\s\S]*)\]\]>$/im, '$1');
            s = s.replace(/^<\!--([\s\S]*)-->$/im, '$1');

            return jQuery(this).setTemplate(s, includes, settings);
        };

        /**
        * Check it HTML Elements have a template. Return count of templates.
        * @return {number} Number of templates.
        * @memberOf jQuery.fn
        */
        jQuery.fn.hasTemplate = function () {
            var count = 0;
            jQuery(this).each(function () {
                if (jQuery.getTemplate(this)) {
                    ++count;
                }
            });
            return count;
        };

        /**
        * Remote Template from HTML Element(s)
        * @return {jQuery} chainable jQuery class
        */
        jQuery.fn.removeTemplate = function () {
            jQuery(this).processTemplateStop();
            return jQuery(this).each(function () {
                jQuery.removeData(this, 'jTemplate');
            });
        };

        /**
        * Set to parameter 'name' value 'value'.
        * @param {string} name
        * @param {object} value
        * @return {jQuery} chainable jQuery class
        * @memberOf jQuery.fn
        */
        jQuery.fn.setParam = function (name, value) {
            return jQuery(this).each(function () {
                var t = jQuery.getTemplate(this);
                if (t === undefined) {
                    if (Template.DEBUG_MODE)
                        throw new Error('jTemplates: Template is not defined.');
                    else
                        return;
                }
                t.setParam(name, value);
            });
        };

        /**
        * Process template using data 'd' and parameters 'param'. Update HTML code.
        * @param {object} d data 
        * @param {object} [param] parameters
        * @return {jQuery} chainable jQuery class
        * @memberOf jQuery.fn
        */
        jQuery.fn.processTemplate = function (d, param) {
            return jQuery(this).each(function () {
                var t = jQuery.getTemplate(this);
                if (t === undefined) {
                    if (Template.DEBUG_MODE)
                        throw new Error('jTemplates: Template is not defined.');
                    else
                        return;
                }
                jQuery.data(this, 'jTemplateSID', jQuery.data(this, 'jTemplateSID') + 1);
                jQuery(this).html(t.get(d, param, this, 0));
            });
        };

        /**
        * Process template using data from URL 'url_' (only format JSON) and parameters 'param'. Update HTML code.
        * @param {string} url_ URL to data (in JSON)
        * @param {object} [param] parameters
        * @param {object} options options and callbacks
        * @return {jQuery} chainable jQuery class
        * @memberOf jQuery.fn
        */
        jQuery.fn.processTemplateURL = function (url_, param, options) {
            var that = this;

            options = jQuery.extend({
                type: 'GET',
                async: true,
                cache: false
            }, options);

            jQuery.ajax({
                url: url_,
                type: options.type,
                data: options.data,
                dataFilter: options.dataFilter,
                async: options.async,
                cache: options.cache,
                timeout: options.timeout,
                dataType: 'json',
                success: function (d) {
                    var r = jQuery(that).processTemplate(d, param);
                    if (options.on_success) {
                        options.on_success(r);
                    }
                },
                error: options.on_error,
                complete: options.on_complete
            });
            return this;
        };

        //#####>UPDATER
        /**
        * Create new Updater.
        * @name Updater
        * @class This class is used for 'Live Refresh!'.
        * @param {string} url A destination URL
        * @param {object} param Parameters (for template)
        * @param {number} interval Time refresh interval
        * @param {object} args Additional URL parameters (in URL alter ?) as assoc array.
        * @param {array} objs An array of HTMLElement which will be modified by Updater.
        * @param {object} options options and callbacks
        */
        var Updater = function (url, param, interval, args, objs, options) {
            this._url = url;
            this._param = param;
            this._interval = interval;
            this._args = args;
            this.objs = objs;
            this.timer = null;
            this._options = options || {};

            var that = this;
            jQuery(objs).each(function () {
                jQuery.data(this, 'jTemplateUpdater', that);
            });
            this.run();
        };

        /**
        * Create new HTTP request to server, get data (as JSON) and send it to templates. Also check does HTMLElements still exists in Document.
        */
        Updater.prototype.run = function () {
            this.detectDeletedNodes();
            if (this.objs.length == 0) {
                return;
            }
            var that = this;
            jQuery.getJSON(this._url, this._args, function (d) {
                var r = jQuery(that.objs).processTemplate(d, that._param);
                if (that._options.on_success) {
                    that._options.on_success(r);
                }
            });
            this.timer = setTimeout(function () { that.run(); }, this._interval);
        };

        /**
        * Check does HTMLElements still exists in HTML Document.
        * If not exist, delete it from property 'objs'.
        */
        Updater.prototype.detectDeletedNodes = function () {
            this.objs = jQuery.grep(this.objs, function (o) {
                if (jQuery.browser.msie) {
                    var n = o.parentNode;
                    while (n && n != document) {
                        n = n.parentNode;
                    }
                    return n != null;
                } else {
                    return o.parentNode != null;
                }
            });
        };

        /**
        * Start 'Live Refresh!'.
        * @param {string} url A destination URL
        * @param {object} param Parameters (for template)
        * @param {number} interval Time refresh interval
        * @param {object} args Additional URL parameters (in URL alter ?) as assoc array.
        * @param {object} options options and callbacks
        * @return {Updater} an Updater object
        * @memberOf jQuery.fn
        */
        jQuery.fn.processTemplateStart = function (url, param, interval, args, options) {
            return new Updater(url, param, interval, args, this, options);
        };

        /**
        * Stop 'Live Refresh!'.
        * @return {jQuery} chainable jQuery class
        * @memberOf jQuery.fn
        */
        jQuery.fn.processTemplateStop = function () {
            return jQuery(this).each(function () {
                var updater = jQuery.data(this, 'jTemplateUpdater');
                if (updater == null) {
                    return;
                }
                var that = this;
                updater.objs = jQuery.grep(updater.objs, function (o) {
                    return o != that;
                });
                jQuery.removeData(this, 'jTemplateUpdater');
            });
        };
        //#####<UPDATER

        jQuery.extend(/** @scope jQuery.prototype */{
        /**
        * Create new Template.
        * @param {string} s A template string (like: "Text: {$T.txt}.").
        * @param {array} includes Array of included templates.
        * @param {object} settings Settings. (see Template)
        * @return {Template}
        */
        createTemplate: function (s, includes, settings) {
            return new Template(s, includes, settings);
        },

        /**
        * Create new Template from URL.
        * @param {string} url_ URL to template
        * @param {array} includes Array of included templates.
        * @param {object} settings Settings. (see Template)
        * @return {Template}
        */
        createTemplateURL: function (url_, includes, settings) {
            var s = jQuery.ajax({
                url: url_,
                async: false
            }).responseText;

            return new Template(s, includes, settings);
        },

        /**
        * Get a Template for HTML node
        * @param {Element} HTML node
        * @return {Template} a Template or "undefined"
        */
        getTemplate: function (element) {
            return jQuery.data(element, 'jTemplate');
        },

        /**
        * Process template and return text content.
        * @param {Template} template A Template
        * @param {object} data data
        * @param {object} param parameters
        * @return {string} Content of template
        */
        processTemplateToText: function (template, data, parameter) {
            return template.get(data, parameter, undefined, 0);
        },

        /**
        * Set Debug Mode
        * @param {Boolean} value
        */
        jTemplatesDebugMode: function (value) {
            Template.DEBUG_MODE = value;
        }
    });

})(jQuery);}

(function($) {                                          // Compliant with jquery.noConflict()
$.fn.jCarouselLite = function(o) {
    o = $.extend({
        btnPrev: null,
        btnNext: null,
        btnGo: null,
        mouseWheel: false,
        auto: null,

        speed: 200,
        easing: null,

        vertical: false,
        circular: true,
        visible: 3,
        start: 0,
        scroll: 1,

        beforeStart: null,
        afterEnd: null
    }, o || {});

    return this.each(function() {                           // Returns the element collection. Chainable.

        var running = false, animCss=o.vertical?"top":"left", sizeCss=o.vertical?"height":"width";
        var div = $(this), ul = $("ul", div), tLi = $("li", ul), tl = tLi.size(), v = o.visible;

        if(o.circular) {
            ul.prepend(tLi.slice(tl-v-1+1).clone())
              .append(tLi.slice(0,v).clone());
            o.start += v;
        }

        var li = $("li", ul), itemLength = li.size(), curr = o.start;
        div.css("visibility", "visible");

        li.css({overflow: "hidden", float: o.vertical ? "none" : "left"});
        ul.css({margin: "0", padding: "0", position: "relative", "list-style-type": "none", "z-index": "1"});
        div.css({overflow: "hidden", position: "relative", "z-index": "2", left: "0px"});

        var liSize = o.vertical ? height(li) : width(li);   // Full li size(incl margin)-Used for animation
        var ulSize = liSize * itemLength;                   // size of full ul(total length, not just for the visible items)
        var divSize = liSize * v;                           // size of entire div(total length for just the visible items)

        li.css({width: li.width(), height: li.height()});
        ul.css(sizeCss, ulSize+"px").css(animCss, -(curr*liSize));

        div.css(sizeCss, divSize+"px");                     // Width of the DIV. length of visible images

        if(o.btnPrev)
            $(o.btnPrev).click(function() {
                return go(curr-o.scroll);
            });

        if(o.btnNext)
            $(o.btnNext).click(function() {
                return go(curr+o.scroll);
            });

        if(o.btnGo)
            $.each(o.btnGo, function(i, val) {
                $(val).click(function() {
                    return go(o.circular ? o.visible+i : i);
                });
            });

        if(o.mouseWheel && div.mousewheel)
            div.mousewheel(function(e, d) {
                return d>0 ? go(curr-o.scroll) : go(curr+o.scroll);
            });

        if(o.auto)
            setInterval(function() {
                go(curr+o.scroll);
            }, o.auto+o.speed);

        function vis() {
            return li.slice(curr).slice(0,v);
        };

        function go(to) {
            if(!running) {

                if(o.beforeStart)
                    o.beforeStart.call(this, vis());

                if(o.circular) {            // If circular we are in first or last, then goto the other end
                    if(to<=o.start-v-1) {           // If first, then goto last
                        ul.css(animCss, -((itemLength-(v*2))*liSize)+"px");
                        // If "scroll" > 1, then the "to" might not be equal to the condition; it can be lesser depending on the number of elements.
                        curr = to==o.start-v-1 ? itemLength-(v*2)-1 : itemLength-(v*2)-o.scroll;
                    } else if(to>=itemLength-v+1) { // If last, then goto first
                        ul.css(animCss, -( (v) * liSize ) + "px" );
                        // If "scroll" > 1, then the "to" might not be equal to the condition; it can be greater depending on the number of elements.
                        curr = to==itemLength-v+1 ? v+1 : v+o.scroll;
                    } else curr = to;
                } else {                    // If non-circular and to points to first or last, we just return.
                    if(to<0 || to>itemLength-v) return;
                    else curr = to;
                }                           // If neither overrides it, the curr will still be "to" and we can proceed.

                running = true;

                ul.animate(
                    animCss == "left" ? { left: -(curr*liSize) } : { top: -(curr*liSize) } , o.speed, o.easing,
                    function() {
                        if(o.afterEnd)
                            o.afterEnd.call(this, vis());
                        running = false;
                    }
                );
                // Disable buttons when the carousel reaches the last/first, and enable when not
                if(!o.circular) {
                    $(o.btnPrev + "," + o.btnNext).removeClass("disabled");
                    $( (curr-o.scroll<0 && o.btnPrev)
                        ||
                       (curr+o.scroll > itemLength-v && o.btnNext)
                        ||
                       []
                     ).addClass("disabled");
                }

            }
            return false;
        };
    });
};

function css(el, prop) {
    return parseInt($.css(el[0], prop)) || 0;
};
function width(el) {
    return  el[0].offsetWidth + css(el, 'marginLeft') + css(el, 'marginRight');
};
function height(el) {
    return el[0].offsetHeight + css(el, 'marginTop') + css(el, 'marginBottom');
};

})(jQuery);



