
/*01-jquery.preload-1.0.8.min.js*/
/**
 * jQuery.Preload - Multifunctional preloader
 */
;(function($){var h=$.preload=function(c,d){if(c.split)c=$(c);d=$.extend({},h.defaults,d);var f=$.map(c,function(a){if(!a)return;if(a.split)return d.base+a+d.ext;var b=a.src||a.href;if(typeof d.placeholder=='string'&&a.src)a.src=d.placeholder;if(b&&d.find)b=b.replace(d.find,d.replace);return b||null}),data={loaded:0,failed:0,next:0,done:0,total:f.length};if(!data.total)return finish();var g=$(Array(d.threshold+1).join('<img/>')).load(handler).error(handler).bind('abort',handler).each(fetch);function handler(e){data.element=this;data.found=e.type=='load';data.image=this.src;data.index=this.index;var a=data.original=c[this.index];data[data.found?'loaded':'failed']++;data.done++;if(d.enforceCache)h.cache.push($('<img/>').attr('src',data.image)[0]);if(d.placeholder&&a.src)a.src=data.found?data.image:d.notFound||a.src;if(d.onComplete)d.onComplete(data);if(data.done<data.total)fetch(0,this);else{if(g&&g.unbind)g.unbind('load').unbind('error').unbind('abort');g=null;finish()}};function fetch(i,a,b){if(a.attachEvent&&data.next&&data.next%h.gap==0&&!b){setTimeout(function(){fetch(i,a,1)},0);return!1}if(data.next==data.total)return!1;a.index=data.next;a.src=f[data.next++];if(d.onRequest){data.index=a.index;data.element=a;data.image=a.src;data.original=c[data.next-1];d.onRequest(data)}};function finish(){if(d.onFinish)d.onFinish(data)}};h.gap=14;h.cache=[];h.defaults={threshold:2,base:'',ext:'',replace:''};$.fn.preload=function(a){h(this,a);return this}})(jQuery);
/*02-jquery.pngFix.min.js*/
/**
 * --------------------------------------------------------------------
 * jQuery-Plugin "pngFix"
 * Version: 1.2, 09.03.2009
 * by Andreas Eberhard, andreas.eberhard@gmail.com
 *                      http://jquery.andreaseberhard.de/
 *
 * Copyright (c) 2007 Andreas Eberhard
 * Licensed under GPL (http://www.opensource.org/licenses/gpl-license.php)
 *
 * Changelog:
 *    09.03.2009 Version 1.2
 *    - Update for jQuery 1.3.x, removed @ from selectors
 *    11.09.2007 Version 1.1
 *    - removed noConflict
 *    - added png-support for input type=image
 *    - 01.08.2007 CSS background-image support extension added by Scott Jehl, scott@filamentgroup.com, http://www.filamentgroup.com
 *    31.05.2007 initial Version 1.0
 * --------------------------------------------------------------------
 * @example $(function(){$(document).pngFix();});
 * @desc Fixes all PNG's in the document on document.ready
 *
 * jQuery(function(){jQuery(document).pngFix();});
 * @desc Fixes all PNG's in the document on document.ready when using noConflict
 *
 * @example $(function(){$('div.examples').pngFix();});
 * @desc Fixes all PNG's within div with class examples
 *
 * @example $(function(){$('div.examples').pngFix( { blankgif:'ext.gif' } );});
 * @desc Fixes all PNG's within div with class examples, provides blank gif for input with png
 * --------------------------------------------------------------------
 */

(function($) {

jQuery.fn.pngFix = function(settings) {

	// Settings
	settings = jQuery.extend({
		blankgif: 'blank.gif'
	}, settings);

	var ie55 = (navigator.appName == "Microsoft Internet Explorer" && parseInt(navigator.appVersion) == 4 && navigator.appVersion.indexOf("MSIE 5.5") != -1);
	var ie6 = (navigator.appName == "Microsoft Internet Explorer" && parseInt(navigator.appVersion) == 4 && navigator.appVersion.indexOf("MSIE 6.0") != -1);

	if (jQuery.browser.msie && (ie55 || ie6)) {

		//fix images with png-source
		jQuery(this).find("img[src$=.png]").each(function() {

			jQuery(this).attr('width',jQuery(this).width());
			jQuery(this).attr('height',jQuery(this).height());

			var prevStyle = '';
			var strNewHTML = '';
			var imgId = (jQuery(this).attr('id')) ? 'id="' + jQuery(this).attr('id') + '" ' : '';
			var imgClass = (jQuery(this).attr('class')) ? 'class="' + jQuery(this).attr('class') + '" ' : '';
			var imgTitle = (jQuery(this).attr('title')) ? 'title="' + jQuery(this).attr('title') + '" ' : '';
			var imgAlt = (jQuery(this).attr('alt')) ? 'alt="' + jQuery(this).attr('alt') + '" ' : '';
			var imgAlign = (jQuery(this).attr('align')) ? 'float:' + jQuery(this).attr('align') + ';' : '';
			var imgHand = (jQuery(this).parent().attr('href')) ? 'cursor:hand;' : '';
			if (this.style.border) {
				prevStyle += 'border:'+this.style.border+';';
				this.style.border = '';
			}
			if (this.style.padding) {
				prevStyle += 'padding:'+this.style.padding+';';
				this.style.padding = '';
			}
			if (this.style.margin) {
				prevStyle += 'margin:'+this.style.margin+';';
				this.style.margin = '';
			}
			var imgStyle = (this.style.cssText);

			strNewHTML += '<span '+imgId+imgClass+imgTitle+imgAlt;
			strNewHTML += 'style="position:relative;white-space:pre-line;display:inline-block;background:transparent;'+imgAlign+imgHand;
			strNewHTML += 'width:' + jQuery(this).width() + 'px;' + 'height:' + jQuery(this).height() + 'px;';
			strNewHTML += 'filter:progid:DXImageTransform.Microsoft.AlphaImageLoader' + '(src=\'' + jQuery(this).attr('src') + '\', sizingMethod=\'scale\');';
			strNewHTML += imgStyle+'"></span>';
			if (prevStyle != ''){
				strNewHTML = '<span style="position:relative;display:inline-block;'+prevStyle+imgHand+'width:' + jQuery(this).width() + 'px;' + 'height:' + jQuery(this).height() + 'px;'+'">' + strNewHTML + '</span>';
			}

			jQuery(this).hide();
			jQuery(this).after(strNewHTML);

		});

		// fix css background pngs
		jQuery(this).find("*").each(function(){
			var bgIMG = jQuery(this).css('background-image');
			if(bgIMG.indexOf(".png")!=-1){
				var iebg = bgIMG.split('url("')[1].split('")')[0];
				jQuery(this).css('background-image', 'none');
				jQuery(this).get(0).runtimeStyle.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + iebg + "',sizingMethod='scale')";
			}
		});
		
		//fix input with png-source
		jQuery(this).find("input[src$=.png]").each(function() {
			var bgIMG = jQuery(this).attr('src');
			jQuery(this).get(0).runtimeStyle.filter = 'progid:DXImageTransform.Microsoft.AlphaImageLoader' + '(src=\'' + bgIMG + '\', sizingMethod=\'scale\');';
   		jQuery(this).attr('src', settings.blankgif)
		});
	
	}
	
	return jQuery;

};

})(jQuery);

/*03-jquery.easing-1.3.min.js*/
/*
* jQuery Easing v1.3 - http://gsgd.co.uk/sandbox/jquery/easing/
*
* Uses the built in easing capabilities added In jQuery 1.1
* to offer multiple easing options
*
* TERMS OF USE - jQuery Easing
* 
* Open source under the BSD License. 
* 
* Copyright Â© 2008 George McGinley Smith
* All rights reserved.
* 
* Redistribution and use in source and binary forms, with or without modification, 
* are permitted provided that the following conditions are met:
* 
* Redistributions of source code must retain the above copyright notice, this list of 
* conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this list 
* of conditions and the following disclaimer in the documentation and/or other materials 
* provided with the distribution.
* 
* Neither the name of the author nor the names of contributors may be used to endorse 
* or promote products derived from this software without specific prior written permission.
* 
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
*  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
*  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
*  GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
*  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 
* OF THE POSSIBILITY OF SUCH DAMAGE. 
*
*/

// t: current time, b: begInnIng value, c: change In value, d: duration
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;
    }
});
/*04-jquery.cluetip.min.js*/
/*
* jQuery clueTip plugin
* Version 1.1  (2010-10-20)
* @requires jQuery v1.3+
*
* Dual licensed under the MIT and GPL licenses:
* http://www.opensource.org/licenses/mit-license.php
* http://www.gnu.org/licenses/gpl.html
*
*/

/*
*
* Full list of options/settings can be found at the bottom of this file and at http://plugins.learningjquery.com/cluetip/
*
* Examples can be found at http://plugins.learningjquery.com/cluetip/demo/
*
*/

(function ($) {
    $.cluetip = { version: '1.1pre' };
    var $cluetip, $cluetipInner, $cluetipOuter, $cluetipTitle, $cluetipArrows, $cluetipWait, $dropShadow, imgCount;
    var insertionType = 'appendTo', insertionElement = 'body';
    var standardClasses = 'ui-widget ui-widget-content ui-cluetip';


    $.fn.cluetip = function (js, options) {
        if (typeof js == 'object') {
            options = js;
            js = null;
        }
        if (js == 'destroy') {
            return this.removeData('cluetip').unbind('.cluetip');
        }

        // merge per-call options with defaults
        options = $.extend(true, {}, $.fn.cluetip.defaults, options || {});

        /** =create cluetip divs **/

        if (!$('#cluetip').length) {
            $(['<div id="cluetip">',
        '<div id="cluetip-outer" class="ui-cluetip-outer">',
          '<h3 id="cluetip-title" class="ui-widget-header ui-cluetip-header"></h3>',
          '<div id="cluetip-inner" class="ui-widget-content ui-cluetip-content"></div>',
        '</div>',
        '<div id="cluetip-extra"></div>',
        '<div id="cluetip-arrows" class="cluetip-arrows"></div>',
      '</div>'].join(''))
      [insertionType](insertionElement).hide();

            var cluezIndex = +options.cluezIndex;

            $cluetip = $('#cluetip').css({ position: 'absolute' });
            $cluetipOuter = $('#cluetip-outer').css({ position: 'relative', zIndex: cluezIndex });
            $cluetipInner = $('#cluetip-inner');
            $cluetipTitle = $('#cluetip-title');
            $cluetipArrows = $('#cluetip-arrows');
            $cluetipWait = $('<div id="cluetip-waitimage"></div>')
        .css({ position: 'absolute' }).insertBefore($cluetip).hide();
        }
        var cluetipPadding = (parseInt($cluetip.css('paddingLeft'), 10) || 0) + (parseInt($cluetip.css('paddingRight'), 10) || 0);


        this.each(function (index) {
            var link = this, $this = $(this);

            // support metadata plugin (v1.0 and 2.0)
            var opts = $.extend(true, {}, options, $.metadata ? $this.metadata() : $.meta ? $this.data() : {});


            // start out with no contents (for ajax activation)
            var cluetipContents = false;

            cluezIndex = +opts.cluezIndex;
            $this.data('cluetip', { title: link.title, zIndex: cluezIndex });
            var isActive = false, closeOnDelay = 0;

            var tipAttribute = $this.attr(opts.attribute), ctClass = opts.cluetipClass;
            if (!tipAttribute && !opts.splitTitle && !js) {
                return true;
            }
            // if hideLocal is set to true, on DOM ready hide the local content that will be displayed in the clueTip
            if (opts.local && opts.localPrefix) { tipAttribute = opts.localPrefix + tipAttribute; }
            if (opts.local && opts.hideLocal && tipAttribute) { $(tipAttribute + ':first').hide(); }
            var tOffset = parseInt(opts.topOffset, 10), lOffset = parseInt(opts.leftOffset, 10);
            // vertical measurement variables
            var tipHeight, wHeight,
          defHeight = isNaN(parseInt(opts.height, 10)) ? 'auto' : (/\D/g).test(opts.height) ? opts.height : opts.height + 'px';
            var sTop, linkTop, posY, tipY, mouseY, baseline;
            // horizontal measurement variables
            var tipInnerWidth = parseInt(opts.width, 10) || 275,
          tipWidth = tipInnerWidth + cluetipPadding + opts.dropShadowSteps,
          linkWidth = this.offsetWidth,
          linkLeft, posX, tipX, mouseX, winWidth;

            // parse the title
            var tipParts;
            var tipTitle = (opts.attribute != 'title') ? $this.attr(opts.titleAttribute) : '';
            if (opts.splitTitle) {
                if (tipTitle == undefined) { tipTitle = ''; }
                tipParts = tipTitle.split(opts.splitTitle);
                tipTitle = tipParts.shift();
            }
            if (opts.escapeTitle) {
                tipTitle = tipTitle.replace(/&/g, '&amp;').replace(/>/g, '&gt;').replace(/</g, '&lt;');
            }

            var localContent;
            function returnFalse() { return false; }

            /***************************************
            * ACTIVATION
            ****************************************/

            //activate clueTip
            var activate = function (event) {
                if (!opts.onActivate($this)) {
                    return false;
                }
                isActive = true;
                $cluetip.removeClass().css({ width: tipInnerWidth });
                if (tipAttribute == $this.attr('href')) {
                    $this.css('cursor', opts.cursor);
                }
                if (opts.hoverClass) {
                    $this.addClass(opts.hoverClass);
                }
                linkTop = posY = $this.offset().top;
                linkLeft = $this.offset().left;
                mouseX = event.pageX;
                mouseY = event.pageY;
                if (link.tagName.toLowerCase() != 'area') {
                    sTop = $(document).scrollTop();
                    winWidth = $(window).width();
                }
                // position clueTip horizontally
                if (opts.positionBy == 'fixed') {
                    posX = linkWidth + linkLeft + lOffset;
                    $cluetip.css({ left: posX });
                } else {
                    posX = (linkWidth > linkLeft && linkLeft > tipWidth)
          || linkLeft + linkWidth + tipWidth + lOffset > winWidth
          ? linkLeft - tipWidth - lOffset
          : linkWidth + linkLeft + lOffset;
                    if (link.tagName.toLowerCase() == 'area' || opts.positionBy == 'mouse' || linkWidth + tipWidth > winWidth) { // position by mouse
                        if (mouseX + 20 + tipWidth > winWidth) {
                            $cluetip.addClass(' cluetip-' + ctClass);
                            posX = (mouseX - tipWidth - lOffset) >= 0 ? mouseX - tipWidth - lOffset - parseInt($cluetip.css('marginLeft'), 10) + parseInt($cluetipInner.css('marginRight'), 10) : mouseX - (tipWidth / 2);
                        } else {
                            posX = mouseX + lOffset;
                        }
                    }
                    var pY = posX < 0 ? event.pageY + tOffset : event.pageY;
                    $cluetip.css({
                        left: (posX > 0 && opts.positionBy != 'bottomTop') ? posX : (mouseX + (tipWidth / 2) > winWidth) ? winWidth / 2 - tipWidth / 2 : Math.max(mouseX - (tipWidth / 2), 0),
                        zIndex: $this.data('cluetip').zIndex
                    });
                    $cluetipArrows.css({ zIndex: $this.data('cluetip').zIndex + 1 });
                }
                wHeight = $(window).height();

                /***************************************
                * load a string from cluetip method's first argument
                ***************************************/
                if (js) {
                    if (typeof js == 'function') {
                        js = js.call(link);
                    }
                    $cluetipInner.html(js);
                    cluetipShow(pY);
                }
                /***************************************
                * load the title attribute only (or user-selected attribute).
                * clueTip title is the string before the first delimiter
                * subsequent delimiters place clueTip body text on separate lines
                ***************************************/

                else if (tipParts) {
                    var tpl = tipParts.length;
                    $cluetipInner.html(tpl ? tipParts[0] : '');
                    if (tpl > 1) {
                        for (var i = 1; i < tpl; i++) {
                            $cluetipInner.append('<div class="split-body">' + tipParts[i] + '</div>');
                        }
                    }
                    cluetipShow(pY);
                }
                /***************************************
                * load external file via ajax
                ***************************************/

                else if (!opts.local && tipAttribute.indexOf('#') !== 0) {
                    if (/\.(jpe?g|tiff?|gif|png)(?:\?.*)?$/i.test(tipAttribute)) {
                        $cluetipInner.html('<img src="' + tipAttribute + '" alt="' + tipTitle + '" />');
                        cluetipShow(pY);
                    } else if (cluetipContents && opts.ajaxCache) {
                        $cluetipInner.html(cluetipContents);
                        cluetipShow(pY);
                    } else {
                        var optionBeforeSend = opts.ajaxSettings.beforeSend,
              optionError = opts.ajaxSettings.error,
              optionSuccess = opts.ajaxSettings.success,
              optionComplete = opts.ajaxSettings.complete;
                        var ajaxSettings = {
                            cache: false, // force requested page not to be cached by browser
                            url: tipAttribute,
                            beforeSend: function (xhr) {
                                if (optionBeforeSend) { optionBeforeSend.call(link, xhr, $cluetip, $cluetipInner); }
                                $cluetipOuter.children().empty();
                                if (opts.waitImage) {
                                    $cluetipWait
                .css({ top: mouseY + 20, left: mouseX + 20, zIndex: $this.data('cluetip').zIndex - 1 })
                .show();
                                }
                            },
                            error: function (xhr, textStatus) {
                                if (isActive) {
                                    if (optionError) {
                                        optionError.call(link, xhr, textStatus, $cluetip, $cluetipInner);
                                    } else {
                                        $cluetipInner.html('<i>sorry, the contents could not be loaded</i>');
                                    }
                                }
                            },
                            success: function (data, textStatus) {
                                cluetipContents = opts.ajaxProcess.call(link, data);
                                if (isActive) {
                                    if (optionSuccess) { optionSuccess.call(link, data, textStatus, $cluetip, $cluetipInner); }
                                    $cluetipInner.html(cluetipContents);
                                }
                            },
                            complete: function (xhr, textStatus) {
                                if (optionComplete) { optionComplete.call(link, xhr, textStatus, $cluetip, $cluetipInner); }
                                var imgs = $cluetipInner[0].getElementsByTagName('img');
                                imgCount = imgs.length;
                                for (var i = 0, l = imgs.length; i < l; i++) {
                                    if (imgs[i].complete) {
                                        imgCount--;
                                    }
                                }
                                if (imgCount && !$.browser.opera) {
                                    $(imgs).bind('load error', function () {
                                        imgCount--;
                                        if (imgCount < 1) {
                                            $cluetipWait.hide();
                                            if (isActive) { cluetipShow(pY); }
                                        }
                                    });
                                } else {
                                    $cluetipWait.hide();
                                    if (isActive) { cluetipShow(pY); }
                                }
                            }
                        };
                        var ajaxMergedSettings = $.extend(true, {}, opts.ajaxSettings, ajaxSettings);

                        $.ajax(ajaxMergedSettings);
                    }

                    /***************************************
                    * load an element from the same page
                    ***************************************/
                } else if (opts.local) {

                    var $localContent = $(tipAttribute + (/#\S+$/.test(tipAttribute) ? '' : ':eq(' + index + ')')).clone(true).show();
                    if (opts.localIdSuffix) {
                        $localContent.attr('id', $localContent[0].id + opts.localIdSuffix);
                    }
                    $cluetipInner.html($localContent);
                    cluetipShow(pY);
                }
            };

            // get dimensions and options for cluetip and prepare it to be shown
            var cluetipShow = function (bpY) {
                $cluetip.addClass('cluetip-' + ctClass);
                if (opts.truncate) {
                    var $truncloaded = $cluetipInner.text().slice(0, opts.truncate) + '...';
                    $cluetipInner.html($truncloaded);
                }

                function doNothing() { }; //empty function

                tipTitle ? $cluetipTitle.show().html(tipTitle) : (opts.showTitle) ? $cluetipTitle.show().html('&nbsp;') : $cluetipTitle.hide();
                if (opts.sticky) {
                    var $closeLink = $('<div id="cluetip-close"><a href="#">' + opts.closeText + '</a></div>');
                    (opts.closePosition == 'bottom') ? $closeLink.appendTo($cluetipInner) : (opts.closePosition == 'title') ? $closeLink.prependTo($cluetipTitle) : $closeLink.prependTo($cluetipInner);
                    $closeLink.bind('click.cluetip', function () {
                        cluetipClose();
                        return false;
                    });
                    if (opts.mouseOutClose) {
                        $cluetip.bind('mouseleave.cluetip', function () {
                            cluetipClose();
                        });
                    } else {
                        $cluetip.unbind('mouseleave.cluetip');
                    }
                }
                // now that content is loaded, finish the positioning
                var direction = '';
                $cluetipOuter.css({ zIndex: $this.data('cluetip').zIndex, overflow: defHeight == 'auto' ? 'visible' : 'auto', height: defHeight });
                tipHeight = defHeight == 'auto' ? Math.max($cluetip.outerHeight(), $cluetip.height()) : parseInt(defHeight, 10);
                tipY = posY;
                baseline = sTop + wHeight;
                if (opts.positionBy == 'fixed') {
                    tipY = posY - opts.dropShadowSteps + tOffset;
                } else if ((posX < mouseX && Math.max(posX, 0) + tipWidth > mouseX) || opts.positionBy == 'bottomTop') {
                    if (posY + tipHeight + tOffset > baseline && mouseY - sTop > tipHeight + tOffset) {
                        tipY = mouseY - tipHeight - tOffset;
                        direction = 'top';
                    } else {
                        tipY = mouseY + tOffset;
                        direction = 'bottom';
                    }
                } else if (posY + tipHeight + tOffset > baseline) {
                    tipY = (tipHeight >= wHeight) ? sTop : baseline - tipHeight - tOffset;
                } else if ($this.css('display') == 'block' || link.tagName.toLowerCase() == 'area' || opts.positionBy == "mouse") {
                    tipY = bpY - tOffset;
                } else {
                    tipY = posY - opts.dropShadowSteps;
                }
                if (direction == '') {
                    posX < linkLeft ? direction = 'left' : direction = 'right';
                }
                // add classes
                var dynamicClasses = ' clue-' + direction + '-' + ctClass + ' cluetip-' + ctClass;
                if (ctClass == 'rounded') {
                    dynamicClasses += ' ui-corner-all';
                }
                $cluetip.css({ top: tipY + 'px' }).attr({ 'className': standardClasses + dynamicClasses });
                // set up arrow positioning to align with element
                if (opts.arrows) {
                    var bgY = (posY - tipY - opts.dropShadowSteps);
                    $cluetipArrows.css({ top: (/(left|right)/.test(direction) && posX >= 0 && bgY > 0) ? bgY + 'px' : /(left|right)/.test(direction) ? 0 : '' }).show();
                } else {
                    $cluetipArrows.hide();
                }

                // (first hide, then) ***SHOW THE CLUETIP***
                // handle dropshadow divs first
                $dropShadow = createDropShadows(opts);
                if ($dropShadow && $dropShadow.length) {
                    $dropShadow.hide().css({ height: tipHeight, width: tipInnerWidth, zIndex: $this.data('cluetip').zIndex - 1 }).show();
                }

                $cluetip.hide()[opts.fx.open](opts.fx.openSpeed || 0);
                if ($.fn.bgiframe) { $cluetip.bgiframe(); }
                // delayed close (not fully tested)
                if (opts.delayedClose > 0) {
                    closeOnDelay = setTimeout(cluetipClose, opts.delayedClose);
                }
                // trigger the optional onShow function
                opts.onShow.call(link, $cluetip, $cluetipInner);
            };

            /***************************************
            =INACTIVATION
            -------------------------------------- */
            var inactivate = function (event) {
                isActive = false;
                $cluetipWait.hide();
                if (!opts.sticky || (/click|toggle/).test(opts.activation)) {
                    cluetipClose();
                    clearTimeout(closeOnDelay);
                }
                if (opts.hoverClass) {
                    $this.removeClass(opts.hoverClass);
                }
            };
            // close cluetip and reset some things
            var cluetipClose = function () {
                $cluetipOuter
      .parent().hide().removeClass();
                opts.onHide.call(link, $cluetip, $cluetipInner);
                $this.removeClass('cluetip-clicked');
                if (tipTitle) {
                    $this.attr(opts.titleAttribute, tipTitle);
                }
                $this.css('cursor', '');
                if (opts.arrows) {
                    $cluetipArrows.css({ top: '' });
                }
            };

            $(document).bind('hideCluetip', function (e) {
                cluetipClose();
            });
            /***************************************
            =BIND EVENTS
            -------------------------------------- */
            // activate by click
            if ((/click|toggle/).test(opts.activation)) {
                $this.bind('click.cluetip', function (event) {
                    if ($cluetip.is(':hidden') || !$this.is('.cluetip-clicked')) {
                        activate(event);
                        $('.cluetip-clicked').removeClass('cluetip-clicked');
                        $this.addClass('cluetip-clicked');
                    } else {
                        inactivate(event);
                    }
                    this.blur();
                    return false;
                });
                // activate by focus; inactivate by blur
            } else if (opts.activation == 'focus') {
                $this.bind('focus.cluetip', function (event) {
                    $this.attr('title', '');
                    activate(event);
                });
                $this.bind('blur.cluetip', function (event) {
                    $this.attr('title', $this.data('thisInfo').title);
                    inactivate(event);
                });
                // activate by hover
            } else {
                // clicking is returned false if clickThrough option is set to false
                $this[opts.clickThrough ? 'unbind' : 'bind']('click', returnFalse);
                //set up mouse tracking
                var mouseTracks = function (evt) {
                    if (opts.tracking == true) {
                        var trackX = posX - evt.pageX;
                        var trackY = tipY ? tipY - evt.pageY : posY - evt.pageY;
                        $this.bind('mousemove.cluetip', function (evt) {
                            $cluetip.css({ left: evt.pageX + trackX, top: evt.pageY + trackY });
                        });
                    }
                };
                if ($.fn.hoverIntent && opts.hoverIntent) {
                    $this.hoverIntent({
                        sensitivity: opts.hoverIntent.sensitivity,
                        interval: opts.hoverIntent.interval,
                        over: function (event) {
                            activate(event);
                            mouseTracks(event);
                        },
                        timeout: opts.hoverIntent.timeout,
                        out: function (event) { inactivate(event); $this.unbind('mousemove.cluetip'); }
                    });
                } else {
                    $this.bind('mouseenter.cluetip', function (event) {
                        activate(event);
                        mouseTracks(event);
                    })
          .bind('mouseleave.cluetip', function (event) {
              inactivate(event);
              $this.unbind('mousemove.cluetip');
          });
                }

                $this.bind('mouseover.cluetip', function (event) {
                    $this.attr('title', '');
                }).bind('mouseleave.cluetip', function (event) {
                    $this.attr('title', $this.data('cluetip').title);
                });
            }
        });

        /** =private functions
        ************************************************************/
        /** =create dropshadow divs **/

        function createDropShadows(options, newDropShadow) {
            var dropShadowSteps = (options.dropShadow && options.dropShadowSteps) ? +options.dropShadowSteps : 0;
            if ($.support.boxShadow) {
                var dsOffsets = dropShadowSteps === 0 ? '0 0 ' : '1px 1px ';
                $('#cluetip').css($.support.boxShadow, dsOffsets + dropShadowSteps + 'px rgba(0,0,0,0.5)');
                return false;
            }
            var oldDropShadow = $('#cluetip .cluetip-drop-shadow');
            if (dropShadowSteps == oldDropShadow.length) {
                return oldDropShadow;
            }
            oldDropShadow.remove();
            var dropShadows = [];
            for (var i = 0; i < dropShadowSteps; ) {
                dropShadows[i++] = '<div style="top:' + i + 'px;left:' + i + 'px;"></div>';
            }

            newDropShadow = $(dropShadows.join(''))
      .css({
          position: 'absolute',
          backgroundColor: '#000',
          zIndex: cluezIndex - 1,
          opacity: 0.1
      })
      .addClass('cluetip-drop-shadow')
      .prependTo('#cluetip');
            return newDropShadow;

        }


        return this;
    };

    (function () {
        $.support = $.support || {};
        // check support for CSS3 properties (currently only boxShadow)
        var div = document.createElement('div'),
        divStyle = div.style,
        styleProps = ['boxShadow'],
        prefixes = ['moz', 'Moz', 'webkit', 'o'];

        for (var i = 0, sl = styleProps.length; i < sl; i++) {
            var prop = styleProps[i],
          uProp = prop.charAt(0).toUpperCase() + prop.slice(1);

            if (typeof divStyle[prop] !== 'undefined') {
                $.support[prop] = prop;
            } else {
                for (var j = 0, pl = prefixes.length; j < pl; j++) {

                    if (typeof divStyle[prefixes[j] + uProp] !== 'undefined') {
                        $.support[prop] = prefixes[j] + uProp;
                        break;
                    }
                }
            }
        }
        div = null;
    })();

    /*
    * options for clueTip
    *
    * each one can be explicitly overridden by changing its value.
    * for example: $.fn.cluetip.defaults.width = 200;
    * would change the default width for all clueTips to 200.
    *
    * each one can also be overridden by passing an options map to the cluetip method.
    * for example: $('a.example').cluetip({width: 200});
    * would change the default width to 200 for clueTips invoked by a link with class of "example"
    *
    */

    $.fn.cluetip.defaults = {  // set up default options
        width: 275,      // The width of the clueTip
        height: 'auto',   // The height of the clueTip
        cluezIndex: 97,       // Sets the z-index style property of the clueTip
        positionBy: 'auto',   // Sets the type of positioning: 'auto', 'mouse','bottomTop', 'fixed'
        topOffset: 15,       // Number of px to offset clueTip from top of invoking element
        leftOffset: 15,       // Number of px to offset clueTip from left of invoking element
        local: false,    // Whether to use content from the same page for the clueTip's body
        localPrefix: null,       // string to be prepended to the tip attribute if local is true
        localIdSuffix: null,     // string to be appended to the cluetip content element's id if local is true
        hideLocal: true,     // If local option is set to true, this determines whether local content
        // to be shown in clueTip should be hidden at its original location
        attribute: 'rel',    // the attribute to be used for fetching the clueTip's body content
        titleAttribute: 'title',  // the attribute to be used for fetching the clueTip's title
        splitTitle: '',       // A character used to split the title attribute into the clueTip title and divs
        // within the clueTip body. more info below [6]
        escapeTitle: false,    // whether to html escape the title attribute
        showTitle: true,     // show title bar of the clueTip, even if title attribute not set
        cluetipClass: 'default', // class added to outermost clueTip div in the form of 'cluetip-' + clueTipClass.
        hoverClass: '',       // class applied to the invoking element onmouseover and removed onmouseout
        waitImage: true,     // whether to show a "loading" img, which is set in jquery.cluetip.css
        cursor: 'help',
        arrows: false,    // if true, displays arrow on appropriate side of clueTip
        dropShadow: true,     // set to false if you don't want the drop-shadow effect on the clueTip
        dropShadowSteps: 6,        // adjusts the size of the drop shadow
        sticky: false,    // keep visible until manually closed
        mouseOutClose: false,    // close when clueTip is moused out
        activation: 'hover',  // set to 'click' to force user to click to show clueTip
        // set to 'focus' to show on focus of a form element and hide on blur
        clickThrough: true,    // if true, and activation is not 'click', then clicking on link will take user to the link's href,
        // even if href and tipAttribute are equal
        tracking: false,    // if true, clueTip will track mouse movement (experimental)
        delayedClose: 0,        // close clueTip on a timed delay (experimental)
        closePosition: 'top',    // location of close text for sticky cluetips; can be 'top' or 'bottom' or 'title'
        closeText: 'Close',  // text (or HTML) to to be clicked to close sticky clueTips
        truncate: 0,        // number of characters to truncate clueTip's contents. if 0, no truncation occurs

        // effect and speed for opening clueTips
        fx: {
            open: 'show', // can be 'show' or 'slideDown' or 'fadeIn'
            openSpeed: ''
        },

        // settings for when hoverIntent plugin is used
        hoverIntent: {
            sensitivity: 3,
            interval: 50,
            timeout: 0
        },

        // short-circuit function to run just before clueTip is shown.
        onActivate: function (e) { return true; },
        // function to run just after clueTip is shown.
        onShow: function (ct, ci) { },
        // function to run just after clueTip is hidden.
        onHide: function (ct, ci) { },
        // whether to cache results of ajax request to avoid unnecessary hits to server
        ajaxCache: true,

        // process data retrieved via xhr before it's displayed
        ajaxProcess: function (data) {
            data = data.replace(/<(script|style|title)[^<]+<\/(script|style|title)>/gm, '').replace(/<(link|meta)[^>]+>/g, '');
            return data;
        },

        // can pass in standard $.ajax() parameters. Callback functions, such as beforeSend,
        // will be queued first within the default callbacks.
        // The only exception is error, which overrides the default
        ajaxSettings: {
            // error: function(ct, ci) { /* override default error callback */ }
            // beforeSend: function(ct, ci) { /* called first within default beforeSend callback }
            dataType: 'html'
        },
        debug: false
    };


    /*
    * Global defaults for clueTips. Apply to all calls to the clueTip plugin.
    *
    * @example $.cluetip.setup({
    *   insertionType: 'prependTo',
    *   insertionElement: '#container'
    * });
    *
    * @property
    * @name $.cluetip.setup
    * @type Map
    * @cat Plugins/tooltip
    * @option String insertionType: Default is 'appendTo'. Determines the method to be used for inserting the clueTip into the DOM. Permitted values are 'appendTo', 'prependTo', 'insertBefore', and 'insertAfter'
    * @option String insertionElement: Default is 'body'. Determines which element in the DOM the plugin will reference when inserting the clueTip.
    *
    */

    $.cluetip.setup = function (options) {
        if (options && options.insertionType && (options.insertionType).match(/appendTo|prependTo|insertBefore|insertAfter/)) {
            insertionType = options.insertionType;
        }
        if (options && options.insertionElement) {
            insertionElement = options.insertionElement;
        }
    };

})(jQuery);

/*08-jquery.watermark.min.js*/
/*
	Watermark v3.0.6 (June 21, 2010) plugin for jQuery
	http://jquery-watermark.googlecode.com/
	Copyright (c) 2009-2010 Todd Northrop
	http://www.speednet.biz/
	Dual licensed under the MIT or GPL Version 2 licenses.
*/
(function(b){var l="function",j="password",d="maxLength",f="type",c=true,a="",e=false,t="watermark",u,m=t,i="watermarkClass",q="watermarkFocus",k="watermarkSubmit",o="watermarkMaxLength",h="watermarkPassword",g="watermarkText",s=":data("+m+")",n=":text,:password,:search,textarea",p=["Page_ClientValidate"],r=e;b.extend(b.expr[":"],{search:function(b){return "search"===(b.type||a)},data:function(g,i,h){var f,d=/^((?:[^=!^$*]|[!^$*](?!=))+)(?:([!^$*]?=)(.*))?$/.exec(h[3]);if(d){f=b(g).data(d[1]);if(f!==u){if(d[2]){f=a+f;switch(d[2]){case "=":return f==d[3];case "!=":return f!=d[3];case "^=":return f.slice(0,d[3].length)==d[3];case "$=":return f.slice(-d[3].length)==d[3];case "*=":return f.indexOf(d[3])!==-1}}return c}}return e}});b.watermark={version:"3.0.6",options:{className:t,useNative:c},hide:function(a){b(a).filter(s).each(function(){b.watermark._hide(b(this))})},_hide:function(b,n){var m=b.val()||a,k=b.data(g)||a,l=b.data(o)||0,j=b.data(i);if(k.length&&m==k){b.val(a);if(b.data(h))if((b.attr(f)||a)==="text"){var e=b.data(h)||[],c=b.parent()||[];if(e.length&&c.length){c[0].removeChild(b[0]);c[0].appendChild(e[0]);b=e}}if(l){b.attr(d,l);b.removeData(o)}if(n){b.attr("autocomplete","off");window.setTimeout(function(){b.select()},1)}}j&&b.removeClass(j)},show:function(a){b(a).filter(s).each(function(){b.watermark._show(b(this))})},_show:function(e){var t=e.val()||a,k=e.data(g)||a,p=e.attr(f)||a,s=e.data(i);if((t.length==0||t==k)&&!e.data(q)){r=c;if(e.data(h))if(p===j){var n=e.data(h)||[],m=e.parent()||[];if(n.length&&m.length){m[0].removeChild(e[0]);m[0].appendChild(n[0]);e=n;e.attr(d,k.length)}}if(p==="text"||p==="search"){var l=e.attr(d)||0;if(l>0&&k.length>l){e.data(o,l);e.attr(d,k.length)}}s&&e.addClass(s);e.val(k)}else b.watermark._hide(e)},hideAll:function(){if(r){b.watermark.hide(n);r=e}},showAll:function(){b.watermark.show(n)}};b.fn.watermark=function(r,o){var p="string";if(!this.length)return this;var s=e,t=typeof r===p;if(typeof o==="object"){s=typeof o.className===p;o=b.extend({},b.watermark.options,o)}else if(typeof o===p){s=c;o=b.extend({},b.watermark.options,{className:o})}else o=b.watermark.options;if(typeof o.useNative!==l)o.useNative=o.useNative?function(){return c}:function(){return e};return this.each(function(){var v="dragleave",u="dragenter",x=this,e=b(x);if(!e.is(n))return;if(e.data(m)){if(t||s){b.watermark._hide(e);t&&e.data(g,r);s&&e.data(i,o.className)}}else{if(o.useNative.call(x,e))if((a+e.css("-webkit-appearance")).replace("undefined",a)!==a&&(e.attr("tagName")||a)!=="TEXTAREA"){t&&e.attr("placeholder",r);return}e.data(g,t?r:a);e.data(i,o.className);e.data(m,1);if((e.attr(f)||a)===j){var y=e.wrap("<span>").parent(),l=b(y.html().replace(/type=["']?password["']?/i,'type="text"'));l.data(g,e.data(g));l.data(i,e.data(i));l.data(m,1);l.attr(d,r.length);l.focus(function(){b.watermark._hide(l,c)}).bind(u,function(){b.watermark._hide(l)}).bind("dragend",function(){window.setTimeout(function(){l.blur()},1)});e.blur(function(){b.watermark._show(e)}).bind(v,function(){b.watermark._show(e)});l.data(h,e);e.data(h,l)}else e.focus(function(){e.data(q,1);b.watermark._hide(e,c)}).blur(function(){e.data(q,0);b.watermark._show(e)}).bind(u,function(){b.watermark._hide(e)}).bind(v,function(){b.watermark._show(e)}).bind("dragend",function(){window.setTimeout(function(){b.watermark._show(e)},1)}).bind("drop",function(c){var b=c.originalEvent.dataTransfer.getData("Text");e.val().replace(b,a)===e.data(g)&&e.val(b);e.focus()});if(x.form){var p=x.form,w=b(p);if(!w.data(k)){w.submit(b.watermark.hideAll);if(p.submit){w.data(k,p.submit);p.submit=function(c,a){return function(){var d=a.data(k);b.watermark.hideAll();if(d.apply)d.apply(c,Array.prototype.slice.call(arguments));else d()}}(p,w)}else{w.data(k,1);p.submit=function(a){return function(){b.watermark.hideAll();delete a.submit;a.submit()}}(p)}}}}b.watermark._show(e)})};p.length&&b(function(){for(var a,c,d=p.length-1;d>=0;d--){a=p[d];c=window[a];if(typeof c===l)window[a]=function(a){return function(){b.watermark.hideAll();return a.apply(null,Array.prototype.slice.call(arguments))}}(c)}})})(jQuery);
/*09-jquery.jcarousel.min.js*/
/*!
* jCarousel - Riding carousels with jQuery
*   http://sorgalla.com/jcarousel/
*
* Copyright (c) 2006 Jan Sorgalla (http://sorgalla.com)
* Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php)
* and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses.
*
* Built on top of the jQuery library
*   http://jquery.com
*
* Inspired by the "Carousel Component" by Bill Scott
*   http://billwscott.com/carousel/
*/

/*global window, jQuery */
(function ($) {
    // Default configuration properties.
    var defaults = {
        vertical: false,
        rtl: false,
        start: 1,
        offset: 1,
        size: null,
        scroll: 3,
        visible: null,
        animation: 'normal',
        easing: 'swing',
        auto: 0,
        wrap: null,
        initCallback: null,
        reloadCallback: null,
        itemLoadCallback: null,
        itemFirstInCallback: null,
        itemFirstOutCallback: null,
        itemLastInCallback: null,
        itemLastOutCallback: null,
        itemVisibleInCallback: null,
        itemVisibleOutCallback: null,
        buttonNextHTML: '<div></div>',
        buttonPrevHTML: '<div></div>',
        buttonNextEvent: 'click',
        buttonPrevEvent: 'click',
        buttonNextCallback: null,
        buttonPrevCallback: null,
        itemFallbackDimension: null
    }, windowLoaded = false;

    $(window).bind('load.jcarousel', function () { windowLoaded = true; });

    /**
    * The jCarousel object.
    *
    * @constructor
    * @class jcarousel
    * @param e {HTMLElement} The element to create the carousel for.
    * @param o {Object} A set of key/value pairs to set as configuration properties.
    * @cat Plugins/jCarousel
    */
    $.jcarousel = function (e, o) {
        this.options = $.extend({}, defaults, o || {});

        this.locked = false;
        this.autoStopped = false;

        this.container = null;
        this.clip = null;
        this.list = null;
        this.buttonNext = null;
        this.buttonPrev = null;
        this.buttonNextState = null;
        this.buttonPrevState = null;

        // Only set if not explicitly passed as option
        if (!o || o.rtl === undefined) {
            this.options.rtl = ($(e).attr('dir') || $('html').attr('dir') || '').toLowerCase() == 'rtl';
        }

        this.wh = !this.options.vertical ? 'width' : 'height';
        this.lt = !this.options.vertical ? (this.options.rtl ? 'right' : 'left') : 'top';

        // Extract skin class
        var skin = '', split = e.className.split(' ');

        for (var i = 0; i < split.length; i++) {
            if (split[i].indexOf('jcarousel-skin') != -1) {
                $(e).removeClass(split[i]);
                skin = split[i];
                break;
            }
        }

        if (e.nodeName.toUpperCase() == 'UL' || e.nodeName.toUpperCase() == 'OL') {
            this.list = $(e);
            this.container = this.list.parent();

            if (this.container.hasClass('jcarousel-clip')) {
                if (!this.container.parent().hasClass('jcarousel-container')) {
                    this.container = this.container.wrap('<div></div>');
                }

                this.container = this.container.parent();
            } else if (!this.container.hasClass('jcarousel-container')) {
                this.container = this.list.wrap('<div></div>').parent();
            }
        } else {
            this.container = $(e);
            this.list = this.container.find('ul,ol').eq(0);
        }

        if (skin !== '' && this.container.parent()[0].className.indexOf('jcarousel-skin') == -1) {
            this.container.wrap('<div class=" ' + skin + '"></div>');
        }

        this.clip = this.list.parent();

        if (!this.clip.length || !this.clip.hasClass('jcarousel-clip')) {
            this.clip = this.list.wrap('<div></div>').parent();
        }

        this.buttonNext = $('.jcarousel-next', this.container);

        if (this.buttonNext.size() === 0 && this.options.buttonNextHTML !== null) {
            this.buttonNext = this.clip.after(this.options.buttonNextHTML).next();
        }

        this.buttonNext.addClass(this.className('jcarousel-next'));

        this.buttonPrev = $('.jcarousel-prev', this.container);

        if (this.buttonPrev.size() === 0 && this.options.buttonPrevHTML !== null) {
            this.buttonPrev = this.clip.after(this.options.buttonPrevHTML).next();
        }

        this.buttonPrev.addClass(this.className('jcarousel-prev'));

        this.clip.addClass(this.className('jcarousel-clip')).css({
            overflow: 'hidden',
            position: 'relative'
        });

        this.list.addClass(this.className('jcarousel-list')).css({
            overflow: 'hidden',
            position: 'relative',
            top: 0,
            margin: 0,
            padding: 0
        }).css((this.options.rtl ? 'right' : 'left'), 0);

        this.container.addClass(this.className('jcarousel-container')).css({
            position: 'relative'
        });

        if (!this.options.vertical && this.options.rtl) {
            this.container.addClass('jcarousel-direction-rtl').attr('dir', 'rtl');
        }

        var di = this.options.visible !== null ? Math.ceil(this.clipping() / this.options.visible) : null;
        var li = this.list.children('li');

        var self = this;

        if (li.size() > 0) {
            var wh = 0, j = this.options.offset;
            li.each(function () {
                self.format(this, j++);
                wh += self.dimension(this, di);
            });

            this.list.css(this.wh, (wh + 100) + 'px');

            // Only set if not explicitly passed as option
            if (!o || o.size === undefined) {
                this.options.size = li.size();
            }
        }

        // For whatever reason, .show() does not work in Safari...
        this.container.css('display', 'block');
        this.buttonNext.css('display', 'block');
        this.buttonPrev.css('display', 'block');

        this.funcNext = function () { self.next(); };
        this.funcPrev = function () { self.prev(); };
        this.funcResize = function () { self.reload(); };

        if (this.options.initCallback !== null) {
            this.options.initCallback(this, 'init');
        }

        if (!windowLoaded && $.browser.safari) {
            this.buttons(false, false);
            $(window).bind('load.jcarousel', function () { self.setup(); });
        } else {
            this.setup();
        }
    };

    // Create shortcut for internal use
    var $jc = $.jcarousel;

    $jc.fn = $jc.prototype = {
        jcarousel: '0.2.7'
    };

    $jc.fn.extend = $jc.extend = $.extend;

    $jc.fn.extend({
        /**
        * Setups the carousel.
        *
        * @method setup
        * @return undefined
        */
        setup: function () {
            this.first = null;
            this.last = null;
            this.prevFirst = null;
            this.prevLast = null;
            this.animating = false;
            this.timer = null;
            this.tail = null;
            this.inTail = false;

            if (this.locked) {
                return;
            }

            this.list.css(this.lt, this.pos(this.options.offset) + 'px');
            var p = this.pos(this.options.start, true);
            this.prevFirst = this.prevLast = null;
            this.animate(p, false);

            $(window).unbind('resize.jcarousel', this.funcResize).bind('resize.jcarousel', this.funcResize);
        },

        /**
        * Clears the list and resets the carousel.
        *
        * @method reset
        * @return undefined
        */
        reset: function () {
            this.list.empty();

            this.list.css(this.lt, '0px');
            this.list.css(this.wh, '10px');

            if (this.options.initCallback !== null) {
                this.options.initCallback(this, 'reset');
            }

            this.setup();
        },

        /**
        * Reloads the carousel and adjusts positions.
        *
        * @method reload
        * @return undefined
        */
        reload: function () {
            if (this.tail !== null && this.inTail) {
                this.list.css(this.lt, $jc.intval(this.list.css(this.lt)) + this.tail);
            }

            this.tail = null;
            this.inTail = false;

            if (this.options.reloadCallback !== null) {
                this.options.reloadCallback(this);
            }

            if (this.options.visible !== null) {
                var self = this;
                var di = Math.ceil(this.clipping() / this.options.visible), wh = 0, lt = 0;
                this.list.children('li').each(function (i) {
                    wh += self.dimension(this, di);
                    if (i + 1 < self.first) {
                        lt = wh;
                    }
                });

                this.list.css(this.wh, wh + 'px');
                this.list.css(this.lt, -lt + 'px');
            }

            this.scroll(this.first, false);
        },

        /**
        * Locks the carousel.
        *
        * @method lock
        * @return undefined
        */
        lock: function () {
            this.locked = true;
            this.buttons();
        },

        /**
        * Unlocks the carousel.
        *
        * @method unlock
        * @return undefined
        */
        unlock: function () {
            this.locked = false;
            this.buttons();
        },

        /**
        * Sets the size of the carousel.
        *
        * @method size
        * @return undefined
        * @param s {Number} The size of the carousel.
        */
        size: function (s) {
            if (s !== undefined) {
                this.options.size = s;
                if (!this.locked) {
                    this.buttons();
                }
            }

            return this.options.size;
        },

        /**
        * Checks whether a list element exists for the given index (or index range).
        *
        * @method get
        * @return bool
        * @param i {Number} The index of the (first) element.
        * @param i2 {Number} The index of the last element.
        */
        has: function (i, i2) {
            if (i2 === undefined || !i2) {
                i2 = i;
            }

            if (this.options.size !== null && i2 > this.options.size) {
                i2 = this.options.size;
            }

            for (var j = i; j <= i2; j++) {
                var e = this.get(j);
                if (!e.length || e.hasClass('jcarousel-item-placeholder')) {
                    return false;
                }
            }

            return true;
        },

        /**
        * Returns a jQuery object with list element for the given index.
        *
        * @method get
        * @return jQuery
        * @param i {Number} The index of the element.
        */
        get: function (i) {
            return $('.jcarousel-item-' + i, this.list);
        },

        /**
        * Adds an element for the given index to the list.
        * If the element already exists, it updates the inner html.
        * Returns the created element as jQuery object.
        *
        * @method add
        * @return jQuery
        * @param i {Number} The index of the element.
        * @param s {String} The innerHTML of the element.
        */
        add: function (i, s) {
            var e = this.get(i), old = 0, n = $(s);

            if (e.length === 0) {
                var c, j = $jc.intval(i);
                e = this.create(i);
                while (true) {
                    c = this.get(--j);
                    if (j <= 0 || c.length) {
                        if (j <= 0) {
                            this.list.prepend(e);
                        } else {
                            c.after(e);
                        }
                        break;
                    }
                }
            } else {
                old = this.dimension(e);
            }

            if (n.get(0).nodeName.toUpperCase() == 'LI') {
                e.replaceWith(n);
                e = n;
            } else {
                e.empty().append(s);
            }

            this.format(e.removeClass(this.className('jcarousel-item-placeholder')), i);

            var di = this.options.visible !== null ? Math.ceil(this.clipping() / this.options.visible) : null;
            var wh = this.dimension(e, di) - old;

            if (i > 0 && i < this.first) {
                this.list.css(this.lt, $jc.intval(this.list.css(this.lt)) - wh + 'px');
            }

            this.list.css(this.wh, $jc.intval(this.list.css(this.wh)) + wh + 'px');

            return e;
        },

        /**
        * Removes an element for the given index from the list.
        *
        * @method remove
        * @return undefined
        * @param i {Number} The index of the element.
        */
        remove: function (i) {
            var e = this.get(i);

            // Check if item exists and is not currently visible
            if (!e.length || (i >= this.first && i <= this.last)) {
                return;
            }

            var d = this.dimension(e);

            if (i < this.first) {
                this.list.css(this.lt, $jc.intval(this.list.css(this.lt)) + d + 'px');
            }

            e.remove();

            this.list.css(this.wh, $jc.intval(this.list.css(this.wh)) - d + 'px');
        },

        /**
        * Moves the carousel forwards.
        *
        * @method next
        * @return undefined
        */
        next: function () {
            if (this.tail !== null && !this.inTail) {
                this.scrollTail(false);
            } else {
                this.scroll(((this.options.wrap == 'both' || this.options.wrap == 'last') && this.options.size !== null && this.last == this.options.size) ? 1 : this.first + this.options.scroll);
            }
        },

        /**
        * Moves the carousel backwards.
        *
        * @method prev
        * @return undefined
        */
        prev: function () {
            if (this.tail !== null && this.inTail) {
                this.scrollTail(true);
            } else {
                this.scroll(((this.options.wrap == 'both' || this.options.wrap == 'first') && this.options.size !== null && this.first == 1) ? this.options.size : this.first - this.options.scroll);
            }
        },

        /**
        * Scrolls the tail of the carousel.
        *
        * @method scrollTail
        * @return undefined
        * @param b {Boolean} Whether scroll the tail back or forward.
        */
        scrollTail: function (b) {
            if (this.locked || this.animating || !this.tail) {
                return;
            }

            this.pauseAuto();

            var pos = $jc.intval(this.list.css(this.lt));

            pos = !b ? pos - this.tail : pos + this.tail;
            this.inTail = !b;

            // Save for callbacks
            this.prevFirst = this.first;
            this.prevLast = this.last;

            this.animate(pos);
        },

        /**
        * Scrolls the carousel to a certain position.
        *
        * @method scroll
        * @return undefined
        * @param i {Number} The index of the element to scoll to.
        * @param a {Boolean} Flag indicating whether to perform animation.
        */
        scroll: function (i, a) {
            if (this.locked || this.animating) {
                return;
            }

            this.pauseAuto();
            this.animate(this.pos(i), a);
        },

        /**
        * Prepares the carousel and return the position for a certian index.
        *
        * @method pos
        * @return {Number}
        * @param i {Number} The index of the element to scoll to.
        * @param fv {Boolean} Whether to force last item to be visible.
        */
        pos: function (i, fv) {
            var pos = $jc.intval(this.list.css(this.lt));

            if (this.locked || this.animating) {
                return pos;
            }

            if (this.options.wrap != 'circular') {
                i = i < 1 ? 1 : (this.options.size && i > this.options.size ? this.options.size : i);
            }

            var back = this.first > i;

            // Create placeholders, new list width/height
            // and new list position
            var f = this.options.wrap != 'circular' && this.first <= 1 ? 1 : this.first;
            var c = back ? this.get(f) : this.get(this.last);
            var j = back ? f : f - 1;
            var e = null, l = 0, p = false, d = 0, g;

            while (back ? --j >= i : ++j < i) {
                e = this.get(j);
                p = !e.length;
                if (e.length === 0) {
                    e = this.create(j).addClass(this.className('jcarousel-item-placeholder'));
                    c[back ? 'before' : 'after'](e);

                    if (this.first !== null && this.options.wrap == 'circular' && this.options.size !== null && (j <= 0 || j > this.options.size)) {
                        g = this.get(this.index(j));
                        if (g.length) {
                            e = this.add(j, g.clone(true));
                        }
                    }
                }

                c = e;
                d = this.dimension(e);

                if (p) {
                    l += d;
                }

                if (this.first !== null && (this.options.wrap == 'circular' || (j >= 1 && (this.options.size === null || j <= this.options.size)))) {
                    pos = back ? pos + d : pos - d;
                }
            }

            // Calculate visible items
            var clipping = this.clipping(), cache = [], visible = 0, v = 0;
            c = this.get(i - 1);
            j = i;

            while (++visible) {
                e = this.get(j);
                p = !e.length;
                if (e.length === 0) {
                    e = this.create(j).addClass(this.className('jcarousel-item-placeholder'));
                    // This should only happen on a next scroll
                    if (c.length === 0) {
                        this.list.prepend(e);
                    } else {
                        c[back ? 'before' : 'after'](e);
                    }

                    if (this.first !== null && this.options.wrap == 'circular' && this.options.size !== null && (j <= 0 || j > this.options.size)) {
                        g = this.get(this.index(j));
                        if (g.length) {
                            e = this.add(j, g.clone(true));
                        }
                    }
                }

                c = e;
                d = this.dimension(e);
                if (d === 0) {
                    throw new Error('jCarousel: No width/height set for items. This will cause an infinite loop. Aborting...');
                }

                if (this.options.wrap != 'circular' && this.options.size !== null && j > this.options.size) {
                    cache.push(e);
                } else if (p) {
                    l += d;
                }

                v += d;

                if (v >= clipping) {
                    break;
                }

                j++;
            }

            // Remove out-of-range placeholders
            for (var x = 0; x < cache.length; x++) {
                cache[x].remove();
            }

            // Resize list
            if (l > 0) {
                this.list.css(this.wh, this.dimension(this.list) + l + 'px');

                if (back) {
                    pos -= l;
                    this.list.css(this.lt, $jc.intval(this.list.css(this.lt)) - l + 'px');
                }
            }

            // Calculate first and last item
            var last = i + visible - 1;
            if (this.options.wrap != 'circular' && this.options.size && last > this.options.size) {
                last = this.options.size;
            }

            if (j > last) {
                visible = 0;
                j = last;
                v = 0;
                while (++visible) {
                    e = this.get(j--);
                    if (!e.length) {
                        break;
                    }
                    v += this.dimension(e);
                    if (v >= clipping) {
                        break;
                    }
                }
            }

            var first = last - visible + 1;
            if (this.options.wrap != 'circular' && first < 1) {
                first = 1;
            }

            if (this.inTail && back) {
                pos += this.tail;
                this.inTail = false;
            }

            this.tail = null;
            if (this.options.wrap != 'circular' && last == this.options.size && (last - visible + 1) >= 1) {
                var m = $jc.margin(this.get(last), !this.options.vertical ? 'marginRight' : 'marginBottom');
                if ((v - m) > clipping) {
                    this.tail = v - clipping - m;
                }
            }

            if (fv && i === this.options.size && this.tail) {
                pos -= this.tail;
                this.inTail = true;
            }

            // Adjust position
            while (i-- > first) {
                pos += this.dimension(this.get(i));
            }

            // Save visible item range
            this.prevFirst = this.first;
            this.prevLast = this.last;
            this.first = first;
            this.last = last;

            return pos;
        },

        /**
        * Animates the carousel to a certain position.
        *
        * @method animate
        * @return undefined
        * @param p {Number} Position to scroll to.
        * @param a {Boolean} Flag indicating whether to perform animation.
        */
        animate: function (p, a) {
            if (this.locked || this.animating) {
                return;
            }

            this.animating = true;

            var self = this;
            var scrolled = function () {
                self.animating = false;

                if (p === 0) {
                    self.list.css(self.lt, 0);
                }

                if (!self.autoStopped && (self.options.wrap == 'circular' || self.options.wrap == 'both' || self.options.wrap == 'last' || self.options.size === null || self.last < self.options.size || (self.last == self.options.size && self.tail !== null && !self.inTail))) {
                    self.startAuto();
                }

                self.buttons();
                self.notify('onAfterAnimation');

                // This function removes items which are appended automatically for circulation.
                // This prevents the list from growing infinitely.
                if (self.options.wrap == 'circular' && self.options.size !== null) {
                    for (var i = self.prevFirst; i <= self.prevLast; i++) {
                        if (i !== null && !(i >= self.first && i <= self.last) && (i < 1 || i > self.options.size)) {
                            self.remove(i);
                        }
                    }
                }
            };

            this.notify('onBeforeAnimation');

            // Animate
            if (!this.options.animation || a === false) {
                this.list.css(this.lt, p + 'px');
                scrolled();
            } else {
                var o = !this.options.vertical ? (this.options.rtl ? { 'right': p} : { 'left': p }) : { 'top': p };
                this.list.animate(o, this.options.animation, this.options.easing, scrolled);
            }
        },

        /**
        * Starts autoscrolling.
        *
        * @method auto
        * @return undefined
        * @param s {Number} Seconds to periodically autoscroll the content.
        */
        startAuto: function (s) {
            if (s !== undefined) {
                this.options.auto = s;
            }

            if (this.options.auto === 0) {
                return this.stopAuto();
            }

            if (this.timer !== null) {
                return;
            }

            this.autoStopped = false;

            var self = this;
            this.timer = window.setTimeout(function () { self.next(); }, this.options.auto * 1000);
        },

        /**
        * Stops autoscrolling.
        *
        * @method stopAuto
        * @return undefined
        */
        stopAuto: function () {
            this.pauseAuto();
            this.autoStopped = true;
        },

        /**
        * Pauses autoscrolling.
        *
        * @method pauseAuto
        * @return undefined
        */
        pauseAuto: function () {
            if (this.timer === null) {
                return;
            }

            window.clearTimeout(this.timer);
            this.timer = null;
        },

        /**
        * Sets the states of the prev/next buttons.
        *
        * @method buttons
        * @return undefined
        */
        buttons: function (n, p) {
            if (n == null) {
                n = !this.locked && this.options.size !== 0 && ((this.options.wrap && this.options.wrap != 'first') || this.options.size === null || this.last < this.options.size);
                if (!this.locked && (!this.options.wrap || this.options.wrap == 'first') && this.options.size !== null && this.last >= this.options.size) {
                    n = this.tail !== null && !this.inTail;
                }
            }

            if (p == null) {
                p = !this.locked && this.options.size !== 0 && ((this.options.wrap && this.options.wrap != 'last') || this.first > 1);
                if (!this.locked && (!this.options.wrap || this.options.wrap == 'last') && this.options.size !== null && this.first == 1) {
                    p = this.tail !== null && this.inTail;
                }
            }

            var self = this;

            if (this.buttonNext.size() > 0) {
                this.buttonNext.unbind(this.options.buttonNextEvent + '.jcarousel', this.funcNext);

                if (n) {
                    this.buttonNext.bind(this.options.buttonNextEvent + '.jcarousel', this.funcNext);
                }

                this.buttonNext[n ? 'removeClass' : 'addClass'](this.className('jcarousel-next-disabled')).attr('disabled', n ? false : true);

                if (this.options.buttonNextCallback !== null && this.buttonNext.data('jcarouselstate') != n) {
                    this.buttonNext.each(function () { self.options.buttonNextCallback(self, this, n); }).data('jcarouselstate', n);
                }
            } else {
                if (this.options.buttonNextCallback !== null && this.buttonNextState != n) {
                    this.options.buttonNextCallback(self, null, n);
                }
            }

            if (this.buttonPrev.size() > 0) {
                this.buttonPrev.unbind(this.options.buttonPrevEvent + '.jcarousel', this.funcPrev);

                if (p) {
                    this.buttonPrev.bind(this.options.buttonPrevEvent + '.jcarousel', this.funcPrev);
                }

                this.buttonPrev[p ? 'removeClass' : 'addClass'](this.className('jcarousel-prev-disabled')).attr('disabled', p ? false : true);

                if (this.options.buttonPrevCallback !== null && this.buttonPrev.data('jcarouselstate') != p) {
                    this.buttonPrev.each(function () { self.options.buttonPrevCallback(self, this, p); }).data('jcarouselstate', p);
                }
            } else {
                if (this.options.buttonPrevCallback !== null && this.buttonPrevState != p) {
                    this.options.buttonPrevCallback(self, null, p);
                }
            }

            this.buttonNextState = n;
            this.buttonPrevState = p;
        },

        /**
        * Notify callback of a specified event.
        *
        * @method notify
        * @return undefined
        * @param evt {String} The event name
        */
        notify: function (evt) {
            var state = this.prevFirst === null ? 'init' : (this.prevFirst < this.first ? 'next' : 'prev');

            // Load items
            this.callback('itemLoadCallback', evt, state);

            if (this.prevFirst !== this.first) {
                this.callback('itemFirstInCallback', evt, state, this.first);
                this.callback('itemFirstOutCallback', evt, state, this.prevFirst);
            }

            if (this.prevLast !== this.last) {
                this.callback('itemLastInCallback', evt, state, this.last);
                this.callback('itemLastOutCallback', evt, state, this.prevLast);
            }

            this.callback('itemVisibleInCallback', evt, state, this.first, this.last, this.prevFirst, this.prevLast);
            this.callback('itemVisibleOutCallback', evt, state, this.prevFirst, this.prevLast, this.first, this.last);
        },

        callback: function (cb, evt, state, i1, i2, i3, i4) {
            if (this.options[cb] == null || (typeof this.options[cb] != 'object' && evt != 'onAfterAnimation')) {
                return;
            }

            var callback = typeof this.options[cb] == 'object' ? this.options[cb][evt] : this.options[cb];

            if (!$.isFunction(callback)) {
                return;
            }

            var self = this;

            if (i1 === undefined) {
                callback(self, state, evt);
            } else if (i2 === undefined) {
                this.get(i1).each(function () { callback(self, this, i1, state, evt); });
            } else {
                var call = function (i) {
                    self.get(i).each(function () { callback(self, this, i, state, evt); });
                };
                for (var i = i1; i <= i2; i++) {
                    if (i !== null && !(i >= i3 && i <= i4)) {
                        call(i);
                    }
                }
            }
        },

        create: function (i) {
            return this.format('<li></li>', i);
        },

        format: function (e, i) {
            e = $(e);
            var split = e.get(0).className.split(' ');
            for (var j = 0; j < split.length; j++) {
                if (split[j].indexOf('jcarousel-') != -1) {
                    e.removeClass(split[j]);
                }
            }
            e.addClass(this.className('jcarousel-item')).addClass(this.className('jcarousel-item-' + i)).css({
                'float': (this.options.rtl ? 'right' : 'left'),
                'list-style': 'none'
            }).attr('jcarouselindex', i);
            return e;
        },

        className: function (c) {
            return c + ' ' + c + (!this.options.vertical ? '-horizontal' : '-vertical');
        },

        dimension: function (e, d) {
            var el = e.jquery !== undefined ? e[0] : e;

            var old = !this.options.vertical ?
                (el.offsetWidth || $jc.intval(this.options.itemFallbackDimension)) + $jc.margin(el, 'marginLeft') + $jc.margin(el, 'marginRight') :
                (el.offsetHeight || $jc.intval(this.options.itemFallbackDimension)) + $jc.margin(el, 'marginTop') + $jc.margin(el, 'marginBottom');

            if (d == null || old == d) {
                return old;
            }

            var w = !this.options.vertical ?
                d - $jc.margin(el, 'marginLeft') - $jc.margin(el, 'marginRight') :
                d - $jc.margin(el, 'marginTop') - $jc.margin(el, 'marginBottom');

            $(el).css(this.wh, w + 'px');

            return this.dimension(el);
        },

        clipping: function () {
            return !this.options.vertical ?
                this.clip[0].offsetWidth - $jc.intval(this.clip.css('borderLeftWidth')) - $jc.intval(this.clip.css('borderRightWidth')) :
                this.clip[0].offsetHeight - $jc.intval(this.clip.css('borderTopWidth')) - $jc.intval(this.clip.css('borderBottomWidth'));
        },

        index: function (i, s) {
            if (s == null) {
                s = this.options.size;
            }

            return Math.round((((i - 1) / s) - Math.floor((i - 1) / s)) * s) + 1;
        }
    });

    $jc.extend({
        /**
        * Gets/Sets the global default configuration properties.
        *
        * @method defaults
        * @return {Object}
        * @param d {Object} A set of key/value pairs to set as configuration properties.
        */
        defaults: function (d) {
            return $.extend(defaults, d || {});
        },

        margin: function (e, p) {
            if (!e) {
                return 0;
            }

            var el = e.jquery !== undefined ? e[0] : e;

            if (p == 'marginRight' && $.browser.safari) {
                var old = { 'display': 'block', 'float': 'none', 'width': 'auto' }, oWidth, oWidth2;

                $.swap(el, old, function () { oWidth = el.offsetWidth; });

                old.marginRight = 0;
                $.swap(el, old, function () { oWidth2 = el.offsetWidth; });

                return oWidth2 - oWidth;
            }

            return $jc.intval($.css(el, p));
        },

        intval: function (v) {
            v = parseInt(v, 10);
            return isNaN(v) ? 0 : v;
        }
    });

    /**
    * Creates a carousel for all matched elements.
    *
    * @example $("#mycarousel").jcarousel();
    * @before <ul id="mycarousel" class="jcarousel-skin-name"><li>First item</li><li>Second item</li></ul>
    * @result
    *
    * <div class="jcarousel-skin-name">
    *   <div class="jcarousel-container">
    *     <div class="jcarousel-clip">
    *       <ul class="jcarousel-list">
    *         <li class="jcarousel-item-1">First item</li>
    *         <li class="jcarousel-item-2">Second item</li>
    *       </ul>
    *     </div>
    *     <div disabled="disabled" class="jcarousel-prev jcarousel-prev-disabled"></div>
    *     <div class="jcarousel-next"></div>
    *   </div>
    * </div>
    *
    * @method jcarousel
    * @return jQuery
    * @param o {Hash|String} A set of key/value pairs to set as configuration properties or a method name to call on a formerly created instance.
    */
    $.fn.jcarousel = function (o) {
        if (typeof o == 'string') {
            var instance = $(this).data('jcarousel'), args = Array.prototype.slice.call(arguments, 1);
            return instance[o].apply(instance, args);
        } else {
            return this.each(function () {
                $(this).data('jcarousel', new $jc(this, o));
            });
        }
    };

})(jQuery);

/*11-jquery.maphilight.min.js*/
(function(f){var b,c,j,m,l,i,g,e,h,a,k;b=document.namespaces;has_canvas=!!document.createElement("canvas").getContext;if(!(has_canvas||b)){f.fn.maphilight=function(){return this};return}if(has_canvas){g=function(p,o,n){if(o<=1){p.style.opacity=o;window.setTimeout(g,10,p,o+0.1,10)}};e=function(n){return Math.max(0,Math.min(parseInt(n,16),255))};h=function(n,o){return"rgba("+e(n.substr(0,2))+","+e(n.substr(2,2))+","+e(n.substr(4,2))+","+o+")"};c=function(n){var o=f('<canvas style="width:'+n.width+"px;height:"+n.height+'px;"></canvas>').get(0);o.getContext("2d").clearRect(0,0,o.width,o.height);return o};j=function(q,n,t,p,o){var s,r=q.getContext("2d");r.beginPath();if(n=="rect"){r.rect(t[0],t[1],t[2]-t[0],t[3]-t[1])}else{if(n=="poly"){r.moveTo(t[0],t[1]);for(s=2;s<t.length;s+=2){r.lineTo(t[s],t[s+1])}}else{if(n=="circ"){r.arc(t[0],t[1],t[2],0,Math.PI*2,false)}}}r.closePath();if(p.fill){r.fillStyle=h(p.fillColor,p.fillOpacity);r.fill()}if(p.stroke){r.strokeStyle=h(p.strokeColor,p.strokeOpacity);r.lineWidth=p.strokeWidth;r.stroke()}if(p.fade){g(q,0)}};m=function(n){n.getContext("2d").clearRect(0,0,n.width,n.height)}}else{c=function(n){return f('<var style="zoom:1;overflow:hidden;display:block;width:'+n.width+"px;height:"+n.height+'px;"></var>').get(0)};j=function(o,r,s,v,n){var t,u,p,q;t='<v:fill color="#'+v.fillColor+'" opacity="'+(v.fill?v.fillOpacity:0)+'" />';u=(v.stroke?'strokeweight="'+v.strokeWidth+'" stroked="t" strokecolor="#'+v.strokeColor+'"':'stroked="f"');p='<v:stroke opacity="'+v.strokeOpacity+'"/>';if(r=="rect"){q=f('<v:rect name="'+n+'" filled="t" '+u+' style="zoom:1;margin:0;padding:0;display:block;position:absolute;left:'+s[0]+"px;top:"+s[1]+"px;width:"+(s[2]-s[0])+"px;height:"+(s[3]-s[1])+'px;"></v:rect>')}else{if(r=="poly"){q=f('<v:shape name="'+n+'" filled="t" '+u+' coordorigin="0,0" coordsize="'+o.width+","+o.height+'" path="m '+s[0]+","+s[1]+" l "+s.join(",")+' x e" style="zoom:1;margin:0;padding:0;display:block;position:absolute;top:0px;left:0px;width:'+o.width+"px;height:"+o.height+'px;"></v:shape>')}else{if(r=="circ"){q=f('<v:oval name="'+n+'" filled="t" '+u+' style="zoom:1;margin:0;padding:0;display:block;position:absolute;left:'+(s[0]-s[2])+"px;top:"+(s[1]-s[2])+"px;width:"+(s[2]*2)+"px;height:"+(s[2]*2)+'px;"></v:oval>')}}}q.get(0).innerHTML=t+p;f(o).append(q)};m=function(n){f(n).find("[name=highlighted]").remove()}}l=function(o){var n,p=o.getAttribute("coords").split(",");for(n=0;n<p.length;n++){p[n]=parseFloat(p[n])}return[o.getAttribute("shape").toLowerCase().substr(0,4),p]};k=function(p,o){var n=f(p);return f.extend({},o,f.metadata?n.metadata():false,n.data("maphilight"))};a=function(n){if(!n.complete){return false}if(typeof n.naturalWidth!="undefined"&&n.naturalWidth==0){return false}return true};i={position:"absolute",left:0,top:0,padding:0,border:0};var d=false;f.fn.maphilight=function(p){p=f.extend({},f.fn.maphilight.defaults,p);if(f.browser.msie&&!d){document.namespaces.add("v","urn:schemas-microsoft-com:vml");var o=document.createStyleSheet();var n=["shape","rect","oval","circ","fill","stroke","imagedata","group","textbox"];f.each(n,function(){o.addRule("v\\:"+this,"behavior: url(#default#VML); antialias:true")});d=true}return this.each(function(){var v,s,z,r,u,w,y,t,x;v=f(this);if(!a(this)){return window.setTimeout(function(){v.maphilight(p)},200)}z=f.extend({},p,f.metadata?v.metadata():false,v.data("maphilight"));x=v.get(0).getAttribute("usemap");r=f('map[name="'+x.substr(1)+'"]');if(!(v.is("img")&&x&&r.size()>0)){return}if(v.hasClass("maphilighted")){var q=v.parent();v.insertBefore(q);q.remove();f(r).unbind(".maphilight").find("area[coords]").unbind(".maphilight")}s=f("<div></div>").css({display:"block",background:"url("+this.src+")",position:"relative",padding:0,width:this.width,height:this.height});if(z.wrapClass){if(z.wrapClass===true){s.addClass(f(this).attr("class"))}else{s.addClass(z.wrapClass)}}v.before(s).css("opacity",0).css(i).remove();if(f.browser.msie){v.css("filter","Alpha(opacity=0)")}s.append(v);u=c(this);f(u).css(i);u.height=this.height;u.width=this.width;y=function(C){var A,B;B=k(this,z);if(!B.neverOn&&!B.alwaysOn){A=l(this);j(u,A[0],A[1],B,"highlighted");if(B.groupBy&&f(this).attr(B.groupBy)){var D=this;r.find("area["+B.groupBy+"="+f(this).attr(B.groupBy)+"]").each(function(){if(this!=D){var F=k(this,z);if(!F.neverOn&&!F.alwaysOn){var E=l(this);j(u,E[0],E[1],F,"highlighted")}}})}}};f(r).bind("alwaysOn.maphilight",function(){if(w){m(w)}if(!has_canvas){f(u).empty()}f(r).find("area[coords]").each(function(){var A,B;B=k(this,z);if(B.alwaysOn){if(!w&&has_canvas){w=c(v.get());f(w).css(i);w.width=v.width();w.height=v.height();v.before(w)}A=l(this);if(has_canvas){j(w,A[0],A[1],B,"")}else{j(u,A[0],A[1],B,"")}}})});if(z.alwaysOn){f(r).find("area[coords]").each(y)}else{f(r).find("area[coords]").trigger("alwaysOn.maphilight").bind("mouseover.maphilight",y).bind("mouseout.maphilight",function(A){m(u)})}v.before(u);v.addClass("maphilighted")})};f.fn.maphilight.defaults={fill:true,fillColor:"000000",fillOpacity:0.2,stroke:true,strokeColor:"ff0000",strokeOpacity:1,strokeWidth:1,fade:true,alwaysOn:false,neverOn:false,groupBy:false,wrapClass:true}})(jQuery);
/*12-jquery.mousewheel-3.0.2.min.js*/
/*! Copyright (c) 2009 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.
 * Thanks to: http://adomas.org/javascript-mouse-wheel/ for some pointers.
 * Thanks to: Mathias Bank(http://www.mathias-bank.de) for a scope bug fix.
 *
 * Version: 3.0.2
 * 
 * Requires: 1.2.2+
 */

(function(b){function d(a){var f=[].slice.call(arguments,1),e=0;a=b.event.fix(a||window.event);a.type="mousewheel";if(a.wheelDelta)e=a.wheelDelta/120;if(a.detail)e=-a.detail/3;f.unshift(a,e);return b.event.handle.apply(this,f)}var c=["DOMMouseScroll","mousewheel"];b.event.special.mousewheel={setup:function(){if(this.addEventListener)for(var a=c.length;a;)this.addEventListener(c[--a],d,false);else this.onmousewheel=d},teardown:function(){if(this.removeEventListener)for(var a=c.length;a;)this.removeEventListener(c[--a],
d,false);else this.onmousewheel=null}};b.fn.extend({mousewheel:function(a){return a?this.bind("mousewheel",a):this.trigger("mousewheel")},unmousewheel:function(a){return this.unbind("mousewheel",a)}})})(jQuery);
/*12-jquery.url.min.js*/
// JQuery URL Parser
// Written by Mark Perkins, mark@allmarkedup.com
// License: http://unlicense.org/ (i.e. do what you want with it!)

jQuery.url = function()
{
	var segments = {};
	
	var parsed = {};
	
	/**
    * Options object. Only the URI and strictMode values can be changed via the setters below.
    */
  	var options = {
	
		url : window.location, // default URI is the page in which the script is running
		
		strictMode: false, // 'loose' parsing by default
	
		key: ["source","protocol","authority","userInfo","user","password","host","port","relative","path","directory","file","query","anchor"], // keys available to query 
		
		q: {
			name: "queryKey",
			parser: /(?:^|&)([^&=]*)=?([^&]*)/g
		},
		
		parser: {
			strict: /^(?:([^:\/?#]+):)?(?:\/\/((?:(([^:@]*):?([^:@]*))?@)?([^:\/?#]*)(?::(\d*))?))?((((?:[^?#\/]*\/)*)([^?#]*))(?:\?([^#]*))?(?:#(.*))?)/,  //less intuitive, more accurate to the specs
			loose:  /^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:@]*):?([^:@]*))?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/ // more intuitive, fails on relative paths and deviates from specs
		}
		
	};
	
    /**
     * Deals with the parsing of the URI according to the regex above.
 	 * Written by Steven Levithan - see credits at top.
     */		
	var parseUri = function()
	{
		str = decodeURI( options.url );
		
		var m = options.parser[ options.strictMode ? "strict" : "loose" ].exec( str );
		var uri = {};
		var i = 14;

		while ( i-- ) {
			uri[ options.key[i] ] = m[i] || "";
		}

		uri[ options.q.name ] = {};
		uri[ options.key[12] ].replace( options.q.parser, function ( $0, $1, $2 ) {
			if ($1) {
				uri[options.q.name][$1] = $2;
			}
		});

		return uri;
	};

    /**
     * Returns the value of the passed in key from the parsed URI.
  	 * 
	 * @param string key The key whose value is required
     */		
	var key = function( key )
	{
//		if ( jQuery.isEmptyObject(parsed) )
	    //		{

	    try {
	        setUp(); // if the URI has not been parsed yet then do this first...	
	    } catch (e) {

	    }

//		} 
		if ( key == "base" )
		{
			if ( parsed.port !== null && parsed.port !== "" )
			{
				return parsed.protocol+"://"+parsed.host+":"+parsed.port+"/";	
			}
			else
			{
				return parsed.protocol+"://"+parsed.host+"/";
			}
		}
	
		return ( parsed[key] === "" ) ? null : parsed[key];
	};
	
	/**
     * Returns the value of the required query string parameter.
  	 * 
	 * @param string item The parameter whose value is required
     */		
	var param = function( item )
	{
		  try {
			setUp(); // if the URI has not been parsed yet then do this first...	
} catch (e) {

}
		return ( parsed.queryKey[item] === null ) ? null : parsed.queryKey[item];
	};

    /**
     * 'Constructor' (not really!) function.
     *  Called whenever the URI changes to kick off re-parsing of the URI and splitting it up into segments. 
     */	
	var setUp = function()
	{
		parsed = parseUri();
		
		getSegments();	
	};
	
    /**
     * Splits up the body of the URI into segments (i.e. sections delimited by '/')
     */
	var getSegments = function()
	{
		var p = parsed.path;
		segments = []; // clear out segments array
		segments = parsed.path.length == 1 ? {} : ( p.charAt( p.length - 1 ) == "/" ? p.substring( 1, p.length - 1 ) : path = p.substring( 1 ) ).split("/");
	};
	
	return {
		
	    /**
	     * Sets the parsing mode - either strict or loose. Set to loose by default.
	     *
	     * @param string mode The mode to set the parser to. Anything apart from a value of 'strict' will set it to loose!
	     */
		setMode : function( mode )
		{
			options.strictMode = mode == "strict" ? true : false;
			return this;
		},
		
		/**
	     * Sets URI to parse if you don't want to to parse the current page's URI.
		 * Calling the function with no value for newUri resets it to the current page's URI.
	     *
	     * @param string newUri The URI to parse.
	     */		
		setUrl : function( newUri )
		{
			options.url = newUri === undefined ? window.location : newUri;
			setUp();
			return this;
		},		
		
		/**
	     * Returns the value of the specified URI segment. Segments are numbered from 1 to the number of segments.
		 * For example the URI http://test.com/about/company/ segment(1) would return 'about'.
		 *
		 * If no integer is passed into the function it returns the number of segments in the URI.
	     *
	     * @param int pos The position of the segment to return. Can be empty.
	     */	
		segment : function( pos )
		{
			try
			{
				setUp(); // if the URI has not been parsed yet then do this first...	
			  } catch (e) {

	    }
			if ( pos === undefined )
			{
				return segments.length;
			}
			return ( segments[pos] === "" || segments[pos] === undefined ) ? null : segments[pos];
		},
		
		attr : key, // provides public access to private 'key' function - see above
		
		param : param // provides public access to private 'param' function - see above
		
	};
	
}();
/*13-jquery.hoverIntent.min.js*/
/**
* hoverIntent is similar to jQuery's built-in "hover" function except that
* instead of firing the onMouseOver event immediately, hoverIntent checks
* to see if the user's mouse has slowed down (beneath the sensitivity
* threshold) before firing the onMouseOver event.
* 
* hoverIntent r5 // 2007.03.27 // jQuery 1.1.2
* <http://cherne.net/brian/resources/jquery.hoverIntent.html>
* 
* hoverIntent is currently available for use in all personal or commercial 
* projects under both MIT and GPL licenses. This means that you can choose 
* the license that best suits your project, and use it accordingly.
* 
* // basic usage (just like .hover) receives onMouseOver and onMouseOut functions
* $("ul li").hoverIntent( showNav , hideNav );
* 
* // advanced usage receives configuration object only
* $("ul li").hoverIntent({
*	sensitivity: 2, // number = sensitivity threshold (must be 1 or higher)
*	interval: 50,   // number = milliseconds of polling interval
*	over: showNav,  // function = onMouseOver callback (required)
*	timeout: 100,   // number = milliseconds delay before onMouseOut function call
*	out: hideNav    // function = onMouseOut callback (required)
* });
* 
* @param  f  onMouseOver function || An object with configuration options
* @param  g  onMouseOut function  || Nothing (use configuration options object)
* @return    The object (aka "this") that called hoverIntent, and the event object
* @author    Brian Cherne <brian@cherne.net>
* 
* modified by Karl Swedberg. Namespaced events in order to work better with clueTip plugin
*/
(function($) {
	$.fn.hoverIntent = function(f,g) {
		// default configuration options
		var cfg = {
			sensitivity: 7,
			interval: 100,
			timeout: 0
		};
		// override configuration options with user supplied object
		cfg = $.extend(cfg, g ? { over: f, out: g } : f );

		// instantiate variables
		// cX, cY = current X and Y position of mouse, updated by mousemove event
		// pX, pY = previous X and Y position of mouse, set by mouseover and polling interval
		var cX, cY, pX, pY;

		// A private function for getting mouse position
		var track = function(ev) {
			cX = ev.pageX;
			cY = ev.pageY;
		};

		// A private function for comparing current and previous mouse position
		var compare = function(ev,ob) {
			ob.hoverIntent_t = clearTimeout(ob.hoverIntent_t);
			// compare mouse positions to see if they've crossed the threshold
			if ( ( Math.abs(pX-cX) + Math.abs(pY-cY) ) < cfg.sensitivity ) {
				$(ob).unbind("mousemove",track);
				// set hoverIntent state to true (so mouseOut can be called)
				ob.hoverIntent_s = 1;
				return cfg.over.apply(ob,[ev]);
			} else {
				// set previous coordinates for next time
				pX = cX; pY = cY;
				// use self-calling timeout, guarantees intervals are spaced out properly (avoids JavaScript timer bugs)
				ob.hoverIntent_t = setTimeout( function(){compare(ev, ob);} , cfg.interval );
			}
		};

		// A private function for delaying the mouseOut function
		var delay = function(ev,ob) {
			ob.hoverIntent_t = clearTimeout(ob.hoverIntent_t);
			ob.hoverIntent_s = 0;
			return cfg.out.apply(ob,[ev]);
		};

		// A private function for handling mouse 'hovering'
		var handleHover = function(e) {
			// next three lines copied from jQuery.hover, ignore children onMouseOver/onMouseOut
			var p = (e.type == "mouseover" ? e.fromElement : e.toElement) || e.relatedTarget;
			while ( p && p != this ) { try { p = p.parentNode; } catch(e) { p = this; } }
			if ( p == this ) { return false; }

			// copy objects to be passed into t (required for event object to be passed in IE)
			var ev = jQuery.extend({},e);
			var ob = this;

			// cancel hoverIntent timer if it exists
			if (ob.hoverIntent_t) { ob.hoverIntent_t = clearTimeout(ob.hoverIntent_t); }

			// else e.type == "onmouseover"
			if (e.type == "mouseover") {
				// set "previous" X and Y position based on initial entry point
				pX = ev.pageX; pY = ev.pageY;
				// update "current" X and Y position based on mousemove
				$(ob).bind("mousemove.cluetip",track);
				// start polling interval (self-calling timeout) to compare mouse coordinates over time
				if (ob.hoverIntent_s != 1) { ob.hoverIntent_t = setTimeout( function(){compare(ev,ob);} , cfg.interval );}

			// else e.type == "onmouseout"
			} else {
				// unbind expensive mousemove event
				$(ob).unbind("mousemove.cluetip",track);
				// if hoverIntent state is true, then call the mouseOut function after the specified delay
				if (ob.hoverIntent_s == 1) { ob.hoverIntent_t = setTimeout( function(){delay(ev,ob);} , cfg.timeout );}
			}
		};

		// bind the function to the two event listeners
		return this.bind('mouseover.cluetip', handleHover).bind('mouseout.cluetip', handleHover);
	};
})(jQuery);
/*14-jquery.ae.image.resize.min.js*/
(function ($) {
    $.fn.aeImageResize = function (params) {
        var aspectRatio = 0;
        // Nasty I know but it's done only once, so not too bad I guess
        // Alternate suggestions welcome :)
        var isIE6 = $.browser.msie && (6 == ~ ~$.browser.version);

        // We cannot do much unless we have one of these
        if (!params.height && !params.width) {
            return this;
        }

        // Calculate aspect ratio now, if possible
        if (params.height && params.width) {
            aspectRatio = params.width / params.height;
        }

        // Attach handler to load
        // Handler is executed just once per element
        // Load event required for Webkit browsers
        return this.one("load", function () {

            // Remove all attributes and CSS rules
            this.removeAttribute("height");
            this.removeAttribute("width");
            this.style.height = this.style.width = "";

            var imgHeight = this.height;
            var imgWidth = this.width;
            var imgAspectRatio = imgWidth / imgHeight;
            var bxHeight = params.height;
            var bxWidth = params.width;
            var bxAspectRatio = aspectRatio;

            // Work the magic!
            // If one parameter is missing, we just force calculate it
            if (!bxAspectRatio) {
                if (bxHeight) {
                    bxAspectRatio = imgAspectRatio + 1;
                } else {
                    bxAspectRatio = imgAspectRatio - 1;
                }
            }

            // Only resize the images that need resizing
            if ((bxHeight && imgHeight > bxHeight) || (bxWidth && imgWidth > bxWidth)) {
                if (imgAspectRatio > bxAspectRatio) {
                    bxHeight = ~ ~(imgHeight / imgWidth * bxWidth);
                } else {
                    bxWidth = ~ ~(imgWidth / imgHeight * bxHeight);
                }
                this.height = bxHeight;
                this.width = bxWidth;
            }

        }).each(function () {
        // Trigger load event (for Gecko and MSIE)
        if (this.complete || isIE6) {
            $(this).trigger("load");
        }
    });
    };
})(jQuery);
/*99-jquery.colorbox.min.js*/
// ColorBox v1.3.15 - a full featured, light-weight, customizable lightbox based on jQuery 1.3+
// Copyright (c) 2010 Jack Moore - jack@colorpowered.com
// Licensed under the MIT license: http://www.opensource.org/licenses/mit-license.php
(function ($, window) {

    var 
    // ColorBox Default Settings.	
    // See http://colorpowered.com/colorbox for details.
	defaults = {
	    transition: "elastic",
	    speed: 300,
	    width: false,
	    initialWidth: "600",
	    innerWidth: false,
	    maxWidth: false,
	    height: false,
	    initialHeight: "450",
	    innerHeight: false,
	    maxHeight: false,
	    scalePhotos: true,
	    scrolling: true,
	    inline: false,
	    html: false,
	    iframe: false,
	    photo: false,
	    href: false,
	    title: false,
	    subtitle: false,
	    video: false,
	    rel: false,
	    opacity: 0.9,
	    preloading: true,
	    current: "{current} of {total}",
	    previous: "previous",
	    next: "next",
	    close: "<a href='#'>CLOSE</a>",
	    open: false,
	    returnFocus: true,
	    loop: true,
	    slideshow: false,
	    slideshowAuto: true,
	    slideshowSpeed: 2500,
	    slideshowStart: "start slideshow",
	    slideshowStop: "stop slideshow",
	    onOpen: false,
	    onLoad: false,
	    onComplete: false,
	    onCleanup: false,
	    onClosed: false,
	    overlayClose: true,
	    escKey: true,
	    arrowKey: true
	},

    // Abstracting the HTML and event identifiers for easy rebranding
	colorbox = 'colorbox',
	prefix = 'cbox',

    // Events	
	event_open = prefix + '_open',
	event_load = prefix + '_load',
	event_complete = prefix + '_complete',
	event_cleanup = prefix + '_cleanup',
	event_closed = prefix + '_closed',
	event_purge = prefix + '_purge',
	event_loaded = prefix + '_loaded',

    // Special Handling for IE
	isIE = $.browser.msie && !$.support.opacity, // feature detection alone gave a false positive on at least one phone browser and on some development versions of Chrome.
	isIE6 = isIE && $.browser.version < 7,
	event_ie6 = prefix + '_IE6',

    // Cached jQuery Object Variables
	$overlay,
	$box,
	$wrap,
	$content,
	$topBorder,
	$leftBorder,
	$rightBorder,
	$bottomBorder,
	$related,
	$window,
	$loaded,
	$loadingBay,
	$loadingOverlay,
	$title,
    $title2,
	$current,
	$slideshow,
	$next,
	$prev,
	$close,

    // Variables for cached values or use across multiple functions
	interfaceHeight,
	interfaceWidth,
	loadedHeight,
	loadedWidth,
	element,
	index,
	settings,
	open,
	active,
	closing = false,

	publicMethod,
	boxElement = prefix + 'Element';

    // ****************
    // HELPER FUNCTIONS
    // ****************

    // jQuery object generator to reduce code size
    function $div(id, css) {
        id = id ? ' id="' + prefix + id + '"' : '';
        css = css ? ' style="' + css + '"' : '';
        return $('<div' + id + css + '/>');
    }

    // Convert % values to pixels
    function setSize(size, dimension) {
        dimension = dimension === 'x' ? $window.width() : $window.height();
        return (typeof size === 'string') ? Math.round((/%/.test(size) ? (dimension / 100) * parseInt(size, 10) : parseInt(size, 10))) : size;
    }

    // Checks an href to see if it is a photo.
    // There is a force photo option (photo: true) for hrefs that cannot be matched by this regex.
    function isImage(url) {
        return settings.photo || /\.(gif|png|jpg|jpeg|bmp)(?:\?([^#]*))?(?:#(\.*))?$/i.test(url);
    }

    // Assigns function results to their respective settings.  This allows functions to be used as values.
    function process(settings) {
        for (var i in settings) {
            if ($.isFunction(settings[i]) && i.substring(0, 2) !== 'on') { // checks to make sure the function isn't one of the callbacks, they will be handled at the appropriate time.
                settings[i] = settings[i].call(element);
            }
        }

        settings.rel = settings.rel || element.rel || 'nofollow';
        
        settings.href = settings.href || $(element).attr('href');
       

        if ($(element).attr('maintitle')) {
            settings.title = $(element).attr('maintitle');
        } else {
            settings.subtitle = "";
        }

        if ($(element).attr('subtitle')) {
            settings.subtitle = $(element).attr('subtitle');
        } else {
            settings.subtitle = "";
        }

        if ($(element).attr('video')) {
            settings.video = $(element).attr('video');
        } else {
            settings.video = "";
        }

        return settings;
    }

    function trigger(event, callback) {
        if (callback) {
            callback.call(element);
        }
        $.event.trigger(event);
    }

    // Slideshow functionality
    function slideshow() {
        var 
		timeOut,
		className = prefix + "Slideshow_",
		click = "click." + prefix,
		start,
		stop,
		clear;

        if (settings.slideshow && $related[1]) {
            start = function () {
                $slideshow
					.text(settings.slideshowStop)
					.unbind(click)
					.bind(event_complete, function () {
					    if (index < $related.length - 1 || settings.loop) {
					        timeOut = setTimeout(publicMethod.next, settings.slideshowSpeed);
					    }
					})
					.bind(event_load, function () {
					    clearTimeout(timeOut);
					})
					.one(click + ' ' + event_cleanup, stop);
                $box.removeClass(className + "off").addClass(className + "on");
                timeOut = setTimeout(publicMethod.next, settings.slideshowSpeed);
            };

            stop = function () {
                clearTimeout(timeOut);
                $slideshow
					.text(settings.slideshowStart)
					.unbind([event_complete, event_load, event_cleanup, click].join(' '))
					.one(click, start);
                $box.removeClass(className + "on").addClass(className + "off");
            };

            if (settings.slideshowAuto) {
                start();
            } else {
                stop();
            }
        }
    }

    function launch(elem) {
        if (!closing) {

            element = elem;

            settings = process($.extend({}, $.data(element, colorbox)));

            $related = $(element);

            index = 0;

            if (settings.rel !== 'nofollow') {
                $related = $('.' + boxElement).filter(function () {
                    var relRelated = $.data(this, colorbox).rel || this.rel;
                    return (relRelated === settings.rel);
                });
                index = $related.index(element);

                // Check direct calls to ColorBox.
                if (index === -1) {
                    $related = $related.add(element);
                    index = $related.length - 1;
                }
            }

            if (!open) {
                open = active = true; // Prevents the page-change action from queuing up if the visitor holds down the left or right keys.

                $box.show();

                if (settings.returnFocus) {
                    try {
                        element.blur();
                        $(element).one(event_closed, function () {
                            try {
                                this.focus();
                            } catch (e) {
                                // do nothing
                            }
                        });
                    } catch (e) {
                        // do nothing
                    }
                }

                // +settings.opacity avoids a problem in IE when using non-zero-prefixed-string-values, like '.5'
                $overlay.css({ "opacity": +settings.opacity, "cursor": settings.overlayClose ? "pointer" : "auto" }).show();

                // Opens inital empty ColorBox prior to content being loaded.
                settings.w = setSize(settings.initialWidth, 'x');
                settings.h = setSize(settings.initialHeight, 'y');
                publicMethod.position(0);

                if (isIE6) {
                    $window.bind('resize.' + event_ie6 + ' scroll.' + event_ie6, function () {
                        $overlay.css({ width: $window.width(), height: $window.height(), top: $window.scrollTop(), left: $window.scrollLeft() });
                    }).trigger('scroll.' + event_ie6);
                }

                trigger(event_open, settings.onOpen);

                $current.add($prev).add($next).add($slideshow).add($title).add($title2).hide();

                $close.html(settings.close).show();
            }

            publicMethod.load(true);
        }
    }

    // ****************
    // PUBLIC FUNCTIONS
    // Usage format: $.fn.colorbox.close();
    // Usage from within an iframe: parent.$.fn.colorbox.close();
    // ****************

    publicMethod = $.fn[colorbox] = $[colorbox] = function (options, callback) {
        var $this = this, autoOpen;

        if (!$this[0] && $this.selector) { // if a selector was given and it didn't match any elements, go ahead and exit.
            return $this;
        }

        options = options || {};

        if (callback) {
            options.onComplete = callback;
        }

        if (!$this[0] || $this.selector === undefined) { // detects $.colorbox() and $.fn.colorbox()
            $this = $('<a/>');
            options.open = true; // assume an immediate open
        }

        $this.each(function () {
            $.data(this, colorbox, $.extend({}, $.data(this, colorbox) || defaults, options));
            $(this).addClass(boxElement);
        });

        autoOpen = options.open;

        if ($.isFunction(autoOpen)) {
            autoOpen = autoOpen.call($this);
        }

        if (autoOpen) {
            launch($this[0]);
        }

        return $this;
    };

    // Initialize ColorBox: store common calculations, preload the interface graphics, append the html.
    // This preps colorbox for a speedy open when clicked, and lightens the burdon on the browser by only
    // having to run once, instead of each time colorbox is opened.
    publicMethod.init = function () {
        // Create & Append jQuery Objects
        $window = $(window);
        $box = $div().attr({ id: colorbox, 'class': isIE ? prefix + 'IE' : '' });
        $overlay = $div("Overlay", isIE6 ? 'position:absolute' : '').hide();

        $wrap = $div("Wrapper");
        $content = $div("Content").append(
			$loaded = $div("LoadedContent", 'width:0; height:0; overflow:hidden'),
			$loadingOverlay = $div("LoadingOverlay").add($div("LoadingGraphic")),
			$title = $div("Title"),
            $title2 = $div("Title2"),
			$current = $div("Current"),
			$next = $div("Next"),
			$prev = $div("Previous"),
			$slideshow = $div("Slideshow").bind(event_open, slideshow)

		);
        $wrap.append( // The 3x3 Grid that makes up ColorBox
			$div().append(
				$div("TopLeft"),
				$topBorder = $div("TopCenter"),
				$div("TopRight")
			),
            $div(false, 'clear:left').append(
				$close = $div("Close")
			),
			$div(false, 'clear:left').append(
				$leftBorder = $div("MiddleLeft"),
				$content,
				$rightBorder = $div("MiddleRight")
			),
			$div(false, 'clear:left').append(
				$div("BottomLeft"),
				$bottomBorder = $div("BottomCenter"),
				$div("BottomRight")
			)

		).children().children().css({ 'float': 'left' });

        $loadingBay = $div(false, 'position:absolute; width:9999px; visibility:hidden; display:none');

        $('body').prepend($overlay, $box.append($wrap, $loadingBay));

        $content.children()
		.hover(function () {
		    $(this).addClass('hover');
		}, function () {
		    $(this).removeClass('hover');
		}).addClass('hover');

        // Cache values needed for size calculations
        interfaceHeight = $topBorder.height() + $bottomBorder.height() + $content.outerHeight(true) - $content.height(); //Subtraction needed for IE6
        interfaceWidth = $leftBorder.width() + $rightBorder.width() + $content.outerWidth(true) - $content.width();
        loadedHeight = $loaded.outerHeight(true);
        loadedWidth = $loaded.outerWidth(true);

        // Setting padding to remove the need to do size conversions during the animation step.
        $box.css({ "padding-bottom": interfaceHeight, "padding-right": interfaceWidth }).hide();

        // Setup button events.
        $next.click(publicMethod.next);
        $prev.click(publicMethod.prev);
        $close.click(publicMethod.close);

        // Adding the 'hover' class allowed the browser to load the hover-state
        // background graphics.  The class can now can be removed.
        $content.children().removeClass('hover');

        $('.' + boxElement).live('click', function (e) {
            // checks to see if it was a non-left mouse-click and for clicks modified with ctrl, shift, or alt.
            if (!((e.button !== 0 && typeof e.button !== 'undefined') || e.ctrlKey || e.shiftKey || e.altKey)) {
                e.preventDefault();
                launch(this);
            }
        });

        $overlay.click(function () {
            if (settings.overlayClose) {
                publicMethod.close();
            }
        });

        // Set Navigation Key Bindings
        $(document).bind("keydown", function (e) {
            if (open && settings.escKey && e.keyCode === 27) {
                e.preventDefault();
                publicMethod.close();
            }
            if (open && settings.arrowKey && !active && $related[1]) {
                if (e.keyCode === 37 && (index || settings.loop)) {
                    e.preventDefault();
                    $prev.click();
                } else if (e.keyCode === 39 && (index < $related.length - 1 || settings.loop)) {
                    e.preventDefault();
                    $next.click();
                }
            }
        });
    };

    publicMethod.remove = function () {
        $box.add($overlay).remove();
        $('.' + boxElement).die('click').removeData(colorbox).removeClass(boxElement);
    };

    publicMethod.position = function (speed, loadedCallback) {
        var 
		animate_speed,
        // keeps the top and left positions within the browser's viewport.
		posTop = Math.max(document.documentElement.clientHeight - settings.h - loadedHeight - interfaceHeight, 0) / 2 + $window.scrollTop(),
		posLeft = Math.max($window.width() - settings.w - loadedWidth - interfaceWidth, 0) / 2 + $window.scrollLeft();

        // setting the speed to 0 to reduce the delay between same-sized content.
        animate_speed = ($box.width() === settings.w + loadedWidth && $box.height() === settings.h + loadedHeight) ? 0 : speed;

        // this gives the wrapper plenty of breathing room so it's floated contents can move around smoothly,
        // but it has to be shrank down around the size of div#colorbox when it's done.  If not,
        // it can invoke an obscure IE bug when using iframes.
        $wrap[0].style.width = $wrap[0].style.height = "9999px";

        function modalDimensions(that) {
            // loading overlay height has to be explicitly set for IE6.
            $topBorder[0].style.width = $bottomBorder[0].style.width = $content[0].style.width = that.style.width;
            $loadingOverlay[0].style.height = $loadingOverlay[1].style.height = $content[0].style.height = $leftBorder[0].style.height = $rightBorder[0].style.height = that.style.height;
        }

        $box.dequeue().animate({ width: settings.w + loadedWidth, height: settings.h + loadedHeight, top: posTop, left: posLeft }, {
            duration: animate_speed,
            complete: function () {
                modalDimensions(this);

                active = false;

                // shrink the wrapper down to exactly the size of colorbox to avoid a bug in IE's iframe implementation.
                $wrap[0].style.width = (settings.w + loadedWidth + interfaceWidth) + "px";
                $wrap[0].style.height = (settings.h + loadedHeight + interfaceHeight) + "px";

                if (loadedCallback) {
                    loadedCallback();
                }
            },
            step: function () {
                modalDimensions(this);
            }
        });
    };

    publicMethod.resize = function (options) {
        if (open) {
            options = options || {};

            if (options.width) {
                settings.w = setSize(options.width, 'x') - loadedWidth - interfaceWidth;
            }
            if (options.innerWidth) {
                settings.w = setSize(options.innerWidth, 'x');
            }
            $loaded.css({ width: settings.w });

            if (options.height) {
                settings.h = setSize(options.height, 'y') - loadedHeight - interfaceHeight;
            }
            if (options.innerHeight) {
                settings.h = setSize(options.innerHeight, 'y');
            }
            if (!options.innerHeight && !options.height) {
                var $child = $loaded.wrapInner("<div style='overflow:auto'></div>").children(); // temporary wrapper to get an accurate estimate of just how high the total content should be.
                settings.h = $child.height();
                $child.replaceWith($child.children()); // ditch the temporary wrapper div used in height calculation
            }
            $loaded.css({ height: settings.h });

            publicMethod.position(settings.transition === "none" ? 0 : settings.speed);
        }
    };

    publicMethod.prep = function (object) {
        if (!open) {
            return;
        }

        var photo,
		speed = settings.transition === "none" ? 0 : settings.speed;

        $window.unbind('resize.' + prefix);
        $loaded.remove();
        $loaded = $div('LoadedContent').html(object);

        function getWidth() {
            settings.w = settings.w || $loaded.width();
            settings.w = settings.mw && settings.mw < settings.w ? settings.mw : settings.w;
            return settings.w;
        }
        function getHeight() {
            settings.h = settings.h || $loaded.height();
            settings.h = settings.mh && settings.mh < settings.h ? settings.mh : settings.h;
            return settings.h;
        }

        $loaded.hide()
		.appendTo($loadingBay.show())// content has to be appended to the DOM for accurate size calculations.
		.css({ width: getWidth(), overflow: settings.scrolling ? 'auto' : 'hidden' })
		.css({ height: getHeight() })// sets the height independently from the width in case the new width influences the value of height.
		.prependTo($content);

        $loadingBay.hide();

        // floating the IMG removes the bottom line-height and fixed a problem where IE miscalculates the width of the parent element as 100% of the document width.
        $('#' + prefix + 'Photo').css({ cssFloat: 'none', marginLeft: 'auto', marginRight: 'auto' });

        // Hides SELECT elements in IE6 because they would otherwise sit on top of the overlay.
        if (isIE6) {
            $('select').not($box.find('select')).filter(function () {
                return this.style.visibility !== 'hidden';
            }).css({ 'visibility': 'hidden' }).one(event_cleanup, function () {
                this.style.visibility = 'inherit';
            });
        }

        function setPosition(s) {
            var prev, prevSrc, next, nextSrc, total = $related.length, loop = settings.loop;
            publicMethod.position(s, function () {
                function defilter() {
                    if (isIE) {
                        //IE adds a filter when ColorBox fades in and out that can cause problems if the loaded content contains transparent pngs.
                        $box[0].style.removeAttribute("filter");
                    }
                }

                if (!open) {
                    return;
                }

                if (isIE) {
                    //This fadeIn helps the bicubic resampling to kick-in.
                    if (photo) {
                        $loaded.fadeIn(100);
                    }
                }

                $loaded.show();

                trigger(event_loaded);

                $title.show().html(settings.title);
                $title2.show().html(settings.subtitle);

                if (total > 1) { // handle grouping
                    if (typeof settings.current === "string") {
                        $current.html(settings.current.replace(/\{current\}/, index + 1).replace(/\{total\}/, total)).show();
                    }

                    $next[(loop || index < total - 1) ? "show" : "hide"]().html(settings.next);
                    $prev[(loop || index) ? "show" : "hide"]().html(settings.previous);

                    prev = index ? $related[index - 1] : $related[total - 1];
                    next = index < total - 1 ? $related[index + 1] : $related[0];

                    if (settings.slideshow) {
                        $slideshow.show();
                    }

                    // Preloads images within a rel group
                    if (settings.preloading) {
                        nextSrc = $.data(next, colorbox).href || next.href;
                        prevSrc = $.data(prev, colorbox).href || prev.href;

                        nextSrc = $.isFunction(nextSrc) ? nextSrc.call(next) : nextSrc;
                        prevSrc = $.isFunction(prevSrc) ? prevSrc.call(prev) : prevSrc;

                        if (isImage(nextSrc)) {
                            $('<img/>')[0].src = nextSrc;
                        }

                        if (isImage(prevSrc)) {
                            $('<img/>')[0].src = prevSrc;
                        }
                    }
                }

                $loadingOverlay.hide();

                if (settings.transition === 'fade') {
                    $box.fadeTo(speed, 1, function () {
                        defilter();
                    });
                } else {
                    defilter();
                }

                $window.bind('resize.' + prefix, function () {
                    publicMethod.position(0);
                });

                trigger(event_complete, settings.onComplete);
            });
        }

        if (settings.transition === 'fade') {
            $box.fadeTo(speed, 0, function () {
                setPosition(0);
            });
        } else {
            setPosition(speed);
        }
    };

    publicMethod.load = function (launched) {
        var href, img, setResize, prep = publicMethod.prep;

        $next.removeClass("cboxNextDisabled");
        $prev.removeClass("cboxPreviousDisabled");
        if (index == $related.length - 1) {
            $next.addClass("cboxNextDisabled");
        }
        if (index == 0) {
            $prev.addClass("cboxPreviousDisabled");
        }

        active = true;
        element = $related[index];

        if (!launched) {
            settings = process($.extend({}, $.data(element, colorbox)));
        }

        trigger(event_purge);

        trigger(event_load, settings.onLoad);

        settings.h = settings.height ?
				setSize(settings.height, 'y') - loadedHeight - interfaceHeight :
				settings.innerHeight && setSize(settings.innerHeight, 'y');

        settings.w = settings.width ?
				setSize(settings.width, 'x') - loadedWidth - interfaceWidth :
				settings.innerWidth && setSize(settings.innerWidth, 'x');

        // Sets the minimum dimensions for use in image scaling
        settings.mw = settings.w;
        settings.mh = settings.h;

        // Re-evaluate the minimum width and height based on maxWidth and maxHeight values.
        // If the width or height exceed the maxWidth or maxHeight, use the maximum values instead.
        if (settings.maxWidth) {
            settings.mw = setSize(settings.maxWidth, 'x') - loadedWidth - interfaceWidth;
            settings.mw = settings.w && settings.w < settings.mw ? settings.w : settings.mw;
        }
        if (settings.maxHeight) {
            settings.mh = setSize(settings.maxHeight, 'y') - loadedHeight - interfaceHeight;
            settings.mh = settings.h && settings.h < settings.mh ? settings.h : settings.mh;
        }

        href = settings.href;

        $loadingOverlay.show();

        if (settings.inline) {
            // Inserts an empty placeholder where inline content is being pulled from.
            // An event is bound to put inline content back when ColorBox closes or loads new content.
            $div().hide().insertBefore($(href)[0]).one(event_purge, function () {
                $(this).replaceWith($loaded.children());
            });
            prep($(href));
        } else if (settings.iframe) {
            // IFrame element won't be added to the DOM until it is ready to be displayed,
            // to avoid problems with DOM-ready JS that might be trying to run in that iframe.
            $box.one(event_loaded, function () {
                var iframe = $("<iframe frameborder='0' style='width:100%; height:100%; border:0; display:block'/>")[0];
                iframe.name = prefix + (+new Date());
                iframe.src = settings.href;
                if (!settings.scrolling) {
                    iframe.scrolling = "no";
                }
                if (isIE) {
                    iframe.allowtransparency = "true";
                }
                $(iframe).appendTo($loaded).one(event_purge, function () {
                    iframe.src = "//about:blank";
                });
            });
            prep(" ");
        } else if (settings.video) {
            //            var videocontent = "<div id='galleryvideowrapper'><div id='galleryvideo'></div></div>";
            //            prep(videocontent);
            //            swfobject.embedSWF(settings.video, "galleryvideo", "400", "300", "10.0.0", "/swf/expressInstall.swf", {}, {}, {});

            $box.one(event_loaded, function () {
                var iframe = $("<iframe frameborder='0' style='width:100%; height:80%; border:0; display:block; margin-top:10px;'/>")[0];
                iframe.name = prefix + (+new Date());
                iframe.src = settings.video;
                if (!settings.scrolling) {
                    iframe.scrolling = "no";
                }
                if (isIE) {
                    iframe.allowtransparency = "true";
                }
                $(iframe).appendTo($loaded).one(event_purge, function () {
                    iframe.src = "//about:blank";
                });
            });
            prep(" ");

        } else if (settings.html) {
            prep(settings.html);
        } else if (isImage(href)) {
            img = new Image();
            img.onload = function () {
                var percent;
                img.onload = null;
                img.id = prefix + 'Photo';
                $(img).css({ border: 'none', display: 'block', cssFloat: 'left' });
                if (settings.scalePhotos) {
                    setResize = function () {
                        img.height -= img.height * percent;
                        img.width -= img.width * percent;
                    };
                    if (settings.mw && img.width > settings.mw) {
                        percent = (img.width - settings.mw) / img.width;
                        setResize();
                    }
                    if (settings.mh && img.height > settings.mh) {
                        percent = (img.height - settings.mh) / img.height;
                        setResize();
                    }
                }

                if (settings.h) {
                    img.style.marginTop = "10px";// Math.max(settings.h - img.height, 0) / 2 + 'px';
                }

                if ($related[1] && (index < $related.length - 1 || settings.loop)) {
                    $(img).css({ cursor: 'pointer' }).click(publicMethod.next);
                }

                if (isIE) {
                    img.style.msInterpolationMode = 'bicubic';
                }

                setTimeout(function () { // Chrome will sometimes report a 0 by 0 size if there isn't pause in execution
                    prep(img);
                }, 1);
            };

            setTimeout(function () { // Opera 10.6+ will sometimes load the src before the onload function is set
                img.src = href;
            }, 1);
        } else if (href) {
            $loadingBay.load(href, function (data, status, xhr) {
                prep(status === 'error' ? 'Request unsuccessful: ' + xhr.statusText : $(this).children());
            });
        }
    };

    // Navigates to the next page/image in a set.
    publicMethod.next = function () {
        if (!active) {
            index = index < $related.length - 1 ? index + 1 : 0;

            publicMethod.load();
        }
    };
    publicMethod.prev = function () {
        if (!active) {
            index = index ? index - 1 : $related.length - 1;

            publicMethod.load();
        }
    };


    // Note: to use this within an iframe use the following format: parent.$.fn.colorbox.close();
    publicMethod.close = function () {
        if (open && !closing) {
            closing = true;

            open = false;

            trigger(event_cleanup, settings.onCleanup);

            $window.unbind('.' + prefix + ' .' + event_ie6);

            $overlay.fadeTo('fast', 0);

            $box.stop().fadeTo('fast', 0, function () {

                trigger(event_purge);

                $loaded.remove();

                $box.add($overlay).css({ 'opacity': 1, cursor: 'auto' }).hide();

                setTimeout(function () {
                    closing = false;
                    trigger(event_closed, settings.onClosed);
                }, 1);
            });
        }
    };

    // A method for fetching the current element ColorBox is referencing.
    // returns a jQuery object.
    publicMethod.element = function () {
        return $(element);
    };

    publicMethod.settings = defaults;

    // Initializes ColorBox when the DOM has loaded
    $(publicMethod.init);

} (jQuery, this));


