PageSourceSearch

https://www.artonne.fr/js/jssor/jssor.js

js artonne.fr collected 2026-10-02 23:55:02 UTC 93,628 bytes, 2,928 lines download raw bytes

1/*
2* Jssor 19.0
3* http://www.jssor.com/
4*
5* Licensed under the MIT license:
6* http://www.opensource.org/licenses/MIT
7* 
8* TERMS OF USE - Jssor
9* 
10* Copyright 2014 Jssor
11*
12* Permission is hereby granted, free of charge, to any person obtaining
13* a copy of this software and associated documentation files (the
14* "Software"), to deal in the Software without restriction, including
15* without limitation the rights to use, copy, modify, merge, publish,
16* distribute, sublicense, and/or sell copies of the Software, and to
17* permit persons to whom the Software is furnished to do so, subject to
18* the following conditions:
19* 
20* The above copyright notice and this permission notice shall be
21* included in all copies or substantial portions of the Software.
22* 
23* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
27* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
28* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
29* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30*/
31
32/*! Jssor */
33
34//$JssorDebug$
35var $JssorDebug$ = new function () {
36
37    this.$DebugMode = true;
38
39    // Methods
40
41    this.$Log = function (msg, important) {
42        var console = window.console || {};
43        var debug = this.$DebugMode;
44
45        if (debug && console.log) {
46            console.log(msg);
47        } else if (debug && important) {
48            alert(msg);
49        }
50    };
51
52    this.$Error = function (msg, e) {
53        var console = window.console || {};
54        var debug = this.$DebugMode;
55
56        if (debug && console.error) {
57            console.error(msg);
58        } else if (debug) {
59            alert(msg);
60        }
61
62        if (debug) {
63            // since we're debugging, fail fast by crashing
64            throw e || new Error(msg);
65        }
66    };
67
68    this.$Fail = function (msg) {
69        throw new Error(msg);
70    };
71
72    this.$Assert = function (value, msg) {
73        var debug = this.$DebugMode;
74        if (debug) {
75            if (!value)
76                throw new Error("Assert failed " + msg || "");
77        }
78    };
79
80    this.$Trace = function (msg) {
81        var console = window.console || {};
82        var debug = this.$DebugMode;
83
84        if (debug && console.log) {
85            console.log(msg);
86        }
87    };
88
89    this.$Execute = function (func) {
90        var debug = this.$DebugMode;
91        if (debug)
92            func();
93    };
94
95    this.$LiveStamp = function (obj, id) {
96        var debug = this.$DebugMode;
97        if (debug) {
98            var stamp = document.createElement("DIV");
99            stamp.setAttribute("id", id);
100
101            obj.$Live = stamp;
102        }
103    };
104
105    this.$C_AbstractProperty = function () {
106        ///	<summary>
107        ///		Tells compiler the property is abstract, it should be implemented by subclass.
108        ///	</summary>
109
110        throw new Error("The property is abstract, it should be implemented by subclass.");
111    };
112
113    this.$C_AbstractMethod = function () {
114        ///	<summary>
115        ///		Tells compiler the method is abstract, it should be implemented by subclass.
116        ///	</summary>
117
118        throw new Error("The method is abstract, it should be implemented by subclass.");
119    };
120
121    function C_AbstractClass(instance) {
122        ///	<summary>
123        ///		Tells compiler the class is abstract, it should be implemented by subclass.
124        ///	</summary>
125
126        if (instance.constructor === C_AbstractClass.caller)
127            throw new Error("Cannot create instance of an abstract class.");
128    }
129
130    this.$C_AbstractClass = C_AbstractClass;
131};
132
133//$JssorEasing$
134var $JssorEasing$ = window.$JssorEasing$ = {
135    $EaseLinear: function (t) {
136        return t;
137    },
138    $EaseGoBack: function (t) {
139        return 1 - Math.abs((t *= 2) - 1);
140    },
141    $EaseSwing: function (t) {
142        return -Math.cos(t * Math.PI) / 2 + .5;
143    },
144    $EaseInQuad: function (t) {
145        return t * t;
146    },
147    $EaseOutQuad: function (t) {
148        return -t * (t - 2);
149    },
150    $EaseInOutQuad: function (t) {
151        return (t *= 2) < 1 ? 1 / 2 * t * t : -1 / 2 * (--t * (t - 2) - 1);
152    },
153    $EaseInCubic: function (t) {
154        return t * t * t;
155    },
156    $EaseOutCubic: function (t) {
157        return (t -= 1) * t * t + 1;
158    },
159    $EaseInOutCubic: function (t) {
160        return (t *= 2) < 1 ? 1 / 2 * t * t * t : 1 / 2 * ((t -= 2) * t * t + 2);
161    },
162    $EaseInQuart: function (t) {
163        return t * t * t * t;
164    },
165    $EaseOutQuart: function (t) {
166        return -((t -= 1) * t * t * t - 1);
167    },
168    $EaseInOutQuart: function (t) {
169        return (t *= 2) < 1 ? 1 / 2 * t * t * t * t : -1 / 2 * ((t -= 2) * t * t * t - 2);
170    },
171    $EaseInQuint: function (t) {
172        return t * t * t * t * t;
173    },
174    $EaseOutQuint: function (t) {
175        return (t -= 1) * t * t * t * t + 1;
176    },
177    $EaseInOutQuint: function (t) {
178        return (t *= 2) < 1 ? 1 / 2 * t * t * t * t * t : 1 / 2 * ((t -= 2) * t * t * t * t + 2);
179    },
180    $EaseInSine: function (t) {
181        return 1 - Math.cos(t * Math.PI / 2);
182    },
183    $EaseOutSine: function (t) {
184        return Math.sin(t * Math.PI / 2);
185    },
186    $EaseInOutSine: function (t) {
187        return -1 / 2 * (Math.cos(Math.PI * t) - 1);
188    },
189    $EaseInExpo: function (t) {
190        return t == 0 ? 0 : Math.pow(2, 10 * (t - 1));
191    },
192    $EaseOutExpo: function (t) {
193        return t == 1 ? 1 : -Math.pow(2, -10 * t) + 1;
194    },
195    $EaseInOutExpo: function (t) {
196        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);
197    },
198    $EaseInCirc: function (t) {
199        return -(Math.sqrt(1 - t * t) - 1);
200    },
201    $EaseOutCirc: function (t) {
202        return Math.sqrt(1 - (t -= 1) * t);
203    },
204    $EaseInOutCirc: function (t) {
205        return (t *= 2) < 1 ? -1 / 2 * (Math.sqrt(1 - t * t) - 1) : 1 / 2 * (Math.sqrt(1 - (t -= 2) * t) + 1);
206    },
207    $EaseInElastic: function (t) {
208        if (!t || t == 1)
209            return t;
210        var p = .3, s = .075;
211        return -(Math.pow(2, 10 * (t -= 1)) * Math.sin((t - s) * 2 * Math.PI / p));
212    },
213    $EaseOutElastic: function (t) {
214        if (!t || t == 1)
215            return t;
216        var p = .3, s = .075;
217        return Math.pow(2, -10 * t) * Math.sin((t - s) * 2 * Math.PI / p) + 1;
218    },
219    $EaseInOutElastic: function (t) {
220        if (!t || t == 1)
221            return t;
222        var p = .45, s = .1125;
223        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;
224    },
225    $EaseInBack: function (t) {
226        var s = 1.70158;
227        return t * t * ((s + 1) * t - s);
228    },
229    $EaseOutBack: function (t) {
230        var s = 1.70158;
231        return (t -= 1) * t * ((s + 1) * t + s) + 1;
232    },
233    $EaseInOutBack: function (t) {
234        var s = 1.70158;
235        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);
236    },
237    $EaseInBounce: function (t) {
238        return 1 - $JssorEasing$.$EaseOutBounce(1 - t)
239    },
240    $EaseOutBounce: function (t) {
241        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;
242    },
243    $EaseInOutBounce: function (t) {
244        return t < 1 / 2 ? $JssorEasing$.$EaseInBounce(t * 2) * .5 : $JssorEasing$.$EaseOutBounce(t * 2 - 1) * .5 + .5;
245    },
246    $EaseInWave: function (t) {
247        return 1 - Math.cos(t * Math.PI * 2)
248    },
249    $EaseOutWave: function (t) {
250        return Math.sin(t * Math.PI * 2);
251    },
252    $EaseOutJump: function (t) {
253        return 1 - (((t *= 2) < 1) ? (t = 1 - t) * t * t : (t -= 1) * t * t);
254    },
255    $EaseInJump: function (t) {
256        return ((t *= 2) < 1) ? t * t * t : (t = 2 - t) * t * t;
257    }
258};
259
260var $JssorDirection$ = window.$JssorDirection$ = {
261    $TO_LEFT: 0x0001,
262    $TO_RIGHT: 0x0002,
263    $TO_TOP: 0x0004,
264    $TO_BOTTOM: 0x0008,
265    $HORIZONTAL: 0x0003,
266    $VERTICAL: 0x000C,
267    //$LEFTRIGHT: 0x0003,
268    //$TOPBOTOM: 0x000C,
269    //$TOPLEFT: 0x0005,
270    //$TOPRIGHT: 0x0006,
271    //$BOTTOMLEFT: 0x0009,
272    //$BOTTOMRIGHT: 0x000A,
273    //$AROUND: 0x000F,
274
275    $GetDirectionHorizontal: function (direction) {
276        return direction & 0x0003;
277    },
278    $GetDirectionVertical: function (direction) {
279        return direction & 0x000C;
280    },
281    //$ChessHorizontal: function (direction) {
282    //    return (~direction & 0x0003) + (direction & 0x000C);
283    //},
284    //$ChessVertical: function (direction) {
285    //    return (~direction & 0x000C) + (direction & 0x0003);
286    //},
287    //$IsToLeft: function (direction) {
288    //    return (direction & 0x0003) == 0x0001;
289    //},
290    //$IsToRight: function (direction) {
291    //    return (direction & 0x0003) == 0x0002;
292    //},
293    //$IsToTop: function (direction) {
294    //    return (direction & 0x000C) == 0x0004;
295    //},
296    //$IsToBottom: function (direction) {
297    //    return (direction & 0x000C) == 0x0008;
298    //},
299    $IsHorizontal: function (direction) {
300        return direction & 0x0003;
301    },
302    $IsVertical: function (direction) {
303        return direction & 0x000C;
304    }
305};
306
307var $JssorKeyCode$ = {
308    $BACKSPACE: 8,
309    $COMMA: 188,
310    $DELETE: 46,
311    $DOWN: 40,
312    $END: 35,
313    $ENTER: 13,
314    $ESCAPE: 27,
315    $HOME: 36,
316    $LEFT: 37,
317    $NUMPAD_ADD: 107,
318    $NUMPAD_DECIMAL: 110,
319    $NUMPAD_DIVIDE: 111,
320    $NUMPAD_ENTER: 108,
321    $NUMPAD_MULTIPLY: 106,
322    $NUMPAD_SUBTRACT: 109,
323    $PAGE_DOWN: 34,
324    $PAGE_UP: 33,
325    $PERIOD: 190,
326    $RIGHT: 39,
327    $SPACE: 32,
328    $TAB: 9,
329    $UP: 38
330};
331
332//var $JssorAlignment$ = {
333//    $TopLeft: 0x11,
334//    $TopCenter: 0x12,
335//    $TopRight: 0x14,
336//    $MiddleLeft: 0x21,
337//    $MiddleCenter: 0x22,
338//    $MiddleRight: 0x24,
339//    $BottomLeft: 0x41,
340//    $BottomCenter: 0x42,
341//    $BottomRight: 0x44,
342//    $IsTop: function (aligment) {
343//        return aligment & 0x10 > 0;
344//    },
345//    $IsMiddle: function (alignment) {
346//        return alignment & 0x20 > 0;
347//    },
348//    $IsBottom: function (alignment) {
349//        return alignment & 0x40 > 0;
350//    },
351//    $IsLeft: function (alignment) {
352//        return alignment & 0x01 > 0;
353//    },
354//    $IsCenter: function (alignment) {
355//        return alignment & 0x02 > 0;
356//    },
357//    $IsRight: function (alignment) {
358//        return alignment & 0x04 > 0;
359//    }
360//};
361
362// $Jssor$ is a static class, so make it singleton instance
363var $Jssor$ = window.$Jssor$ = new function () {
364    var _This = this;
365
366    //#region Constants
367    var REGEX_WHITESPACE_GLOBAL = /\S+/g;
368    var ROWSER_UNKNOWN = 0;
369    var BROWSER_IE = 1;
370    var BROWSER_FIREFOX = 2;
371    var BROWSER_SAFARI = 3;
372    var BROWSER_CHROME = 4;
373    var BROWSER_OPERA = 5;
374
375    //var arrActiveX = ["Msxml2.XMLHTTP", "Msxml3.XMLHTTP", "Microsoft.XMLHTTP"];
376    //#endregion
377
378    //#region Variables
379    var _Device;
380    var _Browser = 0;
381    var _BrowserRuntimeVersion = 0;
382    var _BrowserEngineVersion = 0;
383    var _BrowserJavascriptVersion = 0;
384    var _WebkitVersion = 0;
385
386    var _Navigator = navigator;
387    var _AppName = _Navigator.appName;
388    var _AppVersion = _Navigator.appVersion;
389    var _UserAgent = _Navigator.userAgent;
390
391    var _DocElmt = document.documentElement;
392    var _TransformProperty;
393    //#endregion
394
395    function Device() {
396        if (!_Device) {
397            _Device = {
398                $Evt_Down: "mousedown",
399                $Evt_Move: "mousemove",
400                $Evt_Up: "mouseup"
401            };
402            var msPrefix;
403            if (_Navigator.pointerEnabled || (msPrefix = _Navigator.msPointerEnabled)) {
404                _Device = {
405                    $Evt_Down: msPrefix ? "MSPointerDown" : "pointerdown",
406                    $Evt_Move: msPrefix ? "MSPointerMove" : "pointermove",
407                    $Evt_Up: msPrefix ? "MSPointerUp" : "pointerup",
408                    $Evt_Cancel: msPrefix ? "MSPointerCancel" : "pointercancel",
409                    $TouchActionAttr: msPrefix ? "msTouchAction" : "touchAction",
410                    $Touchable: _UserAgent.match(/iemobile/i)
411                };
412            }
413            else if ("ontouchstart" in window || "createTouch" in document) {
414                _Device = {
415                    $Evt_Down: "touchstart",
416                    $Evt_Move: "touchmove",
417                    $Evt_Up: "touchend",
418                    $Evt_Cancel: "touchcancel",
419                    $Touchable: true,
420                    $TouchOnly: true
421                };
422            }
423        }
424
425        return _Device;
426    }
427
428    function DetectBrowser(browser) {
429        if (!_Browser) {
430            if (_AppName == "Microsoft Internet Explorer" &&
431                !!window.attachEvent && !!window.ActiveXObject) {
432
433                var ieOffset = _UserAgent.indexOf("MSIE");
434                _Browser = BROWSER_IE;
435                _BrowserEngineVersion = ParseFloat(_UserAgent.substring(ieOffset + 5, _UserAgent.indexOf(";", ieOffset)));
436
437                //check IE javascript version
438                /*@cc_on
439                _BrowserJavascriptVersion = @_jscript_version;
440                @*/
441
442                // update: for intranet sites and compat view list sites, IE sends
443                // an IE7 User-Agent to the server to be interoperable, and even if
444                // the page requests a later IE version, IE will still report the
445                // IE7 UA to JS. we should be robust to self
446                //var docMode = document.documentMode;
447                //if (typeof docMode !== "undefined") {
448                //    _BrowserRuntimeVersion = docMode;
449                //}
450
451                _BrowserRuntimeVersion = document.documentMode || _BrowserEngineVersion;
452
453            }
454            else if (_AppName == "Netscape" && !!window.addEventListener) {
455
456                var ffOffset = _UserAgent.indexOf("Firefox");
457                var saOffset = _UserAgent.indexOf("Safari");
458                var chOffset = _UserAgent.indexOf("Chrome");
459                var webkitOffset = _UserAgent.indexOf("AppleWebKit");
460
461                if (ffOffset >= 0) {
462                    _Browser = BROWSER_FIREFOX;
463                    _BrowserRuntimeVersion = ParseFloat(_UserAgent.substring(ffOffset + 8));
464                }
465                else if (saOffset >= 0) {
466                    var slash = _UserAgent.substring(0, saOffset).lastIndexOf("/");
467                    _Browser = (chOffset >= 0) ? BROWSER_CHROME : BROWSER_SAFARI;
468                    _BrowserRuntimeVersion = ParseFloat(_UserAgent.substring(slash + 1, saOffset));
469                }
470
471                if (webkitOffset >= 0)
472                    _WebkitVersion = ParseFloat(_UserAgent.substring(webkitOffset + 12));
473            }
474            else {
475                var match = /(opera)(?:.*version|)[ \/]([\w.]+)/i.exec(_UserAgent);
476                if (match) {
477                    _Browser = BROWSER_OPERA;
478                    _BrowserRuntimeVersion = ParseFloat(match[2]);
479                }
480            }
481        }
482
483        return browser == _Browser;
484    }
485
486    function IsBrowserIE() {
487        return DetectBrowser(BROWSER_IE);
488    }
489
490    function IsBrowserIeQuirks() {
491        return IsBrowserIE() && (_BrowserRuntimeVersion < 6 || document.compatMode == "BackCompat");   //Composite to "CSS1Compat"
492    }
493
494    function IsBrowserFireFox() {
495        return DetectBrowser(BROWSER_FIREFOX);
496    }
497
498    function IsBrowserSafari() {
499        return DetectBrowser(BROWSER_SAFARI);
500    }
501
502    function IsBrowserChrome() {
503        return DetectBrowser(BROWSER_CHROME);
504    }
505
506    function IsBrowserOpera() {
507        return DetectBrowser(BROWSER_OPERA);
508    }
509
510    function IsBrowserBadTransform() {
511        return IsBrowserSafari() && (_WebkitVersion > 534) && (_WebkitVersion < 535);
512    }
513
514    function IsBrowserIe9Earlier() {
515        return IsBrowserIE() && _BrowserRuntimeVersion < 9;
516    }
517
518    function GetTransformProperty(elmt) {
519
520        if (!_TransformProperty) {
521            // Note that in some versions of IE9 it is critical that
522            // msTransform appear in this list before MozTransform
523
524            each(['transform', 'WebkitTransform', 'msTransform', 'MozTransform', 'OTransform'], function (property) {
525                if (elmt.style[property] != undefined) {
526                    _TransformProperty = property;
527                    return true;
528                }
529            });
530
531            _TransformProperty = _TransformProperty || "transform";
532        }
533
534        return _TransformProperty;
535    }
536
537    // Helpers
538    function getOffsetParent(elmt, isFixed) {
539        // IE and Opera "fixed" position elements don't have offset parents.
540        // regardless, if it's fixed, its offset parent is the body.
541        if (isFixed && elmt != document.body) {
542            return document.body;
543        } else {
544            return elmt.offsetParent;
545        }
546    }
547
548    function toString(obj) {
549        return Object.prototype.toString.call(obj);
550    }
551
552    // [[Class]] -> type pairs
553    var class2type;
554
555    function each(object, callback) {
556        if (toString(object) == "[object Array]") {
557            for (var i = 0; i < object.length; i++) {
558                if (callback(object[i], i, object)) {
559                    return true;
560                }
561            }
562        }
563        else {
564            for (var name in object) {
565                if (callback(object[name], name, object)) {
566                    return true;
567                }
568            }
569        }
570    }
571
572    function GetClass2Type() {
573        if (!class2type) {
574            class2type = {};
575            each(["Boolean", "Number", "String", "Function", "Array", "Date", "RegExp", "Object"], function (name) {
576                class2type["[object " + name + "]"] = name.toLowerCase();
577            });
578        }
579
580        return class2type;
581    }
582
583    function type(obj) {
584        return obj == null ? String(obj) : GetClass2Type()[toString(obj)] || "object";
585    }
586
587    function isPlainObject(obj) {
588        // Must be an Object.
589        // Because of IE, we also have to check the presence of the constructor property.
590        // Make sure that DOM nodes and window objects don't pass through, as well
591        if (!obj || type(obj) !== "object" || obj.nodeType || _This.$IsWindow(obj)) {
592            return false;
593        }
594
595        var hasOwn = Object.prototype.hasOwnProperty;
596
597        try {
598            // Not own constructor property must be Object
599            if (obj.constructor &&
600				!hasOwn.call(obj, "constructor") &&
601				!hasOwn.call(obj.constructor.prototype, "isPrototypeOf")) {
602                return false;
603            }
604        } catch (e) {
605            // IE8,9 Will throw exceptions on certain host objects #9897
606            return false;
607        }
608
609        // Own properties are enumerated firstly, so to speed up,
610        // if last one is own, then all properties are own.
611
612        var key;
613        for (key in obj) { }
614
615        return key === undefined || hasOwn.call(obj, key);
616    }
617
618    function Point(x, y) {
619        return { x: x, y: y };
620    }
621
622    function Delay(code, delay) {
623        setTimeout(code, delay || 0);
624    }
625
626    function RemoveByReg(str, reg) {
627        var m = reg.exec(str);
628
629        if (m) {
630            var header = str.substr(0, m.index);
631            var tailer = str.substr(m.lastIndex + 1, str.length - (m.lastIndex + 1));
632            str = header + tailer;
633        }
634
635        return str;
636    }
637
638    function BuildNewCss(oldCss, removeRegs, replaceValue) {
639        var css = (!oldCss || oldCss == "inherit") ? "" : oldCss;
640
641        each(removeRegs, function (removeReg) {
642            var m = removeReg.exec(css);
643
644            if (m) {
645                var header = css.substr(0, m.index);
646                var tailer = css.substr(m.lastIndex + 1, css.length - (m.lastIndex + 1));
647                css = header + tailer;
648            }
649        });
650
651        css = replaceValue + (css.indexOf(" ") != 0 ? " " : "") + css;
652
653        return css;
654    }
655
656    function SetStyleFilterIE(elmt, value) {
657        if (_BrowserRuntimeVersion < 9) {
658            elmt.style.filter = value;
659        }
660    }
661
662    function SetStyleMatrixIE(elmt, matrix, offset) {
663        //matrix is not for ie9+ running in ie8- mode
664        if (_BrowserJavascriptVersion < 9) {
665            var oldFilterValue = elmt.style.filter;
666            var matrixReg = new RegExp(/[\s]*progid:DXImageTransform\.Microsoft\.Matrix\([^\)]*\)/g);
667            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')" : "";
668
669            var newFilterValue = BuildNewCss(oldFilterValue, [matrixReg], matrixValue);
670
671            SetStyleFilterIE(elmt, newFilterValue);
672
673            _This.$CssMarginTop(elmt, offset.y);
674            _This.$CssMarginLeft(elmt, offset.x);
675        }
676    }
677
678    // Methods
679
680    //_This.$IsTouchDevice = function () {
681    //    return /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(_UserAgent);
682    //};
683
684    _This.$Device = Device;
685
686    _This.$IsBrowserIE = IsBrowserIE;
687
688    _This.$IsBrowserIeQuirks = IsBrowserIeQuirks;
689
690    _This.$IsBrowserFireFox = IsBrowserFireFox;
691
692    _This.$IsBrowserSafari = IsBrowserSafari;
693
694    _This.$IsBrowserChrome = IsBrowserChrome;
695
696    _This.$IsBrowserOpera = IsBrowserOpera;
697
698    _This.$IsBrowserBadTransform = IsBrowserBadTransform;
699
700    _This.$IsBrowserIe9Earlier = IsBrowserIe9Earlier;
701
702    _This.$BrowserVersion = function () {
703        return _BrowserRuntimeVersion;
704    };
705
706    _This.$BrowserEngineVersion = function () {
707        return _BrowserEngineVersion || _BrowserRuntimeVersion;
708    };
709
710    _This.$WebKitVersion = function () {
711        DetectBrowser();
712
713        return _WebkitVersion;
714    };
715
716    _This.$Delay = Delay;
717
718    _This.$Inherit = function (instance, baseClass) {
719        baseClass.call(instance);
720        return Extend({}, instance);
721    };
722
723    function Construct(instance) {
724        instance.constructor === Construct.caller && instance.$Construct && instance.$Construct.apply(instance, Construct.caller.arguments);
725    }
726
727    _This.$Construct = Construct;
728
729    _This.$GetElement = function (elmt) {
730        if (_This.$IsString(elmt)) {
731            elmt = document.getElementById(elmt);
732        }
733
734        return elmt;
735    };
736
737    function GetEvent(event) {
738        return event || window.event;
739    }
740
741    _This.$GetEvent = GetEvent;
742
743    _This.$EventSrc = function (event) {
744        event = GetEvent(event);
745        return event.target || event.srcElement || document;
746    };
747
748    _This.$EventTarget = function (event) {
749        event = GetEvent(event);
750        return event.relatedTarget || event.toElement;
751    };
752
753    _This.$MousePosition = function (event) {
754        event = GetEvent(event);
755        var body = document.body;
756
757        return {
758            x: event.pageX || event.clientX + (_DocElmt.scrollLeft || body.scrollLeft || 0) - (_DocElmt.clientLeft || body.clientLeft || 0) || 0,
759            y: event.pageY || event.clientY + (_DocElmt.scrollTop || body.scrollTop || 0) - (_DocElmt.clientTop || body.clientTop || 0) || 0
760        };
761    };
762
763    _This.$PageScroll = function () {
764        var body = document.body;
765
766        return {
767            x: (window.pageXOffset || _DocElmt.scrollLeft || body.scrollLeft || 0) - (_DocElmt.clientLeft || body.clientLeft || 0),
768            y: (window.pageYOffset || _DocElmt.scrollTop || body.scrollTop || 0) - (_DocElmt.clientTop || body.clientTop || 0)
769        };
770    };
771
772    _This.$WindowSize = function () {
773        var body = document.body;
774
775        return {
776            x: body.clientWidth || _DocElmt.clientWidth,
777            y: body.clientHeight || _DocElmt.clientHeight
778        };
779    };
780
781    //_This.$GetElementPosition = function (elmt) {
782    //    elmt = _This.$GetElement(elmt);
783    //    var result = Point();
784
785    //    // technique from:
786    //    // http://www.quirksmode.org/js/findpos.html
787    //    // with special check for "fixed" elements.
788
789    //    while (elmt) {
790    //        result.x += elmt.offsetLeft;
791    //        result.y += elmt.offsetTop;
792
793    //        var isFixed = _This.$GetElementStyle(elmt).position == "fixed";
794
795    //        if (isFixed) {
796    //            result = result.$Plus(_This.$PageScroll(window));
797    //        }
798
799    //        elmt = getOffsetParent(elmt, isFixed);
800    //    }
801
802    //    return result;
803    //};
804
805    //_This.$GetMouseScroll = function (event) {
806    //    event = GetEvent(event);
807    //    var delta = 0; // default value
808
809    //    // technique from:
810    //    // http://blog.paranoidferret.com/index.php/2007/10/31/javascript-tutorial-the-scroll-wheel/
811
812    //    if (typeof (event.wheelDelta) == "number") {
813    //        delta = event.wheelDelta;
814    //    } else if (typeof (event.detail) == "number") {
815    //        delta = event.detail * -1;
816    //    } else {
817    //        $JssorDebug$.$Fail("Unknown event mouse scroll, no known technique.");
818    //    }
819
820    //    // normalize value to [-1, 1]
821    //    return delta ? delta / Math.abs(delta) : 0;
822    //};
823
824    //_This.$MakeAjaxRequest = function (url, callback) {
825    //    var async = typeof (callback) == "function";
826    //    var req = null;
827
828    //    if (async) {
829    //        var actual = callback;
830    //        var callback = function () {
831    //            Delay($Jssor$.$CreateCallback(null, actual, req), 1);
832    //        };
833    //    }
834
835    //    if (window.ActiveXObject) {
836    //        for (var i = 0; i < arrActiveX.length; i++) {
837    //            try {
838    //                req = new ActiveXObject(arrActiveX[i]);
839    //                break;
840    //            } catch (e) {
841    //                continue;
842    //            }
843    //        }
844    //    } else if (window.XMLHttpRequest) {
845    //        req = new XMLHttpRequest();
846    //    }
847
848    //    if (!req) {
849    //        $JssorDebug$.$Fail("Browser doesn't support XMLHttpRequest.");
850    //    }
851
852    //    if (async) {
853    //        req.onreadystatechange = function () {
854    //            if (req.readyState == 4) {
855    //                // prevent memory leaks by breaking circular reference now
856    //                req.onreadystatechange = new Function();
857    //                callback();
858    //            }
859    //        };
860    //    }
861
862    //    try {
863    //        req.open("GET", url, async);
864    //        req.send(null);
865    //    } catch (e) {
866    //        $JssorDebug$.$Log(e.name + " while making AJAX request: " + e.message);
867
868    //        req.onreadystatechange = null;
869    //        req = null;
870
871    //        if (async) {
872    //            callback();
873    //        }
874    //    }
875
876    //    return async ? null : req;
877    //};
878
879    //_This.$ParseXml = function (string) {
880    //    var xmlDoc = null;
881
882    //    if (window.ActiveXObject) {
883    //        try {
884    //            xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
885    //            xmlDoc.async = false;
886    //            xmlDoc.loadXML(string);
887    //        } catch (e) {
888    //            $JssorDebug$.$Log(e.name + " while parsing XML (ActiveX): " + e.message);
889    //        }
890    //    } else if (window.DOMParser) {
891    //        try {
892    //            var parser = new DOMParser();
893    //            xmlDoc = parser.parseFromString(string, "text/xml");
894    //        } catch (e) {
895    //            $JssorDebug$.$Log(e.name + " while parsing XML (DOMParser): " + e.message);
896    //        }
897    //    } else {
898    //        $JssorDebug$.$Fail("Browser doesn't support XML DOM.");
899    //    }
900
901    //    return xmlDoc;
902    //};
903
904    function Css(elmt, name, value) {
905        ///	<summary>
906        ///		access css
907        ///     $Jssor$.$Css(elmt, name);         //get css value
908        ///     $Jssor$.$Css(elmt, name, value);  //set css value
909        ///	</summary>
910        ///	<param name="elmt" type="HTMLElement">
911        ///		the element to access css
912        ///	</param>
913        ///	<param name="name" type="String">
914        ///		the name of css property
915        ///	</param>
916        ///	<param name="value" optional="true">
917        ///		the value to set
918        ///	</param>
919        if (value != undefined) {
920            elmt.style[name] = value;
921        }
922        else {
923            var style = elmt.currentStyle || elmt.style;
924            value = style[name];
925
926            if (value == "" && window.getComputedStyle) {
927                style = elmt.ownerDocument.defaultView.getComputedStyle(elmt, null);
928
929                style && (value = style.getPropertyValue(name) || style[name]);
930            }
931
932            return value;
933        }
934    }
935
936    function CssN(elmt, name, value, isDimensional) {
937        ///	<summary>
938        ///		access css as numeric
939        ///     $Jssor$.$CssN(elmt, name);         //get css value
940        ///     $Jssor$.$CssN(elmt, name, value);  //set css value
941        ///	</summary>
942        ///	<param name="elmt" type="HTMLElement">
943        ///		the element to access css
944        ///	</param>
945        ///	<param name="name" type="String">
946        ///		the name of css property
947        ///	</param>
948        ///	<param name="value" type="Number" optional="true">
949        ///		the value to set
950        ///	</param>
951        if (value != undefined) {
952            isDimensional && (value += "px");
953            Css(elmt, name, value);
954        }
955        else {
956            return ParseFloat(Css(elmt, name));
957        }
958    }
959
960    function CssP(elmt, name, value) {
961        ///	<summary>
962        ///		access css in pixel as numeric, like 'top', 'left', 'width', 'height'
963        ///     $Jssor$.$CssP(elmt, name);         //get css value
964        ///     $Jssor$.$CssP(elmt, name, value);  //set css value
965        ///	</summary>
966        ///	<param name="elmt" type="HTMLElement">
967        ///		the element to access css
968        ///	</param>
969        ///	<param name="name" type="String">
970        ///		the name of css property
971        ///	</param>
972        ///	<param name="value" type="Number" optional="true">
973        ///		the value to set
974        ///	</param>
975        return CssN(elmt, name, value, true);
976    }
977
978    function CssProxy(name, numericOrDimension) {
979        ///	<summary>
980        ///		create proxy to access css, CssProxy(name[, numericOrDimension]);
981        ///	</summary>
982        ///	<param name="elmt" type="HTMLElement">
983        ///		the element to access css
984        ///	</param>
985        ///	<param name="numericOrDimension" type="Number" optional="true">
986        ///		not set: access original css, 1: access css as numeric, 2: access css in pixel as numeric
987        ///	</param>
988        var isDimensional = numericOrDimension & 2;
989        var cssAccessor = numericOrDimension ? CssN : Css;
990        return function (elmt, value) {
991            return cssAccessor(elmt, name, value, isDimensional);
992        };
993    }
994
995    function GetStyleOpacity(elmt) {
996        if (IsBrowserIE() && _BrowserEngineVersion < 9) {
997            var match = /opacity=([^)]*)/.exec(elmt.style.filter || "");
998            return match ? (ParseFloat(match[1]) / 100) : 1;
999        }
1000        else
1001            return ParseFloat(elmt.style.opacity || "1");
1002    }
1003
1004    function SetStyleOpacity(elmt, opacity, ie9EarlierForce) {
1005
1006        if (IsBrowserIE() && _BrowserEngineVersion < 9) {
1007            //var filterName = "filter"; // _BrowserEngineVersion < 8 ? "filter" : "-ms-filter";
1008            var finalFilter = elmt.style.filter || "";
1009
1010            // for CSS filter browsers (IE), remove alpha filter if it's unnecessary.
1011            // update: doing _This always since IE9 beta seems to have broken the
1012            // behavior if we rely on the programmatic filters collection.
1013            var alphaReg = new RegExp(/[\s]*alpha\([^\)]*\)/g);
1014
1015            // important: note the lazy star! _This protects against
1016            // multiple filters; we don't want to delete the other ones.
1017            // update: also trimming extra whitespace around filter.
1018
1019            var ieOpacity = Math.round(100 * opacity);
1020            var alphaFilter = "";
1021            if (ieOpacity < 100 || ie9EarlierForce) {
1022                alphaFilter = "alpha(opacity=" + ieOpacity + ") ";
1023                //elmt.style["-ms-filter"] = "progid:DXImageTransform.Microsoft.Alpha(opacity=" + ieOpacity + ") ";
1024            }
1025
1026            var newFilterValue = BuildNewCss(finalFilter, [alphaReg], alphaFilter);
1027
1028            SetStyleFilterIE(elmt, newFilterValue);
1029        }
1030
1031            //if (!IsBrowserIE() || _BrowserEngineVersion >= 9) 
1032        else {
1033            elmt.style.opacity = opacity == 1 ? "" : Math.round(opacity * 100) / 100;
1034        }
1035    }
1036
1037    function SetStyleTransformInternal(elmt, transform) {
1038        var rotate = transform.$Rotate || 0;
1039        var scale = transform.$Scale == undefined ? 1 : transform.$Scale;
1040
1041        if (IsBrowserIe9Earlier()) {
1042            var matrix = _This.$CreateMatrix(rotate / 180 * Math.PI, scale, scale);
1043            SetStyleMatrixIE(elmt, (!rotate && scale == 1) ? null : matrix, _This.$GetMatrixOffset(matrix, transform.$OriginalWidth, transform.$OriginalHeight));
1044        }
1045        else {
1046            //rotate(15deg) scale(.5) translateZ(0)
1047            var transformProperty = GetTransformProperty(elmt);
1048            if (transformProperty) {
1049                var transformValue = "rotate(" + rotate % 360 + "deg) scale(" + scale + ")";
1050
1051                //needed for touch device, no need for desktop device
1052                if (IsBrowserChrome() && _WebkitVersion > 535 && "ontouchstart" in window)
1053                    transformValue += " perspective(2000px)";
1054
1055                elmt.style[transformProperty] = transformValue;
1056            }
1057        }
1058    }
1059
1060    _This.$SetStyleTransform = function (elmt, transform) {
1061        if (IsBrowserBadTransform()) {
1062            Delay(_This.$CreateCallback(null, SetStyleTransformInternal, elmt, transform));
1063        }
1064        else {
1065            SetStyleTransformInternal(elmt, transform);
1066        }
1067    };
1068
1069    _This.$SetStyleTransformOrigin = function (elmt, transformOrigin) {
1070        var transformProperty = GetTransformProperty(elmt);
1071
1072        if (transformProperty)
1073            elmt.style[transformProperty + "Origin"] = transformOrigin;
1074    };
1075
1076    _This.$CssScale = function (elmt, scale) {
1077
1078        if (IsBrowserIE() && _BrowserEngineVersion < 9 || (_BrowserEngineVersion < 10 && IsBrowserIeQuirks())) {
1079            elmt.style.zoom = (scale == 1) ? "" : scale;
1080        }
1081        else {
1082            var transformProperty = GetTransformProperty(elmt);
1083
1084            if (transformProperty) {
1085                //rotate(15deg) scale(.5)
1086                var transformValue = "scale(" + scale + ")";
1087
1088                var oldTransformValue = elmt.style[transformProperty];
1089                var scaleReg = new RegExp(/[\s]*scale\(.*?\)/g);
1090
1091                var newTransformValue = BuildNewCss(oldTransformValue, [scaleReg], transformValue);
1092
1093                elmt.style[transformProperty] = newTransformValue;
1094            }
1095        }
1096    };
1097
1098    _This.$EnableHWA = function (elmt) {
1099        if (!elmt.style[GetTransformProperty(elmt)] || elmt.style[GetTransformProperty(elmt)] == "none")
1100            elmt.style[GetTransformProperty(elmt)] = "perspective(2000px)";
1101    };
1102
1103    _This.$DisableHWA = function (elmt) {
1104        //if (force || elmt.style[GetTransformProperty(elmt)] == "perspective(2000px)")
1105        elmt.style[GetTransformProperty(elmt)] = "none";
1106    };
1107
1108    var ie8OffsetWidth = 0;
1109    var ie8OffsetHeight = 0;
1110    //var ie8WindowResizeCallbackHandlers;
1111    //var ie8LastVerticalScrollbar;
1112    //var toggleInfo = "";
1113
1114    //function Ie8WindowResizeFilter(window, handler) {
1115
1116    //    var trigger = true;
1117
1118    //    var checkElement = (IsBrowserIeQuirks() ? window.document.body : window.document.documentElement);
1119    //    if (checkElement) {
1120    //        //check vertical bar
1121    //        //var hasVerticalBar = checkElement.scrollHeight > checkElement.clientHeight;
1122    //        //var verticalBarToggle = hasVerticalBar != ie8LastVerticalScrollbar;
1123    //        //ie8LastVerticalScrollbar = hasVerticalBar;
1124
1125    //        var widthChange = checkElement.offsetWidth - ie8OffsetWidth;
1126    //        var heightChange = checkElement.offsetHeight - ie8OffsetHeight;
1127    //        if (widthChange || heightChange) {
1128
1129    //            ie8OffsetWidth += widthChange;
1130    //            ie8OffsetHeight += heightChange;
1131    //        }
1132    //        else
1133    //            trigger = false;
1134    //    }
1135
1136    //    trigger && handler();
1137    //}
1138
1139    //_This.$OnWindowResize = function (window, handler) {
1140
1141    //    if (IsBrowserIE() && _BrowserEngineVersion < 9) {
1142    //        if (!ie8WindowResizeCallbackHandlers) {
1143    //            ie8WindowResizeCallbackHandlers = [handler];
1144    //            handler = _This.$CreateCallback(null, Ie8WindowResizeFilter, window);
1145    //        }
1146    //        else {
1147    //            ie8WindowResizeCallbackHandlers.push(handler);
1148    //            return;
1149    //        }
1150    //    }
1151
1152    //    _This.$AddEvent(window, "resize", handler);
1153    //};
1154
1155    _This.$WindowResizeFilter = function (window, handler) {
1156        return IsBrowserIe9Earlier() ? function () {
1157
1158            var trigger = true;
1159
1160            var checkElement = (IsBrowserIeQuirks() ? window.document.body : window.document.documentElement);
1161            if (checkElement) {
1162                //check vertical bar
1163                //var hasVerticalBar = checkElement.scrollHeight > checkElement.clientHeight;
1164                //var verticalBarToggle = hasVerticalBar != ie8LastVerticalScrollbar;
1165                //ie8LastVerticalScrollbar = hasVerticalBar;
1166
1167                var widthChange = checkElement.offsetWidth - ie8OffsetWidth;
1168                var heightChange = checkElement.offsetHeight - ie8OffsetHeight;
1169                if (widthChange || heightChange) {
1170                    ie8OffsetWidth += widthChange;
1171                    ie8OffsetHeight += heightChange;
1172                }
1173                else
1174                    trigger = false;
1175            }
1176
1177            trigger && handler();
1178
1179        } : handler;
1180    };
1181
1182    _This.$MouseOverOutFilter = function (handler, target) {
1183        ///	<param name="target" type="HTMLDomElement">
1184        ///		The target element to detect mouse over/out events. (for ie < 9 compatibility)
1185        ///	</param>
1186
1187        $JssorDebug$.$Execute(function () {
1188            if (!target) {
1189                throw new Error("Null reference, parameter \"target\".");
1190            }
1191        });
1192
1193        return function (event) {
1194            event = GetEvent(event);
1195
1196            var eventName = event.type;
1197            var related = event.relatedTarget || (eventName == "mouseout" ? event.toElement : event.fromElement);
1198
1199            if (!related || (related !== target && !_This.$IsChild(target, related))) {
1200                handler(event);
1201            }
1202        };
1203    };
1204
1205    _This.$AddEvent = function (elmt, eventName, handler, useCapture) {
1206        elmt = _This.$GetElement(elmt);
1207
1208        $JssorDebug$.$Execute(function () {
1209            if (!elmt) {
1210                $JssorDebug$.$Fail("Parameter 'elmt' not specified.");
1211            }
1212
1213            if (!handler) {
1214                $JssorDebug$.$Fail("Parameter 'handler' not specified.");
1215            }
1216
1217            if (!elmt.addEventListener && !elmt.attachEvent) {
1218                $JssorDebug$.$Fail("Unable to attach event handler, no known technique.");
1219            }
1220        });
1221
1222        // technique from:
1223        // http://blog.paranoidferret.com/index.php/2007/08/10/javascript-working-with-events/
1224
1225        //function Handler(event) {
1226        //    handler(event || window.event);
1227        //}
1228
1229        if (elmt.addEventListener) {
1230            if (eventName == "mousewheel") {
1231                elmt.addEventListener("DOMMouseScroll", handler, useCapture);
1232            }
1233            // we are still going to add the mousewheel -- not a mistake!
1234            // _This is for opera, since it uses onmousewheel but needs addEventListener.
1235            elmt.addEventListener(eventName, handler, useCapture);
1236        }
1237        else if (elmt.attachEvent) {
1238            elmt.attachEvent("on" + eventName, handler);
1239            if (useCapture && elmt.setCapture) {
1240                elmt.setCapture();
1241            }
1242        }
1243    };
1244
1245    _This.$RemoveEvent = function (elmt, eventName, handler, useCapture) {
1246        elmt = _This.$GetElement(elmt);
1247
1248        // technique from:
1249        // http://blog.paranoidferret.com/index.php/2007/08/10/javascript-working-with-events/
1250
1251        if (elmt.removeEventListener) {
1252            if (eventName == "mousewheel") {
1253                elmt.removeEventListener("DOMMouseScroll", handler, useCapture);
1254            }
1255            // we are still going to remove the mousewheel -- not a mistake!
1256            // _This is for opera, since it uses onmousewheel but needs removeEventListener.
1257            elmt.removeEventListener(eventName, handler, useCapture);
1258        }
1259        else if (elmt.detachEvent) {
1260            elmt.detachEvent("on" + eventName, handler);
1261            if (useCapture && elmt.releaseCapture) {
1262                elmt.releaseCapture();
1263            }
1264        }
1265    };
1266
1267    _This.$FireEvent = function (elmt, eventName) {
1268        //var document = elmt.document;
1269
1270        $JssorDebug$.$Execute(function () {
1271            if (!document.createEvent && !document.createEventObject) {
1272                $JssorDebug$.$Fail("Unable to fire event, no known technique.");
1273            }
1274
1275            if (!elmt.dispatchEvent && !elmt.fireEvent) {
1276                $JssorDebug$.$Fail("Unable to fire event, no known technique.");
1277            }
1278        });
1279
1280        var evento;
1281
1282        if (document.createEvent) {
1283            evento = document.createEvent("HTMLEvents");
1284            evento.initEvent(eventName, false, false);
1285            elmt.dispatchEvent(evento);
1286        }
1287        else {
1288            var ieEventName = "on" + eventName;
1289            evento = document.createEventObject();
1290            //event.eventType = ieEventName;
1291            //event.eventName = ieEventName;
1292
1293            elmt.fireEvent(ieEventName, evento);
1294        }
1295    };
1296
1297    //_This.$AddEventBrowserMouseUp = function (handler, userCapture) {
1298    //    _This.$AddEvent((IsBrowserIe9Earlier()) ? document : window, "mouseup", handler, userCapture);
1299    //};
1300
1301    //_This.$RemoveEventBrowserMouseUp = function (handler, userCapture) {
1302    //    _This.$RemoveEvent((IsBrowserIe9Earlier()) ? document : window, "mouseup", handler, userCapture);
1303    //};
1304
1305    //_This.$AddEventBrowserMouseDown = function (handler, userCapture) {
1306    //    _This.$AddEvent((IsBrowserIe9Earlier()) ? document : window, "mousedown", handler, userCapture);
1307    //};
1308
1309    //_This.$RemoveEventBrowserMouseDown = function (handler, userCapture) {
1310    //    _This.$RemoveEvent((IsBrowserIe9Earlier()) ? document : window, "mousedown", handler, userCapture);
1311    //};
1312
1313    _This.$CancelEvent = function (event) {
1314        event = GetEvent(event);
1315
1316        // technique from:
1317        // http://blog.paranoidferret.com/index.php/2007/08/10/javascript-working-with-events/
1318
1319        if (event.preventDefault) {
1320            event.preventDefault();     // W3C for preventing default
1321        }
1322
1323        event.cancel = true;            // legacy for preventing default
1324        event.returnValue = false;      // IE for preventing default
1325    };
1326
1327    _This.$StopEvent = function (event) {
1328        event = GetEvent(event);
1329
1330        // technique from:
1331        // http://blog.paranoidferret.com/index.php/2007/08/10/javascript-working-with-events/
1332
1333        if (event.stopPropagation) {
1334            event.stopPropagation();    // W3C for stopping propagation
1335        }
1336
1337        event.cancelBubble = true;      // IE for stopping propagation
1338    };
1339
1340    _This.$CreateCallback = function (object, method) {
1341        // create callback args
1342        var initialArgs = [].slice.call(arguments, 2);
1343
1344        // create closure to apply method
1345        var callback = function () {
1346            // concatenate new args, but make a copy of initialArgs first
1347            var args = initialArgs.concat([].slice.call(arguments, 0));
1348
1349            return method.apply(object, args);
1350        };
1351
1352        //$JssorDebug$.$LiveStamp(callback, "callback_" + ($Jssor$.$GetNow() & 0xFFFFFF));
1353
1354        return callback;
1355    };
1356
1357    //var _Freeer;
1358    //_This.$FreeElement = function (elmt) {
1359    //    if (!_Freeer)
1360    //        _Freeer = _This.$CreateDiv();
1361
1362    //    if (elmt) {
1363    //        $Jssor$.$AppendChild(_Freeer, elmt);
1364    //        $Jssor$.$ClearInnerHtml(_Freeer);
1365    //    }
1366    //};
1367
1368    _This.$InnerText = function (elmt, text) {
1369        if (text == undefined)
1370            return elmt.textContent || elmt.innerText;
1371
1372        var textNode = document.createTextNode(text);
1373        _This.$Empty(elmt);
1374        elmt.appendChild(textNode);
1375    };
1376
1377    _This.$InnerHtml = function (elmt, html) {
1378        if (html == undefined)
1379            return elmt.innerHTML;
1380
1381        elmt.innerHTML = html;
1382    };
1383
1384    _This.$GetClientRect = function (elmt) {
1385        var rect = elmt.getBoundingClientRect();
1386
1387        return { x: rect.left, y: rect.top, w: rect.right - rect.left, h: rect.bottom - rect.top };
1388    };
1389
1390    _This.$ClearInnerHtml = function (elmt) {
1391        elmt.innerHTML = "";
1392    };
1393
1394    _This.$EncodeHtml = function (text) {
1395        var div = _This.$CreateDiv();
1396        _This.$InnerText(div, text);
1397        return _This.$InnerHtml(div);
1398    };
1399
1400    _This.$DecodeHtml = function (html) {
1401        var div = _This.$CreateDiv();
1402        _This.$InnerHtml(div, html);
1403        return _This.$InnerText(div);
1404    };
1405
1406    _This.$SelectElement = function (elmt) {
1407        var userSelection;
1408        if (window.getSelection) {
1409            //W3C default
1410            userSelection = window.getSelection();
1411        }
1412        var theRange = null;
1413        if (document.createRange) {
1414            theRange = document.createRange();
1415            theRange.selectNode(elmt);
1416        }
1417        else {
1418            theRange = document.body.createTextRange();
1419            theRange.moveToElementText(elmt);
1420            theRange.select();
1421        }
1422        //set user selection
1423        if (userSelection)
1424            userSelection.addRange(theRange);
1425    };
1426
1427    _This.$DeselectElements = function () {
1428        if (document.selection) {
1429            document.selection.empty();
1430        } else if (window.getSelection) {
1431            window.getSelection().removeAllRanges();
1432        }
1433    };
1434
1435    _This.$Children = function (elmt, includeAll) {
1436        var children = [];
1437
1438        for (var tmpEl = elmt.firstChild; tmpEl; tmpEl = tmpEl.nextSibling) {
1439            if (includeAll || tmpEl.nodeType == 1) {
1440                children.push(tmpEl);
1441            }
1442        }
1443
1444        return children;
1445    };
1446
1447    function FindChild(elmt, attrValue, noDeep, attrName) {
1448        attrName = attrName || "u";
1449
1450        for (elmt = elmt ? elmt.firstChild : null; elmt; elmt = elmt.nextSibling) {
1451            if (elmt.nodeType == 1) {
1452                if (AttributeEx(elmt, attrName) == attrValue)
1453                    return elmt;
1454
1455                if (!noDeep) {
1456                    var childRet = FindChild(elmt, attrValue, noDeep, attrName);
1457                    if (childRet)
1458                        return childRet;
1459                }
1460            }
1461        }
1462    }
1463
1464    _This.$FindChild = FindChild;
1465
1466    function FindChildren(elmt, attrValue, noDeep, attrName) {
1467        attrName = attrName || "u";
1468
1469        var ret = [];
1470
1471        for (elmt = elmt ? elmt.firstChild : null; elmt; elmt = elmt.nextSibling) {
1472            if (elmt.nodeType == 1) {
1473                if (AttributeEx(elmt, attrName) == attrValue)
1474                    ret.push(elmt);
1475
1476                if (!noDeep) {
1477                    var childRet = FindChildren(elmt, attrValue, noDeep, attrName);
1478                    if (childRet.length)
1479                        ret = ret.concat(childRet);
1480                }
1481            }
1482        }
1483
1484        return ret;
1485    }
1486
1487    _This.$FindChildren = FindChildren;
1488
1489    function FindChildByTag(elmt, tagName, noDeep) {
1490
1491        for (elmt = elmt ? elmt.firstChild : null; elmt; elmt = elmt.nextSibling) {
1492            if (elmt.nodeType == 1) {
1493                if (elmt.tagName == tagName)
1494                    return elmt;
1495
1496                if (!noDeep) {
1497                    var childRet = FindChildByTag(elmt, tagName, noDeep);
1498                    if (childRet)
1499                        return childRet;
1500                }
1501            }
1502        }
1503    }
1504
1505    _This.$FindChildByTag = FindChildByTag;
1506
1507    function FindChildrenByTag(elmt, tagName, noDeep) {
1508        var ret = [];
1509
1510        for (elmt = elmt ? elmt.firstChild : null; elmt; elmt = elmt.nextSibling) {
1511            if (elmt.nodeType == 1) {
1512                if (!tagName || elmt.tagName == tagName)
1513                    ret.push(elmt);
1514
1515                if (!noDeep) {
1516                    var childRet = FindChildrenByTag(elmt, tagName, noDeep);
1517                    if (childRet.length)
1518                        ret = ret.concat(childRet);
1519                }
1520            }
1521        }
1522
1523        return ret;
1524    }
1525
1526    _This.$FindChildrenByTag = FindChildrenByTag;
1527
1528    _This.$GetElementsByTag = function (elmt, tagName) {
1529        return elmt.getElementsByTagName(tagName);
1530    };
1531
1532    function Extend(target) {
1533        for (var i = 1; i < arguments.length; i++) {
1534
1535            var options = arguments[i];
1536
1537            // Only deal with non-null/undefined values
1538            if (options) {
1539                // Extend the base object
1540                for (var name in options) {
1541                    target[name] = options[name];
1542                }
1543            }
1544        }
1545
1546        // Return the modified object
1547        return target;
1548    }
1549
1550    _This.$Extend = Extend;
1551
1552    function Unextend(target, options) {
1553        $JssorDebug$.$Assert(options);
1554
1555        var unextended = {};
1556
1557        // Extend the base object
1558        for (var name in target) {
1559            if (target[name] !== options[name]) {
1560                unextended[name] = target[name];
1561            }
1562        }
1563
1564        // Return the modified object
1565        return unextended;
1566    }
1567
1568    _This.$Unextend = Unextend;
1569
1570    _This.$IsUndefined = function (obj) {
1571        return type(obj) == "undefined";
1572    };
1573
1574    _This.$IsFunction = function (obj) {
1575        return type(obj) == "function";
1576    };
1577
1578    _This.$IsArray = function (obj) {
1579        return type(obj) == "array";
1580    };
1581
1582    _This.$IsString = function (obj) {
1583        return type(obj) == "string";
1584    };
1585
1586    _This.$IsNumeric = function (obj) {
1587        return !isNaN(ParseFloat(obj)) && isFinite(obj);
1588    };
1589
1590    _This.$IsWindow = function (obj) {
1591        return obj && obj == obj.window;
1592    };
1593
1594    _This.$Type = type;
1595
1596    // args is for internal usage only
1597    _This.$Each = each;
1598
1599    _This.$IsPlainObject = isPlainObject;
1600
1601    function CreateElement(tagName) {
1602        return document.createElement(tagName);
1603    }
1604
1605    _This.$CreateElement = CreateElement;
1606
1607    _This.$CreateDiv = function () {
1608        return CreateElement("DIV", document);
1609    };
1610
1611    _This.$CreateSpan = function () {
1612        return CreateElement("SPAN", document);
1613    };
1614
1615    _This.$EmptyFunction = function () { };
1616
1617    function Attribute(elmt, name, value) {
1618        if (value == undefined)
1619            return elmt.getAttribute(name);
1620
1621        elmt.setAttribute(name, value);
1622    }
1623
1624    function AttributeEx(elmt, name) {
1625        return Attribute(elmt, name) || Attribute(elmt, "data-" + name);
1626    }
1627
1628    _This.$Attribute = Attribute;
1629    _This.$AttributeEx = AttributeEx;
1630
1631    function ClassName(elmt, className) {
1632        if (className == undefined)
1633            return elmt.className;
1634
1635        elmt.className = className;
1636    }
1637
1638    _This.$ClassName = ClassName;
1639
1640    function ToHash(array) {
1641        var hash = {};
1642
1643        each(array, function (item) {
1644            hash[item] = item;
1645        });
1646
1647        return hash;
1648    }
1649
1650    _This.$ToHash = ToHash;
1651
1652    function Join(separator, strings) {
1653        ///	<param name="separator" type="String">
1654        ///		The element to show the dialog around
1655        ///	</param>
1656        ///	<param name="strings" type="Array" value="['1']">
1657        ///		The element to show the dialog around
1658        ///	</param>
1659
1660        var joined = "";
1661
1662        each(strings, function (str) {
1663            joined && (joined += separator);
1664            joined += str;
1665        });
1666
1667        return joined;
1668    }
1669
1670    _This.$Join = Join;
1671
1672    _This.$AddClass = function (elmt, className) {
1673        var newClassName = ClassName(elmt) + " " + className;
1674        ClassName(elmt, Join(" ", ToHash(newClassName.match(REGEX_WHITESPACE_GLOBAL))));
1675    };
1676
1677    _This.$RemoveClass = function (elmt, className) {
1678        ClassName(elmt, Join(" ", _This.$Unextend(ToHash(ClassName(elmt).match(REGEX_WHITESPACE_GLOBAL)), ToHash(className.match(REGEX_WHITESPACE_GLOBAL)))));
1679    };
1680
1681    _This.$ParentNode = function (elmt) {
1682        return elmt.parentNode;
1683    };
1684
1685    _This.$HideElement = function (elmt) {
1686        _This.$CssDisplay(elmt, "none");
1687    };
1688
1689    _This.$EnableElement = function (elmt, notEnable) {
1690        if (notEnable) {
1691            _This.$Attribute(elmt, "disabled", true);
1692        }
1693        else {
1694            _This.$RemoveAttribute(elmt, "disabled");
1695        }
1696    };
1697
1698    _This.$HideElements = function (elmts) {
1699        for (var i = 0; i < elmts.length; i++) {
1700            _This.$HideElement(elmts[i]);
1701        }
1702    };
1703
1704    _This.$ShowElement = function (elmt, hide) {
1705        _This.$CssDisplay(elmt, hide ? "none" : "");
1706    };
1707
1708    _This.$ShowElements = function (elmts, hide) {
1709        for (var i = 0; i < elmts.length; i++) {
1710            _This.$ShowElement(elmts[i], hide);
1711        }
1712    };
1713
1714    _This.$RemoveAttribute = function (elmt, attrbuteName) {
1715        elmt.removeAttribute(attrbuteName);
1716    };
1717
1718    _This.$CanClearClip = function () {
1719        return IsBrowserIE() && _BrowserRuntimeVersion < 10;
1720    };
1721
1722    _This.$SetStyleClip = function (elmt, clip) {
1723        if (clip) {
1724            elmt.style.clip = "rect(" + Math.round(clip.$Top) + "px " + Math.round(clip.$Right) + "px " + Math.round(clip.$Bottom) + "px " + Math.round(clip.$Left) + "px)";
1725        }
1726        else {
1727            var cssText = elmt.style.cssText;
1728            var clipRegs = [
1729                new RegExp(/[\s]*clip: rect\(.*?\)[;]?/i),
1730                new RegExp(/[\s]*cliptop: .*?[;]?/i),
1731                new RegExp(/[\s]*clipright: .*?[;]?/i),
1732                new RegExp(/[\s]*clipbottom: .*?[;]?/i),
1733                new RegExp(/[\s]*clipleft: .*?[;]?/i)
1734            ];
1735
1736            var newCssText = BuildNewCss(cssText, clipRegs, "");
1737
1738            $Jssor$.$CssCssText(elmt, newCssText);
1739        }
1740    };
1741
1742    _This.$GetNow = function () {
1743        return new Date().getTime();
1744    };
1745
1746    _This.$AppendChild = function (elmt, child) {
1747        elmt.appendChild(child);
1748    };
1749
1750    _This.$AppendChildren = function (elmt, children) {
1751        each(children, function (child) {
1752            _This.$AppendChild(elmt, child);
1753        });
1754    };
1755
1756    _This.$InsertBefore = function (newNode, refNode, pNode) {
1757        ///	<summary>
1758        ///		Insert a node before a reference node
1759        ///	</summary>
1760        ///	<param name="newNode" type="HTMLElement">
1761        ///		A new node to insert
1762        ///	</param>
1763        ///	<param name="refNode" type="HTMLElement">
1764        ///		The reference node to insert a new node before
1765        ///	</param>
1766        ///	<param name="pNode" type="HTMLElement" optional="true">
1767        ///		The parent node to insert node to
1768        ///	</param>
1769
1770        (pNode || refNode.parentNode).insertBefore(newNode, refNode);
1771    };
1772
1773    _This.$InsertAfter = function (newNode, refNode, pNode) {
1774        ///	<summary>
1775        ///		Insert a node after a reference node
1776        ///	</summary>
1777        ///	<param name="newNode" type="HTMLElement">
1778        ///		A new node to insert
1779        ///	</param>
1780        ///	<param name="refNode" type="HTMLElement">
1781        ///		The reference node to insert a new node after
1782        ///	</param>
1783        ///	<param name="pNode" type="HTMLElement" optional="true">
1784        ///		The parent node to insert node to
1785        ///	</param>
1786
1787        _This.$InsertBefore(newNode, refNode.nextSibling, pNode || refNode.parentNode);
1788    };
1789
1790    _This.$InsertAdjacentHtml = function (elmt, where, text) {
1791        elmt.insertAdjacentHTML(where, text);
1792    };
1793
1794    _This.$RemoveElement = function (elmt, pNode) {
1795        ///	<summary>
1796        ///		Remove element from parent node
1797        ///	</summary>
1798        ///	<param name="elmt" type="HTMLElement">
1799        ///		The element to remove
1800        ///	</param>
1801        ///	<param name="pNode" type="HTMLElement" optional="true">
1802        ///		The parent node to remove elment from
1803        ///	</param>
1804        (pNode || elmt.parentNode).removeChild(elmt);
1805    };
1806
1807    _This.$RemoveElements = function (elmts, pNode) {
1808        each(elmts, function (elmt) {
1809            _This.$RemoveElement(elmt, pNode);
1810        });
1811    };
1812
1813    _This.$Empty = function (elmt) {
1814        _This.$RemoveElements(_This.$Children(elmt, true), elmt);
1815    };
1816
1817    _This.$ParseInt = function (str, radix) {
1818        return parseInt(str, radix || 10);
1819    };
1820
1821    var ParseFloat = parseFloat;
1822
1823    _This.$ParseFloat = ParseFloat;
1824
1825    _This.$IsChild = function (elmtA, elmtB) {
1826        var body = document.body;
1827
1828        while (elmtB && elmtA !== elmtB && body !== elmtB) {
1829            try {
1830                elmtB = elmtB.parentNode;
1831            } catch (e) {
1832                // Firefox sometimes fires events for XUL elements, which throws
1833                // a "permission denied" error. so this is not a child.
1834                return false;
1835            }
1836        }
1837
1838        return elmtA === elmtB;
1839    };
1840
1841    function CloneNode(elmt, noDeep, keepId) {
1842        var clone = elmt.cloneNode(!noDeep);
1843        if (!keepId) {
1844            _This.$RemoveAttribute(clone, "id");
1845        }
1846
1847        return clone;
1848    }
1849
1850    _This.$CloneNode = CloneNode;
1851
1852    //function TranslateTransition(transition) {
1853    //    if (transition) {
1854    //        var flyDirection = transition.$FlyDirection;
1855
1856    //        if (flyDirection & 1) {
1857    //            transition.x = transition.$ScaleHorizontal || 1;
1858    //        }
1859    //        if (flyDirection & 2) {
1860    //            transition.x = -transition.$ScaleHorizontal || -1;
1861    //        }
1862    //        if (flyDirection & 4) {
1863    //            transition.y = transition.$ScaleVertical || 1;
1864    //        }
1865    //        if (flyDirection & 8) {
1866    //            transition.y = -transition.$ScaleVertical || -1;
1867    //        }
1868
1869    //        if (transition.$Rotate == true)
1870    //            transition.$Rotate = 1;
1871
1872    //        TranslateTransition(transition.$Brother);
1873    //    }
1874    //}
1875
1876    //_This.$TranslateTransitions = function (transitions) {
1877    //    ///	<summary>
1878    //    ///		For backward compatibility only.
1879    //    ///	</summary>
1880    //    if (transitions) {
1881    //        for (var i = 0; i < transitions.length; i++) {
1882    //            TranslateTransition(transitions[i]);
1883    //        }
1884    //        for (var name in transitions) {
1885    //            TranslateTransition(transitions[name]);
1886    //        }
1887    //    }
1888    //};
1889
1890    //function ImageLoader() {
1891    //    var _ThisImageLoader = this;
1892    //    var _BaseImageLoader = _This.$Inherit(_ThisImageLoader, $JssorObject$);
1893
1894    //    var _ImageLoading = 1;
1895    //    var _MainImageSrc;
1896    //    var _MainImage;
1897    //    var _CompleteCallback;
1898    //    var _MainImageAbort;
1899
1900    //    function LoadCompleteCallback(image, abort) {
1901    //        _ImageLoading--;
1902
1903    //        if (image) {
1904    //            _This.$RemoveEvent(image, "load");
1905    //            _This.$RemoveEvent(image, "abort");
1906    //            _This.$RemoveEvent(image, "error");
1907
1908    //            if (_MainImageSrc == image.src) {
1909    //                _MainImage = image;
1910    //                _MainImageAbort = abort;
1911    //            }
1912    //        }
1913
1914    //        _CompleteCallback && _CompleteCallback(_MainImage, _MainImageAbort);
1915    //    }
1916
1917    //    function LoadImage(src) {
1918    //        _ImageLoading++;
1919
1920    //        if (IsBrowserOpera() && _BrowserRuntimeVersion < 11.6 || !src) {
1921    //            LoadImageCallback(callback, null, !src);
1922    //        }
1923    //        else {
1924    //            var image = new Image();
1925
1926    //            _This.$AddEvent(image, "load", _This.$CreateCallback(null, LoadImageCallback, image, false));
1927
1928    //            var abortHandler = _This.$CreateCallback(null, LoadImageCallback, image, true);
1929    //            _This.$AddEvent(image, "abort", abortHandler);
1930    //            _This.$AddEvent(image, "error", abortHandler);
1931
1932    //            image.src = src;
1933    //        }
1934    //    }
1935
1936    //    _ThisImageLoader.$LoadImage = function (src, callback) {
1937    //        _MainImageSrc = src;
1938    //        _CompleteCallback = callback;
1939
1940    //        LoadImage(src);
1941    //        LoadComplete();
1942    //    };
1943
1944    //    _ThisImageLoader.$LoadImages = function (imageElmts, mainImageElmt, callback) {
1945    //        mainImageElmt && (_MainImageSrc = mainImageElmt.src);
1946    //        _CompleteCallback = callback;
1947
1948    //        each(imageElmts, function (imageElmt) {
1949    //            LoadImage(imageElmt.src);
1950    //        });
1951    //        LoadComplete();
1952    //    };
1953    //}
1954
1955    _This.$LoadImage = function (src, callback) {
1956        var image = new Image();
1957
1958        function LoadImageCompleteHandler(event, abort) {
1959            _This.$RemoveEvent(image, "load", LoadImageCompleteHandler);
1960            _This.$RemoveEvent(image, "abort", ErrorOrAbortHandler);
1961            _This.$RemoveEvent(image, "error", ErrorOrAbortHandler);
1962
1963            if (callback)
1964                callback(image, abort);
1965        }
1966
1967        function ErrorOrAbortHandler(event) {
1968            LoadImageCompleteHandler(event, true);
1969        }
1970
1971        if (IsBrowserOpera() && _BrowserRuntimeVersion < 11.6 || !src) {
1972            LoadImageCompleteHandler(!src);
1973        }
1974        else {
1975
1976            _This.$AddEvent(image, "load", LoadImageCompleteHandler);
1977            _This.$AddEvent(image, "abort", ErrorOrAbortHandler);
1978            _This.$AddEvent(image, "error", ErrorOrAbortHandler);
1979
1980            image.src = src;
1981        }
1982    };
1983
1984    _This.$LoadImages = function (imageElmts, mainImageElmt, callback) {
1985
1986        var _ImageLoading = imageElmts.length + 1;
1987
1988        function LoadImageCompleteEventHandler(image, abort) {
1989
1990            _ImageLoading--;
1991            if (mainImageElmt && image && image.src == mainImageElmt.src)
1992                mainImageElmt = image;
1993            !_ImageLoading && callback && callback(mainImageElmt);
1994        }
1995
1996        each(imageElmts, function (imageElmt) {
1997            _This.$LoadImage(imageElmt.src, LoadImageCompleteEventHandler);
1998        });
1999
2000        LoadImageCompleteEventHandler();
2001    };
2002
2003    _This.$BuildElement = function (template, tagName, replacer, createCopy) {
2004        if (createCopy)
2005            template = CloneNode(template);
2006
2007        var templateHolders = FindChildren(template, tagName);
2008        if (!templateHolders.length)
2009            templateHolders = $Jssor$.$GetElementsByTag(template, tagName);
2010
2011        for (var j = templateHolders.length - 1; j > -1; j--) {
2012            var templateHolder = templateHolders[j];
2013            var replaceItem = CloneNode(replacer);
2014            ClassName(replaceItem, ClassName(templateHolder));
2015            $Jssor$.$CssCssText(replaceItem, templateHolder.style.cssText);
2016
2017            $Jssor$.$InsertBefore(replaceItem, templateHolder);
2018            $Jssor$.$RemoveElement(templateHolder);
2019        }
2020
2021        return template;
2022    };
2023
2024    function JssorButtonEx(elmt) {
2025        var _Self = this;
2026
2027        var _OriginClassName;
2028
2029        var _IsMouseDown;   //class name 'dn'
2030        var _IsSelected;    //class name 1(active): 'av', 2(passive): 'pv'
2031        var _IsDisabled;    //class name 'ds'
2032
2033        function Highlight() {
2034            var className = _OriginClassName;
2035
2036            if (_IsDisabled) {
2037                className += 'ds';
2038            }
2039            else if (_IsMouseDown) {
2040                className += 'dn';
2041            }
2042            else if (_IsSelected == 2) {
2043                className += "pv";
2044            }
2045            else if (_IsSelected) {
2046                className += "av";
2047            }
2048
2049            ClassName(elmt, className);
2050        }
2051
2052        function MouseUpOrCancelEventHandler(event) {
2053            _IsMouseDown = false;
2054
2055            Highlight();
2056
2057            _This.$RemoveEvent(document, Device().$Evt_Up, MouseUpOrCancelEventHandler);
2058            Device().$Evt_Cancel && _This.$RemoveEvent(document, Device().$Evt_Cancel, MouseUpOrCancelEventHandler);
2059        }
2060
2061        function MouseDownEventHandler(event) {
2062            if (_IsDisabled) {
2063                _This.$CancelEvent(event);
2064            }
2065            else {
2066
2067                _IsMouseDown = true;
2068
2069                Highlight();
2070
2071                _This.$AddEvent(document, Device().$Evt_Up, MouseUpOrCancelEventHandler);
2072                Device().$Evt_Cancel && _This.$AddEvent(document, Device().$Evt_Cancel, MouseUpOrCancelEventHandler);
2073            }
2074        }
2075
2076        _Self.$Selected = function (activate) {
2077            if (activate != undefined) {
2078                _IsSelected = activate;
2079
2080                Highlight();
2081            }
2082            else {
2083                return _IsSelected;
2084            }
2085        };
2086
2087        _Self.$Enable = function (enable) {
2088            if (enable != undefined) {
2089                _IsDisabled = !enable;
2090
2091                Highlight();
2092            }
2093            else {
2094                return !_IsDisabled;
2095            }
2096        };
2097
2098        //JssorButtonEx Constructor
2099        {
2100            elmt = _This.$GetElement(elmt);
2101
2102            _OriginClassName = ClassName(elmt);
2103
2104            $Jssor$.$AddEvent(elmt, Device().$Evt_Down, MouseDownEventHandler);
2105        }
2106    }
2107
2108    _This.$Buttonize = function (elmt) {
2109        return new JssorButtonEx(elmt);
2110    };
2111
2112    _This.$Css = Css;
2113    _This.$CssN = CssN;
2114    _This.$CssP = CssP;
2115
2116    _This.$CssOverflow = CssProxy("overflow");
2117
2118    _This.$CssTop = CssProxy("top", 2);
2119    _This.$CssLeft = CssProxy("left", 2);
2120    _This.$CssWidth = CssProxy("width", 2);
2121    _This.$CssHeight = CssProxy("height", 2);
2122    _This.$CssMarginLeft = CssProxy("marginLeft", 2);
2123    _This.$CssMarginTop = CssProxy("marginTop", 2);
2124    _This.$CssPosition = CssProxy("position");
2125    _This.$CssDisplay = CssProxy("display");
2126    _This.$CssZIndex = CssProxy("zIndex", 1);
2127    _This.$CssFloat = function (elmt, floatValue) {
2128        return Css(elmt, IsBrowserIE() ? "styleFloat" : "cssFloat", floatValue);
2129    };
2130    _This.$CssOpacity = function (elmt, opacity, ie9EarlierForce) {
2131        if (opacity != undefined) {
2132            SetStyleOpacity(elmt, opacity, ie9EarlierForce);
2133        }
2134        else {
2135            return GetStyleOpacity(elmt);
2136        }
2137    };
2138
2139    _This.$CssCssText = function (elmt, text) {
2140        if (text != undefined) {
2141            elmt.style.cssText = text;
2142        }
2143        else {
2144            return elmt.style.cssText;
2145        }
2146    };
2147
2148    var _StyleGetter = {
2149        $Opacity: _This.$CssOpacity,
2150        $Top: _This.$CssTop,
2151        $Left: _This.$CssLeft,
2152        $Width: _This.$CssWidth,
2153        $Height: _This.$CssHeight,
2154        $Position: _This.$CssPosition,
2155        $Display: _This.$CssDisplay,
2156        $ZIndex: _This.$CssZIndex
2157    };
2158
2159    var _StyleSetterReserved;
2160
2161    function StyleSetter() {
2162        if (!_StyleSetterReserved) {
2163            _StyleSetterReserved = Extend({
2164                $MarginTop: _This.$CssMarginTop,
2165                $MarginLeft: _This.$CssMarginLeft,
2166                $Clip: _This.$SetStyleClip,
2167                $Transform: _This.$SetStyleTransform
2168            }, _StyleGetter);
2169        }
2170        return _StyleSetterReserved;
2171    }
2172
2173    function StyleSetterEx() {
2174        StyleSetter();
2175
2176        //For Compression Only
2177        _StyleSetterReserved.$Transform = _StyleSetterReserved.$Transform;
2178
2179        return _StyleSetterReserved;
2180    }
2181
2182    _This.$StyleSetter = StyleSetter;
2183
2184    _This.$StyleSetterEx = StyleSetterEx;
2185
2186    _This.$GetStyles = function (elmt, originStyles) {
2187        StyleSetter();
2188
2189        var styles = {};
2190
2191        each(originStyles, function (value, key) {
2192            if (_StyleGetter[key]) {
2193                styles[key] = _StyleGetter[key](elmt);
2194            }
2195        });
2196
2197        return styles;
2198    };
2199
2200    _This.$SetStyles = function (elmt, styles) {
2201        var styleSetter = StyleSetter();
2202
2203        each(styles, function (value, key) {
2204            styleSetter[key] && styleSetter[key](elmt, value);
2205        });
2206    };
2207
2208    _This.$SetStylesEx = function (elmt, styles) {
2209        StyleSetterEx();
2210
2211        _This.$SetStyles(elmt, styles);
2212    };
2213
2214    var $JssorMatrix$ = new function () {
2215        var _ThisMatrix = this;
2216
2217        function Multiply(ma, mb) {
2218            var acs = ma[0].length;
2219            var rows = ma.length;
2220            var cols = mb[0].length;
2221
2222            var matrix = [];
2223
2224            for (var r = 0; r < rows; r++) {
2225                var row = matrix[r] = [];
2226                for (var c = 0; c < cols; c++) {
2227                    var unitValue = 0;
2228
2229                    for (var ac = 0; ac < acs; ac++) {
2230                        unitValue += ma[r][ac] * mb[ac][c];
2231                    }
2232
2233                    row[c] = unitValue;
2234                }
2235            }
2236
2237            return matrix;
2238        }
2239
2240        _ThisMatrix.$ScaleX = function (matrix, sx) {
2241            return _ThisMatrix.$ScaleXY(matrix, sx, 0);
2242        };
2243
2244        _ThisMatrix.$ScaleY = function (matrix, sy) {
2245            return _ThisMatrix.$ScaleXY(matrix, 0, sy);
2246        };
2247
2248        _ThisMatrix.$ScaleXY = function (matrix, sx, sy) {
2249            return Multiply(matrix, [[sx, 0], [0, sy]]);
2250        };
2251
2252        _ThisMatrix.$TransformPoint = function (matrix, p) {
2253            var pMatrix = Multiply(matrix, [[p.x], [p.y]]);
2254
2255            return Point(pMatrix[0][0], pMatrix[1][0]);
2256        };
2257    };
2258
2259    _This.$CreateMatrix = function (alpha, scaleX, scaleY) {
2260        var cos = Math.cos(alpha);
2261        var sin = Math.sin(alpha);
2262        //var r11 = cos;
2263        //var r21 = sin;
2264        //var r12 = -sin;
2265        //var r22 = cos;
2266
2267        //var m11 = cos * scaleX;
2268        //var m12 = -sin * scaleY;
2269        //var m21 = sin * scaleX;
2270        //var m22 = cos * scaleY;
2271
2272        return [[cos * scaleX, -sin * scaleY], [sin * scaleX, cos * scaleY]];
2273    };
2274
2275    _This.$GetMatrixOffset = function (matrix, width, height) {
2276        var p1 = $JssorMatrix$.$TransformPoint(matrix, Point(-width / 2, -height / 2));
2277        var p2 = $JssorMatrix$.$TransformPoint(matrix, Point(width / 2, -height / 2));
2278        var p3 = $JssorMatrix$.$TransformPoint(matrix, Point(width / 2, height / 2));
2279        var p4 = $JssorMatrix$.$TransformPoint(matrix, Point(-width / 2, height / 2));
2280
2281        return Point(Math.min(p1.x, p2.x, p3.x, p4.x) + width / 2, Math.min(p1.y, p2.y, p3.y, p4.y) + height / 2);
2282    };
2283
2284    _This.$Cast = function (fromStyles, difStyles, interPosition, easings, durings, rounds, options) {
2285
2286        var currentStyles = difStyles;
2287
2288        if (fromStyles) {
2289            currentStyles = {};
2290
2291            for (var key in difStyles) {
2292
2293                var round = rounds[key] || 1;
2294                var during = durings[key] || [0, 1];
2295                var propertyInterPosition = (interPosition - during[0]) / during[1];
2296                propertyInterPosition = Math.min(Math.max(propertyInterPosition, 0), 1);
2297                propertyInterPosition = propertyInterPosition * round;
2298                var floorPosition = Math.floor(propertyInterPosition);
2299                if (propertyInterPosition != floorPosition)
2300                    propertyInterPosition -= floorPosition;
2301
2302                var easing = easings[key] || easings.$Default || $JssorEasing$.$EaseSwing;
2303                var easingValue = easing(propertyInterPosition);
2304                var currentPropertyValue;
2305                var value = fromStyles[key];
2306                var toValue = difStyles[key];
2307                var difValue = difStyles[key];
2308
2309                if ($Jssor$.$IsNumeric(difValue)) {
2310                    currentPropertyValue = value + difValue * easingValue;
2311                }
2312                else {
2313                    currentPropertyValue = $Jssor$.$Extend({ $Offset: {} }, fromStyles[key]);
2314
2315                    $Jssor$.$Each(difValue.$Offset, function (rectX, n) {
2316                        var offsetValue = rectX * easingValue;
2317                        currentPropertyValue.$Offset[n] = offsetValue;
2318                        currentPropertyValue[n] += offsetValue;
2319                    });
2320                }
2321                currentStyles[key] = currentPropertyValue;
2322            }
2323
2324            if (difStyles.$Zoom || difStyles.$Rotate) {
2325                currentStyles.$Transform = { $Rotate: currentStyles.$Rotate || 0, $Scale: currentStyles.$Zoom, $OriginalWidth: options.$OriginalWidth, $OriginalHeight: options.$OriginalHeight };
2326            }
2327        }
2328
2329        if (difStyles.$Clip && options.$Move) {
2330            var styleFrameNClipOffset = currentStyles.$Clip.$Offset;
2331
2332            var offsetY = (styleFrameNClipOffset.$Top || 0) + (styleFrameNClipOffset.$Bottom || 0);
2333            var offsetX = (styleFrameNClipOffset.$Left || 0) + (styleFrameNClipOffset.$Right || 0
2333);
2334
2335            currentStyles.$Left = (currentStyles.$Left || 0) + offsetX;
2336            currentStyles.$Top = (currentStyles.$Top || 0) + offsetY;
2337            currentStyles.$Clip.$Left -= offsetX;
2338            currentStyles.$Clip.$Right -= offsetX;
2339            currentStyles.$Clip.$Top -= offsetY;
2340            currentStyles.$Clip.$Bottom -= offsetY;
2341        }
2342
2343        if (currentStyles.$Clip && $Jssor$.$CanClearClip() && !currentStyles.$Clip.$Top && !currentStyles.$Clip.$Left && (currentStyles.$Clip.$Right == options.$OriginalWidth) && (currentStyles.$Clip.$Bottom == options.$OriginalHeight))
2344            currentStyles.$Clip = null;
2345
2346        return currentStyles;
2347    };
2348};
2349
2350//$JssorObject$
2351function $JssorObject$() {
2352    var _ThisObject = this;
2353    // Fields
2354
2355    var _Listeners = []; // dictionary of eventName --> array of handlers
2356    var _Listenees = [];
2357
2358    // Private Methods
2359    function AddListener(eventName, handler) {
2360
2361        $JssorDebug$.$Execute(function () {
2362            if (eventName == undefined || eventName == null)
2363                throw new Error("param 'eventName' is null or empty.");
2364
2365            if (typeof (handler) != "function") {
2366                throw "param 'handler' must be a function.";
2367            }
2368
2369            $Jssor$.$Each(_Listeners, function (listener) {
2370                if (listener.$EventName == eventName && listener.$Handler === handler) {
2371                    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.");
2372                }
2373            });
2374        });
2375
2376        _Listeners.push({ $EventName: eventName, $Handler: handler });
2377    }
2378
2379    function RemoveListener(eventName, handler) {
2380
2381        $JssorDebug$.$Execute(function () {
2382            if (eventName == undefined || eventName == null)
2383                throw new Error("param 'eventName' is null or empty.");
2384
2385            if (typeof (handler) != "function") {
2386                throw "param 'handler' must be a function.";
2387            }
2388        });
2389
2390        $Jssor$.$Each(_Listeners, function (listener, index) {
2391            if (listener.$EventName == eventName && listener.$Handler === handler) {
2392                _Listeners.splice(index, 1);
2393            }
2394        });
2395    }
2396
2397    function ClearListeners() {
2398        _Listeners = [];
2399    }
2400
2401    function ClearListenees() {
2402
2403        $Jssor$.$Each(_Listenees, function (listenee) {
2404            $Jssor$.$RemoveEvent(listenee.$Obj, listenee.$EventName, listenee.$Handler);
2405        });
2406
2407        _Listenees = [];
2408    }
2409
2410    //Protected Methods
2411    _ThisObject.$Listen = function (obj, eventName, handler, useCapture) {
2412
2413        $JssorDebug$.$Execute(function () {
2414            if (!obj)
2415                throw new Error("param 'obj' is null or empty.");
2416
2417            if (eventName == undefined || eventName == null)
2418                throw new Error("param 'eventName' is null or empty.");
2419
2420            if (typeof (handler) != "function") {
2421                throw "param 'handler' must be a function.";
2422            }
2423
2424            $Jssor$.$Each(_Listenees, function (listenee) {
2425                if (listenee.$Obj === obj && listenee.$EventName == eventName && listenee.$Handler === handler) {
2426                    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.");
2427                }
2428            });
2429        });
2430
2431        $Jssor$.$AddEvent(obj, eventName, handler, useCapture);
2432        _Listenees.push({ $Obj: obj, $EventName: eventName, $Handler: handler });
2433    };
2434
2435    _ThisObject.$Unlisten = function (obj, eventName, handler) {
2436
2437        $JssorDebug$.$Execute(function () {
2438            if (!obj)
2439                throw new Error("param 'obj' is null or empty.");
2440
2441            if (eventName == undefined || eventName == null)
2442                throw new Error("param 'eventName' is null or empty.");
2443
2444            if (typeof (handler) != "function") {
2445                throw "param 'handler' must be a function.";
2446            }
2447        });
2448
2449        $Jssor$.$Each(_Listenees, function (listenee, index) {
2450            if (listenee.$Obj === obj && listenee.$EventName == eventName && listenee.$Handler === handler) {
2451                $Jssor$.$RemoveEvent(obj, eventName, handler);
2452                _Listenees.splice(index, 1);
2453            }
2454        });
2455    };
2456
2457    _ThisObject.$UnlistenAll = ClearListenees;
2458
2459    // Public Methods
2460    _ThisObject.$On = _ThisObject.addEventListener = AddListener;
2461
2462    _ThisObject.$Off = _ThisObject.removeEventListener = RemoveListener;
2463
2464    _ThisObject.$TriggerEvent = function (eventName) {
2465
2466        var args = [].slice.call(arguments, 1);
2467
2468        $Jssor$.$Each(_Listeners, function (listener) {
2469            listener.$EventName == eventName && listener.$Handler.apply(window, args);
2470        });
2471    };
2472
2473    _ThisObject.$Destroy = function () {
2474        ClearListenees();
2475        ClearListeners();
2476
2477        for (var name in _ThisObject)
2478            delete _ThisObject[name];
2479    };
2480
2481    $JssorDebug$.$C_AbstractClass(_ThisObject);
2482};
2483
2484function $JssorAnimator$(delay, duration, options, elmt, fromStyles, difStyles) {
2485    delay = delay || 0;
2486
2487    var _ThisAnimator = this;
2488    var _AutoPlay;
2489    var _Hiden;
2490    var _CombineMode;
2491    var _PlayToPosition;
2492    var _PlayDirection;
2493    var _NoStop;
2494    var _TimeStampLastFrame = 0;
2495
2496    var _SubEasings;
2497    var _SubRounds;
2498    var _SubDurings;
2499    var _Callback;
2500
2501    var _Shift = 0;
2502    var _Position_Current = 0;
2503    var _Position_Display = 0;
2504    var _Hooked;
2505
2506    var _Position_InnerBegin = delay;
2507    var _Position_InnerEnd = delay + duration;
2508    var _Position_OuterBegin;
2509    var _Position_OuterEnd;
2510    var _LoopLength;
2511
2512    var _NestedAnimators = [];
2513    var _StyleSetter;
2514
2515    function GetPositionRange(position, begin, end) {
2516        var range = 0;
2517
2518        if (position < begin)
2519            range = -1;
2520
2521        else if (position > end)
2522            range = 1;
2523
2524        return range;
2525    }
2526
2527    function GetInnerPositionRange(position) {
2528        return GetPositionRange(position, _Position_InnerBegin, _Position_InnerEnd);
2529    }
2530
2531    function GetOuterPositionRange(position) {
2532        return GetPositionRange(position, _Position_OuterBegin, _Position_OuterEnd);
2533    }
2534
2535    function Shift(offset) {
2536        _Position_OuterBegin += offset;
2537        _Position_OuterEnd += offset;
2538        _Position_InnerBegin += offset;
2539        _Position_InnerEnd += offset;
2540
2541        _Position_Current += offset;
2542        _Position_Display += offset;
2543
2544        _Shift = offset;
2545    }
2546
2547    function Locate(position, relative) {
2548        var offset = position - _Position_OuterBegin + delay * relative;
2549
2550        Shift(offset);
2551
2552        //$JssorDebug$.$Execute(function () {
2553        //    _ThisAnimator.$Position_InnerBegin = _Position_InnerBegin;
2554        //    _ThisAnimator.$Position_InnerEnd = _Position_InnerEnd;
2555        //    _ThisAnimator.$Position_OuterBegin = _Position_OuterBegin;
2556        //    _ThisAnimator.$Position_OuterEnd = _Position_OuterEnd;
2557        //});
2558
2559        return _Position_OuterEnd;
2560    }
2561
2562    function GoToPosition(positionOuter, force) {
2563        var trimedPositionOuter = positionOuter;
2564
2565        if (_LoopLength && (trimedPositionOuter >= _Position_OuterEnd || trimedPositionOuter <= _Position_OuterBegin)) {
2566            trimedPositionOuter = ((trimedPositionOuter - _Position_OuterBegin) % _LoopLength + _LoopLength) % _LoopLength + _Position_OuterBegin;
2567        }
2568
2569        if (!_Hooked || _NoStop || force || _Position_Current != trimedPositionOuter) {
2570
2571            var positionToDisplay = Math.min(trimedPositionOuter, _Position_OuterEnd);
2572            positionToDisplay = Math.max(positionToDisplay, _Position_OuterBegin);
2573
2574            if (!_Hooked || _NoStop || force || positionToDisplay != _Position_Display) {
2575                if (difStyles) {
2576
2577                    var interPosition = (positionToDisplay - _Position_InnerBegin) / (duration || 1);
2578
2579                    if (options.$Reverse)
2580                        interPosition = 1 - interPosition;
2581
2582                    var currentStyles = $Jssor$.$Cast(fromStyles, difStyles, interPosition, _SubEasings, _SubDurings, _SubRounds, options);
2583
2584                    $Jssor$.$Each(currentStyles, function (value, key) {
2585                        _StyleSetter[key] && _StyleSetter[key](elmt, value);
2586                    });
2587                }
2588
2589                _ThisAnimator.$OnInnerOffsetChange(_Position_Display - _Position_InnerBegin, positionToDisplay - _Position_InnerBegin);
2590            }
2591
2592            _Position_Display = positionToDisplay;
2593
2594            $Jssor$.$Each(_NestedAnimators, function (animator, i) {
2595                var nestedAnimator = positionOuter < _Position_Current ? _NestedAnimators[_NestedAnimators.length - i - 1] : animator;
2596                nestedAnimator.$GoToPosition(positionOuter - _Shift, force);
2597            });
2598
2599            var positionOld = _Position_Current;
2600            var positionNew = positionOuter;
2601
2602            _Position_Current = trimedPositionOuter;
2603            _Hooked = true;
2604
2605            _ThisAnimator.$OnPositionChange(positionOld, positionNew);
2606        }
2607    }
2608
2609    function Join(animator, combineMode, noExpand) {
2610        ///	<summary>
2611        ///		Combine another animator as nested animator
2612        ///	</summary>
2613        ///	<param name="animator" type="$JssorAnimator$">
2614        ///		An instance of $JssorAnimator$
2615        ///	</param>
2616        ///	<param name="combineMode" type="int">
2617        ///		0: parallel - place the animator parallel to this animator.
2618        ///		1: chain - chain the animator at the _Position_InnerEnd of this animator.
2619        ///	</param>
2620        $JssorDebug$.$Execute(function () {
2621            if (combineMode !== 0 && combineMode !== 1)
2622                $JssorDebug$.$Fail("Argument out of range, the value of 'combineMode' should be either 0 or 1.");
2623        });
2624
2625        if (combineMode)
2626            animator.$Locate(_Position_OuterEnd, 1);
2627
2628        !noExpand && (_Position_OuterEnd = Math.max(_Position_OuterEnd, animator.$GetPosition_OuterEnd() + _Shift));
2629        _NestedAnimators.push(animator);
2630    }
2631
2632    var RequestAnimationFrame = window.requestAnimationFrame
2633    || window.webkitRequestAnimationFrame
2634    || window.mozRequestAnimationFrame
2635    || window.msRequestAnimationFrame;
2636
2637    if ($Jssor$.$IsBrowserSafari() && $Jssor$.$BrowserVersion() < 7) {
2638        RequestAnimationFrame = null;
2639
2640        $JssorDebug$.$Log("Custom animation frame for safari before 7.");
2641    }
2642
2643    RequestAnimationFrame = RequestAnimationFrame || function (callback) {
2644        $Jssor$.$Delay(callback, options.$Interval);
2645    };
2646
2647    function ShowFrame() {
2648        if (_AutoPlay) {
2649            var now = $Jssor$.$GetNow();
2650            var timeOffset = Math.min(now - _TimeStampLastFrame, options.$IntervalMax);
2651            var timePosition = _Position_Current + timeOffset * _PlayDirection;
2652            _TimeStampLastFrame = now;
2653
2654            if (timePosition * _PlayDirection >= _PlayToPosition * _PlayDirection)
2655                timePosition = _PlayToPosition;
2656
2657            GoToPosition(timePosition);
2658
2659            if (!_NoStop && timePosition * _PlayDirection >= _PlayToPosition * _PlayDirection) {
2660                Stop(_Callback);
2661            }
2662            else {
2663                RequestAnimationFrame(ShowFrame);
2664            }
2665        }
2666    }
2667
2668    function PlayToPosition(toPosition, callback, noStop) {
2669        if (!_AutoPlay) {
2670            _AutoPlay = true;
2671            _NoStop = noStop
2672            _Callback = callback;
2673            toPosition = Math.max(toPosition, _Position_OuterBegin);
2674            toPosition = Math.min(toPosition, _Position_OuterEnd);
2675            _PlayToPosition = toPosition;
2676            _PlayDirection = _PlayToPosition < _Position_Current ? -1 : 1;
2677            _ThisAnimator.$OnStart();
2678            _TimeStampLastFrame = $Jssor$.$GetNow();
2679            RequestAnimationFrame(ShowFrame);
2680        }
2681    }
2682
2683    function Stop(callback) {
2684        if (_AutoPlay) {
2685            _NoStop = _AutoPlay = _Callback = false;
2686            _ThisAnimator.$OnStop();
2687
2688            if (callback)
2689                callback();
2690        }
2691    }
2692
2693    _ThisAnimator.$Play = function (positionLength, callback, noStop) {
2694        PlayToPosition(positionLength ? _Position_Current + positionLength : _Position_OuterEnd, callback, noStop);
2695    };
2696
2697    _ThisAnimator.$PlayToPosition = PlayToPosition;
2698
2699    _ThisAnimator.$PlayToBegin = function (callback, noStop) {
2700        PlayToPosition(_Position_OuterBegin, callback, noStop);
2701    };
2702
2703    _ThisAnimator.$PlayToEnd = function (callback, noStop) {
2704        PlayToPosition(_Position_OuterEnd, callback, noStop);
2705    };
2706
2707    _ThisAnimator.$Stop = Stop;
2708
2709    _ThisAnimator.$Continue = function (toPosition) {
2710        PlayToPosition(toPosition);
2711    };
2712
2713    _ThisAnimator.$GetPosition = function () {
2714        return _Position_Current;
2715    };
2716
2717    _ThisAnimator.$GetPlayToPosition = function () {
2718        return _PlayToPosition;
2719    };
2720
2721    _ThisAnimator.$GetPosition_Display = function () {
2722        return _Position_Display;
2723    };
2724
2725    _ThisAnimator.$GoToPosition = GoToPosition;
2726
2727    _ThisAnimator.$GoToBegin = function () {
2728        GoToPosition(_Position_OuterBegin, true);
2729    };
2730
2731    _ThisAnimator.$GoToEnd = function () {
2732        GoToPosition(_Position_OuterEnd, true);
2733    };
2734
2735    _ThisAnimator.$Move = function (offset) {
2736        GoToPosition(_Position_Current + offset);
2737    };
2738
2739    _ThisAnimator.$CombineMode = function () {
2740        return _CombineMode;
2741    };
2742
2743    _ThisAnimator.$GetDuration = function () {
2744        return duration;
2745    };
2746
2747    _ThisAnimator.$IsPlaying = function () {
2748        return _AutoPlay;
2749    };
2750
2751    _ThisAnimator.$IsOnTheWay = function () {
2752        return _Position_Current > _Position_InnerBegin && _Position_Current <= _Position_InnerEnd;
2753    };
2754
2755    _ThisAnimator.$SetLoopLength = function (length) {
2756        _LoopLength = length;
2757    };
2758
2759    _ThisAnimator.$Locate = Locate;
2760
2761    _ThisAnimator.$Shift = Shift;
2762
2763    _ThisAnimator.$Join = Join;
2764
2765    _ThisAnimator.$Combine = function (animator) {
2766        ///	<summary>
2767        ///		Combine another animator parallel to this animator
2768        ///	</summary>
2769        ///	<param name="animator" type="$JssorAnimator$">
2770        ///		An instance of $JssorAnimator$
2771        ///	</param>
2772        Join(animator, 0);
2773    };
2774
2775    _ThisAnimator.$Chain = function (animator) {
2776        ///	<summary>
2777        ///		Chain another animator at the _Position_InnerEnd of this animator
2778        ///	</summary>
2779        ///	<param name="animator" type="$JssorAnimator$">
2780        ///		An instance of $JssorAnimator$
2781        ///	</param>
2782        Join(animator, 1);
2783    };
2784
2785    _ThisAnimator.$GetPosition_InnerBegin = function () {
2786        ///	<summary>
2787        ///		Internal member function, do not use it.
2788        ///	</summary>
2789        ///	<private />
2790        ///	<returns type="int" />
2791        return _Position_InnerBegin;
2792    };
2793
2794    _ThisAnimator.$GetPosition_InnerEnd = function () {
2795        ///	<summary>
2796        ///		Internal member function, do not use it.
2797        ///	</summary>
2798        ///	<private />
2799        ///	<returns type="int" />
2800        return _Position_InnerEnd;
2801    };
2802
2803    _ThisAnimator.$GetPosition_OuterBegin = function () {
2804        ///	<summary>
2805        ///		Internal member function, do not use it.
2806        ///	</summary>
2807        ///	<private />
2808        ///	<returns type="int" />
2809        return _Position_OuterBegin;
2810    };
2811
2812    _ThisAnimator.$GetPosition_OuterEnd = function () {
2813        ///	<summary>
2814        ///		Internal member function, do not use it.
2815        ///	</summary>
2816        ///	<private />
2817        ///	<returns type="int" />
2818        return _Position_OuterEnd;
2819    };
2820
2821    _ThisAnimator.$OnPositionChange = _ThisAnimator.$OnStart = _ThisAnimator.$OnStop = _ThisAnimator.$OnInnerOffsetChange = $Jssor$.$EmptyFunction;
2822    _ThisAnimator.$Version = $Jssor$.$GetNow();
2823
2824    //Constructor  1
2825    {
2826        options = $Jssor$.$Extend({
2827            $Interval: 16,
2828            $IntervalMax: 50
2829        }, options);
2830
2831        //Sodo statement, for development time intellisence only
2832        $JssorDebug$.$Execute(function () {
2833            options = $Jssor$.$Extend({
2834                $LoopLength: undefined,
2835                $Setter: undefined,
2836                $Easing: undefined
2837            }, options);
2838        });
2839
2840        _LoopLength = options.$LoopLength;
2841
2842        _StyleSetter = $Jssor$.$Extend({}, $Jssor$.$StyleSetter(), options.$Setter);
2843
2844        _Position_OuterBegin = _Position_InnerBegin = delay;
2845        _Position_OuterEnd = _Position_InnerEnd = delay + duration;
2846
2847        _SubRounds = options.$Round || {};
2848        _SubDurings = options.$During || {};
2849        _SubEasings = $Jssor$.$Extend({ $Default: $Jssor$.$IsFunction(options.$Easing) && options.$Easing || $JssorEasing$.$EaseSwing }, options.$Easing);
2850    }
2851};
2852
2853function $JssorPlayerClass$() {
2854
2855    var _ThisPlayer = this;
2856    var _PlayerControllers = [];
2857
2858    function PlayerController(playerElement) {
2859        var _SelfPlayerController = this;
2860        var _PlayerInstance;
2861        var _PlayerInstantces = [];
2862
2863        function OnPlayerInstanceDataAvailable(event) {
2864            var srcElement = $Jssor$.$EventSrc(event);
2865            _PlayerInstance = srcElement.pInstance;
2866
2867            $Jssor$.$RemoveEvent(srcElement, "dataavailable", OnPlayerInstanceDataAvailable);
2868            $Jssor$.$Each(_PlayerInstantces, function (playerInstance) {
2869                if (playerInstance != _PlayerInstance) {
2870                    playerInstance.$Remove();
2871                }
2872            });
2873
2874            playerElement.pTagName = _PlayerInstance.tagName;
2875            _PlayerInstantces = null;
2876        }
2877
2878        function HandlePlayerInstance(playerInstanceElement) {
2879            var playerHandler;
2880
2881            if (!playerInstanceElement.pInstance) {
2882                var playerHandlerAttribute = $Jssor$.$AttributeEx(playerInstanceElement, "pHandler");
2883
2884                if ($JssorPlayer$[playerHandlerAttribute]) {
2885                    $Jssor$.$AddEvent(playerInstanceElement, "dataavailable", OnPlayerInstanceDataAvailable);
2886                    playerHandler = new $JssorPlayer$[playerHandlerAttribute](playerElement, playerInstanceElement);
2887                    _PlayerInstantces.push(playerHandler);
2888
2889                    $JssorDebug$.$Execute(function () {
2890                        if ($Jssor$.$Type(playerHandler.$Remove) != "function") {
2891                            $JssorDebug$.$Fail("'pRemove' interface not implemented for player handler '" + playerHandlerAttribute + "'.");
2892                        }
2893                    });
2894                }
2895            }
2896
2897            return playerHandler;
2898        }
2899
2900        _SelfPlayerController.$InitPlayerController = function () {
2901            if (!playerElement.pInstance && !HandlePlayerInstance(playerElement)) {
2902
2903                var playerInstanceElements = $Jssor$.$Children(playerElement);
2904
2905                $Jssor$.$Each(playerInstanceElements, function (playerInstanceElement) {
2906                    HandlePlayerInstance(playerInstanceElement);
2907                });
2908            }
2909        };
2910    }
2911
2912    _ThisPlayer.$EVT_SWITCH = 21;
2913
2914    _ThisPlayer.$FetchPlayers = function (elmt) {
2915        elmt = elmt || document.body;
2916
2917        var playerElements = $Jssor$.$FindChildren(elmt, "player");
2918
2919        $Jssor$.$Each(playerElements, function (playerElement) {
2920            if (!_PlayerControllers[playerElement.pId]) {
2921                playerElement.pId = _PlayerControllers.length;
2922                _PlayerControllers.push(new PlayerController(playerElement));
2923            }
2924            var playerController = _PlayerControllers[playerElement.pId];
2925            playerController.$InitPlayerController();
2926        });
2927    };
2928}

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.