[pytango] 411/483: Fixes #678

Sandor Bodo-Merle sbodomerle-guest at moszumanska.debian.org
Thu Sep 28 19:15:06 UTC 2017


This is an automated email from the git hooks/post-receive script.

sbodomerle-guest pushed a commit to annotated tag bliss_8.10
in repository pytango.

commit ec97fe71c6924f6542250ed697c796f01d656173
Author: tiagocoutinho <tiagocoutinho at 4e9c00fd-8f2e-0410-aa12-93ce3db5e235>
Date:   Tue Sep 30 12:22:41 2014 +0000

    Fixes #678
    
    git-svn-id: http://svn.code.sf.net/p/tango-cs/code/bindings/PyTango/trunk@26595 4e9c00fd-8f2e-0410-aa12-93ce3db5e235
---
 doc/_static/jssor.js             | 2806 ++++++++++++++++++++++++++
 doc/_static/jssor.slider.js      | 4081 ++++++++++++++++++++++++++++++++++++++
 doc/_static/jssor.slider.mini.js |    2 -
 doc/_templates/index.html        |    4 +-
 4 files changed, 6890 insertions(+), 3 deletions(-)

diff --git a/doc/_static/jssor.js b/doc/_static/jssor.js
new file mode 100644
index 0000000..255b990
--- /dev/null
+++ b/doc/_static/jssor.js
@@ -0,0 +1,2806 @@
+/*
+* Jssor 18.0
+* http://www.jssor.com/
+* 
+* TERMS OF USE - Jssor
+* 
+* Copyright 2014 Jssor
+*
+* Permission is hereby granted, free of charge, to any person obtaining
+* a copy of this software and associated documentation files (the
+* "Software"), to deal in the Software without restriction, including
+* without limitation the rights to use, copy, modify, merge, publish,
+* distribute, sublicense, and/or sell copies of the Software, and to
+* permit persons to whom the Software is furnished to do so, subject to
+* the following conditions:
+* 
+* The above copyright notice and this permission notice shall be
+* included in all copies or substantial portions of the Software.
+* 
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+/*! Jssor */
+
+//$JssorDebug$
+var $JssorDebug$ = new function () {
+
+    this.$DebugMode = true;
+
+    // Methods
+
+    this.$Log = function (msg, important) {
+        var console = window.console || {};
+        var debug = this.$DebugMode;
+
+        if (debug && console.log) {
+            console.log(msg);
+        } else if (debug && important) {
+            alert(msg);
+        }
+    };
+
+    this.$Error = function (msg, e) {
+        var console = window.console || {};
+        var debug = this.$DebugMode;
+
+        if (debug && console.error) {
+            console.error(msg);
+        } else if (debug) {
+            alert(msg);
+        }
+
+        if (debug) {
+            // since we're debugging, fail fast by crashing
+            throw e || new Error(msg);
+        }
+    };
+
+    this.$Fail = function (msg) {
+        throw new Error(msg);
+    };
+
+    this.$Assert = function (value, msg) {
+        var debug = this.$DebugMode;
+        if (debug) {
+            if (!value)
+                throw new Error("Assert failed " + msg || "");
+        }
+    };
+
+    this.$Trace = function (msg) {
+        var console = window.console || {};
+        var debug = this.$DebugMode;
+
+        if (debug && console.log) {
+            console.log(msg);
+        }
+    };
+
+    this.$Execute = function (func) {
+        var debug = this.$DebugMode;
+        if (debug)
+            func();
+    };
+
+    this.$LiveStamp = function (obj, id) {
+        var debug = this.$DebugMode;
+        if (debug) {
+            var stamp = document.createElement("DIV");
+            stamp.setAttribute("id", id);
+
+            obj.$Live = stamp;
+        }
+    };
+
+    this.$C_AbstractMethod = function () {
+        ///	<summary>
+        ///		Tells compiler the method is abstract, it should be implemented by subclass.
+        ///	</summary>
+
+        throw new Error("The method is abstract, it should be implemented by subclass.");
+    };
+
+    function C_AbstractClass (instance) {
+        ///	<summary>
+        ///		Tells compiler the class is abstract, it should be implemented by subclass.
+        ///	</summary>
+
+        if(instance.constructor === C_AbstractClass.caller)
+            throw new Error("Cannot create instance of an abstract class.");
+    }
+
+    this.$C_AbstractClass = C_AbstractClass;
+};
+
+//$JssorPoint$
+var $JssorPoint$ = function (x, y) {
+    var _ThisPoint = this;
+
+    // Properties
+    _ThisPoint.x = x;
+    _ThisPoint.y = y;
+
+    _ThisPoint.$Plus = function (point) {
+        return new $JssorPoint$(x + point.x, y + point.y);
+    };
+
+    _ThisPoint.$Minus = function (point) {
+        return new $JssorPoint$(x - point.x, y - point.y);
+    };
+
+    _ThisPoint.$Times = function (factor) {
+        return new $JssorPoint$(x * factor, y * factor);
+    };
+
+    _ThisPoint.$Divide = function (factor) {
+        return new $JssorPoint$(x / factor, y / factor);
+    };
+
+    _ThisPoint.$Negate = function () {
+        return new $JssorPoint$(-x, -y);
+    };
+
+    _ThisPoint.$DistanceTo = function (point) {
+        return Math.sqrt(Math.pow(x - point.x, 2) + Math.pow(y - point.y, 2));
+    };
+
+    _ThisPoint.$Apply = function (func) {
+        return new $JssorPoint$(func(x), func(y));
+    };
+
+    _ThisPoint.$Equals = function (point) {
+        return (point instanceof $JssorPoint$) && (x === point.x) && (y === point.y);
+    };
+
+    _ThisPoint.$ToString = function () {
+        return "(" + x + "," + y + ")";
+    };
+};
+
+//$JssorEasing$
+var $JssorEasing$ = window.$JssorEasing$ = {
+    $EaseLinear: function (t) {
+        return t;
+    },
+    $EaseGoBack: function (t) {
+        return 1 - Math.abs((t *= 2) - 1);
+    },
+    $EaseSwing: function (t) {
+        return -Math.cos(t * Math.PI) / 2 + .5;
+    },
+    $EaseInQuad: function (t) {
+        return t * t;
+    },
+    $EaseOutQuad: function (t) {
+        return -t * (t - 2);
+    },
+    $EaseInOutQuad: function (t) {
+        return (t *= 2) < 1 ? 1 / 2 * t * t : -1 / 2 * (--t * (t - 2) - 1);
+    },
+    $EaseInCubic: function (t) {
+        return t * t * t;
+    },
+    $EaseOutCubic: function (t) {
+        return (t -= 1) * t * t + 1;
+    },
+    $EaseInOutCubic: function (t) {
+        return (t *= 2) < 1 ? 1 / 2 * t * t * t : 1 / 2 * ((t -= 2) * t * t + 2);
+    },
+    $EaseInQuart: function (t) {
+        return t * t * t * t;
+    },
+    $EaseOutQuart: function (t) {
+        return -((t -= 1) * t * t * t - 1);
+    },
+    $EaseInOutQuart: function (t) {
+        return (t *= 2) < 1 ? 1 / 2 * t * t * t * t : -1 / 2 * ((t -= 2) * t * t * t - 2);
+    },
+    $EaseInQuint: function (t) {
+        return t * t * t * t * t;
+    },
+    $EaseOutQuint: function (t) {
+        return (t -= 1) * t * t * t * t + 1;
+    },
+    $EaseInOutQuint: function (t) {
+        return (t *= 2) < 1 ? 1 / 2 * t * t * t * t * t : 1 / 2 * ((t -= 2) * t * t * t * t + 2);
+    },
+    $EaseInSine: function (t) {
+        return 1 - Math.cos(t * Math.PI / 2);
+    },
+    $EaseOutSine: function (t) {
+        return Math.sin(t * Math.PI / 2);
+    },
+    $EaseInOutSine: function (t) {
+        return -1 / 2 * (Math.cos(Math.PI * t) - 1);
+    },
+    $EaseInExpo: function (t) {
+        return t == 0 ? 0 : Math.pow(2, 10 * (t - 1));
+    },
+    $EaseOutExpo: function (t) {
+        return t == 1 ? 1 : -Math.pow(2, -10 * t) + 1;
+    },
+    $EaseInOutExpo: function (t) {
+        return t == 0 || t == 1 ? t : (t *= 2) < 1 ? 1 / 2 * Math.pow(2, 10 * (t - 1)) : 1 / 2 * (-Math.pow(2, -10 * --t) + 2);
+    },
+    $EaseInCirc: function (t) {
+        return -(Math.sqrt(1 - t * t) - 1);
+    },
+    $EaseOutCirc: function (t) {
+        return Math.sqrt(1 - (t -= 1) * t);
+    },
+    $EaseInOutCirc: function (t) {
+        return (t *= 2) < 1 ? -1 / 2 * (Math.sqrt(1 - t * t) - 1) : 1 / 2 * (Math.sqrt(1 - (t -= 2) * t) + 1);
+    },
+    $EaseInElastic: function (t) {
+        if (!t || t == 1)
+            return t;
+        var p = .3, s = .075;
+        return -(Math.pow(2, 10 * (t -= 1)) * Math.sin((t - s) * 2 * Math.PI / p));
+    },
+    $EaseOutElastic: function (t) {
+        if (!t || t == 1)
+            return t;
+        var p = .3, s = .075;
+        return Math.pow(2, -10 * t) * Math.sin((t - s) * 2 * Math.PI / p) + 1;
+    },
+    $EaseInOutElastic: function (t) {
+        if (!t || t == 1)
+            return t;
+        var p = .45, s = .1125;
+        return (t *= 2) < 1 ? -.5 * Math.pow(2, 10 * (t -= 1)) * Math.sin((t - s) * 2 * Math.PI / p) : Math.pow(2, -10 * (t -= 1)) * Math.sin((t - s) * 2 * Math.PI / p) * .5 + 1;
+    },
+    $EaseInBack: function (t) {
+        var s = 1.70158;
+        return t * t * ((s + 1) * t - s);
+    },
+    $EaseOutBack: function (t) {
+        var s = 1.70158;
+        return (t -= 1) * t * ((s + 1) * t + s) + 1;
+    },
+    $EaseInOutBack: function (t) {
+        var s = 1.70158;
+        return (t *= 2) < 1 ? 1 / 2 * t * t * (((s *= 1.525) + 1) * t - s) : 1 / 2 * ((t -= 2) * t * (((s *= 1.525) + 1) * t + s) + 2);
+    },
+    $EaseInBounce: function (t) {
+        return 1 - $JssorEasing$.$EaseOutBounce(1 - t)
+    },
+    $EaseOutBounce: function (t) {
+        return t < 1 / 2.75 ? 7.5625 * t * t : t < 2 / 2.75 ? 7.5625 * (t -= 1.5 / 2.75) * t + .75 : t < 2.5 / 2.75 ? 7.5625 * (t -= 2.25 / 2.75) * t + .9375 : 7.5625 * (t -= 2.625 / 2.75) * t + .984375;
+    },
+    $EaseInOutBounce: function (t) {
+        return t < 1 / 2 ? $JssorEasing$.$EaseInBounce(t * 2) * .5 : $JssorEasing$.$EaseOutBounce(t * 2 - 1) * .5 + .5;
+    },
+    $EaseInWave: function (t) {
+        return 1 - Math.cos(t * Math.PI * 2)
+    },
+    $EaseOutWave: function (t) {
+        return Math.sin(t * Math.PI * 2);
+    },
+    $EaseOutJump: function (t) {
+        return 1 - (((t *= 2) < 1) ? (t = 1 - t) * t * t : (t -= 1) * t * t);
+    },
+    $EaseInJump: function (t) {
+        return ((t *= 2) < 1) ? t * t * t : (t = 2 - t) * t * t;
+    }
+};
+
+var $JssorDirection$ = window.$JssorDirection$ = {
+    $TO_LEFT: 0x0001,
+    $TO_RIGHT: 0x0002,
+    $TO_TOP: 0x0004,
+    $TO_BOTTOM: 0x0008,
+    $HORIZONTAL: 0x0003,
+    $VERTICAL: 0x000C,
+    $LEFTRIGHT: 0x0003,
+    $TOPBOTOM: 0x000C,
+    $TOPLEFT: 0x0005,
+    $TOPRIGHT: 0x0006,
+    $BOTTOMLEFT: 0x0009,
+    $BOTTOMRIGHT: 0x000A,
+    $AROUND: 0x000F,
+
+    $GetDirectionHorizontal: function (direction) {
+        return direction & 0x0003;
+    },
+    $GetDirectionVertical: function (direction) {
+        return direction & 0x000C;
+    },
+    $ChessHorizontal: function (direction) {
+        return (~direction & 0x0003) + (direction & 0x000C);
+    },
+    $ChessVertical: function (direction) {
+        return (~direction & 0x000C) + (direction & 0x0003);
+    },
+    $IsToLeft: function (direction) {
+        return (direction & 0x0003) == 0x0001;
+    },
+    $IsToRight: function (direction) {
+        return (direction & 0x0003) == 0x0002;
+    },
+    $IsToTop: function (direction) {
+        return (direction & 0x000C) == 0x0004;
+    },
+    $IsToBottom: function (direction) {
+        return (direction & 0x000C) == 0x0008;
+    },
+    $IsHorizontal: function (direction) {
+        return (direction & 0x0003) > 0;
+    },
+    $IsVertical: function (direction) {
+        return (direction & 0x000C) > 0;
+    }
+};
+
+var $JssorKeyCode$ = {
+    $BACKSPACE: 8,
+    $COMMA: 188,
+    $DELETE: 46,
+    $DOWN: 40,
+    $END: 35,
+    $ENTER: 13,
+    $ESCAPE: 27,
+    $HOME: 36,
+    $LEFT: 37,
+    $NUMPAD_ADD: 107,
+    $NUMPAD_DECIMAL: 110,
+    $NUMPAD_DIVIDE: 111,
+    $NUMPAD_ENTER: 108,
+    $NUMPAD_MULTIPLY: 106,
+    $NUMPAD_SUBTRACT: 109,
+    $PAGE_DOWN: 34,
+    $PAGE_UP: 33,
+    $PERIOD: 190,
+    $RIGHT: 39,
+    $SPACE: 32,
+    $TAB: 9,
+    $UP: 38
+};
+
+var $JssorAlignment$ = {
+    $TopLeft: 0x11,
+    $TopCenter: 0x12,
+    $TopRight: 0x14,
+    $MiddleLeft: 0x21,
+    $MiddleCenter: 0x22,
+    $MiddleRight: 0x24,
+    $BottomLeft: 0x41,
+    $BottomCenter: 0x42,
+    $BottomRight: 0x44,
+
+    $IsTop: function (aligment) {
+        return aligment & 0x10 > 0;
+    },
+    $IsMiddle: function (alignment) {
+        return alignment & 0x20 > 0;
+    },
+    $IsBottom: function (alignment) {
+        return alignment & 0x40 > 0;
+    },
+    $IsLeft: function (alignment) {
+        return alignment & 0x01 > 0;
+    },
+    $IsCenter: function (alignment) {
+        return alignment & 0x02 > 0;
+    },
+    $IsRight: function (alignment) {
+        return alignment & 0x04 > 0;
+    }
+};
+
+var $JssorMatrix$;
+
+var $JssorAnimator$;
+
+// $Jssor$ is a static class, so make it singleton instance
+var $Jssor$ = window.$Jssor$ = new function () {
+    // Fields
+    var _This = this;
+
+    var REGEX_WHITESPACE_GLOBAL = /\S+/g;
+
+    var ROWSER_UNKNOWN = 0;
+    var BROWSER_IE = 1;
+    var BROWSER_FIREFOX = 2;
+    var BROWSER_FIREFOX = 3;
+    var BROWSER_CHROME = 4;
+    var BROWSER_OPERA = 5;
+
+    //var arrActiveX = ["Msxml2.XMLHTTP", "Msxml3.XMLHTTP", "Microsoft.XMLHTTP"];
+
+    var browser = 0;
+    var browserRuntimeVersion = 0;
+    var browserEngineVersion = 0;
+    var browserJavascriptVersion = 0;
+    var webkitVersion = 0;
+
+    var app = navigator.appName;
+    var ver = navigator.appVersion;
+    var ua = navigator.userAgent;
+
+    var _DocElmt = document.documentElement;
+    var _TransformProperty;
+
+    function DetectBrowser() {
+        if (!browser) {
+            if (app == "Microsoft Internet Explorer" &&
+                !!window.attachEvent && !!window.ActiveXObject) {
+
+                var ieOffset = ua.indexOf("MSIE");
+                browser = BROWSER_IE;
+                browserEngineVersion = ParseFloat(ua.substring(ieOffset + 5, ua.indexOf(";", ieOffset)));
+
+                //check IE javascript version
+                /*@cc_on
+                browserJavascriptVersion = @_jscript_version;
+                @*/
+
+                // update: for intranet sites and compat view list sites, IE sends
+                // an IE7 User-Agent to the server to be interoperable, and even if
+                // the page requests a later IE version, IE will still report the
+                // IE7 UA to JS. we should be robust to self
+                //var docMode = document.documentMode;
+                //if (typeof docMode !== "undefined") {
+                //    browserRuntimeVersion = docMode;
+                //}
+
+                browserRuntimeVersion = document.documentMode || browserEngineVersion;
+
+            }
+            else if (app == "Netscape" && !!window.addEventListener) {
+
+                var ffOffset = ua.indexOf("Firefox");
+                var saOffset = ua.indexOf("Safari");
+                var chOffset = ua.indexOf("Chrome");
+                var webkitOffset = ua.indexOf("AppleWebKit");
+
+                if (ffOffset >= 0) {
+                    browser = BROWSER_FIREFOX;
+                    browserRuntimeVersion = ParseFloat(ua.substring(ffOffset + 8));
+                }
+                else if (saOffset >= 0) {
+                    var slash = ua.substring(0, saOffset).lastIndexOf("/");
+                    browser = (chOffset >= 0) ? BROWSER_CHROME : BROWSER_FIREFOX;
+                    browserRuntimeVersion = ParseFloat(ua.substring(slash + 1, saOffset));
+                }
+
+                if (webkitOffset >= 0)
+                    webkitVersion = ParseFloat(ua.substring(webkitOffset + 12));
+            }
+            else {
+                var match = /(opera)(?:.*version|)[ \/]([\w.]+)/i.exec(ua);
+                if (match) {
+                    browser = BROWSER_OPERA;
+                    browserRuntimeVersion = ParseFloat(match[2]);
+                }
+            }
+        }
+    }
+
+    function IsBrowserIE() {
+        DetectBrowser();
+        return browser == BROWSER_IE;
+    }
+
+    function IsBrowserIeQuirks() {
+        return IsBrowserIE() && (browserRuntimeVersion < 6 || document.compatMode == "BackCompat");   //Composite to "CSS1Compat"
+    }
+
+    function IsBrowserFireFox() {
+        DetectBrowser();
+        return browser == BROWSER_FIREFOX;
+    }
+
+    function IsBrowserSafari() {
+        DetectBrowser();
+        return browser == BROWSER_FIREFOX;
+    }
+
+    function IsBrowserChrome() {
+        DetectBrowser();
+        return browser == BROWSER_CHROME;
+    }
+
+    function IsBrowserOpera() {
+        DetectBrowser();
+        return browser == BROWSER_OPERA;
+    }
+
+    function IsBrowserBadTransform() {
+        return IsBrowserSafari() && (webkitVersion > 534) && (webkitVersion < 535);
+    }
+
+    function IsBrowserSafeHWA() {
+        return IsBrowserSafari() && (webkitVersion < 535);
+    }
+
+    function IsBrowserIe9Earlier() {
+        return IsBrowserIE() && browserRuntimeVersion < 9; 
+    }
+
+    function GetTransformProperty(elmt) {
+
+        if (!_TransformProperty) {
+            // Note that in some versions of IE9 it is critical that
+            // msTransform appear in this list before MozTransform
+
+            each(['transform', 'WebkitTransform', 'msTransform', 'MozTransform', 'OTransform'], function (property) {
+                if (elmt.style[property] != undefined) {
+                    _TransformProperty = property;
+                    return true;
+                }
+            });
+
+            _TransformProperty = _TransformProperty || "transform";
+        }
+
+        return _TransformProperty;
+    }
+
+    // Helpers
+    function getOffsetParent(elmt, isFixed) {
+        // IE and Opera "fixed" position elements don't have offset parents.
+        // regardless, if it's fixed, its offset parent is the body.
+        if (isFixed && elmt != document.body) {
+            return document.body;
+        } else {
+            return elmt.offsetParent;
+        }
+    }
+
+    function toString(obj) {
+        return Object.prototype.toString.call(obj);
+    }
+
+    // [[Class]] -> type pairs
+    var class2type;
+
+    function each(object, callback) {
+        if (toString(object) == "[object Array]") {
+            for (var i = 0; i < object.length; i++) {
+                if (callback(object[i], i, object)) {
+                    return true;
+                }
+            }
+        }
+        else {
+            for (var name in object) {
+                if (callback(object[name], name, object)) {
+                    return true;
+                }
+            }
+        }
+    }
+
+    function GetClass2Type() {
+        if (!class2type) {
+            class2type = {};
+            each(["Boolean", "Number", "String", "Function", "Array", "Date", "RegExp", "Object"], function (name) {
+                class2type["[object " + name + "]"] = name.toLowerCase();
+            });
+        }
+
+        return class2type;
+    }
+
+    function type(obj) {
+        return obj == null ? String(obj) : GetClass2Type()[toString(obj)] || "object";
+    }
+
+    function isPlainObject(obj) {
+        // Must be an Object.
+        // Because of IE, we also have to check the presence of the constructor property.
+        // Make sure that DOM nodes and window objects don't pass through, as well
+        if (!obj || type(obj) !== "object" || obj.nodeType || _This.$IsWindow(obj)) {
+            return false;
+        }
+
+        var hasOwn = Object.prototype.hasOwnProperty;
+
+        try {
+            // Not own constructor property must be Object
+            if (obj.constructor &&
+				!hasOwn.call(obj, "constructor") &&
+				!hasOwn.call(obj.constructor.prototype, "isPrototypeOf")) {
+                return false;
+            }
+        } catch (e) {
+            // IE8,9 Will throw exceptions on certain host objects #9897
+            return false;
+        }
+
+        // Own properties are enumerated firstly, so to speed up,
+        // if last one is own, then all properties are own.
+
+        var key;
+        for (key in obj) { }
+
+        return key === undefined || hasOwn.call(obj, key);
+    }
+
+    function Delay(code, delay) {
+        setTimeout(code, delay || 0);
+    }
+
+    function RemoveByReg(str, reg) {
+        var m = reg.exec(str);
+
+        if (m) {
+            var header = str.substr(0, m.index);
+            var tailer = str.substr(m.lastIndex + 1, str.length - (m.lastIndex + 1));
+            str = header + tailer;
+        }
+
+        return str;
+    }
+
+    function BuildNewCss(oldCss, removeRegs, replaceValue) {
+        var css = (!oldCss || oldCss == "inherit") ? "" : oldCss;
+
+        each(removeRegs, function (removeReg) {
+            var m = removeReg.exec(css);
+
+            if (m) {
+                var header = css.substr(0, m.index);
+                var tailer = css.substr(m.lastIndex + 1, css.length - (m.lastIndex + 1));
+                css = header + tailer;
+            }
+        });
+
+        css = replaceValue + (css.indexOf(" ") != 0 ? " " : "") + css;
+
+        return css;
+    }
+
+    function SetStyleFilterIE(elmt, value) {
+        if (browserRuntimeVersion < 9) {
+            elmt.style.filter = value;
+        }
+    }
+
+    function SetStyleMatrixIE(elmt, matrix, offset) {
+        //matrix is not for ie9+ running in ie8- mode
+        if (browserJavascriptVersion < 9) {
+            var oldFilterValue = elmt.style.filter;
+            var matrixReg = new RegExp(/[\s]*progid:DXImageTransform\.Microsoft\.Matrix\([^\)]*\)/g);
+            var matrixValue = matrix ? "progid:DXImageTransform.Microsoft.Matrix(" + "M11=" + matrix[0][0] + ", M12=" + matrix[0][1] + ", M21=" + matrix[1][0] + ", M22=" + matrix[1][1] + ", SizingMethod='auto expand')" : "";
+
+            var newFilterValue = BuildNewCss(oldFilterValue, [matrixReg], matrixValue);
+
+            SetStyleFilterIE(elmt, newFilterValue);
+
+            _This.$CssMarginTop(elmt, offset.y);
+            _This.$CssMarginLeft(elmt, offset.x);
+        }
+    }
+
+    // Methods
+
+    _This.$IsBrowserIE = IsBrowserIE;
+
+    _This.$IsBrowserIeQuirks = IsBrowserIeQuirks;
+
+    _This.$IsBrowserFireFox = IsBrowserFireFox;
+
+    _This.$IsBrowserSafari = IsBrowserSafari;
+
+    _This.$IsBrowserChrome = IsBrowserChrome;
+
+    _This.$IsBrowserOpera = IsBrowserOpera;
+
+    _This.$IsBrowserBadTransform = IsBrowserBadTransform;
+
+    _This.$IsBrowserSafeHWA = IsBrowserSafeHWA;
+
+    _This.$IsBrowserIe9Earlier = IsBrowserIe9Earlier;
+
+    _This.$BrowserVersion = function () {
+        return browserRuntimeVersion;
+    };
+
+    _This.$BrowserEngineVersion = function () {
+        return browserEngineVersion || browserRuntimeVersion;
+    };
+
+    _This.$WebKitVersion = function () {
+        return webkitVersion;
+    };
+
+    _This.$Delay = Delay;
+
+    _This.$Inherit = function (instance, baseClass) {
+        baseClass.apply(instance, [].slice.call(arguments, 2));
+        return Extend({}, instance);
+    };
+
+    function Construct(instance, constructor) {
+        instance.constructor === Construct.caller && instance.$Construct && instance.$Construct();
+    }
+
+    _This.$Construct = Construct;
+
+    _This.$GetElement = function (elmt) {
+        if (_This.$IsString(elmt)) {
+            elmt = document.getElementById(elmt);
+        }
+
+        return elmt;
+    };
+
+    function GetEvent(event) {
+        return event || window.event;
+    }
+
+    GetEvent = GetEvent;
+
+    _This.$EventSrc = function (event) {
+        event = GetEvent(event);
+        return event.target || event.srcElement || document;
+    };
+
+    _This.$EventDst = function (event) {
+        event = GetEvent(event);
+        return event.relatedTarget || event.toElement;
+    };
+
+    _This.$MousePosition = function (event) {
+        event = GetEvent(event);
+        var body = document.body;
+
+        return {
+            x: event.pageX || event.clientX + (_DocElmt.scrollLeft || body.scrollLeft || 0) - (_DocElmt.clientLeft || body.clientLeft || 0) || 0,
+            y: event.pageY || event.clientY + (_DocElmt.scrollTop || body.scrollTop || 0) - (_DocElmt.clientTop || body.clientTop || 0) || 0
+        };
+    };
+
+    _This.$PageScroll = function () {
+        var body = document.body;
+
+        return {
+            x: (window.pageXOffset || _DocElmt.scrollLeft || body.scrollLeft || 0) - (_DocElmt.clientLeft || body.clientLeft || 0),
+            y: (window.pageYOffset || _DocElmt.scrollTop || body.scrollTop || 0) - (_DocElmt.clientTop || body.clientTop || 0)
+        };
+    };
+
+    _This.$WindowSize = function () {
+        var body = document.body;
+
+        return {
+            x: body.clientWidth || _DocElmt.clientWidth,
+            y: body.clientHeight || _DocElmt.clientHeight
+        };
+    };
+
+    //_This.$GetElementPosition = function (elmt) {
+    //    elmt = _This.$GetElement(elmt);
+    //    var result = new $JssorPoint$();
+
+    //    // technique from:
+    //    // http://www.quirksmode.org/js/findpos.html
+    //    // with special check for "fixed" elements.
+
+    //    while (elmt) {
+    //        result.x += elmt.offsetLeft;
+    //        result.y += elmt.offsetTop;
+
+    //        var isFixed = _This.$GetElementStyle(elmt).position == "fixed";
+
+    //        if (isFixed) {
+    //            result = result.$Plus(_This.$PageScroll(window));
+    //        }
+
+    //        elmt = getOffsetParent(elmt, isFixed);
+    //    }
+
+    //    return result;
+    //};
+
+    //_This.$GetMouseScroll = function (event) {
+    //    event = GetEvent(event);
+    //    var delta = 0; // default value
+
+    //    // technique from:
+    //    // http://blog.paranoidferret.com/index.php/2007/10/31/javascript-tutorial-the-scroll-wheel/
+
+    //    if (typeof (event.wheelDelta) == "number") {
+    //        delta = event.wheelDelta;
+    //    } else if (typeof (event.detail) == "number") {
+    //        delta = event.detail * -1;
+    //    } else {
+    //        $JssorDebug$.$Fail("Unknown event mouse scroll, no known technique.");
+    //    }
+
+    //    // normalize value to [-1, 1]
+    //    return delta ? delta / Math.abs(delta) : 0;
+    //};
+
+    //_This.$MakeAjaxRequest = function (url, callback) {
+    //    var async = typeof (callback) == "function";
+    //    var req = null;
+
+    //    if (async) {
+    //        var actual = callback;
+    //        var callback = function () {
+    //            Delay($Jssor$.$CreateCallback(null, actual, req), 1);
+    //        };
+    //    }
+
+    //    if (window.ActiveXObject) {
+    //        for (var i = 0; i < arrActiveX.length; i++) {
+    //            try {
+    //                req = new ActiveXObject(arrActiveX[i]);
+    //                break;
+    //            } catch (e) {
+    //                continue;
+    //            }
+    //        }
+    //    } else if (window.XMLHttpRequest) {
+    //        req = new XMLHttpRequest();
+    //    }
+
+    //    if (!req) {
+    //        $JssorDebug$.$Fail("Browser doesn't support XMLHttpRequest.");
+    //    }
+
+    //    if (async) {
+    //        req.onreadystatechange = function () {
+    //            if (req.readyState == 4) {
+    //                // prevent memory leaks by breaking circular reference now
+    //                req.onreadystatechange = new Function();
+    //                callback();
+    //            }
+    //        };
+    //    }
+
+    //    try {
+    //        req.open("GET", url, async);
+    //        req.send(null);
+    //    } catch (e) {
+    //        $JssorDebug$.$Log(e.name + " while making AJAX request: " + e.message);
+
+    //        req.onreadystatechange = null;
+    //        req = null;
+
+    //        if (async) {
+    //            callback();
+    //        }
+    //    }
+
+    //    return async ? null : req;
+    //};
+
+    //_This.$ParseXml = function (string) {
+    //    var xmlDoc = null;
+
+    //    if (window.ActiveXObject) {
+    //        try {
+    //            xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
+    //            xmlDoc.async = false;
+    //            xmlDoc.loadXML(string);
+    //        } catch (e) {
+    //            $JssorDebug$.$Log(e.name + " while parsing XML (ActiveX): " + e.message);
+    //        }
+    //    } else if (window.DOMParser) {
+    //        try {
+    //            var parser = new DOMParser();
+    //            xmlDoc = parser.parseFromString(string, "text/xml");
+    //        } catch (e) {
+    //            $JssorDebug$.$Log(e.name + " while parsing XML (DOMParser): " + e.message);
+    //        }
+    //    } else {
+    //        $JssorDebug$.$Fail("Browser doesn't support XML DOM.");
+    //    }
+
+    //    return xmlDoc;
+    //};
+
+    function Css(elmt, name, value) {
+        ///	<summary>
+        ///		access css
+        ///     $Jssor$.$Css(elmt, name);         //get css value
+        ///     $Jssor$.$Css(elmt, name, value);  //set css value
+        ///	</summary>
+        ///	<param name="elmt" type="HTMLElement">
+        ///		the element to access css
+        ///	</param>
+        ///	<param name="name" type="String">
+        ///		the name of css property
+        ///	</param>
+        ///	<param name="value" optional="true">
+        ///		the value to set
+        ///	</param>
+        if (value != undefined) {
+            elmt.style[name] = value;
+        }
+        else {
+            var style = elmt.currentStyle || elmt.style;
+            value = style[name];
+
+            if (value == "" && window.getComputedStyle) {
+                style = elmt.ownerDocument.defaultView.getComputedStyle(elmt, null);
+
+                style && (value = style.getPropertyValue(name) || style[name]);
+            }
+
+            return value;
+        }
+    }
+
+    function CssN(elmt, name, value, isDimensional) {
+        ///	<summary>
+        ///		access css as numeric
+        ///     $Jssor$.$CssN(elmt, name);         //get css value
+        ///     $Jssor$.$CssN(elmt, name, value);  //set css value
+        ///	</summary>
+        ///	<param name="elmt" type="HTMLElement">
+        ///		the element to access css
+        ///	</param>
+        ///	<param name="name" type="String">
+        ///		the name of css property
+        ///	</param>
+        ///	<param name="value" type="Number" optional="true">
+        ///		the value to set
+        ///	</param>
+        if (value != undefined) {
+            isDimensional && (value += "px");
+            Css(elmt, name, value);
+        }
+        else {
+            return ParseFloat(Css(elmt, name));
+        }
+    }
+
+    function CssP(elmt, name, value) {
+        ///	<summary>
+        ///		access css in pixel as numeric, like 'top', 'left', 'width', 'height'
+        ///     $Jssor$.$CssP(elmt, name);         //get css value
+        ///     $Jssor$.$CssP(elmt, name, value);  //set css value
+        ///	</summary>
+        ///	<param name="elmt" type="HTMLElement">
+        ///		the element to access css
+        ///	</param>
+        ///	<param name="name" type="String">
+        ///		the name of css property
+        ///	</param>
+        ///	<param name="value" type="Number" optional="true">
+        ///		the value to set
+        ///	</param>
+        return CssN(elmt, name, value, true);
+    }
+
+    function CssProxy(name, numericOrDimension) {
+        ///	<summary>
+        ///		create proxy to access css, CssProxy(name[, numericOrDimension]);
+        ///	</summary>
+        ///	<param name="elmt" type="HTMLElement">
+        ///		the element to access css
+        ///	</param>
+        ///	<param name="numericOrDimension" type="Number" optional="true">
+        ///		not set: access original css, 1: access css as numeric, 2: access css in pixel as numeric
+        ///	</param>
+        var isDimensional = numericOrDimension & 2;
+        var cssAccessor = numericOrDimension ? CssN : Css;
+        return function (elmt, value) {
+            return cssAccessor(elmt, name, value, isDimensional);
+        };
+    }
+
+    function GetStyleOpacity(elmt) {
+        if (IsBrowserIE() && browserEngineVersion < 9) {
+            var match = /opacity=([^)]*)/.exec(elmt.style.filter || "");
+            return match ? (ParseFloat(match[1]) / 100) : 1;
+        }
+        else
+            return ParseFloat(elmt.style.opacity || "1");
+    }
+
+    function SetStyleOpacity(elmt, opacity, ie9EarlierForce) {
+
+        if (IsBrowserIE() && browserEngineVersion < 9) {
+            //var filterName = "filter"; // browserEngineVersion < 8 ? "filter" : "-ms-filter";
+            var finalFilter = elmt.style.filter || "";
+
+            // for CSS filter browsers (IE), remove alpha filter if it's unnecessary.
+            // update: doing _This always since IE9 beta seems to have broken the
+            // behavior if we rely on the programmatic filters collection.
+            var alphaReg = new RegExp(/[\s]*alpha\([^\)]*\)/g);
+
+            // important: note the lazy star! _This protects against
+            // multiple filters; we don't want to delete the other ones.
+            // update: also trimming extra whitespace around filter.
+
+            var ieOpacity = Math.round(100 * opacity);
+            var alphaFilter = "";
+            if (ieOpacity < 100 || ie9EarlierForce) {
+                alphaFilter = "alpha(opacity=" + ieOpacity + ") ";
+                //elmt.style["-ms-filter"] = "progid:DXImageTransform.Microsoft.Alpha(opacity=" + ieOpacity + ") ";
+            }
+
+            var newFilterValue = BuildNewCss(finalFilter, [alphaReg], alphaFilter);
+
+            SetStyleFilterIE(elmt, newFilterValue);
+        }
+
+            //if (!IsBrowserIE() || browserEngineVersion >= 9) 
+        else {
+            elmt.style.opacity = opacity == 1 ? "" : Math.round(opacity * 100) / 100;
+        }
+    }
+
+    function SetStyleTransformInternal(elmt, transform) {
+        var rotate = transform.$Rotate || 0;
+        var scale = transform.$Scale == undefined ? 1 : transform.$Scale;
+
+        if (IsBrowserIe9Earlier()) {
+            var matrix = _This.$CreateMatrix(rotate / 180 * Math.PI, scale, scale);
+            SetStyleMatrixIE(elmt, (!rotate && scale == 1) ? null : matrix, _This.$GetMatrixOffset(matrix, transform.$OriginalWidth, transform.$OriginalHeight));
+        }
+        else {
+            //rotate(15deg) scale(.5) translateZ(0)
+            var transformProperty = GetTransformProperty(elmt);
+            if (transformProperty) {
+                var transformValue = "rotate(" + rotate % 360 + "deg) scale(" + scale + ")";
+                if (IsBrowserChrome() && webkitVersion > 535)
+                    transformValue += " perspective(2000px)";
+
+                elmt.style[transformProperty] = transformValue;
+            }
+        }
+    }
+
+    _This.$SetStyleTransform = function (elmt, transform) {
+        if (IsBrowserBadTransform()) {
+            Delay(_This.$CreateCallback(null, SetStyleTransformInternal, elmt, transform));
+        }
+        else {
+            SetStyleTransformInternal(elmt, transform);
+        }
+    };
+
+    _This.$SetStyleTransformOrigin = function (elmt, transformOrigin) {
+        var transformProperty = GetTransformProperty(elmt);
+
+        if (transformProperty)
+            elmt.style[transformProperty + "Origin"] = transformOrigin;
+    };
+
+    _This.$CssScale = function (elmt, scale) {
+
+        if (IsBrowserIE() && browserEngineVersion < 9 || (browserEngineVersion < 10 && IsBrowserIeQuirks())) {
+            elmt.style.zoom = (scale == 1) ? "" : scale;
+        }
+        else {
+            var transformProperty = GetTransformProperty(elmt);
+
+            if (transformProperty) {
+                //rotate(15deg) scale(.5)
+                var transformValue = "scale(" + scale + ")";
+
+                var oldTransformValue = elmt.style[transformProperty];
+                var scaleReg = new RegExp(/[\s]*scale\(.*?\)/g);
+
+                var newTransformValue = BuildNewCss(oldTransformValue, [scaleReg], transformValue);
+
+                elmt.style[transformProperty] = newTransformValue;
+            }
+        }
+    };
+
+    _This.$EnableHWA = function (elmt) {
+        if (!elmt.style[GetTransformProperty(elmt)] || elmt.style[GetTransformProperty(elmt)] == "none")
+            elmt.style[GetTransformProperty(elmt)] = "perspective(2000px)";
+    };
+
+    _This.$DisableHWA = function (elmt) {
+        //if (force || elmt.style[GetTransformProperty(elmt)] == "perspective(2000px)")
+        elmt.style[GetTransformProperty(elmt)] = "none";
+    };
+
+    var ie8OffsetWidth = 0;
+    var ie8OffsetHeight = 0;
+    //var ie8WindowResizeCallbackHandlers;
+    //var ie8LastVerticalScrollbar;
+    //var toggleInfo = "";
+
+    //function Ie8WindowResizeFilter(window, handler) {
+
+    //    var trigger = true;
+
+    //    var checkElement = (IsBrowserIeQuirks() ? window.document.body : window.document.documentElement);
+    //    if (checkElement) {
+    //        //check vertical bar
+    //        //var hasVerticalBar = checkElement.scrollHeight > checkElement.clientHeight;
+    //        //var verticalBarToggle = hasVerticalBar != ie8LastVerticalScrollbar;
+    //        //ie8LastVerticalScrollbar = hasVerticalBar;
+
+    //        var widthChange = checkElement.offsetWidth - ie8OffsetWidth;
+    //        var heightChange = checkElement.offsetHeight - ie8OffsetHeight;
+    //        if (widthChange || heightChange) {
+
+    //            ie8OffsetWidth += widthChange;
+    //            ie8OffsetHeight += heightChange;
+    //        }
+    //        else
+    //            trigger = false;
+    //    }
+
+    //    trigger && handler();
+    //}
+
+    //_This.$OnWindowResize = function (window, handler) {
+
+    //    if (IsBrowserIE() && browserEngineVersion < 9) {
+    //        if (!ie8WindowResizeCallbackHandlers) {
+    //            ie8WindowResizeCallbackHandlers = [handler];
+    //            handler = _This.$CreateCallback(null, Ie8WindowResizeFilter, window);
+    //        }
+    //        else {
+    //            ie8WindowResizeCallbackHandlers.push(handler);
+    //            return;
+    //        }
+    //    }
+
+    //    _This.$AddEvent(window, "resize", handler);
+    //};
+
+    _This.$WindowResizeFilter = function (window, handler) {
+        return IsBrowserIe9Earlier() ? function () {
+
+            var trigger = true;
+
+            var checkElement = (IsBrowserIeQuirks() ? window.document.body : window.document.documentElement);
+            if (checkElement) {
+                //check vertical bar
+                //var hasVerticalBar = checkElement.scrollHeight > checkElement.clientHeight;
+                //var verticalBarToggle = hasVerticalBar != ie8LastVerticalScrollbar;
+                //ie8LastVerticalScrollbar = hasVerticalBar;
+
+                var widthChange = checkElement.offsetWidth - ie8OffsetWidth;
+                var heightChange = checkElement.offsetHeight - ie8OffsetHeight;
+                if (widthChange || heightChange) {
+                    ie8OffsetWidth += widthChange;
+                    ie8OffsetHeight += heightChange;
+                }
+                else
+                    trigger = false;
+            }
+
+            trigger && handler();
+
+        } : handler;
+    };
+
+    _This.$MouseOverOutFilter = function (handler, target) {
+        ///	<param name="target" type="HTMLDomElement">
+        ///		The target element to detect mouse over/out events. (for ie < 9 compatibility)
+        ///	</param>
+
+        $JssorDebug$.$Execute(function () {
+            if (!target) {
+                throw new Error("Null reference, parameter \"target\".");
+            }
+        });
+
+        return function (event) {
+            event = GetEvent(event);
+
+            var eventName = event.type;
+            var related = event.relatedTarget || (eventName == "mouseout" ? event.toElement : event.fromElement);
+
+            if (!related || (related !== target && !_This.$IsChild(target, related))) {
+                handler(event);
+            }
+        };
+    };
+
+    _This.$AddEvent = function (elmt, eventName, handler, useCapture) {
+        elmt = _This.$GetElement(elmt);
+
+        // technique from:
+        // http://blog.paranoidferret.com/index.php/2007/08/10/javascript-working-with-events/
+
+        if (elmt.addEventListener) {
+            if (eventName == "mousewheel") {
+                elmt.addEventListener("DOMMouseScroll", handler, useCapture);
+            }
+            // we are still going to add the mousewheel -- not a mistake!
+            // _This is for opera, since it uses onmousewheel but needs addEventListener.
+            elmt.addEventListener(eventName, handler, useCapture);
+        }
+        else if (elmt.attachEvent) {
+            elmt.attachEvent("on" + eventName, handler);
+            if (useCapture && elmt.setCapture) {
+                elmt.setCapture();
+            }
+        }
+
+        $JssorDebug$.$Execute(function () {
+            if (!elmt.addEventListener && !elmt.attachEvent) {
+                $JssorDebug$.$Fail("Unable to attach event handler, no known technique.");
+            }
+        });
+
+    };
+
+    _This.$RemoveEvent = function (elmt, eventName, handler, useCapture) {
+        elmt = _This.$GetElement(elmt);
+
+        // technique from:
+        // http://blog.paranoidferret.com/index.php/2007/08/10/javascript-working-with-events/
+
+        if (elmt.removeEventListener) {
+            if (eventName == "mousewheel") {
+                elmt.removeEventListener("DOMMouseScroll", handler, useCapture);
+            }
+            // we are still going to remove the mousewheel -- not a mistake!
+            // _This is for opera, since it uses onmousewheel but needs removeEventListener.
+            elmt.removeEventListener(eventName, handler, useCapture);
+        }
+        else if (elmt.detachEvent) {
+            elmt.detachEvent("on" + eventName, handler);
+            if (useCapture && elmt.releaseCapture) {
+                elmt.releaseCapture();
+            }
+        }
+    };
+
+    _This.$FireEvent = function (elmt, eventName) {
+        //var document = elmt.document;
+
+        $JssorDebug$.$Execute(function () {
+            if (!document.createEvent && !document.createEventObject) {
+                $JssorDebug$.$Fail("Unable to fire event, no known technique.");
+            }
+
+            if (!elmt.dispatchEvent && !elmt.fireEvent) {
+                $JssorDebug$.$Fail("Unable to fire event, no known technique.");
+            }
+        });
+
+        var evento;
+
+        if (document.createEvent) {
+            evento = document.createEvent("HTMLEvents");
+            evento.initEvent(eventName, false, false);
+            elmt.dispatchEvent(evento);
+        }
+        else {
+            var ieEventName = "on" + eventName;
+            evento = document.createEventObject();
+            //event.eventType = ieEventName;
+            //event.eventName = ieEventName;
+
+            elmt.fireEvent(ieEventName, evento);
+        }
+    };
+
+    _This.$AddEventBrowserMouseUp = function (handler, userCapture) {
+        _This.$AddEvent((IsBrowserIe9Earlier()) ? document : window, "mouseup", handler, userCapture);
+    };
+
+    _This.$RemoveEventBrowserMouseUp = function (handler, userCapture) {
+        _This.$RemoveEvent((IsBrowserIe9Earlier()) ? document : window, "mouseup", handler, userCapture);
+    };
+
+    //_This.$AddEventBrowserMouseDown = function (handler, userCapture) {
+    //    _This.$AddEvent((IsBrowserIe9Earlier()) ? document : window, "mousedown", handler, userCapture);
+    //};
+
+    //_This.$RemoveEventBrowserMouseDown = function (handler, userCapture) {
+    //    _This.$RemoveEvent((IsBrowserIe9Earlier()) ? document : window, "mousedown", handler, userCapture);
+    //};
+
+    _This.$CancelEvent = function (event) {
+        event = GetEvent(event);
+
+        // technique from:
+        // http://blog.paranoidferret.com/index.php/2007/08/10/javascript-working-with-events/
+
+        if (event.preventDefault) {
+            event.preventDefault();     // W3C for preventing default
+        }
+
+        event.cancel = true;            // legacy for preventing default
+        event.returnValue = false;      // IE for preventing default
+    };
+
+    _This.$StopEvent = function (event) {
+        event = GetEvent(event);
+
+        // technique from:
+        // http://blog.paranoidferret.com/index.php/2007/08/10/javascript-working-with-events/
+
+        if (event.stopPropagation) {
+            event.stopPropagation();    // W3C for stopping propagation
+        }
+
+        event.cancelBubble = true;      // IE for stopping propagation
+    };
+
+    _This.$CreateCallback = function (object, method) {
+        // create callback args
+        var initialArgs = [].slice.call(arguments, 2);
+
+        // create closure to apply method
+        var callback = function () {
+            // concatenate new args, but make a copy of initialArgs first
+            var args = initialArgs.concat([].slice.call(arguments, 0));
+
+            return method.apply(object, args);
+        };
+
+        //$JssorDebug$.$LiveStamp(callback, "callback_" + ($Jssor$.$GetNow() & 0xFFFFFF));
+
+        return callback;
+    };
+
+    var _Freeer;
+    _This.$FreeElement = function (elmt) {
+        if (!_Freeer)
+            _Freeer = _This.$CreateDiv();
+
+        if (elmt) {
+            $Jssor$.$AppendChild(_Freeer, elmt);
+            $Jssor$.$ClearInnerHtml(_Freeer);
+        }
+    };
+
+    _This.$InnerText = function (elmt, text) {
+        if (text == undefined)
+            return elmt.textContent || elmt.innerText;
+
+        var textNode = document.createTextNode(text);
+        _This.$ClearInnerHtml(elmt);
+        elmt.appendChild(textNode);
+    };
+    
+    _This.$InnerHtml = function (elmt, html) {
+        if (html == undefined)
+            return elmt.innerHTML;
+
+        elmt.innerHTML = html;
+    };
+
+    _This.$GetClientRect = function (elmt) {
+        var rect = elmt.getBoundingClientRect();
+
+        return { x: rect.left, y: rect.top, w: rect.right - rect.left, h: rect.bottom - rect.top };
+    };
+
+    _This.$ClearInnerHtml = function (elmt) {
+        elmt.innerHTML = "";
+    };
+
+    _This.$EncodeHtml = function (text) {
+        var div = _This.$CreateDiv();
+        _This.$InnerText(div, text);
+        return _This.$InnerHtml(div);
+    };
+
+    _This.$DecodeHtml = function (html) {
+        var div = _This.$CreateDiv();
+        _This.$InnerHtml(div, html);
+        return _This.$InnerText(div);
+    };
+
+    _This.$SelectElement = function (elmt) {
+        var userSelection;
+        if (window.getSelection) {
+            //W3C default
+            userSelection = window.getSelection();
+        }
+        var theRange = null;
+        if (document.createRange) {
+            theRange = document.createRange();
+            theRange.selectNode(elmt);
+        }
+        else {
+            theRange = document.body.createTextRange();
+            theRange.moveToElementText(elmt);
+            theRange.select();
+        }
+        //set user selection
+        if (userSelection)
+            userSelection.addRange(theRange);
+    };
+
+    _This.$DeselectElements = function () {
+        if (document.selection) {
+            document.selection.empty();
+        } else if (window.getSelection) {
+            window.getSelection().removeAllRanges();
+        }
+    };
+
+    _This.$Children = function (elmt) {
+        var children = [];
+
+        for (var tmpEl = elmt.firstChild; tmpEl; tmpEl = tmpEl.nextSibling) {
+            if (tmpEl.nodeType == 1) {
+                children.push(tmpEl);
+            }
+        }
+
+        return children;
+    };
+
+    function FindFirstChild(elmt, attrValue, attrName, deep) {
+        if (!attrName)
+            attrName = "u";
+
+        for (elmt = elmt ? elmt.firstChild : null; elmt; elmt = elmt.nextSibling) {
+            if (elmt.nodeType == 1) {
+                if (AttributeEx(elmt, attrName) == attrValue)
+                    return elmt;
+
+                if (deep) {
+                    var childRet = FindFirstChild(elmt, attrValue, attrName, deep);
+                    if (childRet)
+                        return childRet;
+                }
+            }
+        }
+    }
+
+    _This.$FindFirstChild = FindFirstChild;
+
+    function FindChildren(elmt, attrValue, attrName, deep) {
+        if (!attrName)
+            attrName = "u";
+
+        var ret = [];
+
+        for (elmt = elmt ? elmt.firstChild : null; elmt; elmt = elmt.nextSibling) {
+            if (elmt.nodeType == 1) {
+                if (AttributeEx(elmt, attrName) == attrValue)
+                    ret.push(elmt);
+
+                if (deep) {
+                    var childRet = FindChildren(elmt, attrValue, attrName, deep);
+                    if (childRet.length)
+                        ret = ret.concat(childRet);
+                }
+            }
+        }
+
+        return ret;
+    }
+
+    _This.$FindChildren = FindChildren;
+
+    function FindFirstChildByTag(elmt, tagName, deep) {
+
+        for (elmt = elmt ? elmt.firstChild : null; elmt; elmt = elmt.nextSibling) {
+            if (elmt.nodeType == 1) {
+                if (elmt.tagName == tagName)
+                    return elmt;
+
+                if (deep) {
+                    var childRet = FindFirstChildByTag(elmt, tagName, deep);
+                    if (childRet)
+                        return childRet;
+                }
+            }
+        }
+    }
+
+    _This.$FindFirstChildByTag = FindFirstChildByTag;
+
+    function FindChildrenByTag(elmt, tagName, deep) {
+        var ret = [];
+
+        for (elmt = elmt ? elmt.firstChild : null; elmt; elmt = elmt.nextSibling) {
+            if (elmt.nodeType == 1) {
+                if (!tagName || elmt.tagName == tagName)
+                    ret.push(elmt);
+
+                if (deep) {
+                    var childRet = FindChildrenByTag(elmt, tagName, true);
+                    if (childRet.length)
+                        ret = ret.concat(childRet);
+                }
+            }
+        }
+
+        return ret;
+    }
+
+    _This.$FindChildrenByTag = FindChildrenByTag;
+
+    _This.$GetElementsByTag = function (elmt, tagName) {
+        return elmt.getElementsByTagName(tagName);
+    };
+
+    function Extend(target) {
+        for (var i = 1; i < arguments.length; i++) {
+
+            var options = arguments[i];
+
+            // Only deal with non-null/undefined values
+            if (options) {
+                // Extend the base object
+                for (var name in options) {
+                    target[name] = options[name];
+                }
+            }
+        }
+
+        // Return the modified object
+        return target;
+    }
+
+    _This.$Extend = Extend;
+
+    function Unextend(target, options) {
+        $JssorDebug$.$Assert(options);
+
+        var unextended = {};
+
+        // Extend the base object
+        for (var name in target) {
+            if (target[name] != options[name]) {
+                unextended[name] = target[name];
+            }
+        }
+
+        // Return the modified object
+        return unextended;
+    }
+
+    _This.$Unextend = Unextend;
+
+    _This.$IsUndefined = function (obj) {
+        return type(obj) == "undefined";
+    };
+
+    _This.$IsFunction = function (obj) {
+        return type(obj) == "function";
+    };
+
+    _This.$IsArray = function (obj) {
+        return type(obj) == "array";
+    };
+
+    _This.$IsString = function (obj) {
+        return type(obj) == "string";
+    };
+
+    _This.$IsNumeric = function (obj) {
+        return !isNaN(ParseFloat(obj)) && isFinite(obj);
+    };
+
+    _This.$IsWindow = function (obj) {
+        return obj && obj == obj.window;
+    };
+
+    _This.$Type = type;
+
+    // args is for internal usage only
+    _This.$Each = each;
+
+    _This.$IsPlainObject = isPlainObject;
+
+    function CreateElement(tagName) {
+        return document.createElement(tagName);
+    }
+
+    _This.$CreateElement = CreateElement;
+
+    _This.$CreateDiv = function () {
+        return CreateElement("DIV", document);
+    };
+
+    _This.$CreateSpan = function () {
+        return CreateElement("SPAN", document);
+    };
+
+    _This.$EmptyFunction = function () { };
+
+    function Attribute(elmt, name, value) {
+        if (value == undefined)
+            return elmt.getAttribute(name);
+
+        elmt.setAttribute(name, value);
+    }
+
+    function AttributeEx(elmt, name) {
+        return Attribute(elmt, name) || Attribute(elmt, "data-" + name);
+    }
+
+    _This.$Attribute = Attribute;
+    _This.$AttributeEx = AttributeEx;
+
+    function ClassName(elmt, className) {
+        if (className == undefined)
+            return elmt.className;
+
+        elmt.className = className;
+    }
+
+    _This.$ClassName = ClassName;
+
+    function ToHash(array) {
+        var hash = {};
+
+        each(array, function (item) {
+            hash[item] = item;
+        });
+
+        return hash;
+    }
+
+    _This.$ToHash = ToHash;
+
+    function Join(separator, strings) {
+        ///	<param name="separator" type="String">
+        ///		The element to show the dialog around
+        ///	</param>
+        ///	<param name="strings" type="Array" value="['1']">
+        ///		The element to show the dialog around
+        ///	</param>
+
+        var joined = "";
+
+        each(strings, function (str) {
+            joined && (joined += separator);
+            joined += str;
+        });
+
+        return joined;
+    }
+
+    _This.$Join = Join;
+
+    _This.$AddClass = function (elmt, className) {
+        var newClassName = ClassName(elmt) + " " + className;
+        ClassName(elmt, Join(" ", ToHash(newClassName.match(REGEX_WHITESPACE_GLOBAL))));
+    };
+
+    _This.$RemoveClass = function (elmt, className) {
+        ClassName(elmt, Join(" ", _This.$Unextend(ToHash(ClassName(elmt).match(REGEX_WHITESPACE_GLOBAL)), ToHash(className.match(REGEX_WHITESPACE_GLOBAL)))));
+    };
+
+    _This.$ParentNode = function (elmt) {
+        return elmt.parentNode;
+    };
+
+    _This.$HideElement = function (elmt) {
+        _This.$CssDisplay(elmt, "none");
+    };
+
+    _This.$HideElements = function (elmts) {
+        for (var i = 0; i < elmts.length; i++) {
+            _This.$HideElement(elmts[i]);
+        }
+    };
+
+    _This.$ShowElement = function (elmt, show) {
+        _This.$CssDisplay(elmt, show == false ? "none" : "");
+    };
+
+    _This.$ShowElements = function (elmts) {
+        for (var i = 0; i < elmts.length; i++) {
+            _This.$ShowElement(elmts[i]);
+        }
+    };
+
+    _This.$RemoveAttribute = function (elmt, attrbuteName) {
+        elmt.removeAttribute(attrbuteName);
+    };
+
+    _This.$CanClearClip = function () {
+        return IsBrowserIE() && browserRuntimeVersion < 10;
+    };
+
+    _This.$SetStyleClip = function (elmt, clip) {
+        if (clip) {
+            elmt.style.clip = "rect(" + Math.round(clip.$Top) + "px " + Math.round(clip.$Right) + "px " + Math.round(clip.$Bottom) + "px " + Math.round(clip.$Left) + "px)";
+        }
+        else {
+            var cssText = elmt.style.cssText;
+            var clipRegs = [
+                new RegExp(/[\s]*clip: rect\(.*?\)[;]?/i),
+                new RegExp(/[\s]*cliptop: .*?[;]?/i),
+                new RegExp(/[\s]*clipright: .*?[;]?/i),
+                new RegExp(/[\s]*clipbottom: .*?[;]?/i),
+                new RegExp(/[\s]*clipleft: .*?[;]?/i)
+            ];
+
+            var newCssText = BuildNewCss(cssText, clipRegs, "");
+
+            $Jssor$.$CssCssText(elmt, newCssText);
+        }
+    };
+
+    _This.$GetNow = function () {
+        return new Date().getTime();
+    };
+
+    _This.$AppendChild = function (elmt, child) {
+        elmt.appendChild(child);
+    };
+
+    _This.$AppendChildren = function (elmt, children) {
+        each(children, function (child) {
+            _This.$AppendChild(elmt, child);
+        });
+    };
+
+    _This.$InsertBefore = function (elmt, child, refObject) {
+        elmt.insertBefore(child, refObject);
+    };
+
+    _This.$InsertAdjacentHtml = function (elmt, where, text) {
+        elmt.insertAdjacentHTML(where, text);
+    };
+
+    _This.$RemoveChild = function (elmt, child) {
+        elmt.removeChild(child);
+    };
+
+    _This.$RemoveChildren = function (elmt, children) {
+        each(children, function (child) {
+            _This.$RemoveChild(elmt, child);
+        });
+    };
+
+    _This.$ClearChildren = function (elmt) {
+        _This.$RemoveChildren(elmt, _This.$Children(elmt));
+    };
+
+    _This.$ParseInt = function (str, radix) {
+        return parseInt(str, radix || 10);
+    };
+
+    function ParseFloat(str) {
+        return parseFloat(str);
+    }
+
+    _This.$ParseFloat = ParseFloat;
+
+    _This.$IsChild = function (elmtA, elmtB) {
+        var body = document.body;
+        while (elmtB && elmtA != elmtB && body != elmtB) {
+            try {
+                elmtB = elmtB.parentNode;
+            } catch (e) {
+                // Firefox sometimes fires events for XUL elements, which throws
+                // a "permission denied" error. so this is not a child.
+                return false;
+            }
+        }
+        return elmtA == elmtB;
+    };
+
+    function CloneNode(elmt, deep) {
+        return elmt.cloneNode(deep);
+    }
+
+    _This.$CloneNode = CloneNode;
+
+    function TranslateTransition(transition) {
+        if (transition) {
+            var flyDirection = transition.$FlyDirection;
+
+            if (flyDirection & 1) {
+                transition.x = transition.$ScaleHorizontal || 1;
+            }
+            if (flyDirection & 2) {
+                transition.x = -transition.$ScaleHorizontal || -1;
+            }
+            if (flyDirection & 4) {
+                transition.y = transition.$ScaleVertical || 1;
+            }
+            if (flyDirection & 8) {
+                transition.y = -transition.$ScaleVertical || -1;
+            }
+
+            TranslateTransition(transition.$Brother);
+        }
+    }
+
+    _This.$TranslateTransitions = function (transitions) {
+        ///	<summary>
+        ///		For backward compatibility only.
+        ///	</summary>
+        if (transitions) {
+            for (var i = 0; i < transitions.length; i++) {
+                TranslateTransition(transitions[i]);
+            }
+            for (var name in transitions) {
+                TranslateTransition(transitions[name]);
+            }
+        }
+    };
+
+    function LoadImageCallback(callback, image, abort) {
+        image.onload = null;
+        image.abort = null;
+
+        if (callback)
+            callback(image, abort);
+    }
+
+    _This.$LoadImage = function (src, callback) {
+        if (IsBrowserOpera() && browserRuntimeVersion < 11.6 || !src) {
+            LoadImageCallback(callback, null);
+        }
+        else {
+            var image = new Image();
+            image.onload = _This.$CreateCallback(null, LoadImageCallback, callback, image);
+            image.onabort = _This.$CreateCallback(null, LoadImageCallback, callback, image, true);
+            image.src = src;
+        }
+    };
+
+    _This.$LoadImages = function (imageElmts, mainImageElmt, callback) {
+
+        var _ImageLoading = imageElmts.length + 1;
+
+        function LoadImageCompleteEventHandler(image, abort) {
+            _ImageLoading--;
+            if (mainImageElmt && image && image.src == mainImageElmt.src)
+                mainImageElmt = image;
+            !_ImageLoading && callback && callback(mainImageElmt);
+        }
+
+        each(imageElmts, function (imageElmt) {
+            $Jssor$.$LoadImage(imageElmt.src, LoadImageCompleteEventHandler);
+        });
+
+        LoadImageCompleteEventHandler();
+    };
+
+    _This.$BuildElement = function (template, tagName, replacer, createCopy) {
+        if (createCopy)
+            template = CloneNode(template, true);
+
+        var templateHolders = $Jssor$.$GetElementsByTag(template, tagName);
+        for (var j = templateHolders.length - 1; j > -1; j--) {
+            var templateHolder = templateHolders[j];
+            var replaceItem = CloneNode(replacer, true);
+            ClassName(replaceItem, ClassName(templateHolder));
+            $Jssor$.$CssCssText(replaceItem, templateHolder.style.cssText);
+
+            var thumbnailPlaceHolderParent = $Jssor$.$ParentNode(templateHolder);
+            $Jssor$.$InsertBefore(thumbnailPlaceHolderParent, replaceItem, templateHolder);
+            $Jssor$.$RemoveChild(thumbnailPlaceHolderParent, templateHolder);
+        }
+
+        return template;
+    };
+
+    var _MouseDownButtons;
+    function JssorButtonEx(elmt) {
+        var _Self = this;
+
+        var _OriginClassName;
+
+        var _IsMouseDown;   //class name 'dn'
+        var _IsActive;      //class name 'av'
+        var _IsDisabled;    //class name 'ds'
+
+        function Highlight() {
+            var className = _OriginClassName;
+
+            if (_IsDisabled) {
+                className += 'ds';
+            }
+            else if (_IsMouseDown) {
+                className += 'dn';
+            }
+            else if (_IsActive) {
+                className += "av";
+            }
+
+            ClassName(elmt, className);
+        }
+
+        function OnMouseDown(event) {
+            if (_IsDisabled) {
+                _This.$CancelEvent(event);
+            }
+            else {
+                _MouseDownButtons.push(_Self);
+
+                _IsMouseDown = true;
+
+                Highlight();
+            }
+        }
+
+        _Self.$MouseUp = function () {
+            ///	<summary>
+            ///		Internal member function, do not use it.
+            ///	</summary>
+            ///	<private />
+
+            _IsMouseDown = false;
+
+            Highlight();
+        };
+
+        _Self.$Activate = function (activate) {
+            if (activate != undefined) {
+                _IsActive = activate;
+
+                Highlight();
+            }
+            else {
+                return _IsActive;
+            }
+        };
+
+        _Self.$Enable = function (enable) {
+            if (enable != undefined) {
+                _IsDisabled = !enable;
+
+                Highlight();
+            }
+            else {
+                return !_IsDisabled;
+            }
+        };
+
+        //JssorButtonEx Constructor
+        {
+            elmt = _This.$GetElement(elmt);
+
+            if (!_MouseDownButtons) {
+                _This.$AddEventBrowserMouseUp(function () {
+                    var oldMouseDownButtons = _MouseDownButtons;
+                    _MouseDownButtons = [];
+
+                    each(oldMouseDownButtons, function (button) {
+                        button.$MouseUp();
+                    });
+                });
+
+                _MouseDownButtons = [];
+            }
+
+            _OriginClassName = ClassName(elmt);
+
+            $Jssor$.$AddEvent(elmt, "mousedown", OnMouseDown);
+        }
+    }
+
+    _This.$Buttonize = function (elmt) {
+        return new JssorButtonEx(elmt);
+    };
+
+    _This.$Css = Css;
+    _This.$CssN = CssN;
+    _This.$CssP = CssP;
+
+    _This.$CssOverflow = CssProxy("overflow");
+
+    _This.$CssTop = CssProxy("top", 2);
+    _This.$CssLeft = CssProxy("left", 2);
+    _This.$CssWidth = CssProxy("width", 2);
+    _This.$CssHeight = CssProxy("height", 2);
+    _This.$CssMarginLeft = CssProxy("marginLeft", 2);
+    _This.$CssMarginTop = CssProxy("marginTop", 2);
+    _This.$CssPosition = CssProxy("position");
+    _This.$CssDisplay = CssProxy("display");
+    _This.$CssZIndex = CssProxy("zIndex", 1);
+    _This.$CssFloat = function (elmt, float) {
+        return Css(elmt, IsBrowserIE() ? "styleFloat" : "cssFloat", float);
+    };
+    _This.$CssOpacity = function (elmt, opacity, ie9EarlierForce) {
+        if (opacity != undefined) {
+            SetStyleOpacity(elmt, opacity, ie9EarlierForce);
+        }
+        else {
+            return GetStyleOpacity(elmt);
+        }
+    };
+    _This.$CssCssText = function (elmt, text) {
+        if (text != undefined) {
+            elmt.style.cssText = text;
+        }
+        else {
+            return elmt.style.cssText;
+        }
+    };
+
+    var _StyleGetter = {
+        $Opacity: _This.$CssOpacity,
+        $Top: _This.$CssTop,
+        $Left: _This.$CssLeft,
+        $Width: _This.$CssWidth,
+        $Height: _This.$CssHeight,
+        $Position: _This.$CssPosition,
+        $Display: _This.$CssDisplay,
+        $ZIndex: _This.$CssZIndex
+    };
+
+    //var _StyleGetter = {
+    //    $Opacity: _This.$GetStyleOpacity,
+    //    $Top: _This.$GetStyleTop,
+    //    $Left: _This.$GetStyleLeft,
+    //    $Width: _This.$GetStyleWidth,
+    //    $Height: _This.$GetStyleHeight,
+    //    $Position: _This.$GetStylePosition,
+    //    $Display: _This.$GetStyleDisplay,
+    //    $ZIndex: _This.$GetStyleZIndex
+    //};
+
+    var _StyleSetterReserved;
+
+    //var _StyleSetterReserved = {
+    //    $Opacity: _This.$SetStyleOpacity,
+    //    $Top: _This.$SetStyleTop,
+    //    $Left: _This.$SetStyleLeft,
+    //    $Width: _This.$SetStyleWidth,
+    //    $Height: _This.$SetStyleHeight,
+    //    $Display: _This.$SetStyleDisplay,
+    //    $Clip: _This.$SetStyleClip,
+    //    $MarginLeft: _This.$SetStyleMarginLeft,
+    //    $MarginTop: _This.$SetStyleMarginTop,
+    //    $Transform: _This.$SetStyleTransform,
+    //    $Position: _This.$SetStylePosition,
+    //    $ZIndex: _This.$SetStyleZIndex
+    //};
+
+    function StyleSetter() {
+        if (!_StyleSetterReserved) {
+            _StyleSetterReserved = Extend({
+                $MarginTop: _This.$CssMarginTop,
+                $MarginLeft: _This.$CssMarginLeft,
+                $Clip: _This.$SetStyleClip,
+                $Transform: _This.$SetStyleTransform
+            }, _StyleGetter);
+        }
+        return _StyleSetterReserved;
+    }
+
+    function StyleSetterEx() {
+        StyleSetter();
+
+        //For Compression Only
+        _StyleSetterReserved.$Transform = _StyleSetterReserved.$Transform;
+
+        return _StyleSetterReserved;
+    }
+
+    _This.$StyleSetter = StyleSetter;
+
+    _This.$StyleSetterEx = StyleSetterEx;
+
+    _This.$GetStyles = function (elmt, originStyles) {
+        StyleSetter();
+
+        var styles = {};
+
+        each(originStyles, function (value, key) {
+            if (_StyleGetter[key]) {
+                styles[key] = _StyleGetter[key](elmt);
+            }
+        });
+
+        return styles;
+    };
+
+    _This.$SetStyles = function (elmt, styles) {
+        var styleSetter = StyleSetter();
+
+        each(styles, function (value, key) {
+            styleSetter[key] && styleSetter[key](elmt, value);
+        });
+    };
+
+    _This.$SetStylesEx = function (elmt, styles) {
+        StyleSetterEx();
+
+        _This.$SetStyles(elmt, styles);
+    };
+
+    $JssorMatrix$ = new function () {
+        var _ThisMatrix = this;
+
+        function Multiply(ma, mb) {
+            var acs = ma[0].length;
+            var rows = ma.length;
+            var cols = mb[0].length;
+
+            var matrix = [];
+
+            for (var r = 0; r < rows; r++) {
+                var row = matrix[r] = [];
+                for (var c = 0; c < cols; c++) {
+                    var unitValue = 0;
+
+                    for (var ac = 0; ac < acs; ac++) {
+                        unitValue += ma[r][ac] * mb[ac][c];
+                    }
+
+                    row[c] = unitValue;
+                }
+            }
+
+            return matrix;
+        }
+
+        _ThisMatrix.$ScaleX = function (matrix, sx) {
+            return _ThisMatrix.$ScaleXY(matrix, sx, 0);
+        };
+
+        _ThisMatrix.$ScaleY = function (matrix, sy) {
+            return _ThisMatrix.$ScaleXY(matrix, 0, sy);
+        };
+
+        _ThisMatrix.$ScaleXY = function (matrix, sx, sy) {
+            return Multiply(matrix, [[sx, 0], [0, sy]]);
+        };
+
+        _ThisMatrix.$TransformPoint = function (matrix, p) {
+            var pMatrix = Multiply(matrix, [[p.x], [p.y]]);
+
+            return new $JssorPoint$(pMatrix[0][0], pMatrix[1][0]);
+        };
+    };
+
+    _This.$CreateMatrix = function (alpha, scaleX, scaleY) {
+        var cos = Math.cos(alpha);
+        var sin = Math.sin(alpha);
+        //var r11 = cos;
+        //var r21 = sin;
+        //var r12 = -sin;
+        //var r22 = cos;
+
+        //var m11 = cos * scaleX;
+        //var m12 = -sin * scaleY;
+        //var m21 = sin * scaleX;
+        //var m22 = cos * scaleY;
+
+        return [[cos * scaleX, -sin * scaleY], [sin * scaleX, cos * scaleY]];
+    };
+
+    _This.$GetMatrixOffset = function (matrix, width, height) {
+        var p1 = $JssorMatrix$.$TransformPoint(matrix, new $JssorPoint$(-width / 2, -height / 2));
+        var p2 = $JssorMatrix$.$TransformPoint(matrix, new $JssorPoint$(width / 2, -height / 2));
+        var p3 = $JssorMatrix$.$TransformPoint(matrix, new $JssorPoint$(width / 2, height / 2));
+        var p4 = $JssorMatrix$.$TransformPoint(matrix, new $JssorPoint$(-width / 2, height / 2));
+
+        return new $JssorPoint$(Math.min(p1.x, p2.x, p3.x, p4.x) + width / 2, Math.min(p1.y, p2.y, p3.y, p4.y) + height / 2);
+    };
+};
+
+//for backward compatibility
+//var $JssorUtils$ = window.$JssorUtils$ = $Jssor$;
+
+//$JssorObject$
+var $JssorObject$ = window.$JssorObject$ = function () {
+    var _ThisObject = this;
+    // Fields
+
+    var _Listeners = []; // dictionary of eventName --> array of handlers
+    var _Listenees = [];
+
+    // Private Methods
+    function AddListener(eventName, handler) {
+
+        $JssorDebug$.$Execute(function () {
+            if (eventName == undefined || eventName == null)
+                throw new Error("param 'eventName' is null or empty.");
+
+            if (typeof (handler) != "function") {
+                throw "param 'handler' must be a function.";
+            }
+
+            $Jssor$.$Each(_Listeners, function (listener) {
+                if (listener.$EventName == eventName && listener.$Handler === handler) {
+                    throw new Error("The handler listened to the event already, cannot listen to the same event of the same object with the same handler twice.");
+                }
+            });
+        });
+
+        _Listeners.push({ $EventName: eventName, $Handler: handler });
+    }
+
+    function RemoveListener(eventName, handler) {
+
+        $JssorDebug$.$Execute(function () {
+            if (eventName == undefined || eventName == null)
+                throw new Error("param 'eventName' is null or empty.");
+
+            if (typeof (handler) != "function") {
+                throw "param 'handler' must be a function.";
+            }
+        });
+
+        $Jssor$.$Each(_Listeners, function (listener, index) {
+            if (listener.$EventName == eventName && listener.$Handler === handler) {
+                _Listeners.splice(index, 1);
+            }
+        });
+    }
+
+    function ClearListeners() {
+        _Listeners = [];
+    }
+
+    function ClearListenees() {
+
+        $Jssor$.$Each(_Listenees, function (listenee) {
+            $Jssor$.$RemoveEvent(listenee.$Obj, listenee.$EventName, listenee.$Handler);
+        });
+
+        _Listenees = [];
+    }
+
+    //Protected Methods
+    _ThisObject.$Listen = function (obj, eventName, handler, useCapture) {
+
+        $JssorDebug$.$Execute(function () {
+            if (!obj)
+                throw new Error("param 'obj' is null or empty.");
+
+            if (eventName == undefined || eventName == null)
+                throw new Error("param 'eventName' is null or empty.");
+
+            if (typeof (handler) != "function") {
+                throw "param 'handler' must be a function.";
+            }
+
+            $Jssor$.$Each(_Listenees, function (listenee) {
+                if (listenee.$Obj === obj && listenee.$EventName == eventName && listenee.$Handler === handler) {
+                    throw new Error("The handler listened to the event already, cannot listen to the same event of the same object with the same handler twice.");
+                }
+            });
+        });
+
+        $Jssor$.$AddEvent(obj, eventName, handler, useCapture);
+        _Listenees.push({ $Obj: obj, $EventName: eventName, $Handler: handler });
+    };
+
+    _ThisObject.$Unlisten = function (obj, eventName, handler) {
+
+        $JssorDebug$.$Execute(function () {
+            if (!obj)
+                throw new Error("param 'obj' is null or empty.");
+
+            if (eventName == undefined || eventName == null)
+                throw new Error("param 'eventName' is null or empty.");
+
+            if (typeof (handler) != "function") {
+                throw "param 'handler' must be a function.";
+            }
+        });
+
+        $Jssor$.$Each(_Listenees, function (listenee, index) {
+            if (listenee.$Obj === obj && listenee.$EventName == eventName && listenee.$Handler === handler) {
+                $Jssor$.$RemoveEvent(obj, eventName, handler);
+                _Listenees.splice(index, 1);
+            }
+        });
+    };
+
+    _ThisObject.$UnlistenAll = ClearListenees;
+
+    // Public Methods
+    _ThisObject.$On = _ThisObject.addEventListener = AddListener;
+
+    _ThisObject.$Off = _ThisObject.removeEventListener = RemoveListener;
+
+    _ThisObject.$TriggerEvent = function (eventName) {
+
+        var args = [].slice.call(arguments, 1);
+
+        $Jssor$.$Each(_Listeners, function (listener) {
+            try {
+                listener.$EventName == eventName && listener.$Handler.apply(window, args);
+            } catch (e) {
+                // handler threw an error, ignore, go on to next one
+                $JssorDebug$.$Error(e.name + " while executing " + eventName +
+                        " handler: " + e.message, e);
+            }
+        });
+    };
+
+    _ThisObject.$Destroy = function () {
+        ClearListenees();
+        ClearListeners();
+
+        for (var name in _ThisObject)
+            delete _ThisObject[name];
+    };
+
+    $JssorDebug$.$C_AbstractClass(_ThisObject);
+};
+
+$JssorAnimator$ = function (delay, duration, options, elmt, fromStyles, toStyles) {
+    delay = delay || 0;
+
+    var _ThisAnimator = this;
+    var _AutoPlay;
+    var _Hiden;
+    var _CombineMode;
+    var _PlayToPosition;
+    var _PlayDirection;
+    var _NoStop;
+    var _TimeStampLastFrame = 0;
+
+    var _SubEasings;
+    var _SubRounds;
+    var _SubDurings;
+    var _Callback;
+
+    var _Position_Current = 0;
+    var _Position_Display = 0;
+    var _Hooked;
+
+    var _Position_InnerBegin = delay;
+    var _Position_InnerEnd = delay + duration;
+    var _Position_OuterBegin;
+    var _Position_OuterEnd;
+    var _LoopLength;
+
+    var _NestedAnimators = [];
+    var _StyleSetter;
+
+    function GetPositionRange(position, begin, end) {
+        var range = 0;
+
+        if (position < begin)
+            range = -1;
+
+        else if (position > end)
+            range = 1;
+
+        return range;
+    }
+
+    function GetInnerPositionRange(position) {
+        return GetPositionRange(position, _Position_InnerBegin, _Position_InnerEnd);
+    }
+
+    function GetOuterPositionRange(position) {
+        return GetPositionRange(position, _Position_OuterBegin, _Position_OuterEnd);
+    }
+
+    function Shift(offset) {
+        _Position_OuterBegin += offset;
+        _Position_OuterEnd += offset;
+        _Position_InnerBegin += offset;
+        _Position_InnerEnd += offset;
+
+        _Position_Current += offset;
+        _Position_Display += offset;
+
+        $Jssor$.$Each(_NestedAnimators, function (animator) {
+            animator, animator.$Shift(offset);
+        });
+    }
+
+    function Locate(position, relative) {
+        var offset = position - _Position_OuterBegin + delay * relative;
+
+        Shift(offset);
+
+        //$JssorDebug$.$Execute(function () {
+        //    _ThisAnimator.$Position_InnerBegin = _Position_InnerBegin;
+        //    _ThisAnimator.$Position_InnerEnd = _Position_InnerEnd;
+        //    _ThisAnimator.$Position_OuterBegin = _Position_OuterBegin;
+        //    _ThisAnimator.$Position_OuterEnd = _Position_OuterEnd;
+        //});
+
+        return _Position_OuterEnd;
+    }
+
+    function GoToPosition(positionOuter, force) {
+        var trimedPositionOuter = positionOuter;
+
+        if (_LoopLength && (trimedPositionOuter >= _Position_OuterEnd || trimedPositionOuter <= _Position_OuterBegin)) {
+            trimedPositionOuter = ((trimedPositionOuter - _Position_OuterBegin) % _LoopLength + _LoopLength) % _LoopLength + _Position_OuterBegin;
+        }
+
+        if (!_Hooked || _NoStop || force || _Position_Current != trimedPositionOuter) {
+
+            var positionToDisplay = Math.min(trimedPositionOuter, _Position_OuterEnd);
+            positionToDisplay = Math.max(positionToDisplay, _Position_OuterBegin);
+
+            if (!_Hooked || _NoStop || force || positionToDisplay != _Position_Display) {
+                if (toStyles) {
+                    var currentStyles = toStyles;
+
+                    if (fromStyles) {
+                        var interPosition = (positionToDisplay - _Position_InnerBegin) / (duration || 1);
+                        if (options.$Optimize && $Jssor$.$IsBrowserChrome() && duration) {
+                            interPosition = Math.round(interPosition / 16 * duration) * 16 / duration;
+                        }
+                        if (options.$Reverse)
+                            interPosition = 1 - interPosition;
+
+                        currentStyles = {};
+
+                        for (var key in toStyles) {
+                            var round = _SubRounds[key] || 1;
+                            var during = _SubDurings[key] || [0, 1];
+                            var propertyInterPosition = (interPosition - during[0]) / during[1];
+                            propertyInterPosition = Math.min(Math.max(propertyInterPosition, 0), 1);
+                            propertyInterPosition = propertyInterPosition * round;
+                            var floorPosition = Math.floor(propertyInterPosition);
+                            if (propertyInterPosition != floorPosition)
+                                propertyInterPosition -= floorPosition;
+
+                            var easing = _SubEasings[key] || _SubEasings.$Default;
+                            var easingValue = easing(propertyInterPosition);
+                            var currentPropertyValue;
+                            var value = fromStyles[key];
+                            var toValue = toStyles[key];
+
+                            if ($Jssor$.$IsNumeric(toValue)) {
+                                currentPropertyValue = value + (toValue - value) * easingValue;
+                            }
+                            else {
+                                currentPropertyValue = $Jssor$.$Extend({ $Offset: {} }, fromStyles[key]);
+
+                                $Jssor$.$Each(toValue.$Offset, function (rectX, n) {
+                                    var offsetValue = rectX * easingValue;
+                                    currentPropertyValue.$Offset[n] = offsetValue;
+                                    currentPropertyValue[n] += offsetValue;
+                                });
+                            }
+                            currentStyles[key] = currentPropertyValue;
+                        }
+                    }
+
+                    if (fromStyles.$Zoom) {
+                        currentStyles.$Transform = { $Rotate: currentStyles.$Rotate || 0, $Scale: currentStyles.$Zoom, $OriginalWidth: options.$OriginalWidth, $OriginalHeight: options.$OriginalHeight };
+                    }
+
+                    if (toStyles.$Clip && options.$Move) {
+                        var styleFrameNClipOffset = currentStyles.$Clip.$Offset;
+
+                        var offsetY = (styleFrameNClipOffset.$Top || 0) + (styleFrameNClipOffset.$Bottom || 0);
+                        var offsetX = (styleFrameNClipOffset.$Left || 0) + (styleFrameNClipOffset.$Right || 0);
+
+                        currentStyles.$Left = (currentStyles.$Left || 0) + offsetX;
+                        currentStyles.$Top = (currentStyles.$Top || 0) + offsetY;
+                        currentStyles.$Clip.$Left -= offsetX;
+                        currentStyles.$Clip.$Right -= offsetX;
+                        currentStyles.$Clip.$Top -= offsetY;
+                        currentStyles.$Clip.$Bottom -= offsetY;
+                    }
+
+                    if (currentStyles.$Clip && $Jssor$.$CanClearClip() && !currentStyles.$Clip.$Top && !currentStyles.$Clip.$Left && (currentStyles.$Clip.$Right == options.$OriginalWidth) && (currentStyles.$Clip.$Bottom == options.$OriginalHeight))
+                        currentStyles.$Clip = null;
+
+                    $Jssor$.$Each(currentStyles, function (value, key) {
+                        _StyleSetter[key] && _StyleSetter[key](elmt, value);
+                    });
+                }
+
+                _ThisAnimator.$OnInnerOffsetChange(_Position_Display - _Position_InnerBegin, positionToDisplay - _Position_InnerBegin);
+            }
+
+            _Position_Display = positionToDisplay;
+
+            $Jssor$.$Each(_NestedAnimators, function (animator, i) {
+                var nestedAnimator = positionOuter < _Position_Current ? _NestedAnimators[_NestedAnimators.length - i - 1] : animator;
+                nestedAnimator.$GoToPosition(positionOuter, force);
+            });
+
+            var positionOld = _Position_Current;
+            var positionNew = positionOuter;
+
+            _Position_Current = trimedPositionOuter;
+            _Hooked = true;
+
+            _ThisAnimator.$OnPositionChange(positionOld, positionNew);
+        }
+    }
+
+    function Join(animator, combineMode) {
+        ///	<summary>
+        ///		Combine another animator as nested animator
+        ///	</summary>
+        ///	<param name="animator" type="$JssorAnimator$">
+        ///		An instance of $JssorAnimator$
+        ///	</param>
+        ///	<param name="combineMode" type="int">
+        ///		0: parallel - place the animator parallel to this animator.
+        ///		1: chain - chain the animator at the _Position_InnerEnd of this animator.
+        ///	</param>
+        $JssorDebug$.$Execute(function () {
+            if (combineMode !== 0 && combineMode !== 1)
+                $JssorDebug$.$Fail("Argument out of range, the value of 'combineMode' should be either 0 or 1.");
+        });
+
+        if (combineMode)
+            animator.$Locate(_Position_OuterEnd, 1);
+
+        _Position_OuterEnd = Math.max(_Position_OuterEnd, animator.$GetPosition_OuterEnd());
+        _NestedAnimators.push(animator);
+    }
+
+    function PlayFrame() {
+        if (_AutoPlay) {
+            var now = $Jssor$.$GetNow();
+            //var timeOffset = Math.min(now - _TimeStampLastFrame, $Jssor$.$IsBrowserOpera() ? 80 : 20);
+            var timeOffset = Math.min(now - _TimeStampLastFrame, 80);
+            var timePosition = _Position_Current + timeOffset * _PlayDirection;
+            _TimeStampLastFrame = now;
+
+            if (timePosition * _PlayDirection >= _PlayToPosition * _PlayDirection)
+                timePosition = _PlayToPosition;
+
+            GoToPosition(timePosition);
+
+            if (!_NoStop && timePosition * _PlayDirection >= _PlayToPosition * _PlayDirection) {
+                Stop(_Callback);
+            }
+            else {
+                $Jssor$.$Delay(PlayFrame, options.$Interval);
+            }
+        }
+    }
+
+    function PlayToPosition(toPosition, callback, noStop) {
+        if (!_AutoPlay) {
+            _AutoPlay = true;
+            _NoStop = noStop
+            _Callback = callback;
+            toPosition = Math.max(toPosition, _Position_OuterBegin);
+            toPosition = Math.min(toPosition, _Position_OuterEnd);
+            _PlayToPosition = toPosition;
+            _PlayDirection = _PlayToPosition < _Position_Current ? -1 : 1;
+            _ThisAnimator.$OnStart();
+            _TimeStampLastFrame = $Jssor$.$GetNow();
+            PlayFrame();
+        }
+    }
+
+    function Stop(callback) {
+        if (_AutoPlay) {
+            _NoStop = _AutoPlay = _Callback = false;
+            _ThisAnimator.$OnStop();
+
+            if (callback)
+                callback();
+        }
+    }
+
+    _ThisAnimator.$Play = function (positionLength, callback, noStop) {
+        PlayToPosition(positionLength ? _Position_Current + positionLength : _Position_OuterEnd, callback, noStop);
+    };
+
+    _ThisAnimator.$PlayToPosition = PlayToPosition;
+
+    _ThisAnimator.$PlayToBegin = function (callback, noStop) {
+        PlayToPosition(_Position_OuterBegin, callback, noStop);
+    };
+
+    _ThisAnimator.$PlayToEnd = function (callback, noStop) {
+        PlayToPosition(_Position_OuterEnd, callback, noStop);
+    };
+
+    _ThisAnimator.$Stop = Stop;
+
+    _ThisAnimator.$Continue = function (toPosition) {
+        PlayToPosition(toPosition);
+    };
+
+    _ThisAnimator.$GetPosition = function () {
+        return _Position_Current;
+    };
+
+    _ThisAnimator.$GetPlayToPosition = function () {
+        return _PlayToPosition;
+    };
+
+    _ThisAnimator.$GetPosition_Display = function () {
+        return _Position_Display;
+    };
+
+    _ThisAnimator.$GoToPosition = GoToPosition;
+
+    _ThisAnimator.$GoToBegin = function () {
+        GoToPosition(_Position_OuterBegin, true);
+    };
+
+    _ThisAnimator.$GoToEnd = function () {
+        GoToPosition(_Position_OuterEnd, true);
+    };
+
+    _ThisAnimator.$Move = function (offset) {
+        GoToPosition(_Position_Current + offset);
+    };
+
+    _ThisAnimator.$CombineMode = function () {
+        return _CombineMode;
+    };
+
+    _ThisAnimator.$GetDuration = function () {
+        return duration;
+    };
+
+    _ThisAnimator.$IsPlaying = function () {
+        return _AutoPlay;
+    };
+
+    _ThisAnimator.$IsOnTheWay = function () {
+        return _Position_Current > _Position_InnerBegin && _Position_Current <= _Position_InnerEnd;
+    };
+
+    _ThisAnimator.$SetLoopLength = function (length) {
+        _LoopLength = length;
+    };
+
+    _ThisAnimator.$Locate = Locate;
+
+    _ThisAnimator.$Shift = Shift;
+
+    _ThisAnimator.$Join = Join;
+
+    _ThisAnimator.$Combine = function (animator) {
+        ///	<summary>
+        ///		Combine another animator parallel to this animator
+        ///	</summary>
+        ///	<param name="animator" type="$JssorAnimator$">
+        ///		An instance of $JssorAnimator$
+        ///	</param>
+        Join(animator, 0);
+    };
+
+    _ThisAnimator.$Chain = function (animator) {
+        ///	<summary>
+        ///		Chain another animator at the _Position_InnerEnd of this animator
+        ///	</summary>
+        ///	<param name="animator" type="$JssorAnimator$">
+        ///		An instance of $JssorAnimator$
+        ///	</param>
+        Join(animator, 1);
+    };
+
+    _ThisAnimator.$GetPosition_InnerBegin = function () {
+        ///	<summary>
+        ///		Internal member function, do not use it.
+        ///	</summary>
+        ///	<private />
+        ///	<returns type="int" />
+        return _Position_InnerBegin;
+    };
+
+    _ThisAnimator.$GetPosition_InnerEnd = function () {
+        ///	<summary>
+        ///		Internal member function, do not use it.
+        ///	</summary>
+        ///	<private />
+        ///	<returns type="int" />
+        return _Position_InnerEnd;
+    };
+
+    _ThisAnimator.$GetPosition_OuterBegin = function () {
+        ///	<summary>
+        ///		Internal member function, do not use it.
+        ///	</summary>
+        ///	<private />
+        ///	<returns type="int" />
+        return _Position_OuterBegin;
+    };
+
+    _ThisAnimator.$GetPosition_OuterEnd = function () {
+        ///	<summary>
+        ///		Internal member function, do not use it.
+        ///	</summary>
+        ///	<private />
+        ///	<returns type="int" />
+        return _Position_OuterEnd;
+    };
+
+    _ThisAnimator.$OnPositionChange = _ThisAnimator.$OnStart = _ThisAnimator.$OnStop = _ThisAnimator.$OnInnerOffsetChange = $Jssor$.$EmptyFunction;
+    _ThisAnimator.$Version = $Jssor$.$GetNow();
+
+    //Constructor  1
+    {
+        options = $Jssor$.$Extend({
+            $Interval: 16
+        }, options);
+
+        //Sodo statement, for development time intellisence only
+        $JssorDebug$.$Execute(function () {
+            options = $Jssor$.$Extend({
+                $LoopLength: undefined,
+                $Setter: undefined,
+                $Easing: undefined
+            }, options);
+        });
+
+        _LoopLength = options.$LoopLength;
+
+        _StyleSetter = $Jssor$.$Extend({}, $Jssor$.$StyleSetter(), options.$Setter);
+
+        _Position_OuterBegin = _Position_InnerBegin = delay;
+        _Position_OuterEnd = _Position_InnerEnd = delay + duration;
+
+        var _SubRounds = options.$Round || {};
+        var _SubDurings = options.$During || {};
+        _SubEasings = $Jssor$.$Extend({ $Default: $Jssor$.$IsFunction(options.$Easing) && options.$Easing || $JssorEasing$.$EaseSwing }, options.$Easing);
+    }
+};
+
+function $JssorPlayerClass$() {
+
+    var _ThisPlayer = this;
+    var _PlayerControllers = [];
+
+    function PlayerController(playerElement) {
+        var _SelfPlayerController = this;
+        var _PlayerInstance;
+        var _PlayerInstantces = [];
+
+        function OnPlayerInstanceDataAvailable(event) {
+            var srcElement = $Jssor$.$EventSrc(event);
+            _PlayerInstance = srcElement.pInstance;
+
+            $Jssor$.$RemoveEvent(srcElement, "dataavailable", OnPlayerInstanceDataAvailable);
+            $Jssor$.$Each(_PlayerInstantces, function (playerInstance) {
+                if (playerInstance != _PlayerInstance) {
+                    playerInstance.$Remove();
+                }
+            });
+
+            playerElement.pTagName = _PlayerInstance.tagName;
+            _PlayerInstantces = null;
+        }
+
+        function HandlePlayerInstance(playerInstanceElement) {
+            var playerHandler;
+
+            if (!playerInstanceElement.pInstance) {
+                var playerHandlerAttribute = $Jssor$.$AttributeEx(playerInstanceElement, "pHandler");
+
+                if ($JssorPlayer$[playerHandlerAttribute]) {
+                    $Jssor$.$AddEvent(playerInstanceElement, "dataavailable", OnPlayerInstanceDataAvailable);
+                    playerHandler = new $JssorPlayer$[playerHandlerAttribute](playerElement, playerInstanceElement);
+                    _PlayerInstantces.push(playerHandler);
+
+                    $JssorDebug$.$Execute(function () {
+                        if ($Jssor$.$Type(playerHandler.$Remove) != "function") {
+                            $JssorDebug$.$Fail("'pRemove' interface not implemented for player handler '" + playerHandlerAttribute + "'.");
+                        }
+                    });
+                }
+            }
+
+            return playerHandler;
+        }
+
+        _SelfPlayerController.$InitPlayerController = function () {
+            if (!playerElement.pInstance && !HandlePlayerInstance(playerElement)) {
+
+                var playerInstanceElements = $Jssor$.$Children(playerElement);
+
+                $Jssor$.$Each(playerInstanceElements, function (playerInstanceElement) {
+                    HandlePlayerInstance(playerInstanceElement);
+                });
+            }
+        };
+    }
+
+    _ThisPlayer.$EVT_SWITCH = 21;
+
+    _ThisPlayer.$FetchPlayers = function (elmt) {
+        elmt = elmt || document.body;
+
+        var playerElements = $Jssor$.$FindChildren(elmt, "player", null, true);
+
+        $Jssor$.$Each(playerElements, function (playerElement) {
+            if (!_PlayerControllers[playerElement.pId]) {
+                playerElement.pId = _PlayerControllers.length;
+                _PlayerControllers.push(new PlayerController(playerElement));
+            }
+            var playerController = _PlayerControllers[playerElement.pId];
+            playerController.$InitPlayerController();
+        });
+    };
+}
\ No newline at end of file
diff --git a/doc/_static/jssor.slider.js b/doc/_static/jssor.slider.js
new file mode 100644
index 0000000..77c5acc
--- /dev/null
+++ b/doc/_static/jssor.slider.js
@@ -0,0 +1,4081 @@
+/// <reference path="Jssor.js" />
+
+/*
+* Jssor.Slider 18.0
+* http://www.jssor.com/
+* 
+* TERMS OF USE - Jssor.Slider
+* 
+* Copyright 2014 Jssor
+*
+* Permission is hereby granted, free of charge, to any person obtaining
+* a copy of this software and associated documentation files (the
+* "Software"), to deal in the Software without restriction, including
+* without limitation the rights to use, copy, modify, merge, publish,
+* distribute, sublicense, and/or sell copies of the Software, and to
+* permit persons to whom the Software is furnished to do so, subject to
+* the following conditions:
+* 
+* The above copyright notice and this permission notice shall be
+* included in all copies or substantial portions of the Software.
+* 
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+var $JssorSlider$;
+var $JssorSlideshowFormations$ = window.$JssorSlideshowFormations$ = {};
+var $JssorSlideshowRunner$;
+
+new function () {
+    //Constants +++++++
+
+    var COLUMN_INCREASE = 0;
+    var COLUMN_DECREASE = 1;
+    var ROW_INCREASE = 2;
+    var ROW_DECREASE = 3;
+
+    var DIRECTION_HORIZONTAL = 0x0003;
+    var DIRECTION_VERTICAL = 0x000C;
+
+    var TO_LEFT = 0x0001;
+    var TO_RIGHT = 0x0002;
+    var TO_TOP = 0x0004;
+    var TO_BOTTOM = 0x0008;
+
+    var FROM_LEFT = 0x0100;
+    var FROM_TOP = 0x0200;
+    var FROM_RIGHT = 0x0400;
+    var FROM_BOTTOM = 0x0800;
+
+    var ASSEMBLY_BOTTOM_LEFT = FROM_BOTTOM + TO_LEFT;
+    var ASSEMBLY_BOTTOM_RIGHT = FROM_BOTTOM + TO_RIGHT;
+    var ASSEMBLY_TOP_LEFT = FROM_TOP + TO_LEFT;
+    var ASSEMBLY_TOP_RIGHT = FROM_TOP + TO_RIGHT;
+    var ASSEMBLY_LEFT_TOP = FROM_LEFT + TO_TOP;
+    var ASSEMBLY_LEFT_BOTTOM = FROM_LEFT + TO_BOTTOM;
+    var ASSEMBLY_RIGHT_TOP = FROM_RIGHT + TO_TOP;
+    var ASSEMBLY_RIGHT_BOTTOM = FROM_RIGHT + TO_BOTTOM;
+
+    //Constants -------
+
+    //Formation Definition +++++++
+    function isToLeft(roadValue) {
+        return (roadValue & TO_LEFT) == TO_LEFT;
+    }
+
+    function isToRight(roadValue) {
+        return (roadValue & TO_RIGHT) == TO_RIGHT;
+    }
+
+    function isToTop(roadValue) {
+        return (roadValue & TO_TOP) == TO_TOP;
+    }
+
+    function isToBottom(roadValue) {
+        return (roadValue & TO_BOTTOM) == TO_BOTTOM;
+    }
+
+    function PushFormationOrder(arr, order, formationItem) {
+        formationItem.push(order);
+        arr[order] = arr[order] || [];
+        arr[order].push(formationItem);
+    }
+
+    $JssorSlideshowFormations$.$FormationStraight = function (transition) {
+        var cols = transition.$Cols;
+        var rows = transition.$Rows;
+        var formationDirection = transition.$Assembly;
+        var count = transition.$Count;
+        var a = [];
+        var i = 0;
+        var col = 0;
+        var r = 0;
+        var cl = cols - 1;
+        var rl = rows - 1;
+        var il = count - 1;
+        var cr;
+        var order;
+        for (r = 0; r < rows; r++) {
+            for (col = 0; col < cols; col++) {
+                cr = r + ',' + col;
+                switch (formationDirection) {
+                    case ASSEMBLY_BOTTOM_LEFT:
+                        order = il - (col * rows + (rl - r));
+                        break;
+                    case ASSEMBLY_RIGHT_TOP:
+                        order = il - (r * cols + (cl - col));
+                        break;
+                    case ASSEMBLY_TOP_LEFT:
+                        order = il - (col * rows + r);
+                    case ASSEMBLY_LEFT_TOP:
+                        order = il - (r * cols + col);
+                        break;
+                    case ASSEMBLY_BOTTOM_RIGHT:
+                        order = col * rows + r;
+                        break;
+                    case ASSEMBLY_LEFT_BOTTOM:
+                        order = r * cols + (cl - col);
+                        break;
+                    case ASSEMBLY_TOP_RIGHT:
+                        order = col * rows + (rl - r);
+                        break;
+                    default:
+                        order = r * cols + col;
+                        break; //ASSEMBLY_RIGHT_BOTTOM
+                }
+                PushFormationOrder(a, order, [r, col]);
+            }
+        }
+
+        return a;
+    };
+
+    $JssorSlideshowFormations$.$FormationSwirl = function (transition) {
+        var cols = transition.$Cols;
+        var rows = transition.$Rows;
+        var formationDirection = transition.$Assembly;
+        var count = transition.$Count;
+        var a = [];
+        var hit = [];
+        var i = 0;
+        var col = 0;
+        var r = 0;
+        var cl = cols - 1;
+        var rl = rows - 1;
+        var il = count - 1;
+        var cr;
+        var courses;
+        var course = 0;
+        switch (formationDirection) {
+            case ASSEMBLY_BOTTOM_LEFT:
+                col = cl;
+                r = 0;
+                courses = [ROW_INCREASE, COLUMN_DECREASE, ROW_DECREASE, COLUMN_INCREASE];
+                break;
+            case ASSEMBLY_RIGHT_TOP:
+                col = 0;
+                r = rl;
+                courses = [COLUMN_INCREASE, ROW_DECREASE, COLUMN_DECREASE, ROW_INCREASE];
+                break;
+            case ASSEMBLY_TOP_LEFT:
+                col = cl;
+                r = rl;
+                courses = [ROW_DECREASE, COLUMN_DECREASE, ROW_INCREASE, COLUMN_INCREASE];
+                break;
+            case ASSEMBLY_LEFT_TOP:
+                col = cl;
+                r = rl;
+                courses = [COLUMN_DECREASE, ROW_DECREASE, COLUMN_INCREASE, ROW_INCREASE];
+                break;
+            case ASSEMBLY_BOTTOM_RIGHT:
+                col = 0;
+                r = 0;
+                courses = [ROW_INCREASE, COLUMN_INCREASE, ROW_DECREASE, COLUMN_DECREASE];
+                break;
+            case ASSEMBLY_LEFT_BOTTOM:
+                col = cl;
+                r = 0;
+                courses = [COLUMN_DECREASE, ROW_INCREASE, COLUMN_INCREASE, ROW_DECREASE];
+                break;
+            case ASSEMBLY_TOP_RIGHT:
+                col = 0;
+                r = rl;
+                courses = [ROW_DECREASE, COLUMN_INCREASE, ROW_INCREASE, COLUMN_DECREASE];
+                break;
+            default:
+                col = 0;
+                r = 0;
+                courses = [COLUMN_INCREASE, ROW_INCREASE, COLUMN_DECREASE, ROW_DECREASE];
+                break; //ASSEMBLY_RIGHT_BOTTOM
+        }
+        i = 0;
+        while (i < count) {
+            cr = r + ',' + col;
+            if (col >= 0 && col < cols && r >= 0 && r < rows && !hit[cr]) {
+                //a[cr] = i++;
+                hit[cr] = true;
+                PushFormationOrder(a, i++, [r, col]);
+            }
+            else {
+                switch (courses[course++ % courses.length]) {
+                    case COLUMN_INCREASE:
+                        col--;
+                        break;
+                    case ROW_INCREASE:
+                        r--;
+                        break;
+                    case COLUMN_DECREASE:
+                        col++;
+                        break;
+                    case ROW_DECREASE:
+                        r++;
+                        break;
+                }
+            }
+
+            switch (courses[course % courses.length]) {
+                case COLUMN_INCREASE:
+                    col++;
+                    break;
+                case ROW_INCREASE:
+                    r++;
+                    break;
+                case COLUMN_DECREASE:
+                    col--;
+                    break;
+                case ROW_DECREASE:
+                    r--;
+                    break;
+            }
+        }
+        return a;
+    };
+
+    $JssorSlideshowFormations$.$FormationZigZag = function (transition) {
+        var cols = transition.$Cols;
+        var rows = transition.$Rows;
+        var formationDirection = transition.$Assembly;
+        var count = transition.$Count;
+        var a = [];
+        var i = 0;
+        var col = 0;
+        var r = 0;
+        var cl = cols - 1;
+        var rl = rows - 1;
+        var il = count - 1;
+        var cr;
+        var courses;
+        var course = 0;
+        switch (formationDirection) {
+            case ASSEMBLY_BOTTOM_LEFT:
+                col = cl;
+                r = 0;
+                courses = [ROW_INCREASE, COLUMN_DECREASE, ROW_DECREASE, COLUMN_DECREASE];
+                break;
+            case ASSEMBLY_RIGHT_TOP:
+                col = 0;
+                r = rl;
+                courses = [COLUMN_INCREASE, ROW_DECREASE, COLUMN_DECREASE, ROW_DECREASE];
+                break;
+            case ASSEMBLY_TOP_LEFT:
+                col = cl;
+                r = rl;
+                courses = [ROW_DECREASE, COLUMN_DECREASE, ROW_INCREASE, COLUMN_DECREASE];
+                break;
+            case ASSEMBLY_LEFT_TOP:
+                col = cl;
+                r = rl;
+                courses = [COLUMN_DECREASE, ROW_DECREASE, COLUMN_INCREASE, ROW_DECREASE];
+                break;
+            case ASSEMBLY_BOTTOM_RIGHT:
+                col = 0;
+                r = 0;
+                courses = [ROW_INCREASE, COLUMN_INCREASE, ROW_DECREASE, COLUMN_INCREASE];
+                break;
+            case ASSEMBLY_LEFT_BOTTOM:
+                col = cl;
+                r = 0;
+                courses = [COLUMN_DECREASE, ROW_INCREASE, COLUMN_INCREASE, ROW_INCREASE];
+                break;
+            case ASSEMBLY_TOP_RIGHT:
+                col = 0;
+                r = rl;
+                courses = [ROW_DECREASE, COLUMN_INCREASE, ROW_INCREASE, COLUMN_INCREASE];
+                break;
+            default:
+                col = 0;
+                r = 0;
+                courses = [COLUMN_INCREASE, ROW_INCREASE, COLUMN_DECREASE, ROW_INCREASE];
+                break; //ASSEMBLY_RIGHT_BOTTOM
+        }
+        i = 0;
+        while (i < count) {
+            cr = r + ',' + col;
+            if (col >= 0 && col < cols && r >= 0 && r < rows && typeof (a[cr]) == 'undefined') {
+                PushFormationOrder(a, i++, [r, col]);
+                //a[cr] = i++;
+                switch (courses[course % courses.length]) {
+                    case COLUMN_INCREASE:
+                        col++;
+                        break;
+                    case ROW_INCREASE:
+                        r++;
+                        break;
+                    case COLUMN_DECREASE:
+                        col--;
+                        break;
+                    case ROW_DECREASE:
+                        r--;
+                        break;
+                }
+            }
+            else {
+                switch (courses[course++ % courses.length]) {
+                    case COLUMN_INCREASE:
+                        col--;
+                        break;
+                    case ROW_INCREASE:
+                        r--;
+                        break;
+                    case COLUMN_DECREASE:
+                        col++;
+                        break;
+                    case ROW_DECREASE:
+                        r++;
+                        break;
+                }
+                switch (courses[course++ % courses.length]) {
+                    case COLUMN_INCREASE:
+                        col++;
+                        break;
+                    case ROW_INCREASE:
+                        r++;
+                        break;
+                    case COLUMN_DECREASE:
+                        col--;
+                        break;
+                    case ROW_DECREASE:
+                        r--;
+                        break;
+                }
+            }
+        }
+        return a;
+    };
+
+    $JssorSlideshowFormations$.$FormationStraightStairs = function (transition) {
+        var cols = transition.$Cols;
+        var rows = transition.$Rows;
+        var formationDirection = transition.$Assembly;
+        var count = transition.$Count;
+        var a = [];
+        var i = 0;
+        var col = 0;
+        var r = 0;
+        var cl = cols - 1;
+        var rl = rows - 1;
+        var il = count - 1;
+        var cr;
+        switch (formationDirection) {
+            case ASSEMBLY_BOTTOM_LEFT:
+            case ASSEMBLY_TOP_RIGHT:
+            case ASSEMBLY_TOP_LEFT:
+            case ASSEMBLY_BOTTOM_RIGHT:
+                var C = 0;
+                var R = 0;
+                break;
+            case ASSEMBLY_LEFT_BOTTOM:
+            case ASSEMBLY_RIGHT_TOP:
+            case ASSEMBLY_LEFT_TOP:
+            case ASSEMBLY_RIGHT_BOTTOM:
+                var C = cl;
+                var R = 0;
+                break;
+            default:
+                formationDirection = ASSEMBLY_RIGHT_BOTTOM;
+                var C = cl;
+                var R = 0;
+                break;
+        }
+        col = C;
+        r = R;
+        while (i < count) {
+            cr = r + ',' + col;
+            if (isToTop(formationDirection) || isToRight(formationDirection)) {
+                PushFormationOrder(a, il - i++, [r, col]);
+                //a[cr] = il - i++;
+            }
+            else {
+                PushFormationOrder(a, i++, [r, col]);
+                //a[cr] = i++;
+            }
+            switch (formationDirection) {
+                case ASSEMBLY_BOTTOM_LEFT:
+                case ASSEMBLY_TOP_RIGHT:
+                    col--;
+                    r++;
+                    break;
+                case ASSEMBLY_TOP_LEFT:
+                case ASSEMBLY_BOTTOM_RIGHT:
+                    col++;
+                    r--;
+                    break;
+                case ASSEMBLY_LEFT_BOTTOM:
+                case ASSEMBLY_RIGHT_TOP:
+                    col--;
+                    r--;
+                    break;
+                case ASSEMBLY_RIGHT_BOTTOM:
+                case ASSEMBLY_LEFT_TOP:
+                default:
+                    col++;
+                    r++;
+                    break;
+            }
+            if (col < 0 || r < 0 || col > cl || r > rl) {
+                switch (formationDirection) {
+                    case ASSEMBLY_BOTTOM_LEFT:
+                    case ASSEMBLY_TOP_RIGHT:
+                        C++;
+                        break;
+                    case ASSEMBLY_LEFT_BOTTOM:
+                    case ASSEMBLY_RIGHT_TOP:
+                    case ASSEMBLY_TOP_LEFT:
+                    case ASSEMBLY_BOTTOM_RIGHT:
+                        R++;
+                        break;
+                    case ASSEMBLY_RIGHT_BOTTOM:
+                    case ASSEMBLY_LEFT_TOP:
+                    default:
+                        C--;
+                        break;
+                }
+                if (C < 0 || R < 0 || C > cl || R > rl) {
+                    switch (formationDirection) {
+                        case ASSEMBLY_BOTTOM_LEFT:
+                        case ASSEMBLY_TOP_RIGHT:
+                            C = cl;
+                            R++;
+                            break;
+                        case ASSEMBLY_TOP_LEFT:
+                        case ASSEMBLY_BOTTOM_RIGHT:
+                            R = rl;
+                            C++;
+                            break;
+                        case ASSEMBLY_LEFT_BOTTOM:
+                        case ASSEMBLY_RIGHT_TOP: R = rl; C--;
+                            break;
+                        case ASSEMBLY_RIGHT_BOTTOM:
+                        case ASSEMBLY_LEFT_TOP:
+                        default:
+                            C = 0;
+                            R++;
+                            break;
+                    }
+                    if (R > rl)
+                        R = rl;
+                    else if (R < 0)
+                        R = 0;
+                    else if (C > cl)
+                        C = cl;
+                    else if (C < 0)
+                        C = 0;
+                }
+                r = R;
+                col = C;
+            }
+        }
+        return a;
+    };
+
+    $JssorSlideshowFormations$.$FormationSquare = function (transition) {
+        var cols = transition.$Cols || 1;
+        var rows = transition.$Rows || 1;
+        var arr = [];
+        var i = 0;
+        var col;
+        var r;
+        var dc;
+        var dr;
+        var cr;
+        dc = cols < rows ? (rows - cols) / 2 : 0;
+        dr = cols > rows ? (cols - rows) / 2 : 0;
+        cr = Math.round(Math.max(cols / 2, rows / 2)) + 1;
+        for (col = 0; col < cols; col++) {
+            for (r = 0; r < rows; r++)
+                PushFormationOrder(arr, cr - Math.min(col + 1 + dc, r + 1 + dr, cols - col + dc, rows - r + dr), [r, col]);
+        }
+        return arr;
+    };
+
+    $JssorSlideshowFormations$.$FormationRectangle = function (transition) {
+        var cols = transition.$Cols || 1;
+        var rows = transition.$Rows || 1;
+        var arr = [];
+        var i = 0;
+        var col;
+        var r;
+        var cr;
+        cr = Math.round(Math.min(cols / 2, rows / 2)) + 1;
+        for (col = 0; col < cols; col++) {
+            for (r = 0; r < rows; r++)
+                PushFormationOrder(arr, cr - Math.min(col + 1, r + 1, cols - col, rows - r), [r, col]);
+        }
+        return arr;
+    };
+
+    $JssorSlideshowFormations$.$FormationRandom = function (transition) {
+        var a = [];
+        var r, col, i;
+        for (r = 0; r < transition.$Rows; r++) {
+            for (col = 0; col < transition.$Cols; col++)
+                PushFormationOrder(a, Math.ceil(100000 * Math.random()) % 13, [r, col]);
+        }
+
+        return a;
+    };
+
+    $JssorSlideshowFormations$.$FormationCircle = function (transition) {
+        var cols = transition.$Cols || 1;
+        var rows = transition.$Rows || 1;
+        var arr = [];
+        var i = 0;
+        var col;
+        var r;
+        var hc = cols / 2 - 0.5;
+        var hr = rows / 2 - 0.5;
+        for (col = 0; col < cols; col++) {
+            for (r = 0; r < rows; r++)
+                PushFormationOrder(arr, Math.round(Math.sqrt(Math.pow(col - hc, 2) + Math.pow(r - hr, 2))), [r, col]);
+        }
+        return arr;
+    };
+
+    $JssorSlideshowFormations$.$FormationCross = function (transition) {
+        var cols = transition.$Cols || 1;
+        var rows = transition.$Rows || 1;
+        var arr = [];
+        var i = 0;
+        var col;
+        var r;
+        var hc = cols / 2 - 0.5;
+        var hr = rows / 2 - 0.5;
+        for (col = 0; col < cols; col++) {
+            for (r = 0; r < rows; r++)
+                PushFormationOrder(arr, Math.round(Math.min(Math.abs(col - hc), Math.abs(r - hr))), [r, col]);
+        }
+        return arr;
+    };
+
+    $JssorSlideshowFormations$.$FormationRectangleCross = function (transition) {
+        var cols = transition.$Cols || 1;
+        var rows = transition.$Rows || 1;
+        var arr = [];
+        var i = 0;
+        var col;
+        var r;
+        var hc = cols / 2 - 0.5;
+        var hr = rows / 2 - 0.5;
+        var cr = Math.max(hc, hr) + 1;
+        for (col = 0; col < cols; col++) {
+            for (r = 0; r < rows; r++)
+                PushFormationOrder(arr, Math.round(cr - Math.max(hc - Math.abs(col - hc), hr - Math.abs(r - hr))) - 1, [r, col]);
+        }
+        return arr;
+    };
+
+    function GetFormation(transition) {
+
+        var formationInstance = transition.$Formation(transition);
+
+        return transition.$Reverse ? formationInstance.reverse() : formationInstance;
+
+    } //GetFormation
+
+    //var _PrototypeTransitions = [];
+    function EnsureTransitionInstance(options, slideshowInterval) {
+
+        var _SlideshowTransition = {
+            $Interval: slideshowInterval,  //Delay to play next frame
+            $Duration: 1, //Duration to finish the entire transition
+            $Delay: 0,  //Delay to assembly blocks
+            $Cols: 1,   //Number of columns
+            $Rows: 1,   //Number of rows
+            $Opacity: 0,   //Fade block or not
+            $Zoom: 0,   //Zoom block or not
+            $Clip: 0,   //Clip block or not
+            $Move: false,   //Move block or not
+            $SlideOut: false,   //Slide the previous slide out to display next slide instead
+            //$FlyDirection: 0,   //Specify fly transform with direction
+            $Reverse: false,    //Reverse the assembly or not
+            $Formation: $JssorSlideshowFormations$.$FormationRandom,    //Shape that assembly blocks as
+            $Assembly: ASSEMBLY_RIGHT_BOTTOM,   //The way to assembly blocks
+            $ChessMode: { $Column: 0, $Row: 0 },    //Chess move or fly direction
+            $Easing: $JssorEasing$.$EaseSwing,  //Specify variation of speed during transition
+            $Round: {},
+            $Blocks: [],
+            $During: {}
+        };
+
+        $Jssor$.$Extend(_SlideshowTransition, options);
+
+        _SlideshowTransition.$Count = _SlideshowTransition.$Cols * _SlideshowTransition.$Rows;
+        if ($Jssor$.$IsFunction(_SlideshowTransition.$Easing))
+            _SlideshowTransition.$Easing = { $Default: _SlideshowTransition.$Easing };
+
+        _SlideshowTransition.$FramesCount = Math.ceil(_SlideshowTransition.$Duration / _SlideshowTransition.$Interval);
+        _SlideshowTransition.$EasingInstance = GetEasing(_SlideshowTransition);
+
+        _SlideshowTransition.$GetBlocks = function (width, height) {
+            width /= _SlideshowTransition.$Cols;
+            height /= _SlideshowTransition.$Rows;
+            var wh = width + 'x' + height;
+            if (!_SlideshowTransition.$Blocks[wh]) {
+                _SlideshowTransition.$Blocks[wh] = { $Width: width, $Height: height };
+                for (var col = 0; col < _SlideshowTransition.$Cols; col++) {
+                    for (var r = 0; r < _SlideshowTransition.$Rows; r++)
+                        _SlideshowTransition.$Blocks[wh][r + ',' + col] = { $Top: r * height, $Right: col * width + width, $Bottom: r * height + height, $Left: col * width };
+                }
+            }
+
+            return _SlideshowTransition.$Blocks[wh];
+        };
+
+        if (_SlideshowTransition.$Brother) {
+            _SlideshowTransition.$Brother = EnsureTransitionInstance(_SlideshowTransition.$Brother, slideshowInterval);
+            _SlideshowTransition.$SlideOut = true;
+        }
+
+        return _SlideshowTransition;
+    }
+
+    function GetEasing(transition) {
+        var easing = transition.$Easing;
+        if (!easing.$Default)
+            easing.$Default = $JssorEasing$.$EaseSwing;
+
+        var duration = transition.$FramesCount;
+
+        var cache = easing.$Cache;
+        if (!cache) {
+            var enumerator = $Jssor$.$Extend({}, transition.$Easing, transition.$Round);
+            cache = easing.$Cache = {};
+
+            $Jssor$.$Each(enumerator, function (v, easingName) {
+                var easingFunction = easing[easingName] || easing.$Default;
+                var round = transition.$Round[easingName] || 1;
+
+                if (!$Jssor$.$IsArray(easingFunction.$Cache))
+                    easingFunction.$Cache = [];
+
+                var easingFunctionCache = easingFunction.$Cache[duration] = easingFunction.$Cache[duration] || [];
+
+                if (!easingFunctionCache[round]) {
+                    easingFunctionCache[round] = [0];
+                    for (var t = 1; t <= duration; t++) {
+                        var tRound = t / duration * round;
+                        var tRoundFloor = Math.floor(tRound);
+                        if (tRound != tRoundFloor)
+                            tRound -= tRoundFloor;
+                        easingFunctionCache[round][t] = easingFunction(tRound);
+                    }
+                }
+
+                cache[easingName] = easingFunctionCache;
+
+            });
+        }
+
+        return cache;
+    } //GetEasing
+
+    //Formation Definition -------
+
+    function JssorSlideshowPlayer(slideContainer, slideElement, slideTransition, beginTime, slideContainerWidth, slideContainerHeight) {
+        var _Self = this;
+
+        var _Block;
+        var _StartStylesArr = {};
+        var _AnimationStylesArrs = {};
+        var _AnimationBlockItems = [];
+        var _StyleStart;
+        var _StyleEnd;
+        var _StyleDif;
+        var _ChessModeColumn = slideTransition.$ChessMode.$Column || 0;
+        var _ChessModeRow = slideTransition.$ChessMode.$Row || 0;
+
+        var _Blocks = slideTransition.$GetBlocks(slideContainerWidth, slideContainerHeight);
+        var _FormationInstance = GetFormation(slideTransition);
+        var _MaxOrder = _FormationInstance.length - 1;
+        var _Period = slideTransition.$Duration + slideTransition.$Delay * _MaxOrder;
+        var _EndTime = beginTime + _Period;
+
+        var _SlideOut = slideTransition.$SlideOut;
+        var _IsIn;
+
+        _EndTime += $Jssor$.$IsBrowserChrome() ? 260 : 50;
+
+        _Self.$EndTime = _EndTime;
+
+        _Self.$ShowFrame = function (time) {
+            time -= beginTime;
+
+            var isIn = time < _Period;
+
+            if (isIn || _IsIn) {
+                _IsIn = isIn;
+
+                if (!_SlideOut)
+                    time = _Period - time;
+
+                var frameIndex = Math.ceil(time / slideTransition.$Interval);
+
+                $Jssor$.$Each(_AnimationStylesArrs, function (value, index) {
+
+                    var itemFrameIndex = Math.max(frameIndex, value.$Min);
+                    itemFrameIndex = Math.min(itemFrameIndex, value.length - 1);
+
+                    if (value.$LastFrameIndex != itemFrameIndex) {
+                        if (!value.$LastFrameIndex && !_SlideOut) {
+                            $Jssor$.$ShowElement(_AnimationBlockItems[index]);
+                        }
+                        else if (itemFrameIndex == value.$Max && _SlideOut) {
+                            $Jssor$.$HideElement(_AnimationBlockItems[index]);
+                        }
+                        value.$LastFrameIndex = itemFrameIndex;
+                        $Jssor$.$SetStylesEx(_AnimationBlockItems[index], value[itemFrameIndex]);
+                    }
+                });
+            }
+        };
+
+        function DisableHWA(elmt) {
+            $Jssor$.$DisableHWA(elmt);
+
+            var children = $Jssor$.$Children(elmt);
+
+            $Jssor$.$Each(children, function (child) {
+                DisableHWA(child);
+            });
+        }
+
+        //constructor
+        {
+            slideElement = $Jssor$.$CloneNode(slideElement, true);
+            DisableHWA(slideElement);
+            if ($Jssor$.$IsBrowserIe9Earlier()) {
+                var hasImage = !slideElement["no-image"];
+                var slideChildElements = $Jssor$.$FindChildrenByTag(slideElement, null, true);
+                $Jssor$.$Each(slideChildElements, function (slideChildElement) {
+                    if (hasImage || slideChildElement["jssor-slider"])
+                        $Jssor$.$CssOpacity(slideChildElement, $Jssor$.$CssOpacity(slideChildElement), true);
+                });
+            }
+
+            $Jssor$.$Each(_FormationInstance, function (formationItems, order) {
+                $Jssor$.$Each(formationItems, function (formationItem) {
+                    var row = formationItem[0];
+                    var col = formationItem[1];
+                    {
+                        var columnRow = row + ',' + col;
+
+                        var chessHorizontal = false;
+                        var chessVertical = false;
+                        var chessRotate = false;
+
+                        if (_ChessModeColumn && col % 2) {
+                            if ($JssorDirection$.$IsHorizontal(_ChessModeColumn)) {
+                                chessHorizontal = !chessHorizontal;
+                            }
+                            if ($JssorDirection$.$IsVertical(_ChessModeColumn)) {
+                                chessVertical = !chessVertical;
+                            }
+
+                            if (_ChessModeColumn & 16)
+                                chessRotate = !chessRotate;
+                        }
+
+                        if (_ChessModeRow && row % 2) {
+                            if ($JssorDirection$.$IsHorizontal(_ChessModeRow)) {
+                                chessHorizontal = !chessHorizontal;
+                            }
+                            if ($JssorDirection$.$IsVertical(_ChessModeRow)) {
+                                chessVertical = !chessVertical;
+                            }
+                            if (_ChessModeRow & 16)
+                                chessRotate = !chessRotate;
+                        }
+
+                        slideTransition.$Top = slideTransition.$Top || (slideTransition.$Clip & 4);
+                        slideTransition.$Bottom = slideTransition.$Bottom || (slideTransition.$Clip & 8);
+                        slideTransition.$Left = slideTransition.$Left || (slideTransition.$Clip & 1);
+                        slideTransition.$Right = slideTransition.$Right || (slideTransition.$Clip & 2);
+
+                        var topBenchmark = chessVertical ? slideTransition.$Bottom : slideTransition.$Top;
+                        var bottomBenchmark = chessVertical ? slideTransition.$Top : slideTransition.$Bottom;
+                        var leftBenchmark = chessHorizontal ? slideTransition.$Right : slideTransition.$Left;
+                        var rightBenchmark = chessHorizontal ? slideTransition.$Left : slideTransition.$Right;
+
+                        //$JssorDebug$.$Execute(function () {
+                        //    topBenchmark = bottomBenchmark = leftBenchmark = rightBenchmark = false;
+                        //});
+
+                        slideTransition.$Clip = topBenchmark || bottomBenchmark || leftBenchmark || rightBenchmark;
+
+                        _StyleDif = {};
+                        _StyleEnd = { $Top: 0, $Left: 0, $Opacity: 1, $Width: slideContainerWidth, $Height: slideContainerHeight };
+                        _StyleStart = $Jssor$.$Extend({}, _StyleEnd);
+                        _Block = $Jssor$.$Extend({}, _Blocks[columnRow]);
+
+                        if (slideTransition.$Opacity) {
+                            _StyleEnd.$Opacity = 2 - slideTransition.$Opacity;
+                        }
+
+                        if (slideTransition.$ZIndex) {
+                            _StyleEnd.$ZIndex = slideTransition.$ZIndex;
+                            _StyleStart.$ZIndex = 0;
+                        }
+
+                        var allowClip = slideTransition.$Cols * slideTransition.$Rows > 1 || slideTransition.$Clip;
+
+                        if (slideTransition.$Zoom || slideTransition.$Rotate) {
+                            var allowRotate = true;
+                            if ($Jssor$.$IsBrowserIE() && $Jssor$.$BrowserEngineVersion() < 9) {
+                                if (slideTransition.$Cols * slideTransition.$Rows > 1)
+                                    allowRotate = false;
+                                else
+                                    allowClip = false;
+                            }
+
+                            if (allowRotate) {
+                                _StyleEnd.$Zoom = slideTransition.$Zoom ? slideTransition.$Zoom - 1 : 1;
+                                _StyleStart.$Zoom = 1;
+
+                                if ($Jssor$.$IsBrowserIe9Earlier() || $Jssor$.$IsBrowserOpera())
+                                    _StyleEnd.$Zoom = Math.min(_StyleEnd.$Zoom, 2);
+
+                                var rotate = slideTransition.$Rotate;
+                                //if (rotate == true)
+                                //    rotate = 1;
+
+                                _StyleEnd.$Rotate = rotate * 360 * ((chessRotate) ? -1 : 1);
+                                _StyleStart.$Rotate = 0;
+                            }
+                        }
+
+                        if (allowClip) {
+                            if (slideTransition.$Clip) {
+                                var clipScale = slideTransition.$ScaleClip || 1;
+                                var blockOffset = _Block.$Offset = {};
+                                if (topBenchmark && bottomBenchmark) {
+                                    blockOffset.$Top = _Blocks.$Height / 2 * clipScale;
+                                    blockOffset.$Bottom = -blockOffset.$Top;
+                                }
+                                else if (topBenchmark) {
+                                    blockOffset.$Bottom = -_Blocks.$Height * clipScale;
+                                }
+                                else if (bottomBenchmark) {
+                                    blockOffset.$Top = _Blocks.$Height * clipScale;
+                                }
+
+                                if (leftBenchmark && rightBenchmark) {
+                                    blockOffset.$Left = _Blocks.$Width / 2 * clipScale;
+                                    blockOffset.$Right = -blockOffset.$Left;
+                                }
+                                else if (leftBenchmark) {
+                                    blockOffset.$Right = -_Blocks.$Width * clipScale;
+                                }
+                                else if (rightBenchmark) {
+                                    blockOffset.$Left = _Blocks.$Width * clipScale;
+                                }
+                            }
+
+                            _StyleDif.$Clip = _Block;
+                            _StyleStart.$Clip = _Blocks[columnRow];
+                        }
+
+                        //fly
+                        {
+                            var chessHor = chessHorizontal ? 1 : -1;
+                            var chessVer = chessVertical ? 1 : -1;
+
+                            if (slideTransition.x)
+                                _StyleEnd.$Left += slideContainerWidth * slideTransition.x * chessHor;
+
+                            if (slideTransition.y)
+                                _StyleEnd.$Top += slideContainerHeight * slideTransition.y * chessVer;
+                        }
+
+                        $Jssor$.$Each(_StyleEnd, function (propertyEnd, property) {
+                            if ($Jssor$.$IsNumeric(propertyEnd)) {
+                                if (propertyEnd != _StyleStart[property]) {
+                                    _StyleDif[property] = propertyEnd - _StyleStart[property];
+                                }
+                            }
+                        });
+
+                        _StartStylesArr[columnRow] = _SlideOut ? _StyleStart : _StyleEnd;
+
+                        var animationStylesArr = [];
+                        var virtualFrameCount = Math.round(order * slideTransition.$Delay / slideTransition.$Interval);
+                        _AnimationStylesArrs[columnRow] = new Array(virtualFrameCount);
+                        _AnimationStylesArrs[columnRow].$Min = virtualFrameCount;
+
+                        var framesCount = slideTransition.$FramesCount;
+                        for (var frameN = 0; frameN <= framesCount; frameN++) {
+                            var styleFrameN = {};
+
+                            $Jssor$.$Each(_StyleDif, function (propertyDiff, property) {
+                                var propertyEasings = slideTransition.$EasingInstance[property] || slideTransition.$EasingInstance.$Default;
+                                var propertyEasingArray = propertyEasings[slideTransition.$Round[property] || 1];
+
+                                var propertyDuring = slideTransition.$During[property] || [0, 1];
+                                var propertyFrameN = (frameN / framesCount - propertyDuring[0]) / propertyDuring[1] * framesCount;
+                                propertyFrameN = Math.round(Math.min(framesCount, Math.max(propertyFrameN, 0)));
+
+                                var propertyEasingValue = propertyEasingArray[propertyFrameN];
+
+                                if ($Jssor$.$IsNumeric(propertyDiff)) {
+                                    styleFrameN[property] = _StyleStart[property] + propertyDiff * propertyEasingValue;
+                                }
+                                else {
+                                    var value = styleFrameN[property] = $Jssor$.$Extend({}, _StyleStart[property]);
+                                    value.$Offset = [];
+                                    $Jssor$.$Each(propertyDiff.$Offset, function (rectX, n) {
+                                        var offsetValue = rectX * propertyEasingValue;
+                                        value.$Offset[n] = offsetValue;
+                                        value[n] += offsetValue;
+                                    });
+                                }
+                            });
+
+                            if (_StyleStart.$Zoom) {
+                                styleFrameN.$Transform = { $Rotate: styleFrameN.$Rotate || 0, $Scale: styleFrameN.$Zoom, $OriginalWidth: slideContainerWidth, $OriginalHeight: slideContainerHeight };
+                            }
+                            if (styleFrameN.$Clip && slideTransition.$Move) {
+                                var styleFrameNClipOffset = styleFrameN.$Clip.$Offset;
+                                var offsetY = (styleFrameNClipOffset.$Top || 0) + (styleFrameNClipOffset.$Bottom || 0);
+                                var offsetX = (styleFrameNClipOffset.$Left || 0) + (styleFrameNClipOffset.$Right || 0);
+
+                                styleFrameN.$Left = (styleFrameN.$Left || 0) + offsetX;
+                                styleFrameN.$Top = (styleFrameN.$Top || 0) + offsetY;
+                                styleFrameN.$Clip.$Left -= offsetX;
+                                styleFrameN.$Clip.$Right -= offsetX;
+                                styleFrameN.$Clip.$Top -= offsetY;
+                                styleFrameN.$Clip.$Bottom -= offsetY;
+                            }
+
+                            styleFrameN.$ZIndex = styleFrameN.$ZIndex || 1;
+
+                            _AnimationStylesArrs[columnRow].push(styleFrameN);
+                        }
+
+                    } //for
+                });
+            });
+
+            _FormationInstance.reverse();
+            $Jssor$.$Each(_FormationInstance, function (formationItems) {
+                $Jssor$.$Each(formationItems, function (formationItem) {
+                    var row = formationItem[0];
+                    var col = formationItem[1];
+
+                    var columnRow = row + ',' + col;
+
+                    var image = slideElement;
+                    if (col || row)
+                        image = $Jssor$.$CloneNode(slideElement, true);
+
+                    $Jssor$.$SetStyles(image, _StartStylesArr[columnRow]);
+                    $Jssor$.$CssOverflow(image, "hidden");
+
+                    $Jssor$.$CssPosition(image, "absolute");
+                    slideContainer.$AddClipElement(image);
+                    _AnimationBlockItems[columnRow] = image;
+                    $Jssor$.$ShowElement(image, _SlideOut);
+                });
+            });
+        }
+    }
+
+    //JssorSlideshowRunner++++++++
+    var _SlideshowRunnerCount = 1;
+    $JssorSlideshowRunner$ = window.$JssorSlideshowRunner$ = function (slideContainer, slideContainerWidth, slideContainerHeight, slideshowOptions, handleTouchEventOnly) {
+
+        var _SelfSlideshowRunner = this;
+
+        //var _State = 0; //-1 fullfill, 0 clean, 1 initializing, 2 stay, 3 playing
+        var _EndTime;
+
+        var _SliderFrameCount;
+
+        var _SlideshowPlayerBelow;
+        var _SlideshowPlayerAbove;
+
+        var _PrevItem;
+        var _SlideItem;
+
+        var _TransitionIndex = 0;
+        var _TransitionsOrder = slideshowOptions.$TransitionsOrder;
+
+        var _SlideshowTransition;
+
+        var _SlideshowPerformance = 16;
+
+        function SlideshowProcessor() {
+            var _SelfSlideshowProcessor = this;
+            var _CurrentTime = 0;
+
+            $JssorAnimator$.call(_SelfSlideshowProcessor, 0, _EndTime);
+
+            _SelfSlideshowProcessor.$OnPositionChange = function (oldPosition, newPosition) {
+                if ((newPosition - _CurrentTime) > _SlideshowPerformance) {
+                    _CurrentTime = newPosition;
+
+                    _SlideshowPlayerAbove && _SlideshowPlayerAbove.$ShowFrame(newPosition);
+                    _SlideshowPlayerBelow && _SlideshowPlayerBelow.$ShowFrame(newPosition);
+                }
+            };
+
+            _SelfSlideshowProcessor.$Transition = _SlideshowTransition;
+        }
+
+        //member functions
+        _SelfSlideshowRunner.$GetTransition = function (slideCount) {
+            var n = 0;
+
+            var transitions = slideshowOptions.$Transitions;
+
+            var transitionCount = transitions.length;
+
+            if (_TransitionsOrder) { /*Sequence*/
+                if (transitionCount > slideCount && ($Jssor$.$IsBrowserChrome() || $Jssor$.$IsBrowserSafari() || $Jssor$.$IsBrowserFireFox())) {
+                    transitionCount -= transitionCount % slideCount;
+                }
+                n = _TransitionIndex++ % transitionCount;
+            }
+            else { /*Random*/
+                n = Math.floor(Math.random() * transitionCount);
+            }
+
+            transitions[n] && (transitions[n].$Index = n);
+
+            return transitions[n];
+        };
+
+        _SelfSlideshowRunner.$Initialize = function (slideIndex, prevIndex, slideItem, prevItem, slideshowTransition) {
+            $JssorDebug$.$Execute(function () {
+                if (_SlideshowPlayerBelow) {
+                    $JssorDebug$.$Fail("slideshow runner has not been cleared.");
+                }
+            });
+
+            _SlideshowTransition = slideshowTransition;
+
+            slideshowTransition = EnsureTransitionInstance(slideshowTransition, _SlideshowPerformance);
+
+            _SlideItem = slideItem;
+            _PrevItem = prevItem;
+
+            var prevSlideElement = prevItem.$Item;
+            var currentSlideElement = slideItem.$Item;
+            prevSlideElement["no-image"] = !prevItem.$Image;
+            currentSlideElement["no-image"] = !slideItem.$Image;
+
+            var slideElementAbove = prevSlideElement;
+            var slideElementBelow = currentSlideElement;
+
+            var slideTransitionAbove = slideshowTransition;
+            var slideTransitionBelow = slideshowTransition.$Brother || EnsureTransitionInstance({}, _SlideshowPerformance);
+
+            if (!slideshowTransition.$SlideOut) {
+                slideElementAbove = currentSlideElement;
+                slideElementBelow = prevSlideElement;
+            }
+
+            var shift = slideTransitionBelow.$Shift || 0;
+
+            _SlideshowPlayerBelow = new JssorSlideshowPlayer(slideContainer, slideElementBelow, slideTransitionBelow, Math.max(shift - slideTransitionBelow.$Interval, 0), slideContainerWidth, slideContainerHeight);
+            _SlideshowPlayerAbove = new JssorSlideshowPlayer(slideContainer, slideElementAbove, slideTransitionAbove, Math.max(slideTransitionBelow.$Interval - shift, 0), slideContainerWidth, slideContainerHeight);
+
+            _SlideshowPlayerBelow.$ShowFrame(0);
+            _SlideshowPlayerAbove.$ShowFrame(0);
+
+            _EndTime = Math.max(_SlideshowPlayerBelow.$EndTime, _SlideshowPlayerAbove.$EndTime);
+
+            _SelfSlideshowRunner.$Index = slideIndex;
+        };
+
+        _SelfSlideshowRunner.$Clear = function () {
+            slideContainer.$Clear();
+            _SlideshowPlayerBelow = null;
+            _SlideshowPlayerAbove = null;
+        };
+
+        _SelfSlideshowRunner.$GetProcessor = function () {
+            var slideshowProcessor = null;
+
+            if (_SlideshowPlayerAbove)
+                slideshowProcessor = new SlideshowProcessor();
+
+            return slideshowProcessor;
+        };
+
+        //Constructor
+        {
+            if ($Jssor$.$IsBrowserIe9Earlier() || $Jssor$.$IsBrowserOpera() || (handleTouchEventOnly && $Jssor$.$WebKitVersion() < 537)) {
+                _SlideshowPerformance = 32;
+            }
+
+            $JssorObject$.call(_SelfSlideshowRunner);
+            $JssorAnimator$.call(_SelfSlideshowRunner, -10000000, 10000000);
+
+            $JssorDebug$.$LiveStamp(_SelfSlideshowRunner, "slideshow_runner_" + _SlideshowRunnerCount++);
+        }
+    };
+    //JssorSlideshowRunner--------
+
+    //JssorSlider
+    function JssorSlider(elmt, options) {
+        var _SelfSlider = this;
+
+        //private classes
+        function Conveyor() {
+            var _SelfConveyor = this;
+            $JssorAnimator$.call(_SelfConveyor, -100000000, 200000000);
+
+            _SelfConveyor.$GetCurrentSlideInfo = function () {
+                var positionDisplay = _SelfConveyor.$GetPosition_Display();
+                var virtualIndex = Math.floor(positionDisplay);
+                var slideIndex = GetRealIndex(virtualIndex);
+                var slidePosition = positionDisplay - Math.floor(positionDisplay);
+
+                return { $Index: slideIndex, $VirtualIndex: virtualIndex, $Position: slidePosition };
+            };
+
+            _SelfConveyor.$OnPositionChange = function (oldPosition, newPosition) {
+
+                var index = Math.floor(newPosition);
+                if (index != newPosition && newPosition > oldPosition)
+                    index++;
+
+                ResetNavigator(index, true);
+
+                _SelfSlider.$TriggerEvent(JssorSlider.$EVT_POSITION_CHANGE, GetRealIndex(newPosition), GetRealIndex(oldPosition), newPosition, oldPosition);
+            };
+        }
+
+        //Carousel
+        function Carousel() {
+            var _SelfCarousel = this;
+
+            $JssorAnimator$.call(_SelfCarousel, 0, 0, { $LoopLength: _SlideCount });
+
+            //Carousel Constructor
+            {
+                $Jssor$.$Each(_SlideItems, function (slideItem) {
+                    (_Loop & 1) && slideItem.$SetLoopLength(_SlideCount);
+                    _SelfCarousel.$Chain(slideItem);
+                    slideItem.$Shift(_ParkingPosition / _StepLength);
+                });
+            }
+        }
+        //Carousel
+
+        //Slideshow
+        function Slideshow() {
+            var _SelfSlideshow = this;
+            var _Wrapper = _SlideContainer.$Elmt;
+
+            $JssorAnimator$.call(_SelfSlideshow, -1, 2, { $Easing: $JssorEasing$.$EaseLinear, $Setter: { $Position: SetPosition }, $LoopLength: _SlideCount }, _Wrapper, { $Position: 1 }, { $Position: -1 });
+
+            _SelfSlideshow.$Wrapper = _Wrapper;
+
+            //Slideshow Constructor
+            {
+                $JssorDebug$.$Execute(function () {
+                    $Jssor$.$Attribute(_SlideContainer.$Elmt, "debug-id", "slide_container");
+                });
+            }
+        }
+        //Slideshow
+
+        //CarouselPlayer
+        function CarouselPlayer(carousel, slideshow) {
+            var _SelfCarouselPlayer = this;
+            var _FromPosition;
+            var _ToPosition;
+            var _Duration;
+            var _StandBy;
+            var _StandByPosition;
+
+            $JssorAnimator$.call(_SelfCarouselPlayer, -100000000, 200000000);
+
+            _SelfCarouselPlayer.$OnStart = function () {
+                _IsSliding = true;
+                _LoadingTicket = null;
+
+                //EVT_SWIPE_START
+                _SelfSlider.$TriggerEvent(JssorSlider.$EVT_SWIPE_START, GetRealIndex(_Conveyor.$GetPosition()), _Conveyor.$GetPosition());
+            };
+
+            _SelfCarouselPlayer.$OnStop = function () {
+
+                _IsSliding = false;
+                _StandBy = false;
+
+                var currentSlideInfo = _Conveyor.$GetCurrentSlideInfo();
+
+                //EVT_SWIPE_END
+                _SelfSlider.$TriggerEvent(JssorSlider.$EVT_SWIPE_END, GetRealIndex(_Conveyor.$GetPosition()), _Conveyor.$GetPosition());
+
+                if (!currentSlideInfo.$Position) {
+                    OnPark(currentSlideInfo.$VirtualIndex, _CurrentSlideIndex);
+                }
+            };
+
+            _SelfCarouselPlayer.$OnPositionChange = function (oldPosition, newPosition) {
+
+                var toPosition;
+
+                if (_StandBy)
+                    toPosition = _StandByPosition;
+                else {
+                    toPosition = _ToPosition;
+
+                    if (_Duration) {
+                        var interPosition = newPosition / _Duration;
+                        if ($Jssor$.$IsBrowserChrome() || $Jssor$.$IsBrowserFireFox()) {
+                            Math.round(interPosition * 16 / _Duration) / 16 * _Duration;
+                            interPosition = parseFloat(interPosition.toFixed(4));
+                        }
+                        toPosition = _Options.$SlideEasing(interPosition) * (_ToPosition - _FromPosition) + _FromPosition;
+                    }
+                }
+
+                _Conveyor.$GoToPosition(toPosition);
+            };
+
+            _SelfCarouselPlayer.$PlayCarousel = function (fromPosition, toPosition, duration, callback) {
+                $JssorDebug$.$Execute(function () {
+                    if (_SelfCarouselPlayer.$IsPlaying())
+                        $JssorDebug$.$Fail("The carousel is already playing.");
+                });
+
+                _FromPosition = fromPosition;
+                _ToPosition = toPosition;
+                _Duration = duration;
+
+                _Conveyor.$GoToPosition(fromPosition);
+                _SelfCarouselPlayer.$GoToPosition(0);
+
+                _SelfCarouselPlayer.$PlayToPosition(duration, callback);
+            };
+
+            _SelfCarouselPlayer.$StandBy = function (standByPosition) {
+                _StandBy = true;
+                _StandByPosition = standByPosition;
+                _SelfCarouselPlayer.$Play(standByPosition, null, true);
+            };
+
+            _SelfCarouselPlayer.$SetStandByPosition = function (standByPosition) {
+                _StandByPosition = standByPosition;
+            };
+
+            _SelfCarouselPlayer.$MoveCarouselTo = function (position) {
+                _Conveyor.$GoToPosition(position);
+            };
+
+            //CarouselPlayer Constructor
+            {
+                _Conveyor = new Conveyor();
+
+                _Conveyor.$Combine(carousel);
+                _Conveyor.$Combine(slideshow);
+            }
+        }
+        //CarouselPlayer
+
+        //SlideContainer
+        function SlideContainer() {
+            var _Self = this;
+            var elmt = CreatePanel();
+
+            $Jssor$.$CssZIndex(elmt, 0);
+
+            _Self.$Elmt = elmt;
+
+            _Self.$AddClipElement = function (clipElement) {
+                $Jssor$.$AppendChild(elmt, clipElement);
+                $Jssor$.$ShowElement(elmt);
+            };
+
+            _Self.$Clear = function () {
+                $Jssor$.$HideElement(elmt);
+                $Jssor$.$ClearInnerHtml(elmt);
+            };
+        }
+        //SlideContainer
+
+        //SlideItem
+        function SlideItem(slideElmt, slideIndex) {
+
+            var _SelfSlideItem = this;
+
+            var _CaptionSliderIn;
+            var _CaptionSliderOut;
+            var _CaptionSliderCurrent;
+            var _IsCaptionSliderPlayingWhenDragStart;
+
+            var _Wrapper;
+            var _BaseElement = slideElmt;
+
+            var _LoadingScreen;
+
+            var _ImageItem;
+            var _ImageElmts = [];
+            var _LinkItemOrigin;
+            var _LinkItem;
+            var _ImageLoading;
+            var _ImageLoaded;
+            var _ImageLazyLoading;
+            var _ContentRefreshed;
+
+            var _Processor;
+
+            var _PlayerInstanceElement;
+            var _PlayerInstance;
+
+            var _SequenceNumber;    //for debug only
+
+            $JssorAnimator$.call(_SelfSlideItem, -_DisplayPieces, _DisplayPieces + 1, { $SlideItemAnimator: true });
+
+            function ResetCaptionSlider(fresh) {
+                _CaptionSliderOut && _CaptionSliderOut.$Revert();
+                _CaptionSliderIn && _CaptionSliderIn.$Revert();
+
+                RefreshContent(slideElmt, fresh);
+                _ContentRefreshed = true;
+
+                _CaptionSliderIn = new _CaptionSliderOptions.$Class(slideElmt, _CaptionSliderOptions, 1);
+                $JssorDebug$.$LiveStamp(_CaptionSliderIn, "caption_slider_" + _CaptionSliderCount + "_in");
+                _CaptionSliderOut = new _CaptionSliderOptions.$Class(slideElmt, _CaptionSliderOptions);
+                $JssorDebug$.$LiveStamp(_CaptionSliderOut, "caption_slider_" + _CaptionSliderCount + "_out");
+
+                $JssorDebug$.$Execute(function () {
+                    _CaptionSliderCount++;
+                });
+
+                _CaptionSliderOut.$GoToBegin();
+                _CaptionSliderIn.$GoToBegin();
+            }
+
+            function EnsureCaptionSliderVersion() {
+                if (_CaptionSliderIn.$Version < _CaptionSliderOptions.$Version) {
+                    ResetCaptionSlider();
+                }
+            }
+
+            //event handling begin
+            function LoadImageCompleteEventHandler(completeCallback, loadingScreen, image) {
+                if (!_ImageLoaded) {
+                    _ImageLoaded = true;
+
+                    if (_ImageItem && image) {
+                        var imageWidth = image.width;
+                        var imageHeight = image.height;
+                        var fillWidth = imageWidth;
+                        var fillHeight = imageHeight;
+
+                        if (imageWidth && imageHeight && _Options.$FillMode) {
+
+                            //0 stretch, 1 contain (keep aspect ratio and put all inside slide), 2 cover (keep aspect ratio and cover whole slide), 4 actual size, 5 contain for large image, actual size for small image, default value is 0
+                            if (_Options.$FillMode & 3 && (!(_Options.$FillMode & 4) || imageWidth > _SlideWidth || imageHeight > _SlideHeight)) {
+                                var fitHeight = false;
+                                var ratio = _SlideWidth / _SlideHeight * imageHeight / imageWidth;
+
+                                if (_Options.$FillMode & 1) {
+                                    fitHeight = (ratio > 1);
+                                }
+                                else if (_Options.$FillMode & 2) {
+                                    fitHeight = (ratio < 1);
+                                }
+                                fillWidth = fitHeight ? imageWidth * _SlideHeight / imageHeight : _SlideWidth;
+                                fillHeight = fitHeight ? _SlideHeight : imageHeight * _SlideWidth / imageWidth;
+                            }
+
+                            $Jssor$.$CssWidth(_ImageItem, fillWidth);
+                            $Jssor$.$CssHeight(_ImageItem, fillHeight);
+                            $Jssor$.$CssTop(_ImageItem, (_SlideHeight - fillHeight) / 2);
+                            $Jssor$.$CssLeft(_ImageItem, (_SlideWidth - fillWidth) / 2);
+                        }
+
+                        $Jssor$.$CssPosition(_ImageItem, "absolute");
+
+                        _SelfSlider.$TriggerEvent(JssorSlider.$EVT_LOAD_END, slideItem);
+                    }
+                }
+
+                $Jssor$.$HideElement(loadingScreen);
+                completeCallback && completeCallback(_SelfSlideItem);
+            }
+
+            function LoadSlideshowImageCompleteEventHandler(nextIndex, nextItem, slideshowTransition, loadingTicket) {
+                if (loadingTicket == _LoadingTicket && _CurrentSlideIndex == slideIndex && _AutoPlay) {
+                    if (!_Frozen) {
+                        var nextRealIndex = GetRealIndex(nextIndex);
+                        _SlideshowRunner.$Initialize(nextRealIndex, slideIndex, nextItem, _SelfSlideItem, slideshowTransition);
+                        nextItem.$HideContentForSlideshow();
+                        _Slideshow.$Locate(nextRealIndex, 1);
+                        _Slideshow.$GoToPosition(nextRealIndex);
+                        _CarouselPlayer.$PlayCarousel(nextIndex, nextIndex, 0);
+                    }
+                }
+            }
+
+            function SlideReadyEventHandler(loadingTicket) {
+                if (loadingTicket == _LoadingTicket && _CurrentSlideIndex == slideIndex) {
+
+                    if (!_Processor) {
+                        var slideshowProcessor = null;
+                        if (_SlideshowRunner) {
+                            if (_SlideshowRunner.$Index == slideIndex)
+                                slideshowProcessor = _SlideshowRunner.$GetProcessor();
+                            else
+                                _SlideshowRunner.$Clear();
+                        }
+
+                        EnsureCaptionSliderVersion();
+
+                        _Processor = new Processor(slideIndex, slideshowProcessor, _SelfSlideItem.$GetCaptionSliderIn(), _SelfSlideItem.$GetCaptionSliderOut());
+                        _Processor.$SetPlayer(_PlayerInstance);
+                    }
+
+                    !_Processor.$IsPlaying() && _Processor.$Replay();
+                }
+            }
+
+            function ParkEventHandler(currentIndex, previousIndex) {
+                if (currentIndex == slideIndex) {
+
+                    if (currentIndex != previousIndex)
+                        _SlideItems[previousIndex] && _SlideItems[previousIndex].$ParkOut();
+                    else
+                        _Processor && _Processor.$AdjustIdleOnPark();
+
+                    _PlayerInstance && _PlayerInstance.$Enable();
+
+                    //park in
+                    var loadingTicket = _LoadingTicket = $Jssor$.$GetNow();
+                    _SelfSlideItem.$LoadImage($Jssor$.$CreateCallback(null, SlideReadyEventHandler, loadingTicket));
+                }
+                else {
+                    var distance = Math.abs(slideIndex - currentIndex);
+                    var loadRange = _DisplayPieces + _Options.$LazyLoading;
+                    if (!_ImageLazyLoading || distance <= loadRange || _SlideCount - distance <= loadRange) {
+                        _SelfSlideItem.$LoadImage();
+                    }
+                }
+            }
+
+            function SwipeStartEventHandler() {
+                if (_CurrentSlideIndex == slideIndex && _Processor) {
+                    _Processor.$Stop();
+                    _PlayerInstance && _PlayerInstance.$Quit();
+                    _PlayerInstance && _PlayerInstance.$Disable();
+                    _Processor.$OpenSlideshowPanel();
+                }
+            }
+
+            function FreezeEventHandler() {
+                if (_CurrentSlideIndex == slideIndex && _Processor) {
+                    _Processor.$Stop();
+                }
+            }
+
+            function LinkClickEventHandler(event) {
+                if (_LastDragSucceded) {
+                    $Jssor$.$CancelEvent(event);
+                }
+                else {
+                    _SelfSlider.$TriggerEvent(JssorSlider.$EVT_CLICK, slideIndex, event);
+                }
+            }
+
+            function PlayerAvailableEventHandler() {
+                _PlayerInstance = _PlayerInstanceElement.pInstance;
+                _Processor && _Processor.$SetPlayer(_PlayerInstance);
+            }
+
+            _SelfSlideItem.$LoadImage = function (completeCallback, loadingScreen) {
+                loadingScreen = loadingScreen || _LoadingScreen;
+
+                if (_ImageElmts.length && !_ImageLoaded) {
+
+                    $Jssor$.$ShowElement(loadingScreen);
+
+                    if (!_ImageLoading) {
+                        _ImageLoading = true;
+                        _SelfSlider.$TriggerEvent(JssorSlider.$EVT_LOAD_START);
+
+                        $Jssor$.$Each(_ImageElmts, function (imageElmt) {
+
+                            if (!imageElmt.src) {
+                                imageElmt.src = $Jssor$.$AttributeEx(imageElmt, "src2");
+                                $Jssor$.$CssDisplay(imageElmt, imageElmt["display-origin"]);
+                            }
+                        });
+                    }
+                    $Jssor$.$LoadImages(_ImageElmts, _ImageItem, $Jssor$.$CreateCallback(null, LoadImageCompleteEventHandler, completeCallback, loadingScreen));
+                }
+                else {
+                    LoadImageCompleteEventHandler(completeCallback, loadingScreen);
+                }
+            };
+
+            _SelfSlideItem.$GoForNextSlide = function () {
+                if (_SlideshowRunner) {
+                    var slideshowTransition = _SlideshowRunner.$GetTransition(_SlideCount);
+
+                    if (slideshowTransition) {
+                        var loadingTicket = _LoadingTicket = $Jssor$.$GetNow();
+
+                        var nextIndex = slideIndex + _PlayReverse;
+                        var nextItem = _SlideItems[GetRealIndex(nextIndex)];
+                        return nextItem.$LoadImage($Jssor$.$CreateCallback(null, LoadSlideshowImageCompleteEventHandler, nextIndex, nextItem, slideshowTransition, loadingTicket), _LoadingScreen);
+                    }
+                }
+
+                PlayTo(_CurrentSlideIndex + _Options.$AutoPlaySteps * _PlayReverse);
+            };
+
+            _SelfSlideItem.$TryActivate = function () {
+                ParkEventHandler(slideIndex, slideIndex);
+            };
+
+            _SelfSlideItem.$ParkOut = function () {
+                //park out
+                _PlayerInstance && _PlayerInstance.$Quit();
+                _PlayerInstance && _PlayerInstance.$Disable();
+                _SelfSlideItem.$UnhideContentForSlideshow();
+                _Processor && _Processor.$Abort();
+                _Processor = null;
+                ResetCaptionSlider();
+            };
+
+            //for debug only
+            _SelfSlideItem.$StampSlideItemElements = function (stamp) {
+                stamp = _SequenceNumber + "_" + stamp;
+
+                $JssorDebug$.$Execute(function () {
+                    if (_ImageItem)
+                        $Jssor$.$Attribute(_ImageItem, "debug-id", stamp + "_slide_item_image_id");
+
+                    $Jssor$.$Attribute(slideElmt, "debug-id", stamp + "_slide_item_item_id");
+                });
+
+                $JssorDebug$.$Execute(function () {
+                    $Jssor$.$Attribute(_Wrapper, "debug-id", stamp + "_slide_item_wrapper_id");
+                });
+
+                $JssorDebug$.$Execute(function () {
+                    $Jssor$.$Attribute(_LoadingScreen, "debug-id", stamp + "_loading_container_id");
+                });
+            };
+
+            _SelfSlideItem.$HideContentForSlideshow = function () {
+                $Jssor$.$HideElement(slideElmt);
+            };
+
+            _SelfSlideItem.$UnhideContentForSlideshow = function () {
+                $Jssor$.$ShowElement(slideElmt);
+            };
+
+            _SelfSlideItem.$EnablePlayer = function () {
+                _PlayerInstance && _PlayerInstance.$Enable();
+            };
+
+            function RefreshContent(elmt, fresh, level) {
+                if (elmt["jssor-slider"])
+                    return;
+
+                level = level || 0;
+
+                if (!_ContentRefreshed) {
+                    if (elmt.tagName == "IMG") {
+                        _ImageElmts.push(elmt);
+
+                        if (!elmt.src) {
+                            _ImageLazyLoading = true;
+                            elmt["display-origin"] = $Jssor$.$CssDisplay(elmt);
+                            $Jssor$.$HideElement(elmt);
+                        }
+                    }
+                    if ($Jssor$.$IsBrowserIe9Earlier()) {
+                        $Jssor$.$CssZIndex(elmt, ($Jssor$.$CssZIndex(elmt) || 0) + 1);
+                    }
+                    if (_Options.$HWA && $Jssor$.$WebKitVersion() > 0) {
+                        //if ((_HandleTouchEventOnly && ($Jssor$.$WebKitVersion() < 534 || !_SlideshowEnabled)) || (!_HandleTouchEventOnly && $Jssor$.$WebKitVersion() < 535)) {
+                        //    $Jssor$.$EnableHWA(elmt);
+                        //}
+                        if (!_HandleTouchEventOnly || ($Jssor$.$WebKitVersion() < 534 || !_SlideshowEnabled)) {
+                            $Jssor$.$EnableHWA(elmt);
+                        }
+                    }
+                }
+
+                var childElements = $Jssor$.$Children(elmt);
+
+                $Jssor$.$Each(childElements, function (childElement, i) {
+
+                    var uAttribute = $Jssor$.$AttributeEx(childElement, "u");
+                    if (uAttribute == "player" && !_PlayerInstanceElement) {
+                        _PlayerInstanceElement = childElement;
+                        if (_PlayerInstanceElement.pInstance) {
+                            PlayerAvailableEventHandler();
+                        }
+                        else {
+                            $Jssor$.$AddEvent(_PlayerInstanceElement, "dataavailable", PlayerAvailableEventHandler);
+                        }
+                    }
+
+                    if (uAttribute == "caption") {
+                        if (!$Jssor$.$IsBrowserIE() && !fresh) {
+                            var captionElement = $Jssor$.$CloneNode(childElement, true);
+                            $Jssor$.$InsertBefore(elmt, captionElement, childElement);
+                            $Jssor$.$RemoveChild(elmt, childElement);
+                            childElement = captionElement;
+
+                            fresh = true;
+                        }
+                    }
+                    else if (!_ContentRefreshed && !level && !_ImageItem && $Jssor$.$AttributeEx(childElement, "u") == "image") {
+                        _ImageItem = childElement;
+
+                        if (_ImageItem) {
+                            if (_ImageItem.tagName == "A") {
+                                _LinkItemOrigin = _ImageItem;
+                                $Jssor$.$SetStyles(_LinkItemOrigin, _StyleDef);
+
+                                _LinkItem = $Jssor$.$CloneNode(_ImageItem, false);
+                                //cancel click event on <A> element when a drag of slide succeeded
+                                $Jssor$.$AddEvent(_LinkItem, "click", LinkClickEventHandler);
+
+                                $Jssor$.$SetStyles(_LinkItem, _StyleDef);
+                                $Jssor$.$CssDisplay(_LinkItem, "block");
+                                $Jssor$.$CssOpacity(_LinkItem, 0);
+                                $Jssor$.$Css(_LinkItem, "backgroundColor", "#000");
+
+                                _ImageItem = $Jssor$.$FindFirstChildByTag(_ImageItem, "IMG");
+
+                                $JssorDebug$.$Execute(function () {
+                                    if (!_ImageItem) {
+                                        $JssorDebug$.$Error("slide html code definition error, no 'IMG' found in a 'image with link' slide.\r\n" + elmt.outerHTML);
+                                    }
+                                });
+                            }
+                            _ImageItem.border = 0;
+
+                            $Jssor$.$SetStyles(_ImageItem, _StyleDef);
+                        }
+                    }
+
+                    RefreshContent(childElement, fresh, level + 1);
+                });
+            }
+
+            _SelfSlideItem.$OnInnerOffsetChange = function (oldOffset, newOffset) {
+                var slidePosition = _DisplayPieces - newOffset;
+
+                SetPosition(_Wrapper, slidePosition);
+
+                //following lines are for future usage, not ready yet
+                //if (!_IsDragging || !_IsCaptionSliderPlayingWhenDragStart) {
+                //    var _DealWithParallax;
+                //    if (IsCurrentSlideIndex(slideIndex)) {
+                //        if (_CaptionSliderOptions.$PlayOutMode == 2)
+                //            _DealWithParallax = true;
+                //    }
+                //    else {
+                //        if (!_CaptionSliderOptions.$PlayInMode) {
+                //            //PlayInMode: 0 none
+                //            _CaptionSliderIn.$GoToEnd();
+                //        }
+                //        //else if (_CaptionSliderOptions.$PlayInMode == 1) {
+                //        //    //PlayInMode: 1 chain
+                //        //    _CaptionSliderIn.$GoToBegin();
+                //        //}
+                //        else if (_CaptionSliderOptions.$PlayInMode == 2) {
+                //            //PlayInMode: 2 parallel
+                //            _DealWithParallax = true;
+                //        }
+                //    }
+
+                //    if (_DealWithParallax) {
+                //        _CaptionSliderIn.$GoToPosition((_CaptionSliderIn.$GetPosition_OuterEnd() - _CaptionSliderIn.$GetPosition_OuterBegin()) * Math.abs(newOffset - 1) * .8 + _CaptionSliderIn.$GetPosition_OuterBegin());
+                //    }
+                //}
+            };
+
+            _SelfSlideItem.$GetCaptionSliderIn = function () {
+                return _CaptionSliderIn;
+            };
+
+            _SelfSlideItem.$GetCaptionSliderOut = function () {
+                return _CaptionSliderOut;
+            };
+
+            _SelfSlideItem.$Index = slideIndex;
+
+            $JssorObject$.call(_SelfSlideItem);
+
+            //SlideItem Constructor
+            {
+
+                var thumb = $Jssor$.$FindFirstChild(slideElmt, "thumb");
+                if (thumb) {
+                    _SelfSlideItem.$Thumb = $Jssor$.$CloneNode(thumb, true);
+                    $Jssor$.$RemoveAttribute(thumb, "id");
+                    $Jssor$.$HideElement(thumb);
+                }
+                $Jssor$.$ShowElement(slideElmt);
+
+                _LoadingScreen = $Jssor$.$CloneNode(_LoadingContainer, true);
+                $Jssor$.$CssZIndex(_LoadingScreen, 1000);
+
+                //cancel click event on <A> element when a drag of slide succeeded
+                $Jssor$.$AddEvent(slideElmt, "click", LinkClickEventHandler);
+
+                ResetCaptionSlider(true);
+
+                _SelfSlideItem.$Image = _ImageItem;
+                _SelfSlideItem.$Link = _LinkItem;
+
+                _SelfSlideItem.$Item = slideElmt;
+
+                _SelfSlideItem.$Wrapper = _Wrapper = slideElmt;
+                $Jssor$.$AppendChild(_Wrapper, _LoadingScreen);
+
+                _SelfSlider.$On(203, ParkEventHandler);
+                _SelfSlider.$On(28, FreezeEventHandler);
+                _SelfSlider.$On(24, SwipeStartEventHandler);
+
+                $JssorDebug$.$Execute(function () {
+                    _SequenceNumber = _SlideItemCreatedCount++;
+                });
+
+                $JssorDebug$.$Execute(function () {
+                    $Jssor$.$Attribute(_Wrapper, "debug-id", "slide-" + slideIndex);
+                });
+            }
+        }
+        //SlideItem
+
+        //Processor
+        function Processor(slideIndex, slideshowProcessor, captionSliderIn, captionSliderOut) {
+
+            var _SelfProcessor = this;
+
+            var _ProgressBegin = 0;
+            var _SlideshowBegin = 0;
+            var _SlideshowEnd;
+            var _CaptionInBegin;
+            var _IdleBegin;
+            var _IdleEnd;
+            var _ProgressEnd;
+
+            var _IsSlideshowRunning;
+            var _IsRollingBack;
+
+            var _PlayerInstance;
+            var _IsPlayerOnService;
+
+            var slideItem = _SlideItems[slideIndex];
+
+            $JssorAnimator$.call(_SelfProcessor, 0, 0);
+
+            function UpdateLink() {
+
+                $Jssor$.$ClearChildren(_LinkContainer);
+
+                if (_ShowLink && _IsSlideshowRunning && slideItem.$Link) {
+                    $Jssor$.$AppendChild(_LinkContainer, slideItem.$Link);
+                }
+
+                $Jssor$.$ShowElement(_LinkContainer, _IsSlideshowRunning || !slideItem.$Image);
+            }
+
+            function ProcessCompleteEventHandler() {
+
+                if (_IsRollingBack) {
+                    _IsRollingBack = false;
+                    _SelfSlider.$TriggerEvent(JssorSlider.$EVT_ROLLBACK_END, slideIndex, _IdleEnd, _ProgressBegin, _IdleBegin, _IdleEnd, _ProgressEnd);
+                    _SelfProcessor.$GoToPosition(_IdleBegin);
+                }
+
+                _SelfProcessor.$Replay();
+            }
+
+            function PlayerSwitchEventHandler(isOnService) {
+                _IsPlayerOnService = isOnService;
+
+                _SelfProcessor.$Stop();
+                _SelfProcessor.$Replay();
+            }
+
+            _SelfProcessor.$Replay = function () {
+
+                var currentPosition = _SelfProcessor.$GetPosition_Display();
+
+                if (!_IsDragging && !_IsSliding && !_IsPlayerOnService && _CurrentSlideIndex == slideIndex) {
+
+                    if (!currentPosition) {
+                        if (_SlideshowEnd && !_IsSlideshowRunning) {
+                            _IsSlideshowRunning = true;
+
+                            _SelfProcessor.$OpenSlideshowPanel(true);
+
+                            _SelfSlider.$TriggerEvent(JssorSlider.$EVT_SLIDESHOW_START, slideIndex, _ProgressBegin, _SlideshowBegin, _SlideshowEnd, _ProgressEnd);
+                        }
+
+                        UpdateLink();
+                    }
+
+                    var toPosition;
+                    var stateEvent = JssorSlider.$EVT_STATE_CHANGE;
+
+                    if (currentPosition != _ProgressEnd) {
+                        if (currentPosition == _IdleEnd) {
+                            toPosition = _ProgressEnd;
+                        }
+                        else if (currentPosition == _IdleBegin) {
+                            toPosition = _IdleEnd;
+                        }
+                        else if (!currentPosition) {
+                            toPosition = _IdleBegin;
+                        }
+                        else if (currentPosition > _IdleEnd) {
+                            _IsRollingBack = true;
+                            toPosition = _IdleEnd;
+                            stateEvent = JssorSlider.$EVT_ROLLBACK_START;
+                        }
+                        else {
+                            //continue from break (by drag or lock)
+                            toPosition = _SelfProcessor.$GetPlayToPosition();
+                        }
+                    }
+
+                    _SelfSlider.$TriggerEvent(stateEvent, slideIndex, currentPosition, _ProgressBegin, _IdleBegin, _IdleEnd, _ProgressEnd);
+
+                    var allowAutoPlay = _AutoPlay && (!_HoverToPause || _HoverStatus);
+
+                    if (currentPosition == _ProgressEnd) {
+                        allowAutoPlay && slideItem.$GoForNextSlide();
+                    }
+                    else if (allowAutoPlay || currentPosition != _IdleEnd) {
+                        _SelfProcessor.$PlayToPosition(toPosition, ProcessCompleteEventHandler);
+                    }
+                }
+            };
+
+            _SelfProcessor.$AdjustIdleOnPark = function () {
+                if (_IdleEnd == _ProgressEnd && _IdleEnd == _SelfProcessor.$GetPosition_Display())
+                    _SelfProcessor.$GoToPosition(_IdleBegin);
+            };
+
+            _SelfProcessor.$Abort = function () {
+                _SlideshowRunner && _SlideshowRunner.$Index == slideIndex && _SlideshowRunner.$Clear();
+
+                var currentPosition = _SelfProcessor.$GetPosition_Display();
+                if (currentPosition < _ProgressEnd) {
+                    _SelfSlider.$TriggerEvent(JssorSlider.$EVT_STATE_CHANGE, slideIndex, -currentPosition -1, _ProgressBegin, _IdleBegin, _IdleEnd, _ProgressEnd);
+                }
+            };
+
+            _SelfProcessor.$OpenSlideshowPanel = function (open) {
+                if (slideshowProcessor) {
+                    $Jssor$.$CssOverflow(_SlideshowPanel, open && slideshowProcessor.$Transition.$Outside ? "" : "hidden");
+                }
+            };
+
+            _SelfProcessor.$OnInnerOffsetChange = function (oldPosition, newPosition) {
+
+                if (_IsSlideshowRunning && newPosition >= _SlideshowEnd) {
+                    _IsSlideshowRunning = false;
+                    UpdateLink();
+                    slideItem.$UnhideContentForSlideshow();
+                    _SlideshowRunner.$Clear();
+
+                    _SelfSlider.$TriggerEvent(JssorSlider.$EVT_SLIDESHOW_END, slideIndex, _ProgressBegin, _SlideshowBegin, _SlideshowEnd, _ProgressEnd);
+                }
+
+                _SelfSlider.$TriggerEvent(JssorSlider.$EVT_PROGRESS_CHANGE, slideIndex, newPosition, _ProgressBegin, _IdleBegin, _IdleEnd, _ProgressEnd);
+            };
+
+            _SelfProcessor.$SetPlayer = function (playerInstance) {
+                if (playerInstance && !_PlayerInstance) {
+                    _PlayerInstance = playerInstance;
+
+                    playerInstance.$On($JssorPlayer$.$EVT_SWITCH, PlayerSwitchEventHandler);
+                }
+            };
+
+            //Processor Constructor
+            {
+                if (slideshowProcessor) {
+                    _SelfProcessor.$Chain(slideshowProcessor);
+                }
+
+                _SlideshowEnd = _SelfProcessor.$GetPosition_OuterEnd();
+                _CaptionInBegin = _SelfProcessor.$GetPosition_OuterEnd();
+                _SelfProcessor.$Chain(captionSliderIn);
+                _IdleBegin = captionSliderIn.$GetPosition_OuterEnd();
+                _IdleEnd = _IdleBegin + _Options.$AutoPlayInterval;
+
+                captionSliderOut.$Shift(_IdleEnd);
+                _SelfProcessor.$Combine(captionSliderOut);
+                _ProgressEnd = _SelfProcessor.$GetPosition_OuterEnd();
+            }
+        }
+        //Processor
+        //private classes
+
+        function SetPosition(elmt, position) {
+            var orientation = _DragOrientation > 0 ? _DragOrientation : _PlayOrientation;
+            var x = _StepLengthX * position * (orientation & 1);
+            var y = _StepLengthY * position * ((orientation >> 1) & 1);
+
+            if ($Jssor$.$IsBrowserChrome()) {
+                x = x.toFixed(3);
+                y = y.toFixed(3);
+            }
+            else {
+                x = Math.round(x);
+                y = Math.round(y);
+            }
+
+            if ($Jssor$.$IsBrowserIE() && $Jssor$.$BrowserVersion() >= 10 && $Jssor$.$BrowserVersion() < 11) {
+                elmt.style.msTransform = "translate(" + x + "px, " + y + "px)";
+            }
+            else if ($Jssor$.$IsBrowserChrome() && $Jssor$.$BrowserVersion() >= 30 && $Jssor$.$BrowserVersion() < 34) {
+                elmt.style.WebkitTransition = "transform 0s";
+                elmt.style.WebkitTransform = "translate3d(" + x + "px, " + y + "px, 0px) perspective(2000px)";
+            }
+            else {
+                $Jssor$.$CssLeft(elmt, x);
+                $Jssor$.$CssTop(elmt, y);
+            }
+        }
+
+        //Event handling begin
+
+        function OnMouseDown(event) {
+            var tagName = $Jssor$.$EventSrc(event).tagName;
+            if (!_DragOrientationRegistered && tagName != "INPUT" && tagName != "TEXTAREA" && tagName != "SELECT" && RegisterDrag()) {
+                OnDragStart(event);
+            }
+        }
+
+        function Freeze() {
+
+            _CarouselPlaying_OnFreeze = _IsSliding;
+            _PlayToPosition_OnFreeze = _CarouselPlayer.$GetPlayToPosition();
+            _Position_OnFreeze = _Conveyor.$GetPosition();
+
+            if (_IsDragging || !_HoverStatus && (_HoverToPause & 12)) {
+                _CarouselPlayer.$Stop();
+
+                _SelfSlider.$TriggerEvent(JssorSlider.$EVT_FREEZE);
+            }
+        }
+
+        function Unfreeze(byDrag) {
+
+            if (!_IsDragging && (_HoverStatus || !(_HoverToPause & 12)) && !_CarouselPlayer.$IsPlaying()) {
+
+                var currentPosition = _Conveyor.$GetPosition();
+                var toPosition = Math.ceil(_Position_OnFreeze);
+
+                if (byDrag && Math.abs(_DragOffsetTotal) >= _Options.$MinDragOffsetToSlide) {
+                    toPosition = Math.ceil(currentPosition);
+                    toPosition += _DragIndexAdjust;
+                }
+
+                if (!(_Loop & 1)) {
+                    toPosition = Math.min(_SlideCount - _DisplayPieces, Math.max(toPosition, 0));
+                }
+
+                var t = Math.abs(toPosition - currentPosition);
+                t = 1 - Math.pow(1 - t, 5);
+
+                if (!_LastDragSucceded && _CarouselPlaying_OnFreeze) {
+                    _CarouselPlayer.$Continue(_PlayToPosition_OnFreeze);
+                }
+                else if (currentPosition == toPosition) {
+                    _CurrentSlideItem.$EnablePlayer();
+                    _CurrentSlideItem.$TryActivate();
+                }
+                else {
+
+                    _CarouselPlayer.$PlayCarousel(currentPosition, toPosition, t * _SlideDuration);
+                }
+            }
+        }
+
+        function OnDragStart(event) {
+
+            _IsDragging = true;
+            _DragInvalid = false;
+            _LoadingTicket = null;
+
+            $Jssor$.$AddEvent(document, _MoveEvent, OnDragMove);
+
+            _LastTimeMoveByDrag = $Jssor$.$GetNow() - 50;
+
+            _LastDragSucceded = 0;
+            Freeze();
+
+            if (!_CarouselPlaying_OnFreeze)
+                _DragOrientation = 0;
+
+            if (_HandleTouchEventOnly) {
+                var touchPoint = event.touches[0];
+                _DragStartMouseX = touchPoint.clientX;
+                _DragStartMouseY = touchPoint.clientY;
+            }
+            else {
+                var mousePoint = $Jssor$.$MousePosition(event);
+
+                _DragStartMouseX = mousePoint.x;
+                _DragStartMouseY = mousePoint.y;
+
+                $Jssor$.$CancelEvent(event);
+            }
+
+            _DragOffsetTotal = 0;
+            _DragOffsetLastTime = 0;
+            _DragIndexAdjust = 0;
+
+            //Trigger EVT_DRAGSTART
+            _SelfSlider.$TriggerEvent(JssorSlider.$EVT_DRAG_START, GetRealIndex(_Position_OnFreeze), _Position_OnFreeze, event);
+        }
+
+        function OnDragMove(event) {
+            if (_IsDragging && (!$Jssor$.$IsBrowserIe9Earlier() || event.button)) {
+                var actionPoint;
+
+                if (_HandleTouchEventOnly) {
+                    var touches = event.touches;
+                    if (touches && touches.length > 0) {
+                        actionPoint = new $JssorPoint$(touches[0].clientX, touches[0].clientY);
+                    }
+                }
+                else {
+                    actionPoint = $Jssor$.$MousePosition(event);
+                }
+
+                if (actionPoint) {
+                    var distanceX = actionPoint.x - _DragStartMouseX;
+                    var distanceY = actionPoint.y - _DragStartMouseY;
+
+
+                    if (Math.floor(_Position_OnFreeze) != _Position_OnFreeze)
+                        _DragOrientation = _DragOrientation || (_PlayOrientation & _DragOrientationRegistered);
+
+                    if ((distanceX || distanceY) && !_DragOrientation) {
+                        if (_DragOrientationRegistered == 3) {
+                            if (Math.abs(distanceY) > Math.abs(distanceX)) {
+                                _DragOrientation = 2;
+                            }
+                            else
+                                _DragOrientation = 1;
+                        }
+                        else {
+                            _DragOrientation = _DragOrientationRegistered;
+                        }
+
+                        if (_HandleTouchEventOnly && _DragOrientation == 1 && Math.abs(distanceY) - Math.abs(distanceX) > 3) {
+                            _DragInvalid = true;
+                        }
+                    }
+
+                    if (_DragOrientation) {
+                        var distance = distanceY;
+                        var stepLength = _StepLengthY;
+
+                        if (_DragOrientation == 1) {
+                            distance = distanceX;
+                            stepLength = _StepLengthX;
+                        }
+
+                        if (!(_Loop & 1)) {
+                            if (distance > 0) {
+                                var normalDistance = stepLength * _CurrentSlideIndex;
+                                var sqrtDistance = distance - normalDistance;
+                                if (sqrtDistance > 0) {
+                                    distance = normalDistance + Math.sqrt(sqrtDistance) * 5;
+                                }
+                            }
+
+                            if (distance < 0) {
+                                var normalDistance = stepLength * (_SlideCount - _DisplayPieces - _CurrentSlideIndex);
+                                var sqrtDistance = -distance - normalDistance;
+
+                                if (sqrtDistance > 0) {
+                                    distance = -normalDistance - Math.sqrt(sqrtDistance) * 5;
+                                }
+                            }
+                        }
+
+                        if (_DragOffsetTotal - _DragOffsetLastTime < -2) {
+                            _DragIndexAdjust = 0;
+                        }
+                        else if (_DragOffsetTotal - _DragOffsetLastTime > 2) {
+                            _DragIndexAdjust = -1;
+                        }
+
+                        _DragOffsetLastTime = _DragOffsetTotal;
+                        _DragOffsetTotal = distance;
+                        _PositionToGoByDrag = _Position_OnFreeze - _DragOffsetTotal / stepLength / (_ScaleRatio || 1);
+
+                        if (_DragOffsetTotal && _DragOrientation && !_DragInvalid) {
+                            $Jssor$.$CancelEvent(event);
+                            if (!_IsSliding) {
+                                _CarouselPlayer.$StandBy(_PositionToGoByDrag);
+                            }
+                            else
+                                _CarouselPlayer.$SetStandByPosition(_PositionToGoByDrag);
+                        }
+                        else if ($Jssor$.$IsBrowserIe9Earlier()) {
+                            $Jssor$.$CancelEvent(event);
+                        }
+                    }
+                }
+            }
+            else {
+                OnDragEnd(event);
+            }
+        }
+
+        function OnDragEnd(event) {
+            UnregisterDrag();
+
+            if (_IsDragging) {
+
+                _IsDragging = false;
+
+                _LastTimeMoveByDrag = $Jssor$.$GetNow();
+
+                $Jssor$.$RemoveEvent(document, _MoveEvent, OnDragMove);
+
+                _LastDragSucceded = _DragOffsetTotal;
+
+                _LastDragSucceded && $Jssor$.$CancelEvent(event);
+
+                _CarouselPlayer.$Stop();
+
+                var currentPosition = _Conveyor.$GetPosition();
+
+                //Trigger EVT_DRAG_END
+                _SelfSlider.$TriggerEvent(JssorSlider.$EVT_DRAG_END, GetRealIndex(currentPosition), currentPosition, GetRealIndex(_Position_OnFreeze), _Position_OnFreeze, event);
+
+                Unfreeze(true);
+
+                Freeze();
+            }
+        }
+        //Event handling end
+
+        function SetCurrentSlideIndex(index) {
+            _PrevSlideItem = _SlideItems[_CurrentSlideIndex];
+            _PreviousSlideIndex = _CurrentSlideIndex;
+            _CurrentSlideIndex = GetRealIndex(index);
+            _CurrentSlideItem = _SlideItems[_CurrentSlideIndex];
+            ResetNavigator(index);
+            return _CurrentSlideIndex;
+        }
+
+        function OnPark(slideIndex, prevIndex) {
+            _DragOrientation = 0;
+
+            SetCurrentSlideIndex(slideIndex);
+
+            //Trigger EVT_PARK
+            _SelfSlider.$TriggerEvent(JssorSlider.$EVT_PARK, GetRealIndex(slideIndex), prevIndex);
+        }
+
+        function ResetNavigator(index, temp) {
+            _TempSlideIndex = index;
+            $Jssor$.$Each(_Navigators, function (navigator) {
+                navigator.$SetCurrentIndex(GetRealIndex(index), index, temp);
+            });
+        }
+
+        function RegisterDrag() {
+            var dragRegistry = JssorSlider.$DragRegistry || 0;
+            var dragOrientation = _DragEnabled;
+            if (_HandleTouchEventOnly)
+                (dragOrientation & 1) && (dragOrientation &= 1);
+            JssorSlider.$DragRegistry |= dragOrientation;
+
+            return (_DragOrientationRegistered = dragOrientation & ~dragRegistry);
+        }
+
+        function UnregisterDrag() {
+            if (_DragOrientationRegistered) {
+                JssorSlider.$DragRegistry &= ~_DragEnabled;
+                _DragOrientationRegistered = 0;
+            }
+        }
+
+        function CreatePanel() {
+            var div = $Jssor$.$CreateDiv();
+
+            $Jssor$.$SetStyles(div, _StyleDef);
+            $Jssor$.$CssPosition(div, "absolute");
+
+            return div;
+        }
+
+        function GetRealIndex(index) {
+            return (index % _SlideCount + _SlideCount) % _SlideCount;
+        }
+
+        function IsCurrentSlideIndex(index) {
+            return GetRealIndex(index) == _CurrentSlideIndex;
+        }
+
+        function IsPreviousSlideIndex(index) {
+            return GetRealIndex(index) == _PreviousSlideIndex;
+        }
+
+        //Navigation Request Handler
+        function NavigationClickHandler(index, relative) {
+            if (relative) {
+                if (!_Loop) {
+                    //Stop at threshold
+                    index = Math.min(Math.max(index + _TempSlideIndex, 0), _SlideCount - _DisplayPieces);
+                    relative = false;
+                }
+                else if (_Loop & 2) {
+                    //Rewind
+                    index = GetRealIndex(index + _TempSlideIndex);
+                    relative = false;
+                }
+            }
+            PlayTo(index, _Options.$SlideDuration, relative);
+        }
+
+        function ShowNavigators() {
+            $Jssor$.$Each(_Navigators, function (navigator) {
+                navigator.$Show(navigator.$Options.$ChanceToShow > _HoverStatus);
+            });
+        }
+
+        function MainContainerMouseLeaveEventHandler() {
+            if (!_HoverStatus) {
+
+                //$JssorDebug$.$Log("mouseleave");
+
+                _HoverStatus = 1;
+
+                ShowNavigators();
+
+                if (!_IsDragging) {
+                    (_HoverToPause & 12) && Unfreeze();
+                    (_HoverToPause & 3) && _SlideItems[_CurrentSlideIndex].$TryActivate();
+                }
+            }
+        }
+
+        function MainContainerMouseEnterEventHandler() {
+
+            if (_HoverStatus) {
+
+                //$JssorDebug$.$Log("mouseenter");
+
+                _HoverStatus = 0;
+
+                ShowNavigators();
+
+                _IsDragging || !(_HoverToPause & 12) || Freeze();
+            }
+        }
+
+        function AdjustSlidesContainerSize() {
+            _StyleDef = { $Width: _SlideWidth, $Height: _SlideHeight, $Top: 0, $Left: 0 };
+
+            $Jssor$.$Each(_SlideElmts, function (slideElmt, i) {
+
+                $Jssor$.$SetStyles(slideElmt, _StyleDef);
+                $Jssor$.$CssPosition(slideElmt, "absolute");
+                $Jssor$.$CssOverflow(slideElmt, "hidden");
+
+                $Jssor$.$HideElement(slideElmt);
+            });
+
+            $Jssor$.$SetStyles(_LoadingContainer, _StyleDef);
+        }
+
+        function PlayToOffset(offset, slideDuration) {
+            PlayTo(offset, slideDuration, true);
+        }
+
+        function PlayTo(slideIndex, slideDuration, relative) {
+            ///	<summary>
+            ///		PlayTo( slideIndex [, slideDuration] ); //Play slider to position 'slideIndex' within a period calculated base on 'slideDuration'.
+            ///	</summary>
+            ///	<param name="slideIndex" type="Number">
+            ///		slide slideIndex or position will be playing to
+            ///	</param>
+            ///	<param name="slideDuration" type="Number" optional="true">
+            ///		base slide duration in milliseconds to calculate the whole duration to complete this play request.
+            ///	    default value is '$SlideDuration' value which is specified when initialize the slider.
+            ///	</param>
+            /// http://msdn.microsoft.com/en-us/library/vstudio/bb385682.aspx
+            /// http://msdn.microsoft.com/en-us/library/vstudio/hh542720.aspx
+            if (_CarouselEnabled && (!_IsDragging || _Options.$NaviQuitDrag)) {
+                _IsSliding = true;
+                _IsDragging = false;
+                _CarouselPlayer.$Stop();
+
+                {
+                    //Slide Duration
+                    if (slideDuration == undefined)
+                        slideDuration = _SlideDuration;
+
+                    var positionDisplay = _Carousel.$GetPosition_Display();
+                    var positionTo = slideIndex;
+                    if (relative) {
+                        positionTo = positionDisplay + slideIndex;
+                        if (slideIndex > 0)
+                            positionTo = Math.ceil(positionTo);
+                        else
+                            positionTo = Math.floor(positionTo);
+                    }
+
+
+                    if (!(_Loop & 1)) {
+                        positionTo = GetRealIndex(positionTo);
+                        positionTo = Math.max(0, Math.min(positionTo, _SlideCount - _DisplayPieces));
+                    }
+
+                    var positionOffset = (positionTo - positionDisplay) % _SlideCount;
+                    positionTo = positionDisplay + positionOffset;
+
+                    var duration = positionDisplay == positionTo ? 0 : slideDuration * Math.abs(positionOffset);
+                    duration = Math.min(duration, slideDuration * _DisplayPieces * 1.5);
+
+                    _CarouselPlayer.$PlayCarousel(positionDisplay, positionTo, duration || 1);
+                }
+            }
+        }
+
+        //private functions
+
+        //member functions
+
+        _SelfSlider.$PlayTo = PlayTo;
+
+        _SelfSlider.$GoTo = function (slideIndex) {
+            ///	<summary>
+            ///		instance.$GoTo( slideIndex );   //Go to the specifed slide immediately with no play.
+            ///	</summary>
+            PlayTo(slideIndex, 1);
+        };
+
+        _SelfSlider.$Next = function () {
+            ///	<summary>
+            ///		instance.$Next();   //Play the slider to next slide.
+            ///	</summary>
+            PlayToOffset(1);
+        };
+
+        _SelfSlider.$Prev = function () {
+            ///	<summary>
+            ///		instance.$Prev();   //Play the slider to previous slide.
+            ///	</summary>
+            PlayToOffset(-1);
+        };
+
+        _SelfSlider.$Pause = function () {
+            ///	<summary>
+            ///		instance.$Pause();   //Pause the slider, prevent it from auto playing.
+            ///	</summary>
+            _AutoPlay = false;
+        };
+
+        _SelfSlider.$Play = function () {
+            ///	<summary>
+            ///		instance.$Play();   //Start auto play if the slider is currently paused.
+            ///	</summary>
+            if (!_AutoPlay) {
+                _AutoPlay = true;
+                _SlideItems[_CurrentSlideIndex] && _SlideItems[_CurrentSlideIndex].$TryActivate();
+            }
+        };
+
+        _SelfSlider.$SetSlideshowTransitions = function (transitions) {
+            ///	<summary>
+            ///		instance.$SetSlideshowTransitions( transitions );   //Reset slideshow transitions for the slider.
+            ///	</summary>
+            $JssorDebug$.$Execute(function () {
+                if (!transitions || !transitions.length) {
+                    $JssorDebug$.$Error("Can not set slideshow transitions, no transitions specified.");
+                }
+            });
+
+            $Jssor$.$TranslateTransitions(transitions);    //for old transition compatibility
+            _Options.$SlideshowOptions.$Transitions = transitions;
+        };
+
+        _SelfSlider.$SetCaptionTransitions = function (transitions) {
+            ///	<summary>
+            ///		instance.$SetCaptionTransitions( transitions );   //Reset caption transitions for the slider.
+            ///	</summary>
+            $JssorDebug$.$Execute(function () {
+                if (!transitions || !transitions.length) {
+                    $JssorDebug$.$Error("Can not set caption transitions, no transitions specified");
+                }
+            });
+
+            $Jssor$.$TranslateTransitions(transitions);    //for old transition compatibility
+            _CaptionSliderOptions.$CaptionTransitions = transitions;
+            _CaptionSliderOptions.$Version = $Jssor$.$GetNow();
+        };
+
+        _SelfSlider.$SlidesCount = function () {
+            ///	<summary>
+            ///		instance.$SlidesCount();   //Retrieve slides count of the slider.
+            ///	</summary>
+            return _SlideElmts.length;
+        };
+
+        _SelfSlider.$CurrentIndex = function () {
+            ///	<summary>
+            ///		instance.$CurrentIndex();   //Retrieve current slide index of the slider.
+            ///	</summary>
+            return _CurrentSlideIndex;
+        };
+
+        _SelfSlider.$IsAutoPlaying = function () {
+            ///	<summary>
+            ///		instance.$IsAutoPlaying();   //Retrieve auto play status of the slider.
+            ///	</summary>
+            return _AutoPlay;
+        };
+
+        _SelfSlider.$IsDragging = function () {
+            ///	<summary>
+            ///		instance.$IsDragging();   //Retrieve drag status of the slider.
+            ///	</summary>
+            return _IsDragging;
+        };
+
+        _SelfSlider.$IsSliding = function () {
+            ///	<summary>
+            ///		instance.$IsSliding();   //Retrieve right<-->left sliding status of the slider.
+            ///	</summary>
+            return _IsSliding;
+        };
+
+        _SelfSlider.$IsMouseOver = function () {
+            ///	<summary>
+            ///		instance.$IsMouseOver();   //Retrieve mouse over status of the slider.
+            ///	</summary>
+            return !_HoverStatus;
+        };
+
+        _SelfSlider.$LastDragSucceded = function () {
+            ///	<summary>
+            ///		instance.$IsLastDragSucceded();   //Retrieve last drag succeded status, returns 0 if failed, returns drag offset if succeded
+            ///	</summary>
+            return _LastDragSucceded;
+        };
+
+        function OriginalWidth() {
+            ///	<summary>
+            ///		instance.$OriginalWidth();   //Retrieve original width of the slider.
+            ///	</summary>
+            return $Jssor$.$CssWidth(_ScaleWrapper || elmt);
+        }
+
+        function OriginalHeight() {
+            ///	<summary>
+            ///		instance.$OriginalHeight();   //Retrieve original height of the slider.
+            ///	</summary>
+            return $Jssor$.$CssHeight(_ScaleWrapper || elmt);
+        }
+
+        _SelfSlider.$OriginalWidth = _SelfSlider.$GetOriginalWidth = OriginalWidth;
+
+        _SelfSlider.$OriginalHeight = _SelfSlider.$GetOriginalHeight = OriginalHeight;
+
+        function Scale(dimension, isHeight) {
+            ///	<summary>
+            ///		instance.$ScaleWidth();   //Retrieve scaled dimension the slider currently displays.
+            ///		instance.$ScaleWidth( dimension );   //Scale the slider to new width and keep aspect ratio.
+            ///	</summary>
+
+            if (dimension == undefined)
+                return $Jssor$.$CssWidth(elmt);
+
+            $JssorDebug$.$Execute(function () {
+                if (!dimension || dimension < 0) {
+                    $JssorDebug$.$Fail("'$ScaleWidth' error, 'dimension' should be positive value.");
+                }
+            });
+
+            if (!_ScaleWrapper) {
+                $JssorDebug$.$Execute(function () {
+                    var originalWidthStr = $Jssor$.$Css(elmt, "width");
+                    var originalHeightStr = $Jssor$.$Css(elmt, "height");
+                    var originalWidth = $Jssor$.$CssP(elmt, "width");
+                    var originalHeight = $Jssor$.$CssP(elmt, "height");
+
+                    if (!originalWidthStr) {
+                        $JssorDebug$.$Fail("Cannot scale jssor slider, 'dimension' of 'outer container' not specified. Please specify 'dimension' in pixel. e.g. 'dimension: 600px;'");
+                    }
+
+                    if (!originalHeightStr) {
+                        $JssorDebug$.$Fail("Cannot scale jssor slider, 'height' of 'outer container' not specified. Please specify 'height' in pixel. e.g. 'height: 300px;'");
+                    }
+
+                    if (originalWidthStr.indexOf('%') != -1) {
+                        $JssorDebug$.$Fail("Cannot scale jssor slider, 'dimension' of 'outer container' not valid. Please specify 'dimension' in pixel. e.g. 'dimension: 600px;'");
+                    }
+
+                    if (originalHeightStr.indexOf('%') != -1) {
+                        $JssorDebug$.$Fail("Cannot scale jssor slider, 'height' of 'outer container' not valid. Please specify 'height' in pixel. e.g. 'height: 300px;'");
+                    }
+
+                    if (!originalWidth) {
+                        $JssorDebug$.$Fail("Cannot scale jssor slider, 'dimension' of 'outer container' not valid. 'dimension' of 'outer container' should be positive number. e.g. 'dimension: 600px;'");
+                    }
+
+                    if (!originalHeight) {
+                        $JssorDebug$.$Fail("Cannot scale jssor slider, 'height' of 'outer container' not valid. 'height' of 'outer container' should be positive number. e.g. 'height: 300px;'");
+                    }
+                });
+
+                //var innerWrapper = $Jssor$.$CloneNode(elmt, false);
+                //$Jssor$.$RemoveAttribute(innerWrapper, "id");
+                var innerWrapper = $Jssor$.$CreateDiv(document);
+                $Jssor$.$CssCssText(innerWrapper, $Jssor$.$CssCssText(elmt));
+                $Jssor$.$ClassName(innerWrapper, $Jssor$.$ClassName(elmt));
+
+                $Jssor$.$CssPosition(innerWrapper, "relative");
+                $Jssor$.$CssTop(innerWrapper, 0);
+                $Jssor$.$CssLeft(innerWrapper, 0);
+                $Jssor$.$CssOverflow(innerWrapper, "visible");
+
+                //_ScaleWrapper = $Jssor$.$CloneNode(elmt, false);
+                //$Jssor$.$RemoveAttribute(_ScaleWrapper, "id");
+                //$Jssor$.$CssCssText(_ScaleWrapper, "");
+                _ScaleWrapper = $Jssor$.$CreateDiv(document);
+
+                $Jssor$.$CssPosition(_ScaleWrapper, "absolute");
+                $Jssor$.$CssTop(_ScaleWrapper, 0);
+                $Jssor$.$CssLeft(_ScaleWrapper, 0);
+                $Jssor$.$CssWidth(_ScaleWrapper, $Jssor$.$CssWidth(elmt));
+                $Jssor$.$CssHeight(_ScaleWrapper, $Jssor$.$CssHeight(elmt));
+                $Jssor$.$SetStyleTransformOrigin(_ScaleWrapper, "0 0");
+
+                $Jssor$.$AppendChild(_ScaleWrapper, innerWrapper);
+
+                var children = $Jssor$.$Children(elmt);
+                $Jssor$.$AppendChild(elmt, _ScaleWrapper);
+
+                $Jssor$.$Css(elmt, "backgroundImage", "");
+
+                var noMoveElmts = {
+                    "navigator": _BulletNavigatorOptions && _BulletNavigatorOptions.$Scale == false,
+                    "arrowleft": _ArrowNavigatorOptions && _ArrowNavigatorOptions.$Scale == false,
+                    "arrowright": _ArrowNavigatorOptions && _ArrowNavigatorOptions.$Scale == false,
+                    "thumbnavigator": _ThumbnailNavigatorOptions && _ThumbnailNavigatorOptions.$Scale == false,
+                    "thumbwrapper": _ThumbnailNavigatorOptions && _ThumbnailNavigatorOptions.$Scale == false
+                };
+
+                $Jssor$.$Each(children, function (child) {
+                    $Jssor$.$AppendChild(noMoveElmts[$Jssor$.$AttributeEx(child, "u")] ? elmt : innerWrapper, child);
+                });
+
+                $Jssor$.$ShowElement(innerWrapper);
+                $Jssor$.$ShowElement(_ScaleWrapper);
+            }
+
+            $JssorDebug$.$Execute(function () {
+                if (!_InitialScrollWidth) {
+                    _InitialScrollWidth = _SelfSlider.$Elmt.scrollWidth;
+                }
+            });
+
+            _ScaleRatio = dimension /  (isHeight? $Jssor$.$CssHeight : $Jssor$.$CssWidth)(_ScaleWrapper);
+            $Jssor$.$CssScale(_ScaleWrapper, _ScaleRatio);
+
+            $Jssor$.$CssWidth(elmt, isHeight ? (_ScaleRatio * OriginalWidth()) : dimension);
+            $Jssor$.$CssHeight(elmt, isHeight ? dimension : (_ScaleRatio * OriginalHeight()));
+
+            $Jssor$.$Each(_Navigators, function (navigator) {
+                navigator.$Relocate();
+            });
+        }
+
+        _SelfSlider.$ScaleHeight = _SelfSlider.$GetScaleHeight = function (height) {
+            ///	<summary>
+            ///		instance.$ScaleHeight();   //Retrieve scaled height the slider currently displays.
+            ///		instance.$ScaleHeight( dimension );   //Scale the slider to new height and keep aspect ratio.
+            ///	</summary>
+
+            if (height == undefined)
+                return $Jssor$.$CssHeight(elmt);
+
+            Scale(height, true);
+        };
+
+        _SelfSlider.$ScaleWidth = _SelfSlider.$SetScaleWidth = _SelfSlider.$GetScaleWidth = Scale;
+
+        _SelfSlider.$GetVirtualIndex = function (index) {
+            var parkingIndex = Math.ceil(GetRealIndex(_ParkingPosition / _StepLength));
+            var displayIndex = GetRealIndex(index - _CurrentSlideIndex + parkingIndex);
+
+            if (displayIndex > _DisplayPieces) {
+                if (index - _CurrentSlideIndex > _SlideCount / 2)
+                    index -= _SlideCount;
+                else if (index - _CurrentSlideIndex <= -_SlideCount / 2)
+                    index += _SlideCount;
+            }
+            else {
+                index = _CurrentSlideIndex + displayIndex - parkingIndex;
+            }
+
+            return index;
+        };
+
+        //member functions
+
+        $JssorObject$.call(this);
+
+        //initialize member variables
+        _SelfSlider.$Elmt = elmt = $Jssor$.$GetElement(elmt);
+        //initialize member variables
+
+        var _InitialScrollWidth;    //for debug only
+        var _CaptionSliderCount = 1;    //for debug only
+
+        $JssorDebug$.$Execute(function () {
+            var outerContainerElmt = $Jssor$.$GetElement(elmt);
+            if (!outerContainerElmt)
+                $JssorDebug$.$Fail("Outer container '" + elmt + "' not found.");
+        });
+
+        var _Options = $Jssor$.$Extend({
+            $FillMode: 0,                   //[Optional] The way to fill image in slide, 0 stretch, 1 contain (keep aspect ratio and put all inside slide), 2 cover (keep aspect ratio and cover whole slide), 4 actual size, 5 contain for large image, actual size for small image, default value is 0
+            $LazyLoading: 1,                //[Optional] For image with  lazy loading format (<IMG src2="url" .../>), by default it will be loaded only when the slide comes.
+            //But an integer value (maybe 0, 1, 2 or 3) indicates that how far of nearby slides should be loaded immediately as well, default value is 1.
+            $StartIndex: 0,                 //[Optional] Index of slide to display when initialize, default value is 0
+            $AutoPlay: false,               //[Optional] Whether to auto play, default value is false
+            $Loop: 1,                       //[Optional] Enable loop(circular) of carousel or not, 0: stop, 1: loop, 2 rewind, default value is 1
+            $HWA: true,                     //[Optional] Enable hardware acceleration or not, default value is true
+            $NaviQuitDrag: true,
+            $AutoPlaySteps: 1,              //[Optional] Steps to go of every play (this options applys only when slideshow disabled), default value is 1
+            $AutoPlayInterval: 3000,        //[Optional] Interval to play next slide since the previous stopped if a slideshow is auto playing, default value is 3000
+            $PauseOnHover: 1,               //[Optional] Whether to pause when mouse over if a slider is auto playing, 0 no pause, 1 pause for desktop, 2 pause for touch device, 3 pause for desktop and touch device, 4 freeze for desktop, 8 freeze for touch device, 12 freeze for desktop and touch device, default value is 1
+
+            $SlideDuration: 500,            //[Optional] Specifies default duration (swipe) for slide in milliseconds, default value is 400
+            $SlideEasing: $JssorEasing$.$EaseOutQuad,   //[Optional] Specifies easing for right to left animation, default value is $JssorEasing$.$EaseOutQuad
+            $MinDragOffsetToSlide: 20,      //[Optional] Minimum drag offset that trigger slide, default value is 20
+            $SlideSpacing: 0, 				//[Optional] Space between each slide in pixels, default value is 0
+            $DisplayPieces: 1,              //[Optional] Number of pieces to display (the slideshow would be disabled if the value is set to greater than 1), default value is 1
+            $ParkingPosition: 0,            //[Optional] The offset position to park slide (this options applys only when slideshow disabled), default value is 0.
+            $UISearchMode: 1,               //[Optional] The way (0 parellel, 1 recursive, default value is recursive) to search UI components (slides container, loading screen, navigator container, arrow navigator container, thumbnail navigator container etc.
+            $PlayOrientation: 1,            //[Optional] Orientation to play slide (for auto play, navigation), 1 horizental, 2 vertical, 5 horizental reverse, 6 vertical reverse, default value is 1
+            $DragOrientation: 1             //[Optional] Orientation to drag slide, 0 no drag, 1 horizental, 2 vertical, 3 both, default value is 1 (Note that the $DragOrientation should be the same as $PlayOrientation when $DisplayPieces is greater than 1, or parking position is not 0)
+
+        }, options);
+
+        //Sodo statement for development time intellisence only
+        $JssorDebug$.$Execute(function () {
+            _Options = $Jssor$.$Extend({
+                $ArrowKeyNavigation: undefined,
+                $SlideWidth: undefined,
+                $SlideHeight: undefined,
+                $SlideshowOptions: undefined,
+                $CaptionSliderOptions: undefined,
+                $BulletNavigatorOptions: undefined,
+                $ArrowNavigatorOptions: undefined,
+                $ThumbnailNavigatorOptions: undefined
+            },
+            _Options);
+        });
+
+        var _PlayOrientation = _Options.$PlayOrientation & 3;
+        var _PlayReverse = (_Options.$PlayOrientation & 4) / -4 || 1;
+
+        var _SlideshowOptions = _Options.$SlideshowOptions;
+        var _CaptionSliderOptions = $Jssor$.$Extend({ $Class: $JssorCaptionSliderBase$, $PlayInMode: 1, $PlayOutMode: 1 }, _Options.$CaptionSliderOptions);
+        $Jssor$.$TranslateTransitions(_CaptionSliderOptions.$CaptionTransitions); //for old transition compatibility
+        var _BulletNavigatorOptions = _Options.$BulletNavigatorOptions;
+        var _ArrowNavigatorOptions = _Options.$ArrowNavigatorOptions;
+        var _ThumbnailNavigatorOptions = _Options.$ThumbnailNavigatorOptions;
+
+        $JssorDebug$.$Execute(function () {
+            if (_SlideshowOptions && !_SlideshowOptions.$Class) {
+                $JssorDebug$.$Fail("Option $SlideshowOptions error, class not specified.");
+            }
+        });
+
+        $JssorDebug$.$Execute(function () {
+            if (_Options.$CaptionSliderOptions && !_Options.$CaptionSliderOptions.$Class) {
+                $JssorDebug$.$Fail("Option $CaptionSliderOptions error, class not specified.");
+            }
+        });
+
+        $JssorDebug$.$Execute(function () {
+            if (_BulletNavigatorOptions && !_BulletNavigatorOptions.$Class) {
+                $JssorDebug$.$Fail("Option $BulletNavigatorOptions error, class not specified.");
+            }
+        });
+
+        $JssorDebug$.$Execute(function () {
+            if (_ArrowNavigatorOptions && !_ArrowNavigatorOptions.$Class) {
+                $JssorDebug$.$Fail("Option $ArrowNavigatorOptions error, class not specified.");
+            }
+        });
+
+        $JssorDebug$.$Execute(function () {
+            if (_ThumbnailNavigatorOptions && !_ThumbnailNavigatorOptions.$Class) {
+                $JssorDebug$.$Fail("Option $ThumbnailNavigatorOptions error, class not specified.");
+            }
+        });
+
+        var _UISearchMode = _Options.$UISearchMode;
+        var _ScaleWrapper;
+        var _SlidesContainer = $Jssor$.$FindFirstChild(elmt, "slides", null, _UISearchMode);
+        var _LoadingContainer = $Jssor$.$FindFirstChild(elmt, "loading", null, _UISearchMode) || $Jssor$.$CreateDiv(document);
+
+        var _BulletNavigatorContainer = $Jssor$.$FindFirstChild(elmt, "navigator", null, _UISearchMode);
+
+        var _ArrowLeft = $Jssor$.$FindFirstChild(elmt, "arrowleft", null, _UISearchMode);
+        var _ArrowRight = $Jssor$.$FindFirstChild(elmt, "arrowright", null, _UISearchMode);
+
+        var _ThumbnailNavigatorContainer = $Jssor$.$FindFirstChild(elmt, "thumbnavigator", null, _UISearchMode);
+
+        $JssorDebug$.$Execute(function () {
+            //if (_BulletNavigatorOptions && !_BulletNavigatorContainer) {
+            //    throw new Error("$BulletNavigatorOptions specified but bullet navigator container (<div u=\"navigator\" ...) not defined.");
+            //}
+            if (_BulletNavigatorContainer && !_BulletNavigatorOptions) {
+                throw new Error("Bullet navigator container defined but $BulletNavigatorOptions not specified.");
+            }
+
+            //if (_ArrowNavigatorOptions) {
+            //    if (!_ArrowLeft) {
+            //        throw new Error("$ArrowNavigatorOptions specified, but arrowleft (<span u=\"arrowleft\" ...) not defined.");
+            //    }
+
+            //    if (!_ArrowRight) {
+            //        throw new Error("$ArrowNavigatorOptions specified, but arrowright (<span u=\"arrowright\" ...) not defined.");
+            //    }
+            //}
+
+            if ((_ArrowLeft || _ArrowRight) && !_ArrowNavigatorOptions) {
+                throw new Error("arrowleft or arrowright defined, but $ArrowNavigatorOptions not specified.");
+            }
+
+            //if (_ThumbnailNavigatorOptions && !_ThumbnailNavigatorContainer) {
+            //    throw new Error("$ThumbnailNavigatorOptions specified, but thumbnail navigator container (<div u=\"thumbnavigator\" ...) not defined.");
+            //}
+
+            if (_ThumbnailNavigatorContainer && !_ThumbnailNavigatorOptions) {
+                throw new Error("Thumbnail navigator container defined, but $ThumbnailNavigatorOptions not specified.");
+            }
+        });
+
+        var _SlidesContainerWidth = $Jssor$.$CssWidth(_SlidesContainer);
+        var _SlidesContainerHeight = $Jssor$.$CssHeight(_SlidesContainer);
+
+        $JssorDebug$.$Execute(function () {
+            if (isNaN(_SlidesContainerWidth))
+                $JssorDebug$.$Fail("Width of slides container wrong specification, it should be specified by inline style in pixels (like style='width: 600px;').");
+
+            if (_SlidesContainerWidth == undefined)
+                $JssorDebug$.$Fail("Width of slides container not specified, it should be specified by inline style in pixels (like style='width: 600px;').");
+
+            if (isNaN(_SlidesContainerHeight))
+                $JssorDebug$.$Fail("Height of slides container wrong specification, it should be specified by inline style in pixels (like style='height: 300px;').");
+
+            if (_SlidesContainerHeight == undefined)
+                $JssorDebug$.$Fail("Height of slides container not specified, it should be specified by inline style in pixels (like style='height: 300px;').");
+
+            var slidesContainerOverflow = $Jssor$.$CssOverflow(_SlidesContainer);
+            var slidesContainerOverflowX = $Jssor$.$Css(_SlidesContainer, "overflowX");
+            var slidesContainerOverflowY = $Jssor$.$Css(_SlidesContainer, "overflowY");
+            if (slidesContainerOverflow != "hidden" && (slidesContainerOverflowX != "hidden" || slidesContainerOverflowY != "hidden"))
+                $JssorDebug$.$Fail("Overflow of slides container wrong specification, it should be specified as 'hidden' (style='overflow:hidden;').");
+
+            //var slidesContainerTop = $Jssor$.$CssTop(_SlidesContainer);
+            //var slidesContainerLeft = $Jssor$.$CssLeft(_SlidesContainer);
+
+            //if (isNaN(slidesContainerTop))
+            //    $JssorDebug$.$Fail("Top of slides container wrong specification, it should be specified by inline style in pixels (like style='top: 0px;').");
+
+            //if (slidesContainerTop == undefined)
+            //    $JssorDebug$.$Fail("Top of slides container not specified, it should be specified by inline style in pixels (like style='top: 0px;').");
+
+            //if (isNaN(slidesContainerLeft))
+            //    $JssorDebug$.$Fail("Left of slides container wrong specification, it should be specified by inline style in pixels (like style='left: 0px;').");
+
+            //if (slidesContainerLeft == undefined)
+            //    $JssorDebug$.$Fail("Left of slides container not specified, it should be specified by inline style in pixels (like style='left: 0px;').");
+        });
+
+        $JssorDebug$.$Execute(function () {
+            if (!$Jssor$.$IsNumeric(_Options.$DisplayPieces))
+                $JssorDebug$.$Fail("Option $DisplayPieces error, it should be a numeric value and greater than or equal to 1.");
+
+            if (_Options.$DisplayPieces < 1)
+                $JssorDebug$.$Fail("Option $DisplayPieces error, it should be greater than or equal to 1.");
+
+            if (_Options.$DisplayPieces > 1 && _Options.$DragOrientation && _Options.$DragOrientation != _PlayOrientation)
+                $JssorDebug$.$Fail("Option $DragOrientation error, it should be 0 or the same of $PlayOrientation when $DisplayPieces is greater than 1.");
+
+            if (!$Jssor$.$IsNumeric(_Options.$ParkingPosition))
+                $JssorDebug$.$Fail("Option $ParkingPosition error, it should be a numeric value.");
+
+            if (_Options.$ParkingPosition && _Options.$DragOrientation && _Options.$DragOrientation != _PlayOrientation)
+                $JssorDebug$.$Fail("Option $DragOrientation error, it should be 0 or the same of $PlayOrientation when $ParkingPosition is not equal to 0.");
+        });
+
+        var _StyleDef;
+
+        var _SlideElmts = [];
+
+        {
+            var slideElmts = $Jssor$.$Children(_SlidesContainer);
+            $Jssor$.$Each(slideElmts, function (slideElmt) {
+                if (slideElmt.tagName == "DIV" && !$Jssor$.$AttributeEx(slideElmt, "u")) {
+                    _SlideElmts.push(slideElmt);
+                }
+            });
+        }
+
+        $JssorDebug$.$Execute(function () {
+            if (_SlideElmts.length < 1) {
+                $JssorDebug$.$Error("Slides html code definition error, there must be at least 1 slide to initialize a slider.");
+            }
+        });
+
+        var _SlideItemCreatedCount = 0; //for debug only
+        var _SlideItemReleasedCount = 0;    //for debug only
+
+        var _PreviousSlideIndex;
+        var _CurrentSlideIndex = -1;
+        var _TempSlideIndex;
+        var _PrevSlideItem;
+        var _CurrentSlideItem;
+        var _SlideCount = _SlideElmts.length;
+
+        var _SlideWidth = _Options.$SlideWidth || _SlidesContainerWidth;
+        var _SlideHeight = _Options.$SlideHeight || _SlidesContainerHeight;
+
+        var _SlideSpacing = _Options.$SlideSpacing;
+        var _StepLengthX = _SlideWidth + _SlideSpacing;
+        var _StepLengthY = _SlideHeight + _SlideSpacing;
+        var _StepLength = (_PlayOrientation & 1) ? _StepLengthX : _StepLengthY;
+        var _DisplayPieces = Math.min(_Options.$DisplayPieces, _SlideCount);
+
+        var _SlideshowPanel;
+        var _CurrentBoardIndex = 0;
+        var _DragOrientation;
+        var _DragOrientationRegistered;
+        var _DragInvalid;
+
+        var _HandleTouchEventOnly;
+
+        var _Navigators = [];
+        var _BulletNavigator;
+        var _ArrowNavigator;
+        var _ThumbnailNavigator;
+
+        var _ShowLink;
+
+        var _Frozen;
+        var _AutoPlay;
+        var _AutoPlaySteps = _Options.$AutoPlaySteps;
+        var _HoverToPause = _Options.$PauseOnHover;
+        var _AutoPlayInterval = _Options.$AutoPlayInterval;
+        var _SlideDuration = _Options.$SlideDuration;
+
+        var _SlideshowRunnerClass;
+        var _TransitionsOrder;
+
+        var _SlideshowEnabled;
+        var _ParkingPosition;
+        var _CarouselEnabled = _DisplayPieces < _SlideCount;
+        var _Loop = _CarouselEnabled ? _Options.$Loop : 0;
+
+        var _DragEnabled;
+        var _LastDragSucceded;
+
+        var _HoverStatus = 1;   //0 Hovering, 1 Not hovering
+
+        //Variable Definition
+        var _IsSliding;
+        var _IsDragging;
+        var _LoadingTicket;
+
+        //The X position of mouse/touch when a drag start
+        var _DragStartMouseX = 0;
+        //The Y position of mouse/touch when a drag start
+        var _DragStartMouseY = 0;
+        var _DragOffsetTotal;
+        var _DragOffsetLastTime;
+        var _DragIndexAdjust;
+
+        var _Carousel;
+        var _Conveyor;
+        var _Slideshow;
+        var _CarouselPlayer;
+        var _SlideContainer = new SlideContainer();
+        var _ScaleRatio;
+
+        //$JssorSlider$ Constructor
+        {
+            _AutoPlay = _Options.$AutoPlay;
+            _SelfSlider.$Options = options;
+
+            AdjustSlidesContainerSize();
+
+            elmt["jssor-slider"] = true;
+
+            //_SlideshowPanel = CreatePanel();
+            //$Jssor$.$CssZIndex(elmt, $Jssor$.$CssZIndex(elmt));
+            //$Jssor$.$CssLeft(_SlideshowPanel, $Jssor$.$CssLeft(_SlidesContainer));
+            //$Jssor$.$CssZIndex(_SlidesContainer, $Jssor$.$CssZIndex(_SlidesContainer));
+            //$Jssor$.$CssTop(_SlideshowPanel, $Jssor$.$CssTop(_SlidesContainer));
+            $Jssor$.$CssZIndex(_SlidesContainer, $Jssor$.$CssZIndex(_SlidesContainer) || 0);
+            $Jssor$.$CssPosition(_SlidesContainer, "absolute");
+            _SlideshowPanel = $Jssor$.$CloneNode(_SlidesContainer);
+            $Jssor$.$InsertBefore($Jssor$.$ParentNode(_SlidesContainer), _SlideshowPanel, _SlidesContainer);
+
+            if (_SlideshowOptions) {
+                _ShowLink = _SlideshowOptions.$ShowLink;
+                _SlideshowRunnerClass = _SlideshowOptions.$Class;
+
+                $JssorDebug$.$Execute(function () {
+                    if (!_SlideshowOptions.$Transitions || !_SlideshowOptions.$Transitions.length) {
+                        $JssorDebug$.$Error("Invalid '$SlideshowOptions', no '$Transitions' specified.");
+                    }
+                });
+
+                $Jssor$.$TranslateTransitions(_SlideshowOptions.$Transitions); //for old transition compatibility
+
+                _SlideshowEnabled = _DisplayPieces == 1 && _SlideCount > 1 && _SlideshowRunnerClass && (!$Jssor$.$IsBrowserIE() || $Jssor$.$BrowserVersion() >= 8);
+            }
+
+            _ParkingPosition = (_SlideshowEnabled || _DisplayPieces >= _SlideCount || !(_Loop & 1)) ? 0 : _Options.$ParkingPosition;
+
+            _DragEnabled = ((_DisplayPieces > 1 || _ParkingPosition) ? _PlayOrientation : -1) & _Options.$DragOrientation;
+
+            //SlideBoard
+            var _SlideboardElmt = _SlidesContainer;
+            var _SlideItems = [];
+
+            var _SlideshowRunner;
+            var _LinkContainer;
+
+            var _DownEvent = "mousedown";
+            var _MoveEvent = "mousemove";
+            var _UpEvent = "mouseup";
+            var _CancelEvent;
+
+            var _LastTimeMoveByDrag;
+            var _Position_OnFreeze;
+            var _CarouselPlaying_OnFreeze;
+            var _PlayToPosition_OnFreeze;
+            var _PositionToGoByDrag;
+
+            //SlideBoard Constructor
+            {
+                var msPrefix;
+                if (window.navigator.pointerEnabled || (msPrefix = window.navigator.msPointerEnabled)) {
+
+                    _DownEvent = msPrefix ? "MSPointerDown" : "pointerdown";
+                    _MoveEvent = msPrefix ? "MSPointerMove" : "pointermove";
+                    _UpEvent = msPrefix ? "MSPointerUp" : "pointerup";
+                    _CancelEvent = msPrefix ? "MSPointerCancel" : "pointercancel";
+
+                    if (_DragEnabled) {
+                        var touchAction = "none";
+                        if (_DragEnabled == 1) {
+                            touchAction = "pan-y";
+                        }
+                        else if (_DragEnabled == 2) {
+                            touchAction = "pan-x";
+                        }
+
+                        $Jssor$.$Css(_SlideboardElmt, msPrefix ? "msTouchAction" : "touchAction", touchAction);
+                    }
+                }
+                else if ("ontouchstart" in window || "createTouch" in document) {
+                    _HandleTouchEventOnly = true;
+
+                    _DownEvent = "touchstart";
+                    _MoveEvent = "touchmove";
+                    _UpEvent = "touchend";
+                    _CancelEvent = "touchcancel";
+                }
+
+                _Slideshow = new Slideshow();
+
+                if (_SlideshowEnabled)
+                    _SlideshowRunner = new _SlideshowRunnerClass(_SlideContainer, _SlideWidth, _SlideHeight, _SlideshowOptions, _HandleTouchEventOnly);
+
+                $Jssor$.$AppendChild(_SlideshowPanel, _Slideshow.$Wrapper);
+                $Jssor$.$CssOverflow(_SlidesContainer, "hidden");
+
+                //link container
+                {
+                    _LinkContainer = CreatePanel();
+                    $Jssor$.$Css(_LinkContainer, "backgroundColor", "#000");
+                    $Jssor$.$CssOpacity(_LinkContainer, 0);
+                    $Jssor$.$InsertBefore(_SlideboardElmt, _LinkContainer, _SlideboardElmt.firstChild);
+                }
+
+                for (var i = 0; i < _SlideElmts.length; i++) {
+                    var slideElmt = _SlideElmts[i];
+                    var slideItem = new SlideItem(slideElmt, i);
+                    _SlideItems.push(slideItem);
+                }
+
+                $Jssor$.$HideElement(_LoadingContainer);
+
+                $JssorDebug$.$Execute(function () {
+                    $Jssor$.$Attribute(_LoadingContainer, "debug-id", "loading-container");
+                });
+
+                _Carousel = new Carousel()
+                _CarouselPlayer = new CarouselPlayer(_Carousel, _Slideshow);
+
+                $JssorDebug$.$Execute(function () {
+                    $Jssor$.$Attribute(_SlideboardElmt, "debug-id", "slide-board");
+                });
+
+                if (_DragEnabled) {
+                    $Jssor$.$AddEvent(_SlidesContainer, _DownEvent, OnMouseDown);
+                    $Jssor$.$AddEvent(document, _UpEvent, OnDragEnd);
+                    _CancelEvent && $Jssor$.$AddEvent(document, _CancelEvent, OnDragEnd);
+                }
+            }
+            //SlideBoard
+
+            _HoverToPause &= (_HandleTouchEventOnly ? 10 : 5);
+
+            //Bullet Navigator
+            if (_BulletNavigatorContainer && _BulletNavigatorOptions) {
+                _BulletNavigator = new _BulletNavigatorOptions.$Class(_BulletNavigatorContainer, _BulletNavigatorOptions, OriginalWidth(), OriginalHeight());
+                _Navigators.push(_BulletNavigator);
+            }
+
+            //Arrow Navigator
+            if (_ArrowNavigatorOptions && _ArrowLeft && _ArrowRight) {
+                _ArrowNavigator = new _ArrowNavigatorOptions.$Class(_ArrowLeft, _ArrowRight, _ArrowNavigatorOptions, OriginalWidth(), OriginalHeight());
+                _Navigators.push(_ArrowNavigator);
+            }
+
+            //Thumbnail Navigator
+            if (_ThumbnailNavigatorContainer && _ThumbnailNavigatorOptions) {
+                _ThumbnailNavigatorOptions.$StartIndex = _Options.$StartIndex;
+                _ThumbnailNavigator = new _ThumbnailNavigatorOptions.$Class(_ThumbnailNavigatorContainer, _ThumbnailNavigatorOptions);
+                _Navigators.push(_ThumbnailNavigator);
+            }
+
+            $Jssor$.$Each(_Navigators, function (navigator) {
+                navigator.$Reset(_SlideCount, _SlideItems, _LoadingContainer);
+                navigator.$On($JssorNavigatorEvents$.$NAVIGATIONREQUEST, NavigationClickHandler);
+            });
+
+            Scale(OriginalWidth());
+
+            $Jssor$.$AddEvent(elmt, "mouseout", $Jssor$.$MouseOverOutFilter(MainContainerMouseLeaveEventHandler, elmt));
+            $Jssor$.$AddEvent(elmt, "mouseover", $Jssor$.$MouseOverOutFilter(MainContainerMouseEnterEventHandler, elmt));
+
+            ShowNavigators();
+
+            //Keyboard Navigation
+            if (_Options.$ArrowKeyNavigation) {
+                $Jssor$.$AddEvent(document, "keydown", function (e) {
+                    if (e.keyCode == $JssorKeyCode$.$LEFT) {
+                        //Arrow Left
+                        PlayToOffset(-1);
+                    }
+                    else if (e.keyCode == $JssorKeyCode$.$RIGHT) {
+                        //Arrow Right
+                        PlayToOffset(1);
+                    }
+                });
+            }
+
+            var startPosition = _Options.$StartIndex;
+            if (!(_Loop & 1)) {
+                startPosition = Math.max(0, Math.min(startPosition, _SlideCount - _DisplayPieces));
+            }
+            _CarouselPlayer.$PlayCarousel(startPosition, startPosition, 0);
+        }
+    }
+    //Jssor Slider
+
+    //JssorSlider.$ASSEMBLY_BOTTOM_LEFT = ASSEMBLY_BOTTOM_LEFT;
+    //JssorSlider.$ASSEMBLY_BOTTOM_RIGHT = ASSEMBLY_BOTTOM_RIGHT;
+    //JssorSlider.$ASSEMBLY_TOP_LEFT = ASSEMBLY_TOP_LEFT;
+    //JssorSlider.$ASSEMBLY_TOP_RIGHT = ASSEMBLY_TOP_RIGHT;
+    //JssorSlider.$ASSEMBLY_LEFT_TOP = ASSEMBLY_LEFT_TOP;
+    //JssorSlider.$ASSEMBLY_LEFT_BOTTOM = ASSEMBLY_LEFT_BOTTOM;
+    //JssorSlider.$ASSEMBLY_RIGHT_TOP = ASSEMBLY_RIGHT_TOP;
+    //JssorSlider.$ASSEMBLY_RIGHT_BOTTOM = ASSEMBLY_RIGHT_BOTTOM;
+
+    JssorSlider.$EVT_CLICK = 21;
+    JssorSlider.$EVT_DRAG_START = 22;
+    JssorSlider.$EVT_DRAG_END = 23;
+    JssorSlider.$EVT_SWIPE_START = 24;
+    JssorSlider.$EVT_SWIPE_END = 25;
+
+    JssorSlider.$EVT_LOAD_START = 26;
+    JssorSlider.$EVT_LOAD_END = 27;
+    JssorSlider.$EVT_FREEZE = 28;
+
+    JssorSlider.$EVT_POSITION_CHANGE = 202;
+    JssorSlider.$EVT_PARK = 203;
+
+    JssorSlider.$EVT_SLIDESHOW_START = 206;
+    JssorSlider.$EVT_SLIDESHOW_END = 207;
+
+    JssorSlider.$EVT_PROGRESS_CHANGE = 208;
+    JssorSlider.$EVT_STATE_CHANGE = 209;
+    JssorSlider.$EVT_ROLLBACK_START = 210;
+    JssorSlider.$EVT_ROLLBACK_END = 211;
+
+    window.$JssorSlider$ = $JssorSlider$ = JssorSlider;
+
+    //(function ($) {
+    //    jQuery.fn.jssorSlider = function (options) {
+    //        return this.each(function () {
+    //            return $(this).data('jssorSlider') || $(this).data('jssorSlider', new JssorSlider(this, options));
+    //        });
+    //    };
+    //})(jQuery);
+
+    //window.jQuery && (jQuery.fn.jssorSlider = function (options) {
+    //    return this.each(function () {
+    //        return jQuery(this).data('jssorSlider') || jQuery(this).data('jssorSlider', new JssorSlider(this, options));
+    //    });
+    //});
+};
+
+//$JssorBulletNavigator$
+var $JssorNavigatorEvents$ = {
+    $NAVIGATIONREQUEST: 1,
+    $INDEXCHANGE: 2,
+    $RESET: 3
+};
+
+var $JssorBulletNavigator$ = window.$JssorBulletNavigator$ = function (elmt, options, containerWidth, containerHeight) {
+    var self = this;
+    $JssorObject$.call(self);
+
+    elmt = $Jssor$.$GetElement(elmt);
+
+    var _Count;
+    var _Length;
+    var _Width;
+    var _Height;
+    var _CurrentIndex;
+    var _CurrentInnerIndex = 0;
+    var _Options;
+    var _Steps;
+    var _Lanes;
+    var _SpacingX;
+    var _SpacingY;
+    var _Orientation;
+    var _ItemPrototype;
+    var _PrototypeWidth;
+    var _PrototypeHeight;
+
+    var _ButtonElements = [];
+    var _Buttons = [];
+
+    function Highlight(index) {
+        if (index != -1)
+            _Buttons[index].$Activate(index == _CurrentInnerIndex);
+    }
+
+    function OnNavigationRequest(index) {
+        self.$TriggerEvent($JssorNavigatorEvents$.$NAVIGATIONREQUEST, index * _Steps);
+    }
+
+    self.$Elmt = elmt;
+    self.$GetCurrentIndex = function () {
+        return _CurrentIndex;
+    };
+
+    self.$SetCurrentIndex = function (index) {
+        if (index != _CurrentIndex) {
+            var lastInnerIndex = _CurrentInnerIndex;
+            var innerIndex = Math.floor(index / _Steps);
+            _CurrentInnerIndex = innerIndex;
+            _CurrentIndex = index;
+
+            Highlight(lastInnerIndex);
+            Highlight(innerIndex);
+
+            //self.$TriggerEvent($JssorNavigatorEvents$.$INDEXCHANGE, index);
+        }
+    };
+
+    self.$Show = function (show) {
+        $Jssor$.$ShowElement(elmt, show);
+    };
+
+    var _Located;
+    self.$Relocate = function (force) {
+        if (!_Located || _Options.$Scale == false) {
+            if (_Options.$AutoCenter & 1) {
+                $Jssor$.$CssLeft(elmt, (containerWidth - _Width) / 2);
+            }
+            if (_Options.$AutoCenter & 2) {
+                $Jssor$.$CssTop(elmt, (containerHeight - _Height) / 2);
+            }
+
+            _Located = true;
+        }
+    };
+
+    var _Initialized;
+    self.$Reset = function (length) {
+        if (!_Initialized) {
+            _Length = length;
+            _Count = Math.ceil(length / _Steps);
+            _CurrentInnerIndex = 0;
+
+            var itemOffsetX = _PrototypeWidth + _SpacingX;
+            var itemOffsetY = _PrototypeHeight + _SpacingY;
+
+            var maxIndex = Math.ceil(_Count / _Lanes) - 1;
+
+            _Width = _PrototypeWidth + itemOffsetX * (!_Orientation ? maxIndex : _Lanes - 1);
+            _Height = _PrototypeHeight + itemOffsetY * (_Orientation ? maxIndex : _Lanes - 1);
+
+            $Jssor$.$CssWidth(elmt, _Width);
+            $Jssor$.$CssHeight(elmt, _Height);
+
+            //self.$Relocate(true);
+
+            for (var buttonIndex = 0; buttonIndex < _Count; buttonIndex++) {
+
+                var numberDiv = $Jssor$.$CreateSpan();
+                $Jssor$.$InnerText(numberDiv, buttonIndex + 1);
+
+                var div = $Jssor$.$BuildElement(_ItemPrototype, "NumberTemplate", numberDiv, true);
+                $Jssor$.$CssPosition(div, "absolute");
+
+                var columnIndex = buttonIndex % (maxIndex + 1);
+                $Jssor$.$CssLeft(div, !_Orientation ? itemOffsetX * columnIndex : buttonIndex % _Lanes * itemOffsetX);
+                $Jssor$.$CssTop(div, _Orientation ? itemOffsetY * columnIndex : Math.floor(buttonIndex / (maxIndex + 1)) * itemOffsetY);
+
+                $Jssor$.$AppendChild(elmt, div);
+                _ButtonElements[buttonIndex] = div;
+
+                if (_Options.$ActionMode & 1)
+                    $Jssor$.$AddEvent(div, "click", $Jssor$.$CreateCallback(null, OnNavigationRequest, buttonIndex));
+
+                if (_Options.$ActionMode & 2)
+                    $Jssor$.$AddEvent(div, "mouseover", $Jssor$.$MouseOverOutFilter($Jssor$.$CreateCallback(null, OnNavigationRequest, buttonIndex), div));
+
+                _Buttons[buttonIndex] = $Jssor$.$Buttonize(div);
+            }
+
+            //self.$TriggerEvent($JssorNavigatorEvents$.$RESET);
+            _Initialized = true;
+        }
+    };
+
+    //JssorBulletNavigator Constructor
+    {
+        self.$Options = _Options = $Jssor$.$Extend({
+            $SpacingX: 0,
+            $SpacingY: 0,
+            $Orientation: 1,
+            $ActionMode: 1
+        }, options);
+
+        //Sodo statement for development time intellisence only
+        $JssorDebug$.$Execute(function () {
+            _Options = $Jssor$.$Extend({
+                $Steps: undefined,
+                $Lanes: undefined
+            }, _Options);
+        });
+
+        _ItemPrototype = $Jssor$.$FindFirstChild(elmt, "prototype");
+
+        $JssorDebug$.$Execute(function () {
+            if (!_ItemPrototype)
+                $JssorDebug$.$Fail("Navigator item prototype not defined.");
+
+            if (isNaN($Jssor$.$CssWidth(_ItemPrototype))) {
+                $JssorDebug$.$Fail("Width of 'navigator item prototype' not specified.");
+            }
+
+            if (isNaN($Jssor$.$CssHeight(_ItemPrototype))) {
+                $JssorDebug$.$Fail("Height of 'navigator item prototype' not specified.");
+            }
+        });
+
+        _PrototypeWidth = $Jssor$.$CssWidth(_ItemPrototype);
+        _PrototypeHeight = $Jssor$.$CssHeight(_ItemPrototype);
+
+        $Jssor$.$RemoveChild(elmt, _ItemPrototype);
+
+        _Steps = _Options.$Steps || 1;
+        _Lanes = _Options.$Lanes || 1;
+        _SpacingX = _Options.$SpacingX;
+        _SpacingY = _Options.$SpacingY;
+        _Orientation = _Options.$Orientation - 1;
+    }
+};
+
+var $JssorArrowNavigator$ = window.$JssorArrowNavigator$ = function (arrowLeft, arrowRight, options, containerWidth, containerHeight) {
+    var self = this;
+    $JssorObject$.call(self);
+
+    $JssorDebug$.$Execute(function () {
+        //var arrowLeft = $Jssor$.$FindFirstChild(elmt, "arrowleft", null, uiSearchMode);
+        //var arrowRight = $Jssor$.$FindFirstChild(elmt, "arrowright", null, uiSearchMode);
+
+        if (!arrowLeft)
+            $JssorDebug$.$Fail("Option '$ArrowNavigatorOptions' spepcified, but UI 'arrowleft' not defined. Define 'arrowleft' to enable direct navigation, or remove option '$ArrowNavigatorOptions' to disable direct navigation.");
+
+        if (!arrowRight)
+            $JssorDebug$.$Fail("Option '$ArrowNavigatorOptions' spepcified, but UI 'arrowright' not defined. Define 'arrowright' to enable direct navigation, or remove option '$ArrowNavigatorOptions' to disable direct navigation.");
+
+        if (isNaN($Jssor$.$CssWidth(arrowLeft))) {
+            $JssorDebug$.$Fail("Width of 'arrow left' not specified.");
+        }
+
+        if (isNaN($Jssor$.$CssWidth(arrowRight))) {
+            $JssorDebug$.$Fail("Width of 'arrow right' not specified.");
+        }
+
+        if (isNaN($Jssor$.$CssHeight(arrowLeft))) {
+            $JssorDebug$.$Fail("Height of 'arrow left' not specified.");
+        }
+
+        if (isNaN($Jssor$.$CssHeight(arrowRight))) {
+            $JssorDebug$.$Fail("Height of 'arrow right' not specified.");
+        }
+    });
+
+    //var arrowLeft = $Jssor$.$FindFirstChild(elmt, "arrowleft", null, uiSearchMode);
+    //var arrowRight = $Jssor$.$FindFirstChild(elmt, "arrowright", null, uiSearchMode);
+    var _Length;
+    var _CurrentIndex;
+    var _Options;
+    var _Steps;
+    var _ArrowWidth = $Jssor$.$CssWidth(arrowLeft);
+    var _ArrowHeight = $Jssor$.$CssHeight(arrowLeft);
+
+    function OnNavigationRequest(steps) {
+        self.$TriggerEvent($JssorNavigatorEvents$.$NAVIGATIONREQUEST, steps, true);
+    }
+
+    self.$GetCurrentIndex = function () {
+        return _CurrentIndex;
+    };
+
+    self.$SetCurrentIndex = function (index, virtualIndex, temp) {
+        if (temp) {
+            _CurrentIndex = virtualIndex;
+        }
+        else {
+            _CurrentIndex = index;
+        }
+        //self.$TriggerEvent($JssorNavigatorEvents$.$INDEXCHANGE, index);
+    };
+
+    self.$Show = function (show) {
+        $Jssor$.$ShowElement(arrowLeft, show);
+        $Jssor$.$ShowElement(arrowRight, show);
+    };
+
+    var _Located;
+    self.$Relocate = function (force) {
+        if (!_Located || _Options.$Scale == false) {
+
+            if (_Options.$AutoCenter & 1) {
+                $Jssor$.$CssLeft(arrowLeft, (containerWidth - _ArrowWidth) / 2);
+                $Jssor$.$CssLeft(arrowRight, (containerWidth - _ArrowWidth) / 2);
+            }
+
+            if (_Options.$AutoCenter & 2) {
+                $Jssor$.$CssTop(arrowLeft, (containerHeight - _ArrowHeight) / 2);
+                $Jssor$.$CssTop(arrowRight, (containerHeight - _ArrowHeight) / 2);
+            }
+
+            _Located = true;
+        }
+    };
+
+    var _Initialized;
+    self.$Reset = function (length) {
+        _Length = length;
+        _CurrentIndex = 0;
+
+        if (!_Initialized) {
+
+            //self.$Relocate(true);
+
+            $Jssor$.$AddEvent(arrowLeft, "click", $Jssor$.$CreateCallback(null, OnNavigationRequest, -_Steps));
+            $Jssor$.$AddEvent(arrowRight, "click", $Jssor$.$CreateCallback(null, OnNavigationRequest, _Steps));
+
+            $Jssor$.$Buttonize(arrowLeft);
+            $Jssor$.$Buttonize(arrowRight);
+
+            _Initialized = true;
+        }
+
+        //self.$TriggerEvent($JssorNavigatorEvents$.$RESET);
+    };
+
+    //JssorArrowNavigator Constructor
+    {
+        self.$Options = _Options = $Jssor$.$Extend({
+            $Steps: 1
+        }, options);
+
+        _Steps = _Options.$Steps;
+    }
+};
+
+//$JssorThumbnailNavigator$
+var $JssorThumbnailNavigator$ = window.$JssorThumbnailNavigator$ = function (elmt, options) {
+    var _Self = this;
+    var _Length;
+    var _Count;
+    var _CurrentIndex;
+    var _Options;
+    var _NavigationItems = [];
+
+    var _Width;
+    var _Height;
+    var _Lanes;
+    var _SpacingX;
+    var _SpacingY;
+    var _PrototypeWidth;
+    var _PrototypeHeight;
+    var _DisplayPieces;
+
+    var _Slider;
+    var _CurrentMouseOverIndex = -1;
+
+    var _SlidesContainer;
+    var _ThumbnailPrototype;
+
+    $JssorObject$.call(_Self);
+    elmt = $Jssor$.$GetElement(elmt);
+
+    function NavigationItem(item, index) {
+        var self = this;
+        var _Wrapper;
+        var _Button;
+        var _Thumbnail;
+
+        function Highlight(mouseStatus) {
+            _Button.$Activate(_CurrentIndex == index);
+        }
+
+        function OnNavigationRequest(event) {
+            if (!_Slider.$LastDragSucceded()) {
+                var tail = _Lanes - index % _Lanes;
+                var slideVirtualIndex = _Slider.$GetVirtualIndex((index + tail) / _Lanes - 1);
+                var itemVirtualIndex = slideVirtualIndex * _Lanes + _Lanes - tail;
+                _Self.$TriggerEvent($JssorNavigatorEvents$.$NAVIGATIONREQUEST, itemVirtualIndex);
+            }
+
+            //$JssorDebug$.$Log("navigation request");
+        }
+
+        $JssorDebug$.$Execute(function () {
+            self.$Wrapper = undefined;
+        });
+
+        self.$Index = index;
+
+        self.$Highlight = Highlight;
+
+        //NavigationItem Constructor
+        {
+            _Thumbnail = item.$Thumb || item.$Image || $Jssor$.$CreateDiv();
+            self.$Wrapper = _Wrapper = $Jssor$.$BuildElement(_ThumbnailPrototype, "ThumbnailTemplate", _Thumbnail, true);
+
+            _Button = $Jssor$.$Buttonize(_Wrapper);
+            if (_Options.$ActionMode & 1)
+                $Jssor$.$AddEvent(_Wrapper, "click", OnNavigationRequest);
+            if (_Options.$ActionMode & 2)
+                $Jssor$.$AddEvent(_Wrapper, "mouseover", $Jssor$.$MouseOverOutFilter(OnNavigationRequest, _Wrapper));
+        }
+    }
+
+    _Self.$GetCurrentIndex = function () {
+        return _CurrentIndex;
+    };
+
+    _Self.$SetCurrentIndex = function (index, virtualIndex, temp) {
+        var oldIndex = _CurrentIndex;
+        _CurrentIndex = index;
+        if (oldIndex != -1)
+            _NavigationItems[oldIndex].$Highlight();
+        _NavigationItems[index].$Highlight();
+
+        if (!temp) {
+            _Slider.$PlayTo(_Slider.$GetVirtualIndex(Math.floor(virtualIndex / _Lanes)));
+        }
+    };
+
+    _Self.$Show = function (show) {
+        $Jssor$.$ShowElement(elmt, show);
+    };
+
+    _Self.$Relocate = $Jssor$.$EmptyFunction;
+
+    var _Initialized;
+    _Self.$Reset = function (length, items, loadingContainer) {
+        if (!_Initialized) {
+            _Length = length;
+            _Count = Math.ceil(_Length / _Lanes);
+            _CurrentIndex = -1;
+            _DisplayPieces = Math.min(_DisplayPieces, items.length);
+
+            var horizontal = _Options.$Orientation & 1;
+
+            var slideWidth = _PrototypeWidth + (_PrototypeWidth + _SpacingX) * (_Lanes - 1) * (1 - horizontal);
+            var slideHeight = _PrototypeHeight + (_PrototypeHeight + _SpacingY) * (_Lanes - 1) * horizontal;
+
+            var slidesContainerWidth = slideWidth + (slideWidth + _SpacingX) * (_DisplayPieces - 1) * horizontal;
+            var slidesContainerHeight = slideHeight + (slideHeight + _SpacingY) * (_DisplayPieces - 1) * (1 - horizontal);
+
+            $Jssor$.$CssPosition(_SlidesContainer, "absolute");
+            $Jssor$.$CssOverflow(_SlidesContainer, "hidden");
+            if (_Options.$AutoCenter & 1) {
+                $Jssor$.$CssLeft(_SlidesContainer, (_Width - slidesContainerWidth) / 2);
+            }
+            if (_Options.$AutoCenter & 2) {
+                $Jssor$.$CssTop(_SlidesContainer, (_Height - slidesContainerHeight) / 2);
+            }
+            //$JssorDebug$.$Execute(function () {
+            //    if (!_Options.$AutoCenter) {
+            //        var slidesContainerTop = $Jssor$.$CssTop(_SlidesContainer);
+            //        var slidesContainerLeft = $Jssor$.$CssLeft(_SlidesContainer);
+
+            //        if (isNaN(slidesContainerTop)) {
+            //            $JssorDebug$.$Fail("Position 'top' wrong specification of thumbnail navigator slides container (<div u=\"thumbnavigator\">...<div u=\"slides\">), \r\nwhen option $ThumbnailNavigatorOptions.$AutoCenter set to 0, it should be specified by inline style in pixels (like <div u=\"slides\" style=\"top: 0px;\">)");
+            //        }
+
+            //        if (isNaN(slidesContainerLeft)) {
+            //            $JssorDebug$.$Fail("Position 'left' wrong specification of thumbnail navigator slides container (<div u=\"thumbnavigator\">...<div u=\"slides\">), \r\nwhen option $ThumbnailNavigatorOptions.$AutoCenter set to 0, it should be specified by inline style in pixels (like <div u=\"slides\" style=\"left: 0px;\">)");
+            //        }
+            //    }
+            //});
+            $Jssor$.$CssWidth(_SlidesContainer, slidesContainerWidth);
+            $Jssor$.$CssHeight(_SlidesContainer, slidesContainerHeight);
+
+            var slideItemElmts = [];
+            $Jssor$.$Each(items, function (item, index) {
+                var navigationItem = new NavigationItem(item, index);
+                var navigationItemWrapper = navigationItem.$Wrapper;
+
+                var columnIndex = Math.floor(index / _Lanes);
+                var laneIndex = index % _Lanes;
+
+                $Jssor$.$CssLeft(navigationItemWrapper, (_PrototypeWidth + _SpacingX) * laneIndex * (1 - horizontal));
+                $Jssor$.$CssTop(navigationItemWrapper, (_PrototypeHeight + _SpacingY) * laneIndex * horizontal);
+
+                if (!slideItemElmts[columnIndex]) {
+                    slideItemElmts[columnIndex] = $Jssor$.$CreateDiv();
+                    $Jssor$.$AppendChild(_SlidesContainer, slideItemElmts[columnIndex]);
+                }
+
+                $Jssor$.$AppendChild(slideItemElmts[columnIndex], navigationItemWrapper);
+
+                _NavigationItems.push(navigationItem);
+            });
+
+            var thumbnailSliderOptions = $Jssor$.$Extend({
+                $AutoPlay: false,
+                $NaviQuitDrag: false,
+                $SlideWidth: slideWidth,
+                $SlideHeight: slideHeight,
+                $SlideSpacing: _SpacingX * horizontal + _SpacingY * (1 - horizontal),
+                $MinDragOffsetToSlide: 12,
+                $SlideDuration: 200,
+                $PauseOnHover: 1,
+                $PlayOrientation: _Options.$Orientation,
+                $DragOrientation: _Options.$DisableDrag ? 0 : _Options.$Orientation
+            }, _Options);
+
+            _Slider = new $JssorSlider$(elmt, thumbnailSliderOptions);
+
+            _Initialized = true;
+        }
+
+        //_Self.$TriggerEvent($JssorNavigatorEvents$.$RESET);
+    };
+
+    //JssorThumbnailNavigator Constructor
+    {
+        _Self.$Options = _Options = $Jssor$.$Extend({
+            $SpacingX: 3,
+            $SpacingY: 3,
+            $DisplayPieces: 1,
+            $Orientation: 1,
+            $AutoCenter: 3,
+            $ActionMode: 1
+        }, options);
+
+        //Sodo statement for development time intellisence only
+        $JssorDebug$.$Execute(function () {
+            _Options = $Jssor$.$Extend({
+                $Lanes: undefined,
+                $Width: undefined,
+                $Height: undefined
+            }, _Options);
+        });
+
+        _Width = $Jssor$.$CssWidth(elmt);
+        _Height = $Jssor$.$CssHeight(elmt);
+
+        $JssorDebug$.$Execute(function () {
+            if (!_Width)
+                $JssorDebug$.$Fail("width of 'thumbnavigator' container not specified.");
+            if (!_Height)
+                $JssorDebug$.$Fail("height of 'thumbnavigator' container not specified.");
+        });
+
+        _SlidesContainer = $Jssor$.$FindFirstChild(elmt, "slides");
+        _ThumbnailPrototype = $Jssor$.$FindFirstChild(_SlidesContainer, "prototype");
+
+        $JssorDebug$.$Execute(function () {
+            if (!_ThumbnailPrototype)
+                $JssorDebug$.$Fail("prototype of 'thumbnavigator' not defined.");
+        });
+
+        _PrototypeWidth = $Jssor$.$CssWidth(_ThumbnailPrototype);
+        _PrototypeHeight = $Jssor$.$CssHeight(_ThumbnailPrototype);
+
+        $Jssor$.$RemoveChild(_SlidesContainer, _ThumbnailPrototype);
+
+        _Lanes = _Options.$Lanes || 1;
+        _SpacingX = _Options.$SpacingX;
+        _SpacingY = _Options.$SpacingY;
+        _DisplayPieces = _Options.$DisplayPieces;
+    }
+};
+
+//$JssorCaptionSlider$
+function $JssorCaptionSliderBase$() {
+    $JssorAnimator$.call(this, 0, 0);
+    this.$Revert = $Jssor$.$EmptyFunction;
+}
+
+var $JssorCaptionSlider$ = window.$JssorCaptionSlider$ = function (container, captionSlideOptions, playIn) {
+    $JssorDebug$.$Execute(function () {
+        if (!captionSlideOptions.$CaptionTransitions) {
+            $JssorDebug$.$Error("'$CaptionSliderOptions' option error, '$CaptionSliderOptions.$CaptionTransitions' not specified.");
+        }
+        //else if (!$Jssor$.$IsArray(captionSlideOptions.$CaptionTransitions)) {
+        //    $JssorDebug$.$Error("'$CaptionSliderOptions' option error, '$CaptionSliderOptions.$CaptionTransitions' is not an array.");
+        //}
+    });
+
+    var _Self = this;
+    var _ImmediateOutCaptionHanger;
+    var _PlayMode = playIn ? captionSlideOptions.$PlayInMode : captionSlideOptions.$PlayOutMode;
+
+    var _CaptionTransitions = captionSlideOptions.$CaptionTransitions;
+    var _CaptionTuningFetcher = { $Transition: "t", $Delay: "d", $Duration: "du", x: "x", y: "y", $Rotate: "r", $Zoom: "z", $Opacity: "f", $BeginTime: "b" };
+    var _CaptionTuningTransfer = {
+        $Default: function (value, tuningValue) {
+            if (!isNaN(tuningValue.$Value))
+                value = tuningValue.$Value;
+            else
+                value *= tuningValue.$Percent;
+
+            return value;
+        },
+        $Opacity: function (value, tuningValue) {
+            return this.$Default(value - 1, tuningValue);
+        }
+    };
+    _CaptionTuningTransfer.$Zoom = _CaptionTuningTransfer.$Opacity;
+
+    $JssorAnimator$.call(_Self, 0, 0);
+
+    function GetCaptionItems(element, level) {
+
+        var itemsToPlay = [];
+        var lastTransitionName;
+        var namedTransitions = [];
+        var namedTransitionOrders = [];
+
+        //$JssorDebug$.$Execute(function () {
+
+        //    var debugInfoElement = $Jssor$.$GetElement("debugInfo");
+
+        //    if (debugInfoElement && playIn) {
+
+        //        var text = $Jssor.$InnerHtml(debugInfoElement) + "<br>";
+
+        //        $Jssor$.$InnerHtml(debugInfoElement, text);
+        //    }
+        //});
+
+        function FetchRawTransition(captionElmt, index) {
+            var rawTransition = {};
+
+            $Jssor$.$Each(_CaptionTuningFetcher, function (fetchAttribute, fetchProperty) {
+                var attributeValue = $Jssor$.$AttributeEx(captionElmt, fetchAttribute + (index || ""));
+                if (attributeValue) {
+                    var propertyValue = {};
+
+                    if (fetchAttribute == "t") {
+                        //if (($Jssor$.$IsBrowserChrome() || $Jssor$.$IsBrowserSafari() || $Jssor$.$IsBrowserFireFox()) && attributeValue == "*") {
+                        //    attributeValue = Math.floor(Math.random() * captionSlideOptions.$CaptionTransitions.length);
+                        //    $Jssor$.$Attribute(captionElmt, fetchAttribute + (index || ""), attributeValue);
+                        //}
+
+                        propertyValue.$Value = attributeValue;
+                    }
+                    else if (attributeValue.indexOf("%") + 1)
+                        propertyValue.$Percent = $Jssor$.$ParseFloat(attributeValue) / 100;
+                    else
+                        propertyValue.$Value = $Jssor$.$ParseFloat(attributeValue);
+
+                    rawTransition[fetchProperty] = propertyValue;
+                }
+            });
+
+            return rawTransition;
+        }
+
+        function GetRandomTransition() {
+            //return _CaptionTransitions.length && _CaptionTransitions[Math.floor(Math.random() * 42737 / (i + 1)) % _CaptionTransitions.length];
+            return _CaptionTransitions[Math.floor(Math.random() * _CaptionTransitions.length)];
+        }
+
+        function EvaluateCaptionTransition(transitionName) {
+
+            var transition;
+
+            if (transitionName == "*") {
+                transition = GetRandomTransition();
+            }
+            else if (transitionName) {
+
+                //indexed transition allowed, just the same as named transition
+                var tempTransition = _CaptionTransitions[$Jssor$.$ParseInt(transitionName)] || _CaptionTransitions[transitionName];
+
+                if ($Jssor$.$IsArray(tempTransition)) {
+                    if (transitionName != lastTransitionName) {
+                        lastTransitionName = transitionName;
+                        namedTransitionOrders[transitionName] = 0;
+
+                        namedTransitions[transitionName] = tempTransition[Math.floor(Math.random() * tempTransition.length)];
+                    }
+                    else {
+                        namedTransitionOrders[transitionName]++;
+                    }
+
+                    tempTransition = namedTransitions[transitionName];
+
+                    if ($Jssor$.$IsArray(tempTransition)) {
+                        tempTransition = tempTransition.length && tempTransition[namedTransitionOrders[transitionName] % tempTransition.length];
+
+                        if ($Jssor$.$IsArray(tempTransition)) {
+                            //got transition from array level 3, random for all captions
+                            tempTransition = tempTransition[Math.floor(Math.random() * tempTransition.length)];
+                        }
+                        //else {
+                        //    //got transition from array level 2, in sequence for all adjacent captions with same name specified
+                        //    transition = tempTransition;
+                        //}
+                    }
+                    //else {
+                    //    //got transition from array level 1, random but same for all adjacent captions with same name specified
+                    //    transition = tempTransition;
+                    //}
+                }
+                //else {
+                //    //got transition directly from a simple transition object
+                //    transition = tempTransition;
+                //}
+
+                transition = tempTransition;
+
+                if ($Jssor$.$IsString(transition))
+                    transition = EvaluateCaptionTransition(transition);
+            }
+
+            return transition;
+        }
+
+        var captionElmts = $Jssor$.$Children(element);
+        $Jssor$.$Each(captionElmts, function (captionElmt, i) {
+
+            var transitionsWithTuning = [];
+            transitionsWithTuning.$Elmt = captionElmt;
+            var isCaption = $Jssor$.$AttributeEx(captionElmt, "u") == "caption";
+
+            $Jssor$.$Each(playIn ? [0, 3] : [2], function (j, k) {
+
+                if (isCaption) {
+                    var transition;
+                    var rawTransition;
+
+                    if (j != 2 || !$Jssor$.$AttributeEx(captionElmt, "t3")) {
+                        rawTransition = FetchRawTransition(captionElmt, j);
+
+                        if (j == 2 && !rawTransition.$Transition) {
+                            rawTransition.$Delay = rawTransition.$Delay || { $Value: 0 };
+                            rawTransition = $Jssor$.$Extend(FetchRawTransition(captionElmt, 0), rawTransition);
+                        }
+                    }
+
+                    if (rawTransition && rawTransition.$Transition) {
+
+                        transition = EvaluateCaptionTransition(rawTransition.$Transition.$Value);
+
+                        if (transition) {
+
+                            //var transitionWithTuning = $Jssor$.$Extend({ $Delay: 0, $ScaleHorizontal: 1, $ScaleVertical: 1 }, transition);
+                            var transitionWithTuning = $Jssor$.$Extend({ $Delay: 0 }, transition);
+
+                            $Jssor$.$Each(rawTransition, function (rawPropertyValue, propertyName) {
+                                var tuningPropertyValue = (_CaptionTuningTransfer[propertyName] || _CaptionTuningTransfer.$Default).apply(_CaptionTuningTransfer, [transitionWithTuning[propertyName], rawTransition[propertyName]]);
+                                if (!isNaN(tuningPropertyValue))
+                                    transitionWithTuning[propertyName] = tuningPropertyValue;
+                            });
+
+                            if (!k) {
+                                if (rawTransition.$BeginTime)
+                                    transitionWithTuning.$BeginTime = rawTransition.$BeginTime.$Value || 0;
+                                else if ((_PlayMode) & 2)
+                                    transitionWithTuning.$BeginTime = 0;
+                            }
+                        }
+                    }
+
+                    transitionsWithTuning.push(transitionWithTuning);
+                }
+
+                if ((level % 2) && !k) {
+                    //transitionsWithTuning.$Children = GetCaptionItems(captionElmt, lastTransitionName, [].concat(namedTransitions), [].concat(namedTransitionOrders), level + 1);
+                    transitionsWithTuning.$Children = GetCaptionItems(captionElmt, level + 1);
+                }
+            });
+
+            itemsToPlay.push(transitionsWithTuning);
+        });
+
+        return itemsToPlay;
+    }
+
+    function CreateAnimator(item, transition, immediateOut) {
+
+        var animatorOptions = {
+            $Easing: transition.$Easing,
+            $Round: transition.$Round,
+            $During: transition.$During,
+            $Reverse: playIn && !immediateOut,
+            $Optimize: true
+        };
+
+        $JssorDebug$.$Execute(function () {
+            animatorOptions.$CaptionAnimator = true;
+        });
+
+        var captionItem = item;
+        var captionParent = $Jssor$.$ParentNode(item);
+
+        var captionItemWidth = $Jssor$.$CssWidth(captionItem);
+        var captionItemHeight = $Jssor$.$CssHeight(captionItem);
+        var captionParentWidth = $Jssor$.$CssWidth(captionParent);
+        var captionParentHeight = $Jssor$.$CssHeight(captionParent);
+
+        var toStyles = {};
+        var fromStyles = {};
+        var scaleClip = transition.$ScaleClip || 1;
+
+        //Opacity
+        if (transition.$Opacity) {
+            toStyles.$Opacity = 2 - transition.$Opacity;
+        }
+
+        animatorOptions.$OriginalWidth = captionItemWidth;
+        animatorOptions.$OriginalHeight = captionItemHeight;
+
+        //Transform
+        if (transition.$Zoom || transition.$Rotate) {
+            toStyles.$Zoom = transition.$Zoom ? transition.$Zoom - 1 : 1;
+
+            if ($Jssor$.$IsBrowserIe9Earlier() || $Jssor$.$IsBrowserOpera())
+                toStyles.$Zoom = Math.min(toStyles.$Zoom, 2);
+
+            fromStyles.$Zoom = 1;
+
+            var rotate = transition.$Rotate || 0;
+
+            toStyles.$Rotate = rotate * 360;
+            fromStyles.$Rotate = 0;
+        }
+            //Clip
+        else if (transition.$Clip) {
+            var fromStyleClip = { $Top: 0, $Right: captionItemWidth, $Bottom: captionItemHeight, $Left: 0 };
+            var toStyleClip = $Jssor$.$Extend({}, fromStyleClip);
+
+            var blockOffset = toStyleClip.$Offset = {};
+
+            var topBenchmark = transition.$Clip & 4;
+            var bottomBenchmark = transition.$Clip & 8;
+            var leftBenchmark = transition.$Clip & 1;
+            var rightBenchmark = transition.$Clip & 2;
+
+            if (topBenchmark && bottomBenchmark) {
+                blockOffset.$Top = captionItemHeight / 2 * scaleClip;
+                blockOffset.$Bottom = -blockOffset.$Top;
+            }
+            else if (topBenchmark)
+                blockOffset.$Bottom = -captionItemHeight * scaleClip;
+            else if (bottomBenchmark)
+                blockOffset.$Top = captionItemHeight * scaleClip;
+
+            if (leftBenchmark && rightBenchmark) {
+                blockOffset.$Left = captionItemWidth / 2 * scaleClip;
+                blockOffset.$Right = -blockOffset.$Left;
+            }
+            else if (leftBenchmark)
+                blockOffset.$Right = -captionItemWidth * scaleClip;
+            else if (rightBenchmark)
+                blockOffset.$Left = captionItemWidth * scaleClip;
+
+            animatorOptions.$Move = transition.$Move;
+            toStyles.$Clip = toStyleClip;
+            fromStyles.$Clip = fromStyleClip;
+        }
+
+        //Fly
+        {
+            var toLeft = 0;
+            var toTop = 0;
+
+            if (transition.x)
+                toLeft -= captionParentWidth * transition.x;
+
+            if (transition.y)
+                toTop -= captionParentHeight * transition.y;
+
+            if (toLeft || toTop || animatorOptions.$Move) {
+                toStyles.$Left = toLeft + $Jssor$.$CssLeft(captionItem);
+                toStyles.$Top = toTop + $Jssor$.$CssTop(captionItem);
+            }
+        }
+
+        //duration
+        var duration = transition.$Duration;
+
+        fromStyles = $Jssor$.$Extend(fromStyles, $Jssor$.$GetStyles(captionItem, toStyles));
+
+        animatorOptions.$Setter = $Jssor$.$StyleSetterEx();
+
+        return new $JssorAnimator$(transition.$Delay, duration, animatorOptions, captionItem, fromStyles, toStyles);
+    }
+
+    function CreateAnimators(streamLineLength, captionItems) {
+
+        $Jssor$.$Each(captionItems, function (captionItem, i) {
+
+            $JssorDebug$.$Execute(function () {
+                if (captionItem.length) {
+                    var top = $Jssor$.$CssTop(captionItem.$Elmt);
+                    var left = $Jssor$.$CssLeft(captionItem.$Elmt);
+                    var width = $Jssor$.$CssWidth(captionItem.$Elmt);
+                    var height = $Jssor$.$CssHeight(captionItem.$Elmt);
+
+                    var error = null;
+
+                    if (isNaN(top))
+                        error = "Style 'top' for caption not specified. Please always specify caption like 'position: absolute; top: ...px; left: ...px; width: ...px; height: ...px;'.";
+                    else if (isNaN(left))
+                        error = "Style 'left' not specified. Please always specify caption like 'position: absolute; top: ...px; left: ...px; width: ...px; height: ...px;'.";
+                    else if (isNaN(width))
+                        error = "Style 'width' not specified. Please always specify caption like 'position: absolute; top: ...px; left: ...px; width: ...px; height: ...px;'.";
+                    else if (isNaN(height))
+                        error = "Style 'height' not specified. Please always specify caption like 'position: absolute; top: ...px; left: ...px; width: ...px; height: ...px;'.";
+
+                    if (error)
+                        $JssorDebug$.$Error("Caption " + (i + 1) + " definition error, \r\n" + error + "\r\n" + captionItem.$Elmt.outerHTML);
+                }
+            });
+
+            var animator;
+            var captionElmt = captionItem.$Elmt;
+            var transition = captionItem[0];
+            var transition3 = captionItem[1];
+
+            if (transition) {
+
+                animator = CreateAnimator(captionElmt, transition);
+                streamLineLength = animator.$Locate(transition.$BeginTime == undefined ? streamLineLength : transition.$BeginTime, 1);
+            }
+
+            streamLineLength = CreateAnimators(streamLineLength, captionItem.$Children);
+
+            if (transition3) {
+                var animator3 = CreateAnimator(captionElmt, transition3, 1);
+                animator3.$Locate(streamLineLength, 1);
+                _Self.$Combine(animator3);
+                _ImmediateOutCaptionHanger.$Combine(animator3);
+            }
+
+            if (animator)
+                _Self.$Combine(animator);
+        });
+
+        return streamLineLength;
+    }
+
+    _Self.$Revert = function () {
+        _Self.$GoToPosition(_Self.$GetPosition_OuterEnd() * (playIn || 0));
+        _ImmediateOutCaptionHanger.$GoToBegin();
+    };
+
+    //Constructor
+    {
+        _ImmediateOutCaptionHanger = new $JssorAnimator$(0, 0);
+
+        //var streamLineLength = 0;
+        //var captionItems = GetCaptionItems(container, null, [], [], 1);
+
+        CreateAnimators(0, _PlayMode ? GetCaptionItems(container, 1) : []);
+    }
+};
+
+//Event Table
+
+//$EVT_CLICK = 21;			    function(slideIndex[, event])
+//$EVT_DRAG_START = 22;		    function(position[, virtualPosition, event])
+//$EVT_DRAG_END = 23;		    function(position, startPosition[, virtualPosition, virtualStartPosition, event])
+//$EVT_SWIPE_START = 24;		function(position[, virtualPosition])
+//$EVT_SWIPE_END = 25;		    function(position[, virtualPosition])
+
+//$EVT_LOAD_START = 26;			function(slideIndex)
+//$EVT_LOAD_END = 27;			function(slideIndex)
+
+//$EVT_POSITION_CHANGE = 202;	function(position, fromPosition[, virtualPosition, virtualFromPosition])
+//$EVT_PARK = 203;			    function(slideIndex, fromIndex)
+
+//$EVT_PROGRESS_CHANGE = 208;	function(slideIndex, progress[, progressBegin, idleBegin, idleEnd, progressEnd])
+//$EVT_STATE_CHANGE = 209;	    function(slideIndex, progress[, progressBegin, idleBegin, idleEnd, progressEnd])
+
+//$EVT_ROLLBACK_START = 210;	function(slideIndex, progress[, progressBegin, idleBegin, idleEnd, progressEnd])
+//$EVT_ROLLBACK_END = 211;	    function(slideIndex, progress[, progressBegin, idleBegin, idleEnd, progressEnd])
+
+//$EVT_SLIDESHOW_START = 206;   function(slideIndex[, progressBegin, slideshowBegin, slideshowEnd, progressEnd])
+//$EVT_SLIDESHOW_END = 207;     function(slideIndex[, progressBegin, slideshowBegin, slideshowEnd, progressEnd])
+
+//http://www.jssor.com/development/reference-api.html
diff --git a/doc/_static/jssor.slider.mini.js b/doc/_static/jssor.slider.mini.js
deleted file mode 100644
index b69c55a..0000000
--- a/doc/_static/jssor.slider.mini.js
+++ /dev/null
@@ -1,2 +0,0 @@
-(function(g,f,b,d,c,e,z){/*! Jssor */
-$Jssor$=g.$Jssor$=g.$Jssor$||{};new(function(){});var m=function(){var b=this,a={};b.$On=b.addEventListener=function(b,c){if(typeof c!="function")return;if(!a[b])a[b]=[];a[b].push(c)};b.$Off=b.removeEventListener=function(e,d){var b=a[e];if(typeof d!="function")return;else if(!b)return;for(var c=0;c<b.length;c++)if(d==b[c]){b.splice(c,1);return}};b.g=function(e){var c=a[e],d=[];if(!c)return;for(var b=1;b<arguments.length;b++)d.push(arguments[b]);for(var b=0;b<c.length;b++)try{c[b].apply( [...]
\ No newline at end of file
diff --git a/doc/_templates/index.html b/doc/_templates/index.html
index d9bdf44..4b81976 100644
--- a/doc/_templates/index.html
+++ b/doc/_templates/index.html
@@ -1,7 +1,9 @@
 {% extends "layout.html" %}
 {% set title = 'PyTango documentation' %}
 
-{% set script_files = script_files + ["http://code.jquery.com/jquery-1.9.1.min.js", "_static/jssor.slider.mini.js"] %}
+{% set script_files = script_files + ["http://code.jquery.com/jquery-1.9.1.min.js",
+                                      "_static/jssor.js",
+                                      "_static/jssor.slider.js"] %}
 
 {% block body %}
 

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-science/packages/pytango.git



More information about the debian-science-commits mailing list