PageSourceSearch

https://www.diako-dresden.de/fileadmin/template/js/frontpage.js

js diako-dresden.de collected 2026-10-10 00:51:58 UTC 762,698 bytes, 21,689 lines download raw bytes

vendor: 24,327 bytes, lines 1-704
1/*!
2 * jQuery JavaScript Library v3.2.1
3 * https://jquery.com/
4 *
5 * Includes Sizzle.js
6 * https://sizzlejs.com/
7 *
8 * Copyright JS Foundation and other contributors
9 * Released under the MIT license
10 * https://jquery.org/license
11 *
12 * Date: 2017-03-20T18:59Z
13 */
14(function (global, factory) {
15
16    "use strict";
17
18    if (typeof module === "object" && typeof module.exports === "object") {
19
20        // For CommonJS and CommonJS-like environments where a proper `window`
21        // is present, execute the factory and get jQuery.
22        // For environments that do not have a `window` with a `document`
23        // (such as Node.js), expose a factory as module.exports.
24        // This accentuates the need for the creation of a real `window`.
25        // e.g. var jQuery = require("jquery")(window);
26        // See ticket #14549 for more info.
27        module.exports = global.document ?
28            factory(global, true) :
29            function (w) {
30                if (!w.document) {
31                    throw new Error("jQuery requires a window with a document");
32                }
33                return factory(w);
34            };
35    } else {
36        factory(global);
37    }
38
39// Pass this if window is not defined yet
40})(typeof window !== "undefined" ? window : this, function (window, noGlobal) {
41
42// Edge <= 12 - 13+, Firefox <=18 - 45+, IE 10 - 11, Safari 5.1 - 9+, iOS 6 - 9.1
43// throw exceptions when non-strict code (e.g., ASP.NET 4.5) accesses strict mode
44// arguments.callee.caller (trac-13335). But as of jQuery 3.0 (2016), strict mode should be common
45// enough that all such attempts are guarded in a try block.
46    "use strict";
47
48    var arr = [];
49
50    var document = window.document;
51
52    var getProto = Object.getPrototypeOf;
53
54    var slice = arr.slice;
55
56    var concat = arr.concat;
57
58    var push = arr.push;
59
60    var indexOf = arr.indexOf;
61
62    var class2type = {};
63
64    var toString = class2type.toString;
65
66    var hasOwn = class2type.hasOwnProperty;
67
68    var fnToString = hasOwn.toString;
69
70    var ObjectFunctionString = fnToString.call(Object);
71
72    var support = {};
73
74
75    function DOMEval(code, doc) {
76        doc = doc || document;
77
78        var script = doc.createElement("script");
79
80        script.text = code;
81        doc.head.appendChild(script).parentNode.removeChild(script);
82    }
83
84    /* global Symbol */
85// Defining this global in .eslintrc.json would create a danger of using the global
86// unguarded in another place, it seems safer to define global only for this module
87
88
89    var
90        version = "3.2.1",
91
92        // Define a local copy of jQuery
93        jQuery = function (selector, context) {
94
95            // The jQuery object is actually just the init constructor 'enhanced'
96            // Need init if jQuery is called (just allow error to be thrown if not included)
97            return new jQuery.fn.init(selector, context);
98        },
99
100        // Support: Android <=4.0 only
101        // Make sure we trim BOM and NBSP
102        rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,
103
104        // Matches dashed string for camelizing
105        rmsPrefix = /^-ms-/,
106        rdashAlpha = /-([a-z])/g,
107
108        // Used by jQuery.camelCase as callback to replace()
109        fcamelCase = function (all, letter) {
110            return letter.toUpperCase();
111        };
112
113    jQuery.fn = jQuery.prototype = {
114
115        // The current version of jQuery being used
116        jquery: version,
117
118        constructor: jQuery,
119
120        // The default length of a jQuery object is 0
121        length: 0,
122
123        toArray: function () {
124            return slice.call(this);
125        },
126
127        // Get the Nth element in the matched element set OR
128        // Get the whole matched element set as a clean array
129        get: function (num) {
130
131            // Return all the elements in a clean array
132            if (num == null) {
133                return slice.call(this);
134            }
135
136            // Return just the one element from the set
137            return num < 0 ? this[num + this.length] : this[num];
138        },
139
140        // Take an array of elements and push it onto the stack
141        // (returning the new matched element set)
142        pushStack: function (elems) {
143
144            // Build a new jQuery matched element set
145            var ret = jQuery.merge(this.constructor(), elems);
146
147            // Add the old object onto the stack (as a reference)
148            ret.prevObject = this;
149
150            // Return the newly-formed element set
151            return ret;
152        },
153
154        // Execute a callback for every element in the matched set.
155        each: function (callback) {
156            return jQuery.each(this, callback);
157        },
158
159        map: function (callback) {
160            return this.pushStack(jQuery.map(this, function (elem, i) {
161                return callback.call(elem, i, elem);
162            }));
163        },
164
165        slice: function () {
166            return this.pushStack(slice.apply(this, arguments));
167        },
168
169        first: function () {
170            return this.eq(0);
171        },
172
173        last: function () {
174            return this.eq(-1);
175        },
176
177        eq: function (i) {
178            var len = this.length,
179                j = +i + (i < 0 ? len : 0);
180            return this.pushStack(j >= 0 && j < len ? [this[j]] : []);
181        },
182
183        end: function () {
184            return this.prevObject || this.constructor();
185        },
186
187        // For internal use only.
188        // Behaves like an Array's method, not like a jQuery method.
189        push: push,
190        sort: arr.sort,
191        splice: arr.splice
192    };
193
194    jQuery.extend = jQuery.fn.extend = function () {
195        var options, name, src, copy, copyIsArray, clone,
196            target = arguments[0] || {},
197            i = 1,
198            length = arguments.length,
199            deep = false;
200
201        // Handle a deep copy situation
202        if (typeof target === "boolean") {
203            deep = target;
204
205            // Skip the boolean and the target
206            target = arguments[i] || {};
207            i++;
208        }
209
210        // Handle case when target is a string or something (possible in deep copy)
211        if (typeof target !== "object" && !jQuery.isFunction(target)) {
212            target = {};
213        }
214
215        // Extend jQuery itself if only one argument is passed
216        if (i === length) {
217            target = this;
218            i--;
219        }
220
221        for (; i < length; i++) {
222
223            // Only deal with non-null/undefined values
224            if ((options = arguments[i]) != null) {
225
226                // Extend the base object
227                for (name in options) {
228                    src = target[name];
229                    copy = options[name];
230
231                    // Prevent never-ending loop
232                    if (target === copy) {
233                        continue;
234                    }
235
236                    // Recurse if we're merging plain objects or arrays
237                    if (deep && copy && (jQuery.isPlainObject(copy) ||
238                        (copyIsArray = Array.isArray(copy)))) {
239
240                        if (copyIsArray) {
241                            copyIsArray = false;
242                            clone = src && Array.isArray(src) ? src : [];
243
244                        } else {
245                            clone = src && jQuery.isPlainObject(src) ? src : {};
246                        }
247
248                        // Never move original objects, clone them
249                        target[name] = jQuery.extend(deep, clone, copy);
250
251                        // Don't bring in undefined values
252                    } else if (copy !== undefined) {
253                        target[name] = copy;
254                    }
255                }
256            }
257        }
258
259        // Return the modified object
260        return target;
261    };
262
263    jQuery.extend({
264
265        // Unique for each copy of jQuery on the page
266        expando: "jQuery" + (version + Math.random()).replace(/\D/g, ""),
267
268        // Assume jQuery is ready without the ready module
269        isReady: true,
270
271        error: function (msg) {
272            throw new Error(msg);
273        },
274
275        noop: function () {
276        },
277
278        isFunction: function (obj) {
279            return jQuery.type(obj) === "function";
280        },
281
282        isWindow: function (obj) {
283            return obj != null && obj === obj.window;
284        },
285
286        isNumeric: function (obj) {
287
288            // As of jQuery 3.0, isNumeric is limited to
289            // strings and numbers (primitives or objects)
290            // that can be coerced to finite numbers (gh-2662)
291            var type = jQuery.type(obj);
292            return (type === "number" || type === "string") &&
293
294                // parseFloat NaNs numeric-cast false positives ("")
295                // ...but misinterprets leading-number strings, particularly hex literals ("0x...")
296                // subtraction forces infinities to NaN
297                !isNaN(obj - parseFloat(obj));
298        },
299
300        isPlainObject: function (obj) {
301            var proto, Ctor;
302
303            // Detect obvious negatives
304            // Use toString instead of jQuery.type to catch host objects
305            if (!obj || toString.call(obj) !== "[object Object]") {
306                return false;
307            }
308
309            proto = getProto(obj);
310
311            // Objects with no prototype (e.g., `Object.create( null )`) are plain
312            if (!proto) {
313                return true;
314            }
315
316            // Objects with prototype are plain iff they were constructed by a global Object function
317            Ctor = hasOwn.call(proto, "constructor") && proto.constructor;
318            return typeof Ctor === "function" && fnToString.call(Ctor) === ObjectFunctionString;
319        },
320
321        isEmptyObject: function (obj) {
322
323            /* eslint-disable no-unused-vars */
324            // See https://github.com/eslint/eslint/issues/6125
325            var name;
326
327            for (name in obj) {
328                return false;
329            }
330            return true;
331        },
332
333        type: function (obj) {
334            if (obj == null) {
335                return obj + "";
336            }
337
338            // Support: Android <=2.3 only (functionish RegExp)
339            return typeof obj === "object" || typeof obj === "function" ?
340                class2type[toString.call(obj)] || "object" :
341                typeof obj;
342        },
343
344        // Evaluates a script in a global context
345        globalEval: function (code) {
346            DOMEval(code);
347        },
348
349        // Convert dashed to camelCase; used by the css and data modules
350        // Support: IE <=9 - 11, Edge 12 - 13
351        // Microsoft forgot to hump their vendor prefix (#9572)
352        camelCase: function (string) {
353            return string.replace(rmsPrefix, "ms-").replace(rdashAlpha, fcamelCase);
354        },
355
356        each: function (obj, callback) {
357            var length, i = 0;
358
359            if (isArrayLike(obj)) {
360                length = obj.length;
361                for (; i < length; i++) {
362                    if (callback.call(obj[i], i, obj[i]) === false) {
363                        break;
364                    }
365                }
366            } else {
367                for (i in obj) {
368                    if (callback.call(obj[i], i, obj[i]) === false) {
369                        break;
370                    }
371                }
372            }
373
374            return obj;
375        },
376
377        // Support: Android <=4.0 only
378        trim: function (text) {
379            return text == null ?
380                "" :
381                (text + "").replace(rtrim, "");
382        },
383
384        // results is for internal usage only
385        makeArray: function (arr, results) {
386            var ret = results || [];
387
388            if (arr != null) {
389                if (isArrayLike(Object(arr))) {
390                    jQuery.merge(ret,
391                        typeof arr === "string" ?
392                            [arr] : arr
393                    );
394                } else {
395                    push.call(ret, arr);
396                }
397            }
398
399            return ret;
400        },
401
402        inArray: function (elem, arr, i) {
403            return arr == null ? -1 : indexOf.call(arr, elem, i);
404        },
405
406        // Support: Android <=4.0 only, PhantomJS 1 only
407        // push.apply(_, arraylike) throws on ancient WebKit
408        merge: function (first, second) {
409            var len = +second.length,
410                j = 0,
411                i = first.length;
412
413            for (; j < len; j++) {
414                first[i++] = second[j];
415            }
416
417            first.length = i;
418
419            return first;
420        },
421
422        grep: function (elems, callback, invert) {
423            var callbackInverse,
424                matches = [],
425                i = 0,
426                length = elems.length,
427                callbackExpect = !invert;
428
429            // Go through the array, only saving the items
430            // that pass the validator function
431            for (; i < length; i++) {
432                callbackInverse = !callback(elems[i], i);
433                if (callbackInverse !== callbackExpect) {
434                    matches.push(elems[i]);
435                }
436            }
437
438            return matches;
439        },
440
441        // arg is for internal usage only
442        map: function (elems, callback, arg) {
443            var length, value,
444                i = 0,
445                ret = [];
446
447            // Go through the array, translating each of the items to their new values
448            if (isArrayLike(elems)) {
449                length = elems.length;
450                for (; i < length; i++) {
451                    value = callback(elems[i], i, arg);
452
453                    if (value != null) {
454                        ret.push(value);
455                    }
456                }
457
458                // Go through every key on the object,
459            } else {
460                for (i in elems) {
461                    value = callback(elems[i], i, arg);
462
463                    if (value != null) {
464                        ret.push(value);
465                    }
466                }
467            }
468
469            // Flatten any nested arrays
470            return concat.apply([], ret);
471        },
472
473        // A global GUID counter for objects
474        guid: 1,
475
476        // Bind a function to a context, optionally partially applying any
477        // arguments.
478        proxy: function (fn, context) {
479            var tmp, args, proxy;
480
481            if (typeof context === "string") {
482                tmp = fn[context];
483                context = fn;
484                fn = tmp;
485            }
486
487            // Quick check to determine if target is callable, in the spec
488            // this throws a TypeError, but we will just return undefined.
489            if (!jQuery.isFunction(fn)) {
490                return undefined;
491            }
492
493            // Simulated bind
494            args = slice.call(arguments, 2);
495            proxy = function () {
496                return fn.apply(context || this, args.concat(slice.call(arguments)));
497            };
498
499            // Set the guid of unique handler to the same of original handler, so it can be removed
500            proxy.guid = fn.guid = fn.guid || jQuery.guid++;
501
502            return proxy;
503        },
504
505        now: Date.now,
506
507        // jQuery.support is not used in Core but other projects attach their
508        // properties to it so it needs to exist.
509        support: support
510    });
511
512    if (typeof Symbol === "function") {
513        jQuery.fn[Symbol.iterator] = arr[Symbol.iterator];
514    }
515
516// Populate the class2type map
517    jQuery.each("Boolean Number String Function Array Date RegExp Object Error Symbol".split(" "),
518        function (i, name) {
519            class2type["[object " + name + "]"] = name.toLowerCase();
520        });
521
522    function isArrayLike(obj) {
523
524        // Support: real iOS 8.2 only (not reproducible in simulator)
525        // `in` check used to prevent JIT error (gh-2145)
526        // hasOwn isn't used here due to false negatives
527        // regarding Nodelist length in IE
528        var length = !!obj && "length" in obj && obj.length,
529            type = jQuery.type(obj);
530
531        if (type === "function" || jQuery.isWindow(obj)) {
532            return false;
533        }
534
535        return type === "array" || length === 0 ||
536            typeof length === "number" && length > 0 && (length - 1) in obj;
537    }
538
539    var Sizzle =
540        /*!
541* Sizzle CSS Selector Engine v2.3.3
542* https://sizzlejs.com/
543*
544* Copyright jQuery Foundation and other contributors
545* Released under the MIT license
546* http://jquery.org/license
547*
548* Date: 2016-08-08
549*/
550        (function (window) {
551
552            var i,
553                support,
554                Expr,
555                getText,
556                isXML,
557                tokenize,
558                compile,
559                select,
560                outermostContext,
561                sortInput,
562                hasDuplicate,
563
564                // Local document vars
565                setDocument,
566                document,
567                docElem,
568                documentIsHTML,
569                rbuggyQSA,
570                rbuggyMatches,
571                matches,
572                contains,
573
574                // Instance-specific data
575                expando = "sizzle" + 1 * new Date(),
576                preferredDoc = window.document,
577                dirruns = 0,
578                done = 0,
579                classCache = createCache(),
580                tokenCache = createCache(),
581                compilerCache = createCache(),
582                sortOrder = function (a, b) {
583                    if (a === b) {
584                        hasDuplicate = true;
585                    }
586                    return 0;
587                },
588
589                // Instance methods
590                hasOwn = ({}).hasOwnProperty,
591                arr = [],
592                pop = arr.pop,
593                push_native = arr.push,
594                push = arr.push,
595                slice = arr.slice,
596                // Use a stripped-down indexOf as it's faster than native
597                // https://jsperf.com/thor-indexof-vs-for/5
598                indexOf = function (list, elem) {
599                    var i = 0,
600                        len = list.length;
601                    for (; i < len; i++) {
602                        if (list[i] === elem) {
603                            return i;
604                        }
605                    }
606                    return -1;
607                },
608
609                booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",
610
611                // Regular expressions
612
613                // http://www.w3.org/TR/css3-selectors/#whitespace
614                whitespace = "[\\x20\\t\\r\\n\\f]",
615
616                // http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier
617                identifier = "(?:\\\\.|[\\w-]|[^\0-\\xa0])+",
618
619                // Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors
620                attributes = "\\[" + whitespace + "*(" + identifier + ")(?:" + whitespace +
621                    // Operator (capture 2)
622                    "*([*^$|!~]?=)" + whitespace +
623                    // "Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]"
624                    "*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + whitespace +
625                    "*\\]",
626
627                pseudos = ":(" + identifier + ")(?:\\((" +
628                    // To reduce the number of selectors needing tokenize in the preFilter, prefer arguments:
629                    // 1. quoted (capture 3; capture 4 or capture 5)
630                    "('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" +
631                    // 2. simple (capture 6)
632                    "((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" +
633                    // 3. anything else (capture 2)
634                    ".*" +
635                    ")\\)|)",
636
637                // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter
638                rwhitespace = new RegExp(whitespace + "+", "g"),
639                rtrim = new RegExp("^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g"),
640
641                rcomma = new RegExp("^" + whitespace + "*," + whitespace + "*"),
642                rcombinators = new RegExp("^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*"),
643
644                rattributeQuotes = new RegExp("=" + whitespace + "*([^\\]'\"]*?)" + whitespace + "*\\]", "g"),
645
646                rpseudo = new RegExp(pseudos),
647                ridentifier = new RegExp("^" + identifier + "$"),
648
649                matchExpr = {
650                    "ID": new RegExp("^#(" + identifier + ")"),
651                    "CLASS": new RegExp("^\\.(" + identifier + ")"),
652                    "TAG": new RegExp("^(" + identifier + "|[*])"),
653                    "ATTR": new RegExp("^" + attributes),
654                    "PSEUDO": new RegExp("^" + pseudos),
655                    "CHILD": new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace +
656                        "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace +
657                        "*(\\d+)|))" + whitespace + "*\\)|)", "i"),
658                    "bool": new RegExp("^(?:" + booleans + ")$", "i"),
659                    // For use in libraries implementing .is()
660                    // We use this for POS matching in `select`
661                    "needsContext": new RegExp("^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" +
662                        whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i")
663                },
664
665                rinputs = /^(?:input|select|textarea|button)$/i,
666                rheader = /^h\d$/i,
667
668                rnative = /^[^{]+\{\s*\[native \w/,
669
670                // Easily-parseable/retrievable ID or TAG or CLASS selectors
671                rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,
672
673                rsibling = /[+~]/,
674
675                // CSS escapes
676                // http://www.w3.org/TR/CSS21/syndata.html#escaped-characters
677                runescape = new RegExp("\\\\([\\da-f]{1,6}" + whitespace + "?|(" + whitespace + ")|.)", "ig"),
678                funescape = function (_, escaped, escapedWhitespace) {
679                    var high = "0x" + escaped - 0x10000;
680                    // NaN means non-codepoint
681                    // Support: Firefox<24
682                    // Workaround erroneous numeric interpretation of +"0x"
683                    return high !== high || escapedWhitespace ?
684                        escaped :
685                        high < 0 ?
686                            // BMP codepoint
687                            String.fromCharCode(high + 0x10000) :
688                            // Supplemental Plane codepoint (surrogate pair)
689                            String.fromCharCode(high >> 10 | 0xD800, high & 0x3FF | 0xDC00);
690                },
691
692                // CSS string/identifier serialization
693                // https://drafts.csswg.org/cssom/#common-serializing-idioms
694                rcssescape = /([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,
695                fcssescape = function (ch, asCodePoint) {
696                    if (asCodePoint) {
697
698                        // U+0000 NULL becomes U+FFFD REPLACEMENT CHARACTER
699                        if (ch === "\0") {
700                            return "\uFFFD";
701                        }
702
703                        // Control characters and (dependent upon position) numbers get escaped as code points
704                        return ch.slice(0, -1) + "\\" + ch.charCo
vendor: 26,555 bytes, lines 704-1294
704deAt(ch.length - 1).toString(16) + " ";
705                    }
706
707                    // Other potentially-special ASCII characters get backslash-escaped
708                    return "\\" + ch;
709                },
710
711                // Used for iframes
712                // See setDocument()
713                // Removing the function wrapper causes a "Permission Denied"
714                // error in IE
715                unloadHandler = function () {
716                    setDocument();
717                },
718
719                disabledAncestor = addCombinator(
720                    function (elem) {
721                        return elem.disabled === true && ("form" in elem || "label" in elem);
722                    },
723                    {dir: "parentNode", next: "legend"}
724                );
725
726// Optimize for push.apply( _, NodeList )
727            try {
728                push.apply(
729                    (arr = slice.call(preferredDoc.childNodes)),
730                    preferredDoc.childNodes
731                );
732                // Support: Android<4.0
733                // Detect silently failing push.apply
734                arr[preferredDoc.childNodes.length].nodeType;
735            } catch (e) {
736                push = {
737                    apply: arr.length ?
738
739                        // Leverage slice if possible
740                        function (target, els) {
741                            push_native.apply(target, slice.call(els));
742                        } :
743
744                        // Support: IE<9
745                        // Otherwise append directly
746                        function (target, els) {
747                            var j = target.length,
748                                i = 0;
749                            // Can't trust NodeList.length
750                            while ((target[j++] = els[i++])) {
751                            }
752                            target.length = j - 1;
753                        }
754                };
755            }
756
757            function Sizzle(selector, context, results, seed) {
758                var m, i, elem, nid, match, groups, newSelector,
759                    newContext = context && context.ownerDocument,
760
761                    // nodeType defaults to 9, since context defaults to document
762                    nodeType = context ? context.nodeType : 9;
763
764                results = results || [];
765
766                // Return early from calls with invalid selector or context
767                if (typeof selector !== "string" || !selector ||
768                    nodeType !== 1 && nodeType !== 9 && nodeType !== 11) {
769
770                    return results;
771                }
772
773                // Try to shortcut find operations (as opposed to filters) in HTML documents
774                if (!seed) {
775
776                    if ((context ? context.ownerDocument || context : preferredDoc) !== document) {
777                        setDocument(context);
778                    }
779                    context = context || document;
780
781                    if (documentIsHTML) {
782
783                        // If the selector is sufficiently simple, try using a "get*By*" DOM method
784                        // (excepting DocumentFragment context, where the methods don't exist)
785                        if (nodeType !== 11 && (match = rquickExpr.exec(selector))) {
786
787                            // ID selector
788                            if ((m = match[1])) {
789
790                                // Document context
791                                if (nodeType === 9) {
792                                    if ((elem = context.getElementById(m))) {
793
794                                        // Support: IE, Opera, Webkit
795                                        // TODO: identify versions
796                                        // getElementById can match elements by name instead of ID
797                                        if (elem.id === m) {
798                                            results.push(elem);
799                                            return results;
800                                        }
801                                    } else {
802                                        return results;
803                                    }
804
805                                    // Element context
806                                } else {
807
808                                    // Support: IE, Opera, Webkit
809                                    // TODO: identify versions
810                                    // getElementById can match elements by name instead of ID
811                                    if (newContext && (elem = newContext.getElementById(m)) &&
812                                        contains(context, elem) &&
813                                        elem.id === m) {
814
815                                        results.push(elem);
816                                        return results;
817                                    }
818                                }
819
820                                // Type selector
821                            } else if (match[2]) {
822                                push.apply(results, context.getElementsByTagName(selector));
823                                return results;
824
825                                // Class selector
826                            } else if ((m = match[3]) && support.getElementsByClassName &&
827                                context.getElementsByClassName) {
828
829                                push.apply(results, context.getElementsByClassName(m));
830                                return results;
831                            }
832                        }
833
834                        // Take advantage of querySelectorAll
835                        if (support.qsa &&
836                            !compilerCache[selector + " "] &&
837                            (!rbuggyQSA || !rbuggyQSA.test(selector))) {
838
839                            if (nodeType !== 1) {
840                                newContext = context;
841                                newSelector = selector;
842
843                                // qSA looks outside Element context, which is not what we want
844                                // Thanks to Andrew Dupont for this workaround technique
845                                // Support: IE <=8
846                                // Exclude object elements
847                            } else if (context.nodeName.toLowerCase() !== "object") {
848
849                                // Capture the context ID, setting it first if necessary
850                                if ((nid = context.getAttribute("id"))) {
851                                    nid = nid.replace(rcssescape, fcssescape);
852                                } else {
853                                    context.setAttribute("id", (nid = expando));
854                                }
855
856                                // Prefix every selector in the list
857                                groups = tokenize(selector);
858                                i = groups.length;
859                                while (i--) {
860                                    groups[i] = "#" + nid + " " + toSelector(groups[i]);
861                                }
862                                newSelector = groups.join(",");
863
864                                // Expand context for sibling selectors
865                                newContext = rsibling.test(selector) && testContext(context.parentNode) ||
866                                    context;
867                            }
868
869                            if (newSelector) {
870                                try {
871                                    push.apply(results,
872                                        newContext.querySelectorAll(newSelector)
873                                    );
874                                    return results;
875                                } catch (qsaError) {
876                                } finally {
877                                    if (nid === expando) {
878                                        context.removeAttribute("id");
879                                    }
880                                }
881                            }
882                        }
883                    }
884                }
885
886                // All others
887                return select(selector.replace(rtrim, "$1"), context, results, seed);
888            }
889
890            /**
891             * Create key-value caches of limited size
892             * @returns {function(string, object)} Returns the Object data after storing it on itself with
893             *    property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength)
894             *    deleting the oldest entry
895             */
896            function createCache() {
897                var keys = [];
898
899                function cache(key, value) {
900                    // Use (key + " ") to avoid collision with native prototype properties (see Issue #157)
901                    if (keys.push(key + " ") > Expr.cacheLength) {
902                        // Only keep the most recent entries
903                        delete cache[keys.shift()];
904                    }
905                    return (cache[key + " "] = value);
906                }
907
908                return cache;
909            }
910
911            /**
912             * Mark a function for special use by Sizzle
913             * @param {Function} fn The function to mark
914             */
915            function markFunction(fn) {
916                fn[expando] = true;
917                return fn;
918            }
919
920            /**
921             * Support testing using an element
922             * @param {Function} fn Passed the created element and returns a boolean result
923             */
924            function assert(fn) {
925                var el = document.createElement("fieldset");
926
927                try {
928                    return !!fn(el);
929                } catch (e) {
930                    return false;
931                } finally {
932                    // Remove from its parent by default
933                    if (el.parentNode) {
934                        el.parentNode.removeChild(el);
935                    }
936                    // release memory in IE
937                    el = null;
938                }
939            }
940
941            /**
942             * Adds the same handler for all of the specified attrs
943             * @param {String} attrs Pipe-separated list of attributes
944             * @param {Function} handler The method that will be applied
945             */
946            function addHandle(attrs, handler) {
947                var arr = attrs.split("|"),
948                    i = arr.length;
949
950                while (i--) {
951                    Expr.attrHandle[arr[i]] = handler;
952                }
953            }
954
955            /**
956             * Checks document order of two siblings
957             * @param {Element} a
958             * @param {Element} b
959             * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b
960             */
961            function siblingCheck(a, b) {
962                var cur = b && a,
963                    diff = cur && a.nodeType === 1 && b.nodeType === 1 &&
964                        a.sourceIndex - b.sourceIndex;
965
966                // Use IE sourceIndex if available on both nodes
967                if (diff) {
968                    return diff;
969                }
970
971                // Check if b follows a
972                if (cur) {
973                    while ((cur = cur.nextSibling)) {
974                        if (cur === b) {
975                            return -1;
976                        }
977                    }
978                }
979
980                return a ? 1 : -1;
981            }
982
983            /**
984             * Returns a function to use in pseudos for input types
985             * @param {String} type
986             */
987            function createInputPseudo(type) {
988                return function (elem) {
989                    var name = elem.nodeName.toLowerCase();
990                    return name === "input" && elem.type === type;
991                };
992            }
993
994            /**
995             * Returns a function to use in pseudos for buttons
996             * @param {String} type
997             */
998            function createButtonPseudo(type) {
999                return function (elem) {
1000                    var name = elem.nodeName.toLowerCase();
1001                    return (name === "input" || name === "button") && elem.type === type;
1002                };
1003            }
1004
1005            /**
1006             * Returns a function to use in pseudos for :enabled/:disabled
1007             * @param {Boolean} disabled true for :disabled; false for :enabled
1008             */
1009            function createDisabledPseudo(disabled) {
1010
1011                // Known :disabled false positives: fieldset[disabled] > legend:nth-of-type(n+2) :can-disable
1012                return function (elem) {
1013
1014                    // Only certain elements can match :enabled or :disabled
1015                    // https://html.spec.whatwg.org/multipage/scripting.html#selector-enabled
1016                    // https://html.spec.whatwg.org/multipage/scripting.html#selector-disabled
1017                    if ("form" in elem) {
1018
1019                        // Check for inherited disabledness on relevant non-disabled elements:
1020                        // * listed form-associated elements in a disabled fieldset
1021                        // https://html.spec.whatwg.org/multipage/forms.html#category-listed
1022                        // https://html.spec.whatwg.org/multipage/forms.html#concept-fe-disabled
1023                        // * option elements in a disabled optgroup
1024                        // https://html.spec.whatwg.org/multipage/forms.html#concept-option-disabled
1025                        // All such elements have a "form" property.
1026                        if (elem.parentNode && elem.disabled === false) {
1027
1028                            // Option elements defer to a parent optgroup if present
1029                            if ("label" in elem) {
1030                                if ("label" in elem.parentNode) {
1031                                    return elem.parentNode.disabled === disabled;
1032                                } else {
1033                                    return elem.disabled === disabled;
1034                                }
1035                            }
1036
1037                            // Support: IE 6 - 11
1038                            // Use the isDisabled shortcut property to check for disabled fieldset ancestors
1039                            return elem.isDisabled === disabled ||
1040
1041                                // Where there is no isDisabled, check manually
1042                                /* jshint -W018 */
1043                                elem.isDisabled !== !disabled &&
1044                                disabledAncestor(elem) === disabled;
1045                        }
1046
1047                        return elem.disabled === disabled;
1048
1049                        // Try to winnow out elements that can't be disabled before trusting the disabled property.
1050                        // Some victims get caught in our net (label, legend, menu, track), but it shouldn't
1051                        // even exist on them, let alone have a boolean value.
1052                    } else if ("label" in elem) {
1053                        return elem.disabled === disabled;
1054                    }
1055
1056                    // Remaining elements are neither :enabled nor :disabled
1057                    return false;
1058                };
1059            }
1060
1061            /**
1062             * Returns a function to use in pseudos for positionals
1063             * @param {Function} fn
1064             */
1065            function createPositionalPseudo(fn) {
1066                return markFunction(function (argument) {
1067                    argument = +argument;
1068                    return markFunction(function (seed, matches) {
1069                        var j,
1070                            matchIndexes = fn([], seed.length, argument),
1071                            i = matchIndexes.length;
1072
1073                        // Match elements found at the specified indexes
1074                        while (i--) {
1075                            if (seed[(j = matchIndexes[i])]) {
1076                                seed[j] = !(matches[j] = seed[j]);
1077                            }
1078                        }
1079                    });
1080                });
1081            }
1082
1083            /**
1084             * Checks a node for validity as a Sizzle context
1085             * @param {Element|Object=} context
1086             * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value
1087             */
1088            function testContext(context) {
1089                return context && typeof context.getElementsByTagName !== "undefined" && context;
1090            }
1091
1092// Expose support vars for convenience
1093            support = Sizzle.support = {};
1094
1095            /**
1096             * Detects XML nodes
1097             * @param {Element|Object} elem An element or a document
1098             * @returns {Boolean} True iff elem is a non-HTML XML node
1099             */
1100            isXML = Sizzle.isXML = function (elem) {
1101                // documentElement is verified for cases where it doesn't yet exist
1102                // (such as loading iframes in IE - #4833)
1103                var documentElement = elem && (elem.ownerDocument || elem).documentElement;
1104                return documentElement ? documentElement.nodeName !== "HTML" : false;
1105            };
1106
1107            /**
1108             * Sets document-related variables once based on the current document
1109             * @param {Element|Object} [doc] An element or document object to use to set the document
1110             * @returns {Object} Returns the current document
1111             */
1112            setDocument = Sizzle.setDocument = function (node) {
1113                var hasCompare, subWindow,
1114                    doc = node ? node.ownerDocument || node : preferredDoc;
1115
1116                // Return early if doc is invalid or already selected
1117                if (doc === document || doc.nodeType !== 9 || !doc.documentElement) {
1118                    return document;
1119                }
1120
1121                // Update global variables
1122                document = doc;
1123                docElem = document.documentElement;
1124                documentIsHTML = !isXML(document);
1125
1126                // Support: IE 9-11, Edge
1127                // Accessing iframe documents after unload throws "permission denied" errors (jQuery #13936)
1128                if (preferredDoc !== document &&
1129                    (subWindow = document.defaultView) && subWindow.top !== subWindow) {
1130
1131                    // Support: IE 11, Edge
1132                    if (subWindow.addEventListener) {
1133                        subWindow.addEventListener("unload", unloadHandler, false);
1134
1135                        // Support: IE 9 - 10 only
1136                    } else if (subWindow.attachEvent) {
1137                        subWindow.attachEvent("onunload", unloadHandler);
1138                    }
1139                }
1140
1141                /* Attributes
1142---------------------------------------------------------------------- */
1143
1144                // Support: IE<8
1145                // Verify that getAttribute really returns attributes and not properties
1146                // (excepting IE8 booleans)
1147                support.attributes = assert(function (el) {
1148                    el.className = "i";
1149                    return !el.getAttribute("className");
1150                });
1151
1152                /* getElement(s)By*
1153---------------------------------------------------------------------- */
1154
1155                // Check if getElementsByTagName("*") returns only elements
1156                support.getElementsByTagName = assert(function (el) {
1157                    el.appendChild(document.createComment(""));
1158                    return !el.getElementsByTagName("*").length;
1159                });
1160
1161                // Support: IE<9
1162                support.getElementsByClassName = rnative.test(document.getElementsByClassName);
1163
1164                // Support: IE<10
1165                // Check if getElementById returns elements by name
1166                // The broken getElementById methods don't pick up programmatically-set names,
1167                // so use a roundabout getElementsByName test
1168                support.getById = assert(function (el) {
1169                    docElem.appendChild(el).id = expando;
1170                    return !document.getElementsByName || !document.getElementsByName(expando).length;
1171                });
1172
1173                // ID filter and find
1174                if (support.getById) {
1175                    Expr.filter["ID"] = function (id) {
1176                        var attrId = id.replace(runescape, funescape);
1177                        return function (elem) {
1178                            return elem.getAttribute("id") === attrId;
1179                        };
1180                    };
1181                    Expr.find["ID"] = function (id, context) {
1182                        if (typeof context.getElementById !== "undefined" && documentIsHTML) {
1183                            var elem = context.getElementById(id);
1184                            return elem ? [elem] : [];
1185                        }
1186                    };
1187                } else {
1188                    Expr.filter["ID"] = function (id) {
1189                        var attrId = id.replace(runescape, funescape);
1190                        return function (elem) {
1191                            var node = typeof elem.getAttributeNode !== "undefined" &&
1192                                elem.getAttributeNode("id");
1193                            return node && node.value === attrId;
1194                        };
1195                    };
1196
1197                    // Support: IE 6 - 7 only
1198                    // getElementById is not reliable as a find shortcut
1199                    Expr.find["ID"] = function (id, context) {
1200                        if (typeof context.getElementById !== "undefined" && documentIsHTML) {
1201                            var node, i, elems,
1202                                elem = context.getElementById(id);
1203
1204                            if (elem) {
1205
1206                                // Verify the id attribute
1207                                node = elem.getAttributeNode("id");
1208                                if (node && node.value === id) {
1209                                    return [elem];
1210                                }
1211
1212                                // Fall back on getElementsByName
1213                                elems = context.getElementsByName(id);
1214                                i = 0;
1215                                while ((elem = elems[i++])) {
1216                                    node = elem.getAttributeNode("id");
1217                                    if (node && node.value === id) {
1218                                        return [elem];
1219                                    }
1220                                }
1221                            }
1222
1223                            return [];
1224                        }
1225                    };
1226                }
1227
1228                // Tag
1229                Expr.find["TAG"] = support.getElementsByTagName ?
1230                    function (tag, context) {
1231                        if (typeof context.getElementsByTagName !== "undefined") {
1232                            return context.getElementsByTagName(tag);
1233
1234                            // DocumentFragment nodes don't have gEBTN
1235                        } else if (support.qsa) {
1236                            return context.querySelectorAll(tag);
1237                        }
1238                    } :
1239
1240                    function (tag, context) {
1241                        var elem,
1242                            tmp = [],
1243                            i = 0,
1244                            // By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too
1245                            results = context.getElementsByTagName(tag);
1246
1247                        // Filter out possible comments
1248                        if (tag === "*") {
1249                            while ((elem = results[i++])) {
1250                                if (elem.nodeType === 1) {
1251                                    tmp.push(elem);
1252                                }
1253                            }
1254
1255                            return tmp;
1256                        }
1257                        return results;
1258                    };
1259
1260                // Class
1261                Expr.find["CLASS"] = support.getElementsByClassName && function (className, context) {
1262                    if (typeof context.getElementsByClassName !== "undefined" && documentIsHTML) {
1263                        return context.getElementsByClassName(className);
1264                    }
1265                };
1266
1267                /* QSA/matchesSelector
1268---------------------------------------------------------------------- */
1269
1270                // QSA and matchesSelector support
1271
1272                // matchesSelector(:active) reports false when true (IE9/Opera 11.5)
1273                rbuggyMatches = [];
1274
1275                // qSa(:focus) reports false when true (Chrome 21)
1276                // We allow this because of a bug in IE8/9 that throws an error
1277                // whenever `document.activeElement` is accessed on an iframe
1278                // So, we allow :focus to pass through QSA all the time to avoid the IE error
1279                // See https://bugs.jquery.com/ticket/13378
1280                rbuggyQSA = [];
1281
1282                if ((support.qsa = rnative.test(document.querySelectorAll))) {
1283                    // Build QSA regex
1284                    // Regex strategy adopted from Diego Perini
1285                    assert(function (el) {
1286                        // Select is set to empty string on purpose
1287                        // This is to test IE's treatment of not explicitly
1288                        // setting a boolean content attribute,
1289                        // since its presence should be enough
1290                        // https://bugs.jquery.com/ticket/12359
1291                        docElem.appendChild(el).innerHTML = "<a id='" + expando + "'></a>" +
1292                            "<select id='" + expando + "-\r\\' msallowcapture=''>" +
1293                            "<option selected=''></option></select>";
1294
vendor: 42,283 bytes, lines 1295-2181
1295                        // Support: IE8, Opera 11-12.16
1296                        // Nothing should be selected when empty strings follow ^= or $= or *=
1297                        // The test attribute must be unknown in Opera but "safe" for WinRT
1298                        // https://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section
1299                        if (el.querySelectorAll("[msallowcapture^='']").length) {
1300                            rbuggyQSA.push("[*^$]=" + whitespace + "*(?:''|\"\")");
1301                        }
1302
1303                        // Support: IE8
1304                        // Boolean attributes and "value" are not treated correctly
1305                        if (!el.querySelectorAll("[selected]").length) {
1306                            rbuggyQSA.push("\\[" + whitespace + "*(?:value|" + booleans + ")");
1307                        }
1308
1309                        // Support: Chrome<29, Android<4.4, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.8+
1310                        if (!el.querySelectorAll("[id~=" + expando + "-]").length) {
1311                            rbuggyQSA.push("~=");
1312                        }
1313
1314                        // Webkit/Opera - :checked should return selected option elements
1315                        // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
1316                        // IE8 throws error here and will not see later tests
1317                        if (!el.querySelectorAll(":checked").length) {
1318                            rbuggyQSA.push(":checked");
1319                        }
1320
1321                        // Support: Safari 8+, iOS 8+
1322                        // https://bugs.webkit.org/show_bug.cgi?id=136851
1323                        // In-page `selector#id sibling-combinator selector` fails
1324                        if (!el.querySelectorAll("a#" + expando + "+*").length) {
1325                            rbuggyQSA.push(".#.+[+~]");
1326                        }
1327                    });
1328
1329                    assert(function (el) {
1330                        el.innerHTML = "<a href='' disabled='disabled'></a>" +
1331                            "<select disabled='disabled'><option/></select>";
1332
1333                        // Support: Windows 8 Native Apps
1334                        // The type and name attributes are restricted during .innerHTML assignment
1335                        var input = document.createElement("input");
1336                        input.setAttribute("type", "hidden");
1337                        el.appendChild(input).setAttribute("name", "D");
1338
1339                        // Support: IE8
1340                        // Enforce case-sensitivity of name attribute
1341                        if (el.querySelectorAll("[name=d]").length) {
1342                            rbuggyQSA.push("name" + whitespace + "*[*^$|!~]?=");
1343                        }
1344
1345                        // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled)
1346                        // IE8 throws error here and will not see later tests
1347                        if (el.querySelectorAll(":enabled").length !== 2) {
1348                            rbuggyQSA.push(":enabled", ":disabled");
1349                        }
1350
1351                        // Support: IE9-11+
1352                        // IE's :disabled selector does not pick up the children of disabled fieldsets
1353                        docElem.appendChild(el).disabled = true;
1354                        if (el.querySelectorAll(":disabled").length !== 2) {
1355                            rbuggyQSA.push(":enabled", ":disabled");
1356                        }
1357
1358                        // Opera 10-11 does not throw on post-comma invalid pseudos
1359                        el.querySelectorAll("*,:x");
1360                        rbuggyQSA.push(",.*:");
1361                    });
1362                }
1363
1364                if ((support.matchesSelector = rnative.test((matches = docElem.matches ||
1365                    docElem.webkitMatchesSelector ||
1366                    docElem.mozMatchesSelector ||
1367                    docElem.oMatchesSelector ||
1368                    docElem.msMatchesSelector)))) {
1369
1370                    assert(function (el) {
1371                        // Check to see if it's possible to do matchesSelector
1372                        // on a disconnected node (IE 9)
1373                        support.disconnectedMatch = matches.call(el, "*");
1374
1375                        // This should fail with an exception
1376                        // Gecko does not error, returns false instead
1377                        matches.call(el, "[s!='']:x");
1378                        rbuggyMatches.push("!=", pseudos);
1379                    });
1380                }
1381
1382                rbuggyQSA = rbuggyQSA.length && new RegExp(rbuggyQSA.join("|"));
1383                rbuggyMatches = rbuggyMatches.length && new RegExp(rbuggyMatches.join("|"));
1384
1385                /* Contains
1386---------------------------------------------------------------------- */
1387                hasCompare = rnative.test(docElem.compareDocumentPosition);
1388
1389                // Element contains another
1390                // Purposefully self-exclusive
1391                // As in, an element does not contain itself
1392                contains = hasCompare || rnative.test(docElem.contains) ?
1393                    function (a, b) {
1394                        var adown = a.nodeType === 9 ? a.documentElement : a,
1395                            bup = b && b.parentNode;
1396                        return a === bup || !!(bup && bup.nodeType === 1 && (
1397                            adown.contains ?
1398                                adown.contains(bup) :
1399                                a.compareDocumentPosition && a.compareDocumentPosition(bup) & 16
1400                        ));
1401                    } :
1402                    function (a, b) {
1403                        if (b) {
1404                            while ((b = b.parentNode)) {
1405                                if (b === a) {
1406                                    return true;
1407                                }
1408                            }
1409                        }
1410                        return false;
1411                    };
1412
1413                /* Sorting
1414---------------------------------------------------------------------- */
1415
1416                // Document order sorting
1417                sortOrder = hasCompare ?
1418                    function (a, b) {
1419
1420                        // Flag for duplicate removal
1421                        if (a === b) {
1422                            hasDuplicate = true;
1423                            return 0;
1424                        }
1425
1426                        // Sort on method existence if only one input has compareDocumentPosition
1427                        var compare = !a.compareDocumentPosition - !b.compareDocumentPosition;
1428                        if (compare) {
1429                            return compare;
1430                        }
1431
1432                        // Calculate position if both inputs belong to the same document
1433                        compare = (a.ownerDocument || a) === (b.ownerDocument || b) ?
1434                            a.compareDocumentPosition(b) :
1435
1436                            // Otherwise we know they are disconnected
1437                            1;
1438
1439                        // Disconnected nodes
1440                        if (compare & 1 ||
1441                            (!support.sortDetached && b.compareDocumentPosition(a) === compare)) {
1442
1443                            // Choose the first element that is related to our preferred document
1444                            if (a === document || a.ownerDocument === preferredDoc && contains(preferredDoc, a)) {
1445                                return -1;
1446                            }
1447                            if (b === document || b.ownerDocument === preferredDoc && contains(preferredDoc, b)) {
1448                                return 1;
1449                            }
1450
1451                            // Maintain original order
1452                            return sortInput ?
1453                                (indexOf(sortInput, a) - indexOf(sortInput, b)) :
1454                                0;
1455                        }
1456
1457                        return compare & 4 ? -1 : 1;
1458                    } :
1459                    function (a, b) {
1460                        // Exit early if the nodes are identical
1461                        if (a === b) {
1462                            hasDuplicate = true;
1463                            return 0;
1464                        }
1465
1466                        var cur,
1467                            i = 0,
1468                            aup = a.parentNode,
1469                            bup = b.parentNode,
1470                            ap = [a],
1471                            bp = [b];
1472
1473                        // Parentless nodes are either documents or disconnected
1474                        if (!aup || !bup) {
1475                            return a === document ? -1 :
1476                                b === document ? 1 :
1477                                    aup ? -1 :
1478                                        bup ? 1 :
1479                                            sortInput ?
1480                                                (indexOf(sortInput, a) - indexOf(sortInput, b)) :
1481                                                0;
1482
1483                            // If the nodes are siblings, we can do a quick check
1484                        } else if (aup === bup) {
1485                            return siblingCheck(a, b);
1486                        }
1487
1488                        // Otherwise we need full lists of their ancestors for comparison
1489                        cur = a;
1490                        while ((cur = cur.parentNode)) {
1491                            ap.unshift(cur);
1492                        }
1493                        cur = b;
1494                        while ((cur = cur.parentNode)) {
1495                            bp.unshift(cur);
1496                        }
1497
1498                        // Walk down the tree looking for a discrepancy
1499                        while (ap[i] === bp[i]) {
1500                            i++;
1501                        }
1502
1503                        return i ?
1504                            // Do a sibling check if the nodes have a common ancestor
1505                            siblingCheck(ap[i], bp[i]) :
1506
1507                            // Otherwise nodes in our document sort first
1508                            ap[i] === preferredDoc ? -1 :
1509                                bp[i] === preferredDoc ? 1 :
1510                                    0;
1511                    };
1512
1513                return document;
1514            };
1515
1516            Sizzle.matches = function (expr, elements) {
1517                return Sizzle(expr, null, null, elements);
1518            };
1519
1520            Sizzle.matchesSelector = function (elem, expr) {
1521                // Set document vars if needed
1522                if ((elem.ownerDocument || elem) !== document) {
1523                    setDocument(elem);
1524                }
1525
1526                // Make sure that attribute selectors are quoted
1527                expr = expr.replace(rattributeQuotes, "='$1']");
1528
1529                if (support.matchesSelector && documentIsHTML &&
1530                    !compilerCache[expr + " "] &&
1531                    (!rbuggyMatches || !rbuggyMatches.test(expr)) &&
1532                    (!rbuggyQSA || !rbuggyQSA.test(expr))) {
1533
1534                    try {
1535                        var ret = matches.call(elem, expr);
1536
1537                        // IE 9's matchesSelector returns false on disconnected nodes
1538                        if (ret || support.disconnectedMatch ||
1539                            // As well, disconnected nodes are said to be in a document
1540                            // fragment in IE 9
1541                            elem.document && elem.document.nodeType !== 11) {
1542                            return ret;
1543                        }
1544                    } catch (e) {
1545                    }
1546                }
1547
1548                return Sizzle(expr, document, null, [elem]).length > 0;
1549            };
1550
1551            Sizzle.contains = function (context, elem) {
1552                // Set document vars if needed
1553                if ((context.ownerDocument || context) !== document) {
1554                    setDocument(context);
1555                }
1556                return contains(context, elem);
1557            };
1558
1559            Sizzle.attr = function (elem, name) {
1560                // Set document vars if needed
1561                if ((elem.ownerDocument || elem) !== document) {
1562                    setDocument(elem);
1563                }
1564
1565                var fn = Expr.attrHandle[name.toLowerCase()],
1566                    // Don't get fooled by Object.prototype properties (jQuery #13807)
1567                    val = fn && hasOwn.call(Expr.attrHandle, name.toLowerCase()) ?
1568                        fn(elem, name, !documentIsHTML) :
1569                        undefined;
1570
1571                return val !== undefined ?
1572                    val :
1573                    support.attributes || !documentIsHTML ?
1574                        elem.getAttribute(name) :
1575                        (val = elem.getAttributeNode(name)) && val.specified ?
1576                            val.value :
1577                            null;
1578            };
1579
1580            Sizzle.escape = function (sel) {
1581                return (sel + "").replace(rcssescape, fcssescape);
1582            };
1583
1584            Sizzle.error = function (msg) {
1585                throw new Error("Syntax error, unrecognized expression: " + msg);
1586            };
1587
1588            /**
1589             * Document sorting and removing duplicates
1590             * @param {ArrayLike} results
1591             */
1592            Sizzle.uniqueSort = function (results) {
1593                var elem,
1594                    duplicates = [],
1595                    j = 0,
1596                    i = 0;
1597
1598                // Unless we *know* we can detect duplicates, assume their presence
1599                hasDuplicate = !support.detectDuplicates;
1600                sortInput = !support.sortStable && results.slice(0);
1601                results.sort(sortOrder);
1602
1603                if (hasDuplicate) {
1604                    while ((elem = results[i++])) {
1605                        if (elem === results[i]) {
1606                            j = duplicates.push(i);
1607                        }
1608                    }
1609                    while (j--) {
1610                        results.splice(duplicates[j], 1);
1611                    }
1612                }
1613
1614                // Clear input after sorting to release objects
1615                // See https://github.com/jquery/sizzle/pull/225
1616                sortInput = null;
1617
1618                return results;
1619            };
1620
1621            /**
1622             * Utility function for retrieving the text value of an array of DOM nodes
1623             * @param {Array|Element} elem
1624             */
1625            getText = Sizzle.getText = function (elem) {
1626                var node,
1627                    ret = "",
1628                    i = 0,
1629                    nodeType = elem.nodeType;
1630
1631                if (!nodeType) {
1632                    // If no nodeType, this is expected to be an array
1633                    while ((node = elem[i++])) {
1634                        // Do not traverse comment nodes
1635                        ret += getText(node);
1636                    }
1637                } else if (nodeType === 1 || nodeType === 9 || nodeType === 11) {
1638                    // Use textContent for elements
1639                    // innerText usage removed for consistency of new lines (jQuery #11153)
1640                    if (typeof elem.textContent === "string") {
1641                        return elem.textContent;
1642                    } else {
1643                        // Traverse its children
1644                        for (elem = elem.firstChild; elem; elem = elem.nextSibling) {
1645                            ret += getText(elem);
1646                        }
1647                    }
1648                } else if (nodeType === 3 || nodeType === 4) {
1649                    return elem.nodeValue;
1650                }
1651                // Do not include comment or processing instruction nodes
1652
1653                return ret;
1654            };
1655
1656            Expr = Sizzle.selectors = {
1657
1658                // Can be adjusted by the user
1659                cacheLength: 50,
1660
1661                createPseudo: markFunction,
1662
1663                match: matchExpr,
1664
1665                attrHandle: {},
1666
1667                find: {},
1668
1669                relative: {
1670                    ">": {dir: "parentNode", first: true},
1671                    " ": {dir: "parentNode"},
1672                    "+": {dir: "previousSibling", first: true},
1673                    "~": {dir: "previousSibling"}
1674                },
1675
1676                preFilter: {
1677                    "ATTR": function (match) {
1678                        match[1] = match[1].replace(runescape, funescape);
1679
1680                        // Move the given value to match[3] whether quoted or unquoted
1681                        match[3] = (match[3] || match[4] || match[5] || "").replace(runescape, funescape);
1682
1683                        if (match[2] === "~=") {
1684                            match[3] = " " + match[3] + " ";
1685                        }
1686
1687                        return match.slice(0, 4);
1688                    },
1689
1690                    "CHILD": function (match) {
1691                        /* matches from matchExpr["CHILD"]
1692			1 type (only|nth|...)
1693			2 what (child|of-type)
1694			3 argument (even|odd|\d*|\d*n([+-]\d+)?|...)
1695			4 xn-component of xn+y argument ([+-]?\d*n|)
1696			5 sign of xn-component
1697			6 x of xn-component
1698			7 sign of y-component
1699			8 y of y-component
1700		*/
1701                        match[1] = match[1].toLowerCase();
1702
1703                        if (match[1].slice(0, 3) === "nth") {
1704                            // nth-* requires argument
1705                            if (!match[3]) {
1706                                Sizzle.error(match[0]);
1707                            }
1708
1709                            // numeric x and y parameters for Expr.filter.CHILD
1710                            // remember that false/true cast respectively to 0/1
1711                            match[4] = +(match[4] ? match[5] + (match[6] || 1) : 2 * (match[3] === "even" || match[3] === "odd"));
1712                            match[5] = +((match[7] + match[8]) || match[3] === "odd");
1713
1714                            // other types prohibit arguments
1715                        } else if (match[3]) {
1716                            Sizzle.error(match[0]);
1717                        }
1718
1719                        return match;
1720                    },
1721
1722                    "PSEUDO": function (match) {
1723                        var excess,
1724                            unquoted = !match[6] && match[2];
1725
1726                        if (matchExpr["CHILD"].test(match[0])) {
1727                            return null;
1728                        }
1729
1730                        // Accept quoted arguments as-is
1731                        if (match[3]) {
1732                            match[2] = match[4] || match[5] || "";
1733
1734                            // Strip excess characters from unquoted arguments
1735                        } else if (unquoted && rpseudo.test(unquoted) &&
1736                            // Get excess from tokenize (recursively)
1737                            (excess = tokenize(unquoted, true)) &&
1738                            // advance to the next closing parenthesis
1739                            (excess = unquoted.indexOf(")", unquoted.length - excess) - unquoted.length)) {
1740
1741                            // excess is a negative index
1742                            match[0] = match[0].slice(0, excess);
1743                            match[2] = unquoted.slice(0, excess);
1744                        }
1745
1746                        // Return only captures needed by the pseudo filter method (type and argument)
1747                        return match.slice(0, 3);
1748                    }
1749                },
1750
1751                filter: {
1752
1753                    "TAG": function (nodeNameSelector) {
1754                        var nodeName = nodeNameSelector.replace(runescape, funescape).toLowerCase();
1755                        return nodeNameSelector === "*" ?
1756                            function () {
1757                                return true;
1758                            } :
1759                            function (elem) {
1760                                return elem.nodeName && elem.nodeName.toLowerCase() === nodeName;
1761                            };
1762                    },
1763
1764                    "CLASS": function (className) {
1765                        var pattern = classCache[className + " "];
1766
1767                        return pattern ||
1768                            (pattern = new RegExp("(^|" + whitespace + ")" + className + "(" + whitespace + "|$)")) &&
1769                            classCache(className, function (elem) {
1770                                return pattern.test(typeof elem.className === "string" && elem.className || typeof elem.getAttribute !== "undefined" && elem.getAttribute("class") || "");
1771                            });
1772                    },
1773
1774                    "ATTR": function (name, operator, check) {
1775                        return function (elem) {
1776                            var result = Sizzle.attr(elem, name);
1777
1778                            if (result == null) {
1779                                return operator === "!=";
1780                            }
1781                            if (!operator) {
1782                                return true;
1783                            }
1784
1785                            result += "";
1786
1787                            return operator === "=" ? result === check :
1788                                operator === "!=" ? result !== check :
1789                                    operator === "^=" ? check && result.indexOf(check) === 0 :
1790                                        operator === "*=" ? check && result.indexOf(check) > -1 :
1791                                            operator === "$=" ? check && result.slice(-check.length) === check :
1792                                                operator === "~=" ? (" " + result.replace(rwhitespace, " ") + " ").indexOf(check) > -1 :
1793                                                    operator === "|=" ? result === check || result.slice(0, check.length + 1) === check + "-" :
1794                                                        false;
1795                        };
1796                    },
1797
1798                    "CHILD": function (type, what, argument, first, last) {
1799                        var simple = type.slice(0, 3) !== "nth",
1800                            forward = type.slice(-4) !== "last",
1801                            ofType = what === "of-type";
1802
1803                        return first === 1 && last === 0 ?
1804
1805                            // Shortcut for :nth-*(n)
1806                            function (elem) {
1807                                return !!elem.parentNode;
1808                            } :
1809
1810                            function (elem, context, xml) {
1811                                var cache, uniqueCache, outerCache, node, nodeIndex, start,
1812                                    dir = simple !== forward ? "nextSibling" : "previousSibling",
1813                                    parent = elem.parentNode,
1814                                    name = ofType && elem.nodeName.toLowerCase(),
1815                                    useCache = !xml && !ofType,
1816                                    diff = false;
1817
1818                                if (parent) {
1819
1820                                    // :(first|last|only)-(child|of-type)
1821                                    if (simple) {
1822                                        while (dir) {
1823                                            node = elem;
1824                                            while ((node = node[dir])) {
1825                                                if (ofType ?
1826                                                    node.nodeName.toLowerCase() === name :
1827                                                    node.nodeType === 1) {
1828
1829                                                    return false;
1830                                                }
1831                                            }
1832                                            // Reverse direction for :only-* (if we haven't yet done so)
1833                                            start = dir = type === "only" && !start && "nextSibling";
1834                                        }
1835                                        return true;
1836                                    }
1837
1838                                    start = [forward ? parent.firstChild : parent.lastChild];
1839
1840                                    // non-xml :nth-child(...) stores cache data on `parent`
1841                                    if (forward && useCache) {
1842
1843                                        // Seek `elem` from a previously-cached index
1844
1845                                        // ...in a gzip-friendly way
1846                                        node = parent;
1847                                        outerCache = node[expando] || (node[expando] = {});
1848
1849                                        // Support: IE <9 only
1850                                        // Defend against cloned attroperties (jQuery gh-1709)
1851                                        uniqueCache = outerCache[node.uniqueID] ||
1852                                            (outerCache[node.uniqueID] = {});
1853
1854                                        cache = uniqueCache[type] || [];
1855                                        nodeIndex = cache[0] === dirruns && cache[1];
1856                                        diff = nodeIndex && cache[2];
1857                                        node = nodeIndex && parent.childNodes[nodeIndex];
1858
1859                                        while ((node = ++nodeIndex && node && node[dir] ||
1860
1861                                            // Fallback to seeking `elem` from the start
1862                                            (diff = nodeIndex = 0) || start.pop())) {
1863
1864                                            // When found, cache indexes on `parent` and break
1865                                            if (node.nodeType === 1 && ++diff && node === elem) {
1866                                                uniqueCache[type] = [dirruns, nodeIndex, diff];
1867                                                break;
1868                                            }
1869                                        }
1870
1871                                    } else {
1872                                        // Use previously-cached element index if available
1873                                        if (useCache) {
1874                                            // ...in a gzip-friendly way
1875                                            node = elem;
1876                                            outerCache = node[expando] || (node[expando] = {});
1877
1878                                            // Support: IE <9 only
1879                                            // Defend against cloned attroperties (jQuery gh-1709)
1880                                            uniqueCache = outerCache[node.uniqueID] ||
1881                                                (outerCache[node.uniqueID] = {});
1882
1883                                            cache = uniqueCache[type] || [];
1884                                            nodeIndex = cache[0] === dirruns && cache[1];
1885                                            diff = nodeIndex;
1886                                        }
1887
1888                                        // xml :nth-child(...)
1889                                        // or :nth-last-child(...) or :nth(-last)?-of-type(...)
1890                                        if (diff === false) {
1891                                            // Use the same loop as above to seek `elem` from the start
1892                                            while ((node = ++nodeIndex && node && node[dir] ||
1893                                                (diff = nodeIndex = 0) || start.pop())) {
1894
1895                                                if ((ofType ?
1896                                                        node.nodeName.toLowerCase() === name :
1897                                                        node.nodeType === 1) &&
1898                                                    ++diff) {
1899
1900                                                    // Cache the index of each encountered element
1901                                                    if (useCache) {
1902                                                        outerCache = node[expando] || (node[expando] = {});
1903
1904                                                        // Support: IE <9 only
1905                                                        // Defend against cloned attroperties (jQuery gh-1709)
1906                                                        uniqueCache = outerCache[node.uniqueID] ||
1907                                                            (outerCache[node.uniqueID] = {});
1908
1909                                                        uniqueCache[type] = [dirruns, diff];
1910                                                    }
1911
1912                                                    if (node === elem) {
1913                                                        break;
1914                                                    }
1915                                                }
1916                                            }
1917                                        }
1918                                    }
1919
1920                                    // Incorporate the offset, then check against cycle size
1921                                    diff -= last;
1922                                    return diff === first || (diff % first === 0 && diff / first >= 0);
1923                                }
1924                            };
1925                    },
1926
1927                    "PSEUDO": function (pseudo, argument) {
1928                        // pseudo-class names are case-insensitive
1929                        // http://www.w3.org/TR/selectors/#pseudo-classes
1930                        // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters
1931                        // Remember that setFilters inherits from pseudos
1932                        var args,
1933                            fn = Expr.pseudos[pseudo] || Expr.setFilters[pseudo.toLowerCase()] ||
1934                                Sizzle.error("unsupported pseudo: " + pseudo);
1935
1936                        // The user may use createPseudo to indicate that
1937                        // arguments are needed to create the filter function
1938                        // just as Sizzle does
1939                        if (fn[expando]) {
1940                            return fn(argument);
1941                        }
1942
1943                        // But maintain support for old signatures
1944                        if (fn.length > 1) {
1945                            args = [pseudo, pseudo, "", argument];
1946                            return Expr.setFilters.hasOwnProperty(pseudo.toLowerCase()) ?
1947                                markFunction(function (seed, matches) {
1948                                    var idx,
1949                                        matched = fn(seed, argument),
1950                                        i = matched.length;
1951                                    while (i--) {
1952                                        idx = indexOf(seed, matched[i]);
1953                                        seed[idx] = !(matches[idx] = matched[i]);
1954                                    }
1955                                }) :
1956                                function (elem) {
1957                                    return fn(elem, 0, args);
1958                                };
1959                        }
1960
1961                        return fn;
1962                    }
1963                },
1964
1965                pseudos: {
1966                    // Potentially complex pseudos
1967                    "not": markFunction(function (selector) {
1968                        // Trim the selector passed to compile
1969                        // to avoid treating leading and trailing
1970                        // spaces as combinators
1971                        var input = [],
1972                            results = [],
1973                            matcher = compile(selector.replace(rtrim, "$1"));
1974
1975                        return matcher[expando] ?
1976                            markFunction(function (seed, matches, context, xml) {
1977                                var elem,
1978                                    unmatched = matcher(seed, null, xml, []),
1979                                    i = seed.length;
1980
1981                                // Match elements unmatched by `matcher`
1982                                while (i--) {
1983                                    if ((elem = unmatched[i])) {
1984                                        seed[i] = !(matches[i] = elem);
1985                                    }
1986                                }
1987                            }) :
1988                            function (elem, context, xml) {
1989                                input[0] = elem;
1990                                matcher(input, null, xml, results);
1991                                // Don't keep the element (issue #299)
1992                                input[0] = null;
1993                                return !results.pop();
1994                            };
1995                    }),
1996
1997                    "has": markFunction(function (selector) {
1998                        return function (elem) {
1999                            return Sizzle(selector, elem).length > 0;
2000                        };
2001                    }),
2002
2003                    "contains": markFunction(function (text) {
2004                        text = text.replace(runescape, funescape);
2005                        return function (elem) {
2006                            return (elem.textContent || elem.innerText || getText(elem)).indexOf(text) > -1;
2007                        };
2008                    }),
2009
2010                    // "Whether an element is represented by a :lang() selector
2011                    // is based solely on the element's language value
2012                    // being equal to the identifier C,
2013                    // or beginning with the identifier C immediately followed by "-".
2014                    // The matching of C against the element's language value is performed case-insensitively.
2015                    // The identifier C does not have to be a valid language name."
2016                    // http://www.w3.org/TR/selectors/#lang-pseudo
2017                    "lang": markFunction(function (lang) {
2018                        // lang value must be a valid identifier
2019                        if (!ridentifier.test(lang || "")) {
2020                            Sizzle.error("unsupported lang: " + lang);
2021                        }
2022                        lang = lang.replace(runescape, funescape).toLowerCase();
2023                        return function (elem) {
2024                            var elemLang;
2025                            do {
2026                                if ((elemLang = documentIsHTML ?
2027                                    elem.lang :
2028                                    elem.getAttribute("xml:lang") || elem.getAttribute("lang"))) {
2029
2030                                    elemLang = elemLang.toLowerCase();
2031                                    return elemLang === lang || elemLang.indexOf(lang + "-") === 0;
2032                                }
2033                            } while ((elem = elem.parentNode) && elem.nodeType === 1);
2034                            return false;
2035                        };
2036                    }),
2037
2038                    // Miscellaneous
2039                    "target": function (elem) {
2040                        var hash = window.location && window.location.hash;
2041                        return hash && hash.slice(1) === elem.id;
2042                    },
2043
2044                    "root": function (elem) {
2045                        return elem === docElem;
2046                    },
2047
2048                    "focus": function (elem) {
2049                        return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex);
2050                    },
2051
2052                    // Boolean properties
2053                    "enabled": createDisabledPseudo(false),
2054                    "disabled": createDisabledPseudo(true),
2055
2056                    "checked": function (elem) {
2057                        // In CSS3, :checked should return both checked and selected elements
2058                        // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
2059                        var nodeName = elem.nodeName.toLowerCase();
2060                        return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected);
2061                    },
2062
2063                    "selected": function (elem) {
2064                        // Accessing this property makes selected-by-default
2065                        // options in Safari work properly
2066                        if (elem.parentNode) {
2067                            elem.parentNode.selectedIndex;
2068                        }
2069
2070                        return elem.selected === true;
2071                    },
2072
2073                    // Contents
2074                    "empty": function (elem) {
2075                        // http://www.w3.org/TR/selectors/#empty-pseudo
2076                        // :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5),
2077                        // but not by others (comment: 8; processing instruction: 7; etc.)
2078                        // nodeType < 6 works because attributes (2) do not appear as children
2079                        for (elem = elem.firstChild; elem; elem = elem.nextSibling) {
2080                            if (elem.nodeType < 6) {
2081                                return false;
2082                            }
2083                        }
2084                        return true;
2085                    },
2086
2087                    "parent": function (elem) {
2088                        return !Expr.pseudos["empty"](elem);
2089                    },
2090
2091                    // Element/input types
2092                    "header": function (elem) {
2093                        return rheader.test(elem.nodeName);
2094                    },
2095
2096                    "input": function (elem) {
2097                        return rinputs.test(elem.nodeName);
2098                    },
2099
2100                    "button": function (elem) {
2101                        var name = elem.nodeName.toLowerCase();
2102                        return name === "input" && elem.type === "button" || name === "button";
2103                    },
2104
2105                    "text": function (elem) {
2106                        var attr;
2107                        return elem.nodeName.toLowerCase() === "input" &&
2108                            elem.type === "text" &&
2109
2110                            // Support: IE<8
2111                            // New HTML5 attribute values (e.g., "search") appear with elem.type === "text"
2112                            ((attr = elem.getAttribute("type")) == null || attr.toLowerCase() === "text");
2113                    },
2114
2115                    // Position-in-collection
2116                    "first": createPositionalPseudo(function () {
2117                        return [0];
2118                    }),
2119
2120                    "last": createPositionalPseudo(function (matchIndexes, length) {
2121                        return [length - 1];
2122                    }),
2123
2124                    "eq": createPositionalPseudo(function (matchIndexes, length, argument) {
2125                        return [argument < 0 ? argument + length : argument];
2126                    }),
2127
2128                    "even": createPositionalPseudo(function (matchIndexes, length) {
2129                        var i = 0;
2130                        for (; i < length; i += 2) {
2131                            matchIndexes.push(i);
2132                        }
2133                        return matchIndexes;
2134                    }),
2135
2136                    "odd": createPositionalPseudo(function (matchIndexes, length) {
2137                        var i = 1;
2138                        for (; i < length; i += 2) {
2139                            matchIndexes.push(i);
2140                        }
2141                        return matchIndexes;
2142                    }),
2143
2144                    "lt": createPositionalPseudo(function (matchIndexes, length, argument) {
2145                        var i = argument < 0 ? argument + length : argument;
2146                        for (; --i >= 0;) {
2147                            matchIndexes.push(i);
2148                        }
2149                        return matchIndexes;
2150                    }),
2151
2152                    "gt": createPositionalPseudo(function (matchIndexes, length, argument) {
2153                        var i = argument < 0 ? argument + length : argument;
2154                        for (; ++i < length;) {
2155                            matchIndexes.push(i);
2156                        }
2157                        return matchIndexes;
2158                    })
2159                }
2160            };
2161
2162            Expr.pseudos["nth"] = Expr.pseudos["eq"];
2163
2164// Add button/input type pseudos
2165            for (i in {radio: true, checkbox: true, file: true, password: true, image: true}) {
2166                Expr.pseudos[i] = createInputPseudo(i);
2167            }
2168            for (i in {submit: true, reset: true}) {
2169                Expr.pseudos[i] = createButtonPseudo(i);
2170            }
2171
2172// Easy API for creating new setFilters
2173            function setFilters() {
2174            }
2175
2176            setFilters.prototype = Expr.filters = Expr.pseudos;
2177            Expr.setFilters = new setFilters();
2178
2179            tokenize = Sizzle.tokenize = function (selector, parseOnly) {
2180                var matched, match, tokens, type,
2181                    soFar, groups, preFilters,
vendor: 33,338 bytes, lines 2182-2949
2182                    cached = tokenCache[selector + " "];
2183
2184                if (cached) {
2185                    return parseOnly ? 0 : cached.slice(0);
2186                }
2187
2188                soFar = selector;
2189                groups = [];
2190                preFilters = Expr.preFilter;
2191
2192                while (soFar) {
2193
2194                    // Comma and first run
2195                    if (!matched || (match = rcomma.exec(soFar))) {
2196                        if (match) {
2197                            // Don't consume trailing commas as valid
2198                            soFar = soFar.slice(match[0].length) || soFar;
2199                        }
2200                        groups.push((tokens = []));
2201                    }
2202
2203                    matched = false;
2204
2205                    // Combinators
2206                    if ((match = rcombinators.exec(soFar))) {
2207                        matched = match.shift();
2208                        tokens.push({
2209                            value: matched,
2210                            // Cast descendant combinators to space
2211                            type: match[0].replace(rtrim, " ")
2212                        });
2213                        soFar = soFar.slice(matched.length);
2214                    }
2215
2216                    // Filters
2217                    for (type in Expr.filter) {
2218                        if ((match = matchExpr[type].exec(soFar)) && (!preFilters[type] ||
2219                            (match = preFilters[type](match)))) {
2220                            matched = match.shift();
2221                            tokens.push({
2222                                value: matched,
2223                                type: type,
2224                                matches: match
2225                            });
2226                            soFar = soFar.slice(matched.length);
2227                        }
2228                    }
2229
2230                    if (!matched) {
2231                        break;
2232                    }
2233                }
2234
2235                // Return the length of the invalid excess
2236                // if we're just parsing
2237                // Otherwise, throw an error or return tokens
2238                return parseOnly ?
2239                    soFar.length :
2240                    soFar ?
2241                        Sizzle.error(selector) :
2242                        // Cache the tokens
2243                        tokenCache(selector, groups).slice(0);
2244            };
2245
2246            function toSelector(tokens) {
2247                var i = 0,
2248                    len = tokens.length,
2249                    selector = "";
2250                for (; i < len; i++) {
2251                    selector += tokens[i].value;
2252                }
2253                return selector;
2254            }
2255
2256            function addCombinator(matcher, combinator, base) {
2257                var dir = combinator.dir,
2258                    skip = combinator.next,
2259                    key = skip || dir,
2260                    checkNonElements = base && key === "parentNode",
2261                    doneName = done++;
2262
2263                return combinator.first ?
2264                    // Check against closest ancestor/preceding element
2265                    function (elem, context, xml) {
2266                        while ((elem = elem[dir])) {
2267                            if (elem.nodeType === 1 || checkNonElements) {
2268                                return matcher(elem, context, xml);
2269                            }
2270                        }
2271                        return false;
2272                    } :
2273
2274                    // Check against all ancestor/preceding elements
2275                    function (elem, context, xml) {
2276                        var oldCache, uniqueCache, outerCache,
2277                            newCache = [dirruns, doneName];
2278
2279                        // We can't set arbitrary data on XML nodes, so they don't benefit from combinator caching
2280                        if (xml) {
2281                            while ((elem = elem[dir])) {
2282                                if (elem.nodeType === 1 || checkNonElements) {
2283                                    if (matcher(elem, context, xml)) {
2284                                        return true;
2285                                    }
2286                                }
2287                            }
2288                        } else {
2289                            while ((elem = elem[dir])) {
2290                                if (elem.nodeType === 1 || checkNonElements) {
2291                                    outerCache = elem[expando] || (elem[expando] = {});
2292
2293                                    // Support: IE <9 only
2294                                    // Defend against cloned attroperties (jQuery gh-1709)
2295                                    uniqueCache = outerCache[elem.uniqueID] || (outerCache[elem.uniqueID] = {});
2296
2297                                    if (skip && skip === elem.nodeName.toLowerCase()) {
2298                                        elem = elem[dir] || elem;
2299                                    } else if ((oldCache = uniqueCache[key]) &&
2300                                        oldCache[0] === dirruns && oldCache[1] === doneName) {
2301
2302                                        // Assign to newCache so results back-propagate to previous elements
2303                                        return (newCache[2] = oldCache[2]);
2304                                    } else {
2305                                        // Reuse newcache so results back-propagate to previous elements
2306                                        uniqueCache[key] = newCache;
2307
2308                                        // A match means we're done; a fail means we have to keep checking
2309                                        if ((newCache[2] = matcher(elem, context, xml))) {
2310                                            return true;
2311                                        }
2312                                    }
2313                                }
2314                            }
2315                        }
2316                        return false;
2317                    };
2318            }
2319
2320            function elementMatcher(matchers) {
2321                return matchers.length > 1 ?
2322                    function (elem, context, xml) {
2323                        var i = matchers.length;
2324                        while (i--) {
2325                            if (!matchers[i](elem, context, xml)) {
2326                                return false;
2327                            }
2328                        }
2329                        return true;
2330                    } :
2331                    matchers[0];
2332            }
2333
2334            function multipleContexts(selector, contexts, results) {
2335                var i = 0,
2336                    len = contexts.length;
2337                for (; i < len; i++) {
2338                    Sizzle(selector, contexts[i], results);
2339                }
2340                return results;
2341            }
2342
2343            function condense(unmatched, map, filter, context, xml) {
2344                var elem,
2345                    newUnmatched = [],
2346                    i = 0,
2347                    len = unmatched.length,
2348                    mapped = map != null;
2349
2350                for (; i < len; i++) {
2351                    if ((elem = unmatched[i])) {
2352                        if (!filter || filter(elem, context, xml)) {
2353                            newUnmatched.push(elem);
2354                            if (mapped) {
2355                                map.push(i);
2356                            }
2357                        }
2358                    }
2359                }
2360
2361                return newUnmatched;
2362            }
2363
2364            function setMatcher(preFilter, selector, matcher, postFilter, postFinder, postSelector) {
2365                if (postFilter && !postFilter[expando]) {
2366                    postFilter = setMatcher(postFilter);
2367                }
2368                if (postFinder && !postFinder[expando]) {
2369                    postFinder = setMatcher(postFinder, postSelector);
2370                }
2371                return markFunction(function (seed, results, context, xml) {
2372                    var temp, i, elem,
2373                        preMap = [],
2374                        postMap = [],
2375                        preexisting = results.length,
2376
2377                        // Get initial elements from seed or context
2378                        elems = seed || multipleContexts(selector || "*", context.nodeType ? [context] : context, []),
2379
2380                        // Prefilter to get matcher input, preserving a map for seed-results synchronization
2381                        matcherIn = preFilter && (seed || !selector) ?
2382                            condense(elems, preMap, preFilter, context, xml) :
2383                            elems,
2384
2385                        matcherOut = matcher ?
2386                            // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results,
2387                            postFinder || (seed ? preFilter : preexisting || postFilter) ?
2388
2389                                // ...intermediate processing is necessary
2390                                [] :
2391
2392                                // ...otherwise use results directly
2393                                results :
2394                            matcherIn;
2395
2396                    // Find primary matches
2397                    if (matcher) {
2398                        matcher(matcherIn, matcherOut, context, xml);
2399                    }
2400
2401                    // Apply postFilter
2402                    if (postFilter) {
2403                        temp = condense(matcherOut, postMap);
2404                        postFilter(temp, [], context, xml);
2405
2406                        // Un-match failing elements by moving them back to matcherIn
2407                        i = temp.length;
2408                        while (i--) {
2409                            if ((elem = temp[i])) {
2410                                matcherOut[postMap[i]] = !(matcherIn[postMap[i]] = elem);
2411                            }
2412                        }
2413                    }
2414
2415                    if (seed) {
2416                        if (postFinder || preFilter) {
2417                            if (postFinder) {
2418                                // Get the final matcherOut by condensing this intermediate into postFinder contexts
2419                                temp = [];
2420                                i = matcherOut.length;
2421                                while (i--) {
2422                                    if ((elem = matcherOut[i])) {
2423                                        // Restore matcherIn since elem is not yet a final match
2424                                        temp.push((matcherIn[i] = elem));
2425                                    }
2426                                }
2427                                postFinder(null, (matcherOut = []), temp, xml);
2428                            }
2429
2430                            // Move matched elements from seed to results to keep them synchronized
2431                            i = matcherOut.length;
2432                            while (i--) {
2433                                if ((elem = matcherOut[i]) &&
2434                                    (temp = postFinder ? indexOf(seed, elem) : preMap[i]) > -1) {
2435
2436                                    seed[temp] = !(results[temp] = elem);
2437                                }
2438                            }
2439                        }
2440
2441                        // Add elements to results, through postFinder if defined
2442                    } else {
2443                        matcherOut = condense(
2444                            matcherOut === results ?
2445                                matcherOut.splice(preexisting, matcherOut.length) :
2446                                matcherOut
2447                        );
2448                        if (postFinder) {
2449                            postFinder(null, results, matcherOut, xml);
2450                        } else {
2451                            push.apply(results, matcherOut);
2452                        }
2453                    }
2454                });
2455            }
2456
2457            function matcherFromTokens(tokens) {
2458                var checkContext, matcher, j,
2459                    len = tokens.length,
2460                    leadingRelative = Expr.relative[tokens[0].type],
2461                    implicitRelative = leadingRelative || Expr.relative[" "],
2462                    i = leadingRelative ? 1 : 0,
2463
2464                    // The foundational matcher ensures that elements are reachable from top-level context(s)
2465                    matchContext = addCombinator(function (elem) {
2466                        return elem === checkContext;
2467                    }, implicitRelative, true),
2468                    matchAnyContext = addCombinator(function (elem) {
2469                        return indexOf(checkContext, elem) > -1;
2470                    }, implicitRelative, true),
2471                    matchers = [function (elem, context, xml) {
2472                        var ret = (!leadingRelative && (xml || context !== outermostContext)) || (
2473                            (checkContext = context).nodeType ?
2474                                matchContext(elem, context, xml) :
2475                                matchAnyContext(elem, context, xml));
2476                        // Avoid hanging onto element (issue #299)
2477                        checkContext = null;
2478                        return ret;
2479                    }];
2480
2481                for (; i < len; i++) {
2482                    if ((matcher = Expr.relative[tokens[i].type])) {
2483                        matchers = [addCombinator(elementMatcher(matchers), matcher)];
2484                    } else {
2485                        matcher = Expr.filter[tokens[i].type].apply(null, tokens[i].matches);
2486
2487                        // Return special upon seeing a positional matcher
2488                        if (matcher[expando]) {
2489                            // Find the next relative operator (if any) for proper handling
2490                            j = ++i;
2491                            for (; j < len; j++) {
2492                                if (Expr.relative[tokens[j].type]) {
2493                                    break;
2494                                }
2495                            }
2496                            return setMatcher(
2497                                i > 1 && elementMatcher(matchers),
2498                                i > 1 && toSelector(
2499                                    // If the preceding token was a descendant combinator, insert an implicit any-element `*`
2500                                    tokens.slice(0, i - 1).concat({value: tokens[i - 2].type === " " ? "*" : ""})
2501                                ).replace(rtrim, "$1"),
2502                                matcher,
2503                                i < j && matcherFromTokens(tokens.slice(i, j)),
2504                                j < len && matcherFromTokens((tokens = tokens.slice(j))),
2505                                j < len && toSelector(tokens)
2506                            );
2507                        }
2508                        matchers.push(matcher);
2509                    }
2510                }
2511
2512                return elementMatcher(matchers);
2513            }
2514
2515            function matcherFromGroupMatchers(elementMatchers, setMatchers) {
2516                var bySet = setMatchers.length > 0,
2517                    byElement = elementMatchers.length > 0,
2518                    superMatcher = function (seed, context, xml, results, outermost) {
2519                        var elem, j, matcher,
2520                            matchedCount = 0,
2521                            i = "0",
2522                            unmatched = seed && [],
2523                            setMatched = [],
2524                            contextBackup = outermostContext,
2525                            // We must always have either seed elements or outermost context
2526                            elems = seed || byElement && Expr.find["TAG"]("*", outermost),
2527                            // Use integer dirruns iff this is the outermost matcher
2528                            dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1),
2529                            len = elems.length;
2530
2531                        if (outermost) {
2532                            outermostContext = context === document || context || outermost;
2533                        }
2534
2535                        // Add elements passing elementMatchers directly to results
2536                        // Support: IE<9, Safari
2537                        // Tolerate NodeList properties (IE: "length"; Safari: <number>) matching elements by id
2538                        for (; i !== len && (elem = elems[i]) != null; i++) {
2539                            if (byElement && elem) {
2540                                j = 0;
2541                                if (!context && elem.ownerDocument !== document) {
2542                                    setDocument(elem);
2543                                    xml = !documentIsHTML;
2544                                }
2545                                while ((matcher = elementMatchers[j++])) {
2546                                    if (matcher(elem, context || document, xml)) {
2547                                        results.push(elem);
2548                                        break;
2549                                    }
2550                                }
2551                                if (outermost) {
2552                                    dirruns = dirrunsUnique;
2553                                }
2554                            }
2555
2556                            // Track unmatched elements for set filters
2557                            if (bySet) {
2558                                // They will have gone through all possible matchers
2559                                if ((elem = !matcher && elem)) {
2560                                    matchedCount--;
2561                                }
2562
2563                                // Lengthen the array for every element, matched or not
2564                                if (seed) {
2565                                    unmatched.push(elem);
2566                                }
2567                            }
2568                        }
2569
2570                        // `i` is now the count of elements visited above, and adding it to `matchedCount`
2571                        // makes the latter nonnegative.
2572                        matchedCount += i;
2573
2574                        // Apply set filters to unmatched elements
2575                        // NOTE: This can be skipped if there are no unmatched elements (i.e., `matchedCount`
2576                        // equals `i`), unless we didn't visit _any_ elements in the above loop because we have
2577                        // no element matchers and no seed.
2578                        // Incrementing an initially-string "0" `i` allows `i` to remain a string only in that
2579                        // case, which will result in a "00" `matchedCount` that differs from `i` but is also
2580                        // numerically zero.
2581                        if (bySet && i !== matchedCount) {
2582                            j = 0;
2583                            while ((matcher = setMatchers[j++])) {
2584                                matcher(unmatched, setMatched, context, xml);
2585                            }
2586
2587                            if (seed) {
2588                                // Reintegrate element matches to eliminate the need for sorting
2589                                if (matchedCount > 0) {
2590                                    while (i--) {
2591                                        if (!(unmatched[i] || setMatched[i])) {
2592                                            setMatched[i] = pop.call(results);
2593                                        }
2594                                    }
2595                                }
2596
2597                                // Discard index placeholder values to get only actual matches
2598                                setMatched = condense(setMatched);
2599                            }
2600
2601                            // Add matches to results
2602                            push.apply(results, setMatched);
2603
2604                            // Seedless set matches succeeding multiple successful matchers stipulate sorting
2605                            if (outermost && !seed && setMatched.length > 0 &&
2606                                (matchedCount + setMatchers.length) > 1) {
2607
2608                                Sizzle.uniqueSort(results);
2609                            }
2610                        }
2611
2612                        // Override manipulation of globals by nested matchers
2613                        if (outermost) {
2614                            dirruns = dirrunsUnique;
2615                            outermostContext = contextBackup;
2616                        }
2617
2618                        return unmatched;
2619                    };
2620
2621                return bySet ?
2622                    markFunction(superMatcher) :
2623                    superMatcher;
2624            }
2625
2626            compile = Sizzle.compile = function (selector, match /* Internal Use Only */) {
2627                var i,
2628                    setMatchers = [],
2629                    elementMatchers = [],
2630                    cached = compilerCache[selector + " "];
2631
2632                if (!cached) {
2633                    // Generate a function of recursive functions that can be used to check each element
2634                    if (!match) {
2635                        match = tokenize(selector);
2636                    }
2637                    i = match.length;
2638                    while (i--) {
2639                        cached = matcherFromTokens(match[i]);
2640                        if (cached[expando]) {
2641                            setMatchers.push(cached);
2642                        } else {
2643                            elementMatchers.push(cached);
2644                        }
2645                    }
2646
2647                    // Cache the compiled function
2648                    cached = compilerCache(selector, matcherFromGroupMatchers(elementMatchers, setMatchers));
2649
2650                    // Save selector and tokenization
2651                    cached.selector = selector;
2652                }
2653                return cached;
2654            };
2655
2656            /**
2657             * A low-level selection function that works with Sizzle's compiled
2658             *    selector functions
2659             * @param {String|Function} selector A selector or a pre-compiled
2660             *    selector function built with Sizzle.compile
2661             * @param {Element} context
2662             * @param {Array} [results]
2663             * @param {Array} [seed] A set of elements to match against
2664             */
2665            select = Sizzle.select = function (selector, context, results, seed) {
2666                var i, tokens, token, type, find,
2667                    compiled = typeof selector === "function" && selector,
2668                    match = !seed && tokenize((selector = compiled.selector || selector));
2669
2670                results = results || [];
2671
2672                // Try to minimize operations if there is only one selector in the list and no seed
2673                // (the latter of which guarantees us context)
2674                if (match.length === 1) {
2675
2676                    // Reduce context if the leading compound selector is an ID
2677                    tokens = match[0] = match[0].slice(0);
2678                    if (tokens.length > 2 && (token = tokens[0]).type === "ID" &&
2679                        context.nodeType === 9 && documentIsHTML && Expr.relative[tokens[1].type]) {
2680
2681                        context = (Expr.find["ID"](token.matches[0].replace(runescape, funescape), context) || [])[0];
2682                        if (!context) {
2683                            return results;
2684
2685                            // Precompiled matchers will still verify ancestry, so step up a level
2686                        } else if (compiled) {
2687                            context = context.parentNode;
2688                        }
2689
2690                        selector = selector.slice(tokens.shift().value.length);
2691                    }
2692
2693                    // Fetch a seed set for right-to-left matching
2694                    i = matchExpr["needsContext"].test(selector) ? 0 : tokens.length;
2695                    while (i--) {
2696                        token = tokens[i];
2697
2698                        // Abort if we hit a combinator
2699                        if (Expr.relative[(type = token.type)]) {
2700                            break;
2701                        }
2702                        if ((find = Expr.find[type])) {
2703                            // Search, expanding context for leading sibling combinators
2704                            if ((seed = find(
2705                                token.matches[0].replace(runescape, funescape),
2706                                rsibling.test(tokens[0].type) && testContext(context.parentNode) || context
2707                            ))) {
2708
2709                                // If seed is empty or no tokens remain, we can return early
2710                                tokens.splice(i, 1);
2711                                selector = seed.length && toSelector(tokens);
2712                                if (!selector) {
2713                                    push.apply(results, seed);
2714                                    return results;
2715                                }
2716
2717                                break;
2718                            }
2719                        }
2720                    }
2721                }
2722
2723                // Compile and execute a filtering function if one is not provided
2724                // Provide `match` to avoid retokenization if we modified the selector above
2725                (compiled || compile(selector, match))(
2726                    seed,
2727                    context,
2728                    !documentIsHTML,
2729                    results,
2730                    !context || rsibling.test(selector) && testContext(context.parentNode) || context
2731                );
2732                return results;
2733            };
2734
2735// One-time assignments
2736
2737// Sort stability
2738            support.sortStable = expando.split("").sort(sortOrder).join("") === expando;
2739
2740// Support: Chrome 14-35+
2741// Always assume duplicates if they aren't passed to the comparison function
2742            support.detectDuplicates = !!hasDuplicate;
2743
2744// Initialize against the default document
2745            setDocument();
2746
2747// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27)
2748// Detached nodes confoundingly follow *each other*
2749            support.sortDetached = assert(function (el) {
2750                // Should return 1, but returns 4 (following)
2751                return el.compareDocumentPosition(document.createElement("fieldset")) & 1;
2752            });
2753
2754// Support: IE<8
2755// Prevent attribute/property "interpolation"
2756// https://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx
2757            if (!assert(function (el) {
2758                el.innerHTML = "<a href='#'></a>";
2759                return el.firstChild.getAttribute("href") === "#";
2760            })) {
2761                addHandle("type|href|height|width", function (elem, name, isXML) {
2762                    if (!isXML) {
2763                        return elem.getAttribute(name, name.toLowerCase() === "type" ? 1 : 2);
2764                    }
2765                });
2766            }
2767
2768// Support: IE<9
2769// Use defaultValue in place of getAttribute("value")
2770            if (!support.attributes || !assert(function (el) {
2771                el.innerHTML = "<input/>";
2772                el.firstChild.setAttribute("value", "");
2773                return el.firstChild.getAttribute("value") === "";
2774            })) {
2775                addHandle("value", function (elem, name, isXML) {
2776                    if (!isXML && elem.nodeName.toLowerCase() === "input") {
2777                        return elem.defaultValue;
2778                    }
2779                });
2780            }
2781
2782// Support: IE<9
2783// Use getAttributeNode to fetch booleans when getAttribute lies
2784            if (!assert(function (el) {
2785                return el.getAttribute("disabled") == null;
2786            })) {
2787                addHandle(booleans, function (elem, name, isXML) {
2788                    var val;
2789                    if (!isXML) {
2790                        return elem[name] === true ? name.toLowerCase() :
2791                            (val = elem.getAttributeNode(name)) && val.specified ?
2792                                val.value :
2793                                null;
2794                    }
2795                });
2796            }
2797
2798            return Sizzle;
2799
2800        })(window);
2801
2802
2803    jQuery.find = Sizzle;
2804    jQuery.expr = Sizzle.selectors;
2805
2806// Deprecated
2807    jQuery.expr[":"] = jQuery.expr.pseudos;
2808    jQuery.uniqueSort = jQuery.unique = Sizzle.uniqueSort;
2809    jQuery.text = Sizzle.getText;
2810    jQuery.isXMLDoc = Sizzle.isXML;
2811    jQuery.contains = Sizzle.contains;
2812    jQuery.escapeSelector = Sizzle.escape;
2813
2814
2815    var dir = function (elem, dir, until) {
2816        var matched = [],
2817            truncate = until !== undefined;
2818
2819        while ((elem = elem[dir]) && elem.nodeType !== 9) {
2820            if (elem.nodeType === 1) {
2821                if (truncate && jQuery(elem).is(until)) {
2822                    break;
2823                }
2824                matched.push(elem);
2825            }
2826        }
2827        return matched;
2828    };
2829
2830
2831    var siblings = function (n, elem) {
2832        var matched = [];
2833
2834        for (; n; n = n.nextSibling) {
2835            if (n.nodeType === 1 && n !== elem) {
2836                matched.push(n);
2837            }
2838        }
2839
2840        return matched;
2841    };
2842
2843
2844    var rneedsContext = jQuery.expr.match.needsContext;
2845
2846
2847    function nodeName(elem, name) {
2848
2849        return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();
2850
2851    };
2852    var rsingleTag = (/^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i);
2853
2854
2855    var risSimple = /^.[^:#\[\.,]*$/;
2856
2857// Implement the identical functionality for filter and not
2858    function winnow(elements, qualifier, not) {
2859        if (jQuery.isFunction(qualifier)) {
2860            return jQuery.grep(elements, function (elem, i) {
2861                return !!qualifier.call(elem, i, elem) !== not;
2862            });
2863        }
2864
2865        // Single element
2866        if (qualifier.nodeType) {
2867            return jQuery.grep(elements, function (elem) {
2868                return (elem === qualifier) !== not;
2869            });
2870        }
2871
2872        // Arraylike of elements (jQuery, arguments, Array)
2873        if (typeof qualifier !== "string") {
2874            return jQuery.grep(elements, function (elem) {
2875                return (indexOf.call(qualifier, elem) > -1) !== not;
2876            });
2877        }
2878
2879        // Simple selector that can be filtered directly, removing non-Elements
2880        if (risSimple.test(qualifier)) {
2881            return jQuery.filter(qualifier, elements, not);
2882        }
2883
2884        // Complex selector, compare the two sets, removing non-Elements
2885        qualifier = jQuery.filter(qualifier, elements);
2886        return jQuery.grep(elements, function (elem) {
2887            return (indexOf.call(qualifier, elem) > -1) !== not && elem.nodeType === 1;
2888        });
2889    }
2890
2891    jQuery.filter = function (expr, elems, not) {
2892        var elem = elems[0];
2893
2894        if (not) {
2895            expr = ":not(" + expr + ")";
2896        }
2897
2898        if (elems.length === 1 && elem.nodeType === 1) {
2899            return jQuery.find.matchesSelector(elem, expr) ? [elem] : [];
2900        }
2901
2902        return jQuery.find.matches(expr, jQuery.grep(elems, function (elem) {
2903            return elem.nodeType === 1;
2904        }));
2905    };
2906
2907    jQuery.fn.extend({
2908        find: function (selector) {
2909            var i, ret,
2910                len = this.length,
2911                self = this;
2912
2913            if (typeof selector !== "string") {
2914                return this.pushStack(jQuery(selector).filter(function () {
2915                    for (i = 0; i < len; i++) {
2916                        if (jQuery.contains(self[i], this)) {
2917                            return true;
2918                        }
2919                    }
2920                }));
2921            }
2922
2923            ret = this.pushStack([]);
2924
2925            for (i = 0; i < len; i++) {
2926                jQuery.find(selector, self[i], ret);
2927            }
2928
2929            return len > 1 ? jQuery.uniqueSort(ret) : ret;
2930        },
2931        filter: function (selector) {
2932            return this.pushStack(winnow(this, selector || [], false));
2933        },
2934        not: function (selector) {
2935            return this.pushStack(winnow(this, selector || [], true));
2936        },
2937        is: function (selector) {
2938            return !!winnow(
2939                this,
2940
2941                // If this is a positional/relative selector, check membership in the returned set
2942                // so $("p:first").is("p:last") won't return true for a doc with two "p".
2943                typeof selector === "string" && rneedsContext.test(selector) ?
2944                    jQuery(selector) :
2945                    selector || [],
2946                false
2947            ).length;
2948        }
2949    });
vendor: 7,504 bytes, lines 2950-3159
2950
2951
2952// Initialize a jQuery object
2953
2954
2955// A central reference to the root jQuery(document)
2956    var rootjQuery,
2957
2958        // A simple way to check for HTML strings
2959        // Prioritize #id over <tag> to avoid XSS via location.hash (#9521)
2960        // Strict HTML recognition (#11290: must start with <)
2961        // Shortcut simple #id case for speed
2962        rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/,
2963
2964        init = jQuery.fn.init = function (selector, context, root) {
2965            var match, elem;
2966
2967            // HANDLE: $(""), $(null), $(undefined), $(false)
2968            if (!selector) {
2969                return this;
2970            }
2971
2972            // Method init() accepts an alternate rootjQuery
2973            // so migrate can support jQuery.sub (gh-2101)
2974            root = root || rootjQuery;
2975
2976            // Handle HTML strings
2977            if (typeof selector === "string") {
2978                if (selector[0] === "<" &&
2979                    selector[selector.length - 1] === ">" &&
2980                    selector.length >= 3) {
2981
2982                    // Assume that strings that start and end with <> are HTML and skip the regex check
2983                    match = [null, selector, null];
2984
2985                } else {
2986                    match = rquickExpr.exec(selector);
2987                }
2988
2989                // Match html or make sure no context is specified for #id
2990                if (match && (match[1] || !context)) {
2991
2992                    // HANDLE: $(html) -> $(array)
2993                    if (match[1]) {
2994                        context = context instanceof jQuery ? context[0] : context;
2995
2996                        // Option to run scripts is true for back-compat
2997                        // Intentionally let the error be thrown if parseHTML is not present
2998                        jQuery.merge(this, jQuery.parseHTML(
2999                            match[1],
3000                            context && context.nodeType ? context.ownerDocument || context : document,
3001                            true
3002                        ));
3003
3004                        // HANDLE: $(html, props)
3005                        if (rsingleTag.test(match[1]) && jQuery.isPlainObject(context)) {
3006                            for (match in context) {
3007
3008                                // Properties of context are called as methods if possible
3009                                if (jQuery.isFunction(this[match])) {
3010                                    this[match](context[match]);
3011
3012                                    // ...and otherwise set as attributes
3013                                } else {
3014                                    this.attr(match, context[match]);
3015                                }
3016                            }
3017                        }
3018
3019                        return this;
3020
3021                        // HANDLE: $(#id)
3022                    } else {
3023                        elem = document.getElementById(match[2]);
3024
3025                        if (elem) {
3026
3027                            // Inject the element directly into the jQuery object
3028                            this[0] = elem;
3029                            this.length = 1;
3030                        }
3031                        return this;
3032                    }
3033
3034                    // HANDLE: $(expr, $(...))
3035                } else if (!context || context.jquery) {
3036                    return (context || root).find(selector);
3037
3038                    // HANDLE: $(expr, context)
3039                    // (which is just equivalent to: $(context).find(expr)
3040                } else {
3041                    return this.constructor(context).find(selector);
3042                }
3043
3044                // HANDLE: $(DOMElement)
3045            } else if (selector.nodeType) {
3046                this[0] = selector;
3047                this.length = 1;
3048                return this;
3049
3050                // HANDLE: $(function)
3051                // Shortcut for document ready
3052            } else if (jQuery.isFunction(selector)) {
3053                return root.ready !== undefined ?
3054                    root.ready(selector) :
3055
3056                    // Execute immediately if ready is not present
3057                    selector(jQuery);
3058            }
3059
3060            return jQuery.makeArray(selector, this);
3061        };
3062
3063// Give the init function the jQuery prototype for later instantiation
3064    init.prototype = jQuery.fn;
3065
3066// Initialize central reference
3067    rootjQuery = jQuery(document);
3068
3069
3070    var rparentsprev = /^(?:parents|prev(?:Until|All))/,
3071
3072        // Methods guaranteed to produce a unique set when starting from a unique set
3073        guaranteedUnique = {
3074            children: true,
3075            contents: true,
3076            next: true,
3077            prev: true
3078        };
3079
3080    jQuery.fn.extend({
3081        has: function (target) {
3082            var targets = jQuery(target, this),
3083                l = targets.length;
3084
3085            return this.filter(function () {
3086                var i = 0;
3087                for (; i < l; i++) {
3088                    if (jQuery.contains(this, targets[i])) {
3089                        return true;
3090                    }
3091                }
3092            });
3093        },
3094
3095        closest: function (selectors, context) {
3096            var cur,
3097                i = 0,
3098                l = this.length,
3099                matched = [],
3100                targets = typeof selectors !== "string" && jQuery(selectors);
3101
3102            // Positional selectors never match, since there's no _selection_ context
3103            if (!rneedsContext.test(selectors)) {
3104                for (; i < l; i++) {
3105                    for (cur = this[i]; cur && cur !== context; cur = cur.parentNode) {
3106
3107                        // Always skip document fragments
3108                        if (cur.nodeType < 11 && (targets ?
3109                            targets.index(cur) > -1 :
3110
3111                            // Don't pass non-elements to Sizzle
3112                            cur.nodeType === 1 &&
3113                            jQuery.find.matchesSelector(cur, selectors))) {
3114
3115                            matched.push(cur);
3116                            break;
3117                        }
3118                    }
3119                }
3120            }
3121
3122            return this.pushStack(matched.length > 1 ? jQuery.uniqueSort(matched) : matched);
3123        },
3124
3125        // Determine the position of an element within the set
3126        index: function (elem) {
3127
3128            // No argument, return index in parent
3129            if (!elem) {
3130                return (this[0] && this[0].parentNode) ? this.first().prevAll().length : -1;
3131            }
3132
3133            // Index in selector
3134            if (typeof elem === "string") {
3135                return indexOf.call(jQuery(elem), this[0]);
3136            }
3137
3138            // Locate the position of the desired element
3139            return indexOf.call(this,
3140
3141                // If it receives a jQuery object, the first element is used
3142                elem.jquery ? elem[0] : elem
3143            );
3144        },
3145
3146        add: function (selector, context) {
3147            return this.pushStack(
3148                jQuery.uniqueSort(
3149                    jQuery.merge(this.get(), jQuery(selector, context))
3150                )
3151            );
3152        },
3153
3154        addBack: function (selector) {
3155            return this.add(selector == null ?
3156                this.prevObject : this.prevObject.filter(selector)
3157            );
3158        }
3159    });
vendor: 8,597 bytes, lines 3160-3407
3160
3161    function sibling(cur, dir) {
3162        while ((cur = cur[dir]) && cur.nodeType !== 1) {
3163        }
3164        return cur;
3165    }
3166
3167    jQuery.each({
3168        parent: function (elem) {
3169            var parent = elem.parentNode;
3170            return parent && parent.nodeType !== 11 ? parent : null;
3171        },
3172        parents: function (elem) {
3173            return dir(elem, "parentNode");
3174        },
3175        parentsUntil: function (elem, i, until) {
3176            return dir(elem, "parentNode", until);
3177        },
3178        next: function (elem) {
3179            return sibling(elem, "nextSibling");
3180        },
3181        prev: function (elem) {
3182            return sibling(elem, "previousSibling");
3183        },
3184        nextAll: function (elem) {
3185            return dir(elem, "nextSibling");
3186        },
3187        prevAll: function (elem) {
3188            return dir(elem, "previousSibling");
3189        },
3190        nextUntil: function (elem, i, until) {
3191            return dir(elem, "nextSibling", until);
3192        },
3193        prevUntil: function (elem, i, until) {
3194            return dir(elem, "previousSibling", until);
3195        },
3196        siblings: function (elem) {
3197            return siblings((elem.parentNode || {}).firstChild, elem);
3198        },
3199        children: function (elem) {
3200            return siblings(elem.firstChild);
3201        },
3202        contents: function (elem) {
3203            if (nodeName(elem, "iframe")) {
3204                return elem.contentDocument;
3205            }
3206
3207            // Support: IE 9 - 11 only, iOS 7 only, Android Browser <=4.3 only
3208            // Treat the template element as a regular one in browsers that
3209            // don't support it.
3210            if (nodeName(elem, "template")) {
3211                elem = elem.content || elem;
3212            }
3213
3214            return jQuery.merge([], elem.childNodes);
3215        }
3216    }, function (name, fn) {
3217        jQuery.fn[name] = function (until, selector) {
3218            var matched = jQuery.map(this, fn, until);
3219
3220            if (name.slice(-5) !== "Until") {
3221                selector = until;
3222            }
3223
3224            if (selector && typeof selector === "string") {
3225                matched = jQuery.filter(selector, matched);
3226            }
3227
3228            if (this.length > 1) {
3229
3230                // Remove duplicates
3231                if (!guaranteedUnique[name]) {
3232                    jQuery.uniqueSort(matched);
3233                }
3234
3235                // Reverse order for parents* and prev-derivatives
3236                if (rparentsprev.test(name)) {
3237                    matched.reverse();
3238                }
3239            }
3240
3241            return this.pushStack(matched);
3242        };
3243    });
3244    var rnothtmlwhite = (/[^\x20\t\r\n\f]+/g);
3245
3246
3247// Convert String-formatted options into Object-formatted ones
3248    function createOptions(options) {
3249        var object = {};
3250        jQuery.each(options.match(rnothtmlwhite) || [], function (_, flag) {
3251            object[flag] = true;
3252        });
3253        return object;
3254    }
3255
3256    /*
3257* Create a callback list using the following parameters:
3258*
3259*	options: an optional list of space-separated options that will change how
3260*			the callback list behaves or a more traditional option object
3261*
3262* By default a callback list will act like an event callback list and can be
3263* "fired" multiple times.
3264*
3265* Possible options:
3266*
3267*	once:			will ensure the callback list can only be fired once (like a Deferred)
3268*
3269*	memory:			will keep track of previous values and will call any callback added
3270*					after the list has been fired right away with the latest "memorized"
3271*					values (like a Deferred)
3272*
3273*	unique:			will ensure a callback can only be added once (no duplicate in the list)
3274*
3275*	stopOnFalse:	interrupt callings when a callback returns false
3276*
3277*/
3278    jQuery.Callbacks = function (options) {
3279
3280        // Convert options from String-formatted to Object-formatted if needed
3281        // (we check in cache first)
3282        options = typeof options === "string" ?
3283            createOptions(options) :
3284            jQuery.extend({}, options);
3285
3286        var // Flag to know if list is currently firing
3287            firing,
3288
3289            // Last fire value for non-forgettable lists
3290            memory,
3291
3292            // Flag to know if list was already fired
3293            fired,
3294
3295            // Flag to prevent firing
3296            locked,
3297
3298            // Actual callback list
3299            list = [],
3300
3301            // Queue of execution data for repeatable lists
3302            queue = [],
3303
3304            // Index of currently firing callback (modified by add/remove as needed)
3305            firingIndex = -1,
3306
3307            // Fire callbacks
3308            fire = function () {
3309
3310                // Enforce single-firing
3311                locked = locked || options.once;
3312
3313                // Execute callbacks for all pending executions,
3314                // respecting firingIndex overrides and runtime changes
3315                fired = firing = true;
3316                for (; queue.length; firingIndex = -1) {
3317                    memory = queue.shift();
3318                    while (++firingIndex < list.length) {
3319
3320                        // Run callback and check for early termination
3321                        if (list[firingIndex].apply(memory[0], memory[1]) === false &&
3322                            options.stopOnFalse) {
3323
3324                            // Jump to end and forget the data so .add doesn't re-fire
3325                            firingIndex = list.length;
3326                            memory = false;
3327                        }
3328                    }
3329                }
3330
3331                // Forget the data if we're done with it
3332                if (!options.memory) {
3333                    memory = false;
3334                }
3335
3336                firing = false;
3337
3338                // Clean up if we're done firing for good
3339                if (locked) {
3340
3341                    // Keep an empty list if we have data for future add calls
3342                    if (memory) {
3343                        list = [];
3344
3345                        // Otherwise, this object is spent
3346                    } else {
3347                        list = "";
3348                    }
3349                }
3350            },
3351
3352            // Actual Callbacks object
3353            self = {
3354
3355                // Add a callback or a collection of callbacks to the list
3356                add: function () {
3357                    if (list) {
3358
3359                        // If we have memory from a past run, we should fire after adding
3360                        if (memory && !firing) {
3361                            firingIndex = list.length - 1;
3362                            queue.push(memory);
3363                        }
3364
3365                        (function add(args) {
3366                            jQuery.each(args, function (_, arg) {
3367                                if (jQuery.isFunction(arg)) {
3368                                    if (!options.unique || !self.has(arg)) {
3369                                        list.push(arg);
3370                                    }
3371                                } else if (arg && arg.length && jQuery.type(arg) !== "string") {
3372
3373                                    // Inspect recursively
3374                                    add(arg);
3375                                }
3376                            });
3377                        })(arguments);
3378
3379                        if (memory && !firing) {
3380                            fire();
3381                        }
3382                    }
3383                    return this;
3384                },
3385
3386                // Remove a callback from the list
3387                remove: function () {
3388                    jQuery.each(arguments, function (_, arg) {
3389                        var index;
3390                        while ((index = jQuery.inArray(arg, list, index)) > -1) {
3391                            list.splice(index, 1);
3392
3393                            // Handle firing indexes
3394                            if (index <= firingIndex) {
3395                                firingIndex--;
3396                            }
3397                        }
3398                    });
3399                    return this;
3400                },
3401
3402                // Check if a given callback is in the list.
3403                // If no argument is given, return whether or not list has callbacks attached.
3404                has: function (fn) {
3405                    return fn ?
3406                        jQuery.inArray(fn, list) > -1 :
3407                        list.length > 0;
vendor: 7,076 bytes, lines 3408-3581
3408                },
3409
3410                // Remove all callbacks from the list
3411                empty: function () {
3412                    if (list) {
3413                        list = [];
3414                    }
3415                    return this;
3416                },
3417
3418                // Disable .fire and .add
3419                // Abort any current/pending executions
3420                // Clear all callbacks and values
3421                disable: function () {
3422                    locked = queue = [];
3423                    list = memory = "";
3424                    return this;
3425                },
3426                disabled: function () {
3427                    return !list;
3428                },
3429
3430                // Disable .fire
3431                // Also disable .add unless we have memory (since it would have no effect)
3432                // Abort any pending executions
3433                lock: function () {
3434                    locked = queue = [];
3435                    if (!memory && !firing) {
3436                        list = memory = "";
3437                    }
3438                    return this;
3439                },
3440                locked: function () {
3441                    return !!locked;
3442                },
3443
3444                // Call all callbacks with the given context and arguments
3445                fireWith: function (context, args) {
3446                    if (!locked) {
3447                        args = args || [];
3448                        args = [context, args.slice ? args.slice() : args];
3449                        queue.push(args);
3450                        if (!firing) {
3451                            fire();
3452                        }
3453                    }
3454                    return this;
3455                },
3456
3457                // Call all the callbacks with the given arguments
3458                fire: function () {
3459                    self.fireWith(this, arguments);
3460                    return this;
3461                },
3462
3463                // To know if the callbacks have already been called at least once
3464                fired: function () {
3465                    return !!fired;
3466                }
3467            };
3468
3469        return self;
3470    };
3471
3472
3473    function Identity(v) {
3474        return v;
3475    }
3476
3477    function Thrower(ex) {
3478        throw ex;
3479    }
3480
3481    function adoptValue(value, resolve, reject, noValue) {
3482        var method;
3483
3484        try {
3485
3486            // Check for promise aspect first to privilege synchronous behavior
3487            if (value && jQuery.isFunction((method = value.promise))) {
3488                method.call(value).done(resolve).fail(reject);
3489
3490                // Other thenables
3491            } else if (value && jQuery.isFunction((method = value.then))) {
3492                method.call(value, resolve, reject);
3493
3494                // Other non-thenables
3495            } else {
3496
3497                // Control `resolve` arguments by letting Array#slice cast boolean `noValue` to integer:
3498                // * false: [ value ].slice( 0 ) => resolve( value )
3499                // * true: [ value ].slice( 1 ) => resolve()
3500                resolve.apply(undefined, [value].slice(noValue));
3501            }
3502
3503            // For Promises/A+, convert exceptions into rejections
3504            // Since jQuery.when doesn't unwrap thenables, we can skip the extra checks appearing in
3505            // Deferred#then to conditionally suppress rejection.
3506        } catch (value) {
3507
3508            // Support: Android 4.0 only
3509            // Strict mode functions invoked without .call/.apply get global-object context
3510            reject.apply(undefined, [value]);
3511        }
3512    }
3513
3514    jQuery.extend({
3515
3516        Deferred: function (func) {
3517            var tuples = [
3518
3519                    // action, add listener, callbacks,
3520                    // ... .then handlers, argument index, [final state]
3521                    ["notify", "progress", jQuery.Callbacks("memory"),
3522                        jQuery.Callbacks("memory"), 2],
3523                    ["resolve", "done", jQuery.Callbacks("once memory"),
3524                        jQuery.Callbacks("once memory"), 0, "resolved"],
3525                    ["reject", "fail", jQuery.Callbacks("once memory"),
3526                        jQuery.Callbacks("once memory"), 1, "rejected"]
3527                ],
3528                state = "pending",
3529                promise = {
3530                    state: function () {
3531                        return state;
3532                    },
3533                    always: function () {
3534                        deferred.done(arguments).fail(arguments);
3535                        return this;
3536                    },
3537                    "catch": function (fn) {
3538                        return promise.then(null, fn);
3539                    },
3540
3541                    // Keep pipe for back-compat
3542                    pipe: function ( /* fnDone, fnFail, fnProgress */) {
3543                        var fns = arguments;
3544
3545                        return jQuery.Deferred(function (newDefer) {
3546                            jQuery.each(tuples, function (i, tuple) {
3547
3548                                // Map tuples (progress, done, fail) to arguments (done, fail, progress)
3549                                var fn = jQuery.isFunction(fns[tuple[4]]) && fns[tuple[4]];
3550
3551                                // deferred.progress(function() { bind to newDefer or newDefer.notify })
3552                                // deferred.done(function() { bind to newDefer or newDefer.resolve })
3553                                // deferred.fail(function() { bind to newDefer or newDefer.reject })
3554                                deferred[tuple[1]](function () {
3555                                    var returned = fn && fn.apply(this, arguments);
3556                                    if (returned && jQuery.isFunction(returned.promise)) {
3557                                        returned.promise()
3558                                            .progress(newDefer.notify)
3559                                            .done(newDefer.resolve)
3560                                            .fail(newDefer.reject);
3561                                    } else {
3562                                        newDefer[tuple[0] + "With"](
3563                                            this,
3564                                            fn ? [returned] : arguments
3565                                        );
3566                                    }
3567                                });
3568                            });
3569                            fns = null;
3570                        }).promise();
3571                    },
3572                    then: function (onFulfilled, onRejected, onProgress) {
3573                        var maxDepth = 0;
3574
3575                        function resolve(depth, deferred, handler, special) {
3576                            return function () {
3577                                var that = this,
3578                                    args = arguments,
3579                                    mightThrow = function () {
3580                                        var returned, then;
3581
vendor: 12,956 bytes, lines 3582-3854
3582                                        // Support: Promises/A+ section 2.3.3.3.3
3583                                        // https://promisesaplus.com/#point-59
3584                                        // Ignore double-resolution attempts
3585                                        if (depth < maxDepth) {
3586                                            return;
3587                                        }
3588
3589                                        returned = handler.apply(that, args);
3590
3591                                        // Support: Promises/A+ section 2.3.1
3592                                        // https://promisesaplus.com/#point-48
3593                                        if (returned === deferred.promise()) {
3594                                            throw new TypeError("Thenable self-resolution");
3595                                        }
3596
3597                                        // Support: Promises/A+ sections 2.3.3.1, 3.5
3598                                        // https://promisesaplus.com/#point-54
3599                                        // https://promisesaplus.com/#point-75
3600                                        // Retrieve `then` only once
3601                                        then = returned &&
3602
3603                                            // Support: Promises/A+ section 2.3.4
3604                                            // https://promisesaplus.com/#point-64
3605                                            // Only check objects and functions for thenability
3606                                            (typeof returned === "object" ||
3607                                                typeof returned === "function") &&
3608                                            returned.then;
3609
3610                                        // Handle a returned thenable
3611                                        if (jQuery.isFunction(then)) {
3612
3613                                            // Special processors (notify) just wait for resolution
3614                                            if (special) {
3615                                                then.call(
3616                                                    returned,
3617                                                    resolve(maxDepth, deferred, Identity, special),
3618                                                    resolve(maxDepth, deferred, Thrower, special)
3619                                                );
3620
3621                                                // Normal processors (resolve) also hook into progress
3622                                            } else {
3623
3624                                                // ...and disregard older resolution values
3625                                                maxDepth++;
3626
3627                                                then.call(
3628                                                    returned,
3629                                                    resolve(maxDepth, deferred, Identity, special),
3630                                                    resolve(maxDepth, deferred, Thrower, special),
3631                                                    resolve(maxDepth, deferred, Identity,
3632                                                        deferred.notifyWith)
3633                                                );
3634                                            }
3635
3636                                            // Handle all other returned values
3637                                        } else {
3638
3639                                            // Only substitute handlers pass on context
3640                                            // and multiple values (non-spec behavior)
3641                                            if (handler !== Identity) {
3642                                                that = undefined;
3643                                                args = [returned];
3644                                            }
3645
3646                                            // Process the value(s)
3647                                            // Default process is resolve
3648                                            (special || deferred.resolveWith)(that, args);
3649                                        }
3650                                    },
3651
3652                                    // Only normal processors (resolve) catch and reject exceptions
3653                                    process = special ?
3654                                        mightThrow :
3655                                        function () {
3656                                            try {
3657                                                mightThrow();
3658                                            } catch (e) {
3659
3660                                                if (jQuery.Deferred.exceptionHook) {
3661                                                    jQuery.Deferred.exceptionHook(e,
3662                                                        process.stackTrace);
3663                                                }
3664
3665                                                // Support: Promises/A+ section 2.3.3.3.4.1
3666                                                // https://promisesaplus.com/#point-61
3667                                                // Ignore post-resolution exceptions
3668                                                if (depth + 1 >= maxDepth) {
3669
3670                                                    // Only substitute handlers pass on context
3671                                                    // and multiple values (non-spec behavior)
3672                                                    if (handler !== Thrower) {
3673                                                        that = undefined;
3674                                                        args = [e];
3675                                                    }
3676
3677                                                    deferred.rejectWith(that, args);
3678                                                }
3679                                            }
3680                                        };
3681
3682                                // Support: Promises/A+ section 2.3.3.3.1
3683                                // https://promisesaplus.com/#point-57
3684                                // Re-resolve promises immediately to dodge false rejection from
3685                                // subsequent errors
3686                                if (depth) {
3687                                    process();
3688                                } else {
3689
3690                                    // Call an optional hook to record the stack, in case of exception
3691                                    // since it's otherwise lost when execution goes async
3692                                    if (jQuery.Deferred.getStackHook) {
3693                                        process.stackTrace = jQuery.Deferred.getStackHook();
3694                                    }
3695                                    window.setTimeout(process);
3696                                }
3697                            };
3698                        }
3699
3700                        return jQuery.Deferred(function (newDefer) {
3701
3702                            // progress_handlers.add( ... )
3703                            tuples[0][3].add(
3704                                resolve(
3705                                    0,
3706                                    newDefer,
3707                                    jQuery.isFunction(onProgress) ?
3708                                        onProgress :
3709                                        Identity,
3710                                    newDefer.notifyWith
3711                                )
3712                            );
3713
3714                            // fulfilled_handlers.add( ... )
3715                            tuples[1][3].add(
3716                                resolve(
3717                                    0,
3718                                    newDefer,
3719                                    jQuery.isFunction(onFulfilled) ?
3720                                        onFulfilled :
3721                                        Identity
3722                                )
3723                            );
3724
3725                            // rejected_handlers.add( ... )
3726                            tuples[2][3].add(
3727                                resolve(
3728                                    0,
3729                                    newDefer,
3730                                    jQuery.isFunction(onRejected) ?
3731                                        onRejected :
3732                                        Thrower
3733                                )
3734                            );
3735                        }).promise();
3736                    },
3737
3738                    // Get a promise for this deferred
3739                    // If obj is provided, the promise aspect is added to the object
3740                    promise: function (obj) {
3741                        return obj != null ? jQuery.extend(obj, promise) : promise;
3742                    }
3743                },
3744                deferred = {};
3745
3746            // Add list-specific methods
3747            jQuery.each(tuples, function (i, tuple) {
3748                var list = tuple[2],
3749                    stateString = tuple[5];
3750
3751                // promise.progress = list.add
3752                // promise.done = list.add
3753                // promise.fail = list.add
3754                promise[tuple[1]] = list.add;
3755
3756                // Handle state
3757                if (stateString) {
3758                    list.add(
3759                        function () {
3760
3761                            // state = "resolved" (i.e., fulfilled)
3762                            // state = "rejected"
3763                            state = stateString;
3764                        },
3765
3766                        // rejected_callbacks.disable
3767                        // fulfilled_callbacks.disable
3768                        tuples[3 - i][2].disable,
3769
3770                        // progress_callbacks.lock
3771                        tuples[0][2].lock
3772                    );
3773                }
3774
3775                // progress_handlers.fire
3776                // fulfilled_handlers.fire
3777                // rejected_handlers.fire
3778                list.add(tuple[3].fire);
3779
3780                // deferred.notify = function() { deferred.notifyWith(...) }
3781                // deferred.resolve = function() { deferred.resolveWith(...) }
3782                // deferred.reject = function() { deferred.rejectWith(...) }
3783                deferred[tuple[0]] = function () {
3784                    deferred[tuple[0] + "With"](this === deferred ? undefined : this, arguments);
3785                    return this;
3786                };
3787
3788                // deferred.notifyWith = list.fireWith
3789                // deferred.resolveWith = list.fireWith
3790                // deferred.rejectWith = list.fireWith
3791                deferred[tuple[0] + "With"] = list.fireWith;
3792            });
3793
3794            // Make the deferred a promise
3795            promise.promise(deferred);
3796
3797            // Call given func if any
3798            if (func) {
3799                func.call(deferred, deferred);
3800            }
3801
3802            // All done!
3803            return deferred;
3804        },
3805
3806        // Deferred helper
3807        when: function (singleValue) {
3808            var
3809
3810                // count of uncompleted subordinates
3811                remaining = arguments.length,
3812
3813                // count of unprocessed arguments
3814                i = remaining,
3815
3816                // subordinate fulfillment data
3817                resolveContexts = Array(i),
3818                resolveValues = slice.call(arguments),
3819
3820                // the master Deferred
3821                master = jQuery.Deferred(),
3822
3823                // subordinate callback factory
3824                updateFunc = function (i) {
3825                    return function (value) {
3826                        resolveContexts[i] = this;
3827                        resolveValues[i] = arguments.length > 1 ? slice.call(arguments) : value;
3828                        if (!(--remaining)) {
3829                            master.resolveWith(resolveContexts, resolveValues);
3830                        }
3831                    };
3832                };
3833
3834            // Single- and empty arguments are adopted like Promise.resolve
3835            if (remaining <= 1) {
3836                adoptValue(singleValue, master.done(updateFunc(i)).resolve, master.reject,
3837                    !remaining);
3838
3839                // Use .then() to unwrap secondary thenables (cf. gh-3000)
3840                if (master.state() === "pending" ||
3841                    jQuery.isFunction(resolveValues[i] && resolveValues[i].then)) {
3842
3843                    return master.then();
3844                }
3845            }
3846
3847            // Multiple arguments are aggregated like Promise.all array elements
3848            while (i--) {
3849                adoptValue(resolveValues[i], updateFunc(i), master.reject);
3850            }
3851
3852            return master.promise();
3853        }
3854    });
vendor: 4,235 bytes, lines 3855-3987
3855
3856
3857// These usually indicate a programmer mistake during development,
3858// warn about them ASAP rather than swallowing them by default.
3859    var rerrorNames = /^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;
3860
3861    jQuery.Deferred.exceptionHook = function (error, stack) {
3862
3863        // Support: IE 8 - 9 only
3864        // Console exists when dev tools are open, which can happen at any time
3865        if (window.console && window.console.warn && error && rerrorNames.test(error.name)) {
3866            window.console.warn("jQuery.Deferred exception: " + error.message, error.stack, stack);
3867        }
3868    };
3869
3870
3871    jQuery.readyException = function (error) {
3872        window.setTimeout(function () {
3873            throw error;
3874        });
3875    };
3876
3877
3878// The deferred used on DOM ready
3879    var readyList = jQuery.Deferred();
3880
3881    jQuery.fn.ready = function (fn) {
3882
3883        readyList
3884            .then(fn)
3885
3886            // Wrap jQuery.readyException in a function so that the lookup
3887            // happens at the time of error handling instead of callback
3888            // registration.
3889            .catch(function (error) {
3890                jQuery.readyException(error);
3891            });
3892
3893        return this;
3894    };
3895
3896    jQuery.extend({
3897
3898        // Is the DOM ready to be used? Set to true once it occurs.
3899        isReady: false,
3900
3901        // A counter to track how many items to wait for before
3902        // the ready event fires. See #6781
3903        readyWait: 1,
3904
3905        // Handle when the DOM is ready
3906        ready: function (wait) {
3907
3908            // Abort if there are pending holds or we're already ready
3909            if (wait === true ? --jQuery.readyWait : jQuery.isReady) {
3910                return;
3911            }
3912
3913            // Remember that the DOM is ready
3914            jQuery.isReady = true;
3915
3916            // If a normal DOM Ready event fired, decrement, and wait if need be
3917            if (wait !== true && --jQuery.readyWait > 0) {
3918                return;
3919            }
3920
3921            // If there are functions bound, to execute
3922            readyList.resolveWith(document, [jQuery]);
3923        }
3924    });
3925
3926    jQuery.ready.then = readyList.then;
3927
3928// The ready event handler and self cleanup method
3929    function completed() {
3930        document.removeEventListener("DOMContentLoaded", completed);
3931        window.removeEventListener("load", completed);
3932        jQuery.ready();
3933    }
3934
3935// Catch cases where $(document).ready() is called
3936// after the browser event has already occurred.
3937// Support: IE <=9 - 10 only
3938// Older IE sometimes signals "interactive" too soon
3939    if (document.readyState === "complete" ||
3940        (document.readyState !== "loading" && !document.documentElement.doScroll)) {
3941
3942        // Handle it asynchronously to allow scripts the opportunity to delay ready
3943        window.setTimeout(jQuery.ready);
3944
3945    } else {
3946
3947        // Use the handy event callback
3948        document.addEventListener("DOMContentLoaded", completed);
3949
3950        // A fallback to window.onload, that will always work
3951        window.addEventListener("load", completed);
3952    }
3953
3954
3955// Multifunctional method to get and set values of a collection
3956// The value/s can optionally be executed if it's a function
3957    var access = function (elems, fn, key, value, chainable, emptyGet, raw) {
3958        var i = 0,
3959            len = elems.length,
3960            bulk = key == null;
3961
3962        // Sets many values
3963        if (jQuery.type(key) === "object") {
3964            chainable = true;
3965            for (i in key) {
3966                access(elems, fn, i, key[i], true, emptyGet, raw);
3967            }
3968
3969            // Sets one value
3970        } else if (value !== undefined) {
3971            chainable = true;
3972
3973            if (!jQuery.isFunction(value)) {
3974                raw = true;
3975            }
3976
3977            if (bulk) {
3978
3979                // Bulk operations run against the entire set
3980                if (raw) {
3981                    fn.call(elems, value);
3982                    fn = null;
3983
3984                    // ...except when executing function values
3985                } else {
3986                    bulk = fn;
3987                    fn = function (elem, key, value) {
vendor: 4,187 bytes, lines 3988-4120
3988                        return bulk.call(jQuery(elem), value);
3989                    };
3990                }
3991            }
3992
3993            if (fn) {
3994                for (; i < len; i++) {
3995                    fn(
3996                        elems[i], key, raw ?
3997                            value :
3998                            value.call(elems[i], i, fn(elems[i], key))
3999                    );
4000                }
4001            }
4002        }
4003
4004        if (chainable) {
4005            return elems;
4006        }
4007
4008        // Gets
4009        if (bulk) {
4010            return fn.call(elems);
4011        }
4012
4013        return len ? fn(elems[0], key) : emptyGet;
4014    };
4015    var acceptData = function (owner) {
4016
4017        // Accepts only:
4018        // - Node
4019        // 	- Node.ELEMENT_NODE
4020        // 	- Node.DOCUMENT_NODE
4021        // - Object
4022        // 	- Any
4023        return owner.nodeType === 1 || owner.nodeType === 9 || !(+owner.nodeType);
4024    };
4025
4026
4027    function Data() {
4028        this.expando = jQuery.expando + Data.uid++;
4029    }
4030
4031    Data.uid = 1;
4032
4033    Data.prototype = {
4034
4035        cache: function (owner) {
4036
4037            // Check if the owner object already has a cache
4038            var value = owner[this.expando];
4039
4040            // If not, create one
4041            if (!value) {
4042                value = {};
4043
4044                // We can accept data for non-element nodes in modern browsers,
4045                // but we should not, see #8335.
4046                // Always return an empty object.
4047                if (acceptData(owner)) {
4048
4049                    // If it is a node unlikely to be stringify-ed or looped over
4050                    // use plain assignment
4051                    if (owner.nodeType) {
4052                        owner[this.expando] = value;
4053
4054                        // Otherwise secure it in a non-enumerable property
4055                        // configurable must be true to allow the property to be
4056                        // deleted when data is removed
4057                    } else {
4058                        Object.defineProperty(owner, this.expando, {
4059                            value: value,
4060                            configurable: true
4061                        });
4062                    }
4063                }
4064            }
4065
4066            return value;
4067        },
4068        set: function (owner, data, value) {
4069            var prop,
4070                cache = this.cache(owner);
4071
4072            // Handle: [ owner, key, value ] args
4073            // Always use camelCase key (gh-2257)
4074            if (typeof data === "string") {
4075                cache[jQuery.camelCase(data)] = value;
4076
4077                // Handle: [ owner, { properties } ] args
4078            } else {
4079
4080                // Copy the properties one-by-one to the cache object
4081                for (prop in data) {
4082                    cache[jQuery.camelCase(prop)] = data[prop];
4083                }
4084            }
4085            return cache;
4086        },
4087        get: function (owner, key) {
4088            return key === undefined ?
4089                this.cache(owner) :
4090
4091                // Always use camelCase key (gh-2257)
4092                owner[this.expando] && owner[this.expando][jQuery.camelCase(key)];
4093        },
4094        access: function (owner, key, value) {
4095
4096            // In cases where either:
4097            //
4098            // 1. No key was specified
4099            // 2. A string key was specified, but no value provided
4100            //
4101            // Take the "read" path and allow the get method to determine
4102            // which value to return, respectively either:
4103            //
4104            // 1. The entire cache object
4105            // 2. The data stored at the key
4106            //
4107            if (key === undefined ||
4108                ((key && typeof key === "string") && value === undefined)) {
4109
4110                return this.get(owner, key);
4111            }
4112
4113            // When the key is not a string, or both a key and value
4114            // are specified, set or extend (existing objects) with either:
4115            //
4116            // 1. An object of properties
4117            // 2. A key and value
4118            //
4119            this.set(owner, key, value);
4120
vendor: 4,736 bytes, lines 4121-4266
4121            // Since the "set" path can have two possible entry points
4122            // return the expected data based on which path was taken[*]
4123            return value !== undefined ? value : key;
4124        },
4125        remove: function (owner, key) {
4126            var i,
4127                cache = owner[this.expando];
4128
4129            if (cache === undefined) {
4130                return;
4131            }
4132
4133            if (key !== undefined) {
4134
4135                // Support array or space separated string of keys
4136                if (Array.isArray(key)) {
4137
4138                    // If key is an array of keys...
4139                    // We always set camelCase keys, so remove that.
4140                    key = key.map(jQuery.camelCase);
4141                } else {
4142                    key = jQuery.camelCase(key);
4143
4144                    // If a key with the spaces exists, use it.
4145                    // Otherwise, create an array by matching non-whitespace
4146                    key = key in cache ?
4147                        [key] :
4148                        (key.match(rnothtmlwhite) || []);
4149                }
4150
4151                i = key.length;
4152
4153                while (i--) {
4154                    delete cache[key[i]];
4155                }
4156            }
4157
4158            // Remove the expando if there's no more data
4159            if (key === undefined || jQuery.isEmptyObject(cache)) {
4160
4161                // Support: Chrome <=35 - 45
4162                // Webkit & Blink performance suffers when deleting properties
4163                // from DOM nodes, so set to undefined instead
4164                // https://bugs.chromium.org/p/chromium/issues/detail?id=378607 (bug restricted)
4165                if (owner.nodeType) {
4166                    owner[this.expando] = undefined;
4167                } else {
4168                    delete owner[this.expando];
4169                }
4170            }
4171        },
4172        hasData: function (owner) {
4173            var cache = owner[this.expando];
4174            return cache !== undefined && !jQuery.isEmptyObject(cache);
4175        }
4176    };
4177    var dataPriv = new Data();
4178
4179    var dataUser = new Data();
4180
4181
4182// Implementation Summary
4183//
4184// 1. Enforce API surface and semantic compatibility with 1.9.x branch
4185// 2. Improve the module's maintainability by reducing the storage
4186// 	paths to a single mechanism.
4187// 3. Use the same single mechanism to support "private" and "user" data.
4188// 4. _Never_ expose "private" data to user code (TODO: Drop _data, _removeData)
4189// 5. Avoid exposing implementation details on user objects (eg. expando properties)
4190// 6. Provide a clear path for implementation upgrade to WeakMap in 2014
4191
4192    var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,
4193        rmultiDash = /[A-Z]/g;
4194
4195    function getData(data) {
4196        if (data === "true") {
4197            return true;
4198        }
4199
4200        if (data === "false") {
4201            return false;
4202        }
4203
4204        if (data === "null") {
4205            return null;
4206        }
4207
4208        // Only convert to a number if it doesn't change the string
4209        if (data === +data + "") {
4210            return +data;
4211        }
4212
4213        if (rbrace.test(data)) {
4214            return JSON.parse(data);
4215        }
4216
4217        return data;
4218    }
4219
4220    function dataAttr(elem, key, data) {
4221        var name;
4222
4223        // If nothing was found internally, try to fetch any
4224        // data from the HTML5 data-* attribute
4225        if (data === undefined && elem.nodeType === 1) {
4226            name = "data-" + key.replace(rmultiDash, "-$&").toLowerCase();
4227            data = elem.getAttribute(name);
4228
4229            if (typeof data === "string") {
4230                try {
4231                    data = getData(data);
4232                } catch (e) {
4233                }
4234
4235                // Make sure we set the data so it isn't changed later
4236                dataUser.set(elem, key, data);
4237            } else {
4238                data = undefined;
4239            }
4240        }
4241        return data;
4242    }
4243
4244    jQuery.extend({
4245        hasData: function (elem) {
4246            return dataUser.hasData(elem) || dataPriv.hasData(elem);
4247        },
4248
4249        data: function (elem, name, data) {
4250            return dataUser.access(elem, name, data);
4251        },
4252
4253        removeData: function (elem, name) {
4254            dataUser.remove(elem, name);
4255        },
4256
4257        // TODO: Now that all calls to _data and _removeData have been replaced
4258        // with direct calls to dataPriv methods, these can be deprecated.
4259        _data: function (elem, name, data) {
4260            return dataPriv.access(elem, name, data);
4261        },
4262
4263        _removeData: function (elem, name) {
4264            dataPriv.remove(elem, name);
4265        }
4266    });
vendor: 11,394 bytes, lines 4267-4603
4267
4268    jQuery.fn.extend({
4269        data: function (key, value) {
4270            var i, name, data,
4271                elem = this[0],
4272                attrs = elem && elem.attributes;
4273
4274            // Gets all values
4275            if (key === undefined) {
4276                if (this.length) {
4277                    data = dataUser.get(elem);
4278
4279                    if (elem.nodeType === 1 && !dataPriv.get(elem, "hasDataAttrs")) {
4280                        i = attrs.length;
4281                        while (i--) {
4282
4283                            // Support: IE 11 only
4284                            // The attrs elements can be null (#14894)
4285                            if (attrs[i]) {
4286                                name = attrs[i].name;
4287                                if (name.indexOf("data-") === 0) {
4288                                    name = jQuery.camelCase(name.slice(5));
4289                                    dataAttr(elem, name, data[name]);
4290                                }
4291                            }
4292                        }
4293                        dataPriv.set(elem, "hasDataAttrs", true);
4294                    }
4295                }
4296
4297                return data;
4298            }
4299
4300            // Sets multiple values
4301            if (typeof key === "object") {
4302                return this.each(function () {
4303                    dataUser.set(this, key);
4304                });
4305            }
4306
4307            return access(this, function (value) {
4308                var data;
4309
4310                // The calling jQuery object (element matches) is not empty
4311                // (and therefore has an element appears at this[ 0 ]) and the
4312                // `value` parameter was not undefined. An empty jQuery object
4313                // will result in `undefined` for elem = this[ 0 ] which will
4314                // throw an exception if an attempt to read a data cache is made.
4315                if (elem && value === undefined) {
4316
4317                    // Attempt to get data from the cache
4318                    // The key will always be camelCased in Data
4319                    data = dataUser.get(elem, key);
4320                    if (data !== undefined) {
4321                        return data;
4322                    }
4323
4324                    // Attempt to "discover" the data in
4325                    // HTML5 custom data-* attrs
4326                    data = dataAttr(elem, key);
4327                    if (data !== undefined) {
4328                        return data;
4329                    }
4330
4331                    // We tried really hard, but the data doesn't exist.
4332                    return;
4333                }
4334
4335                // Set the data...
4336                this.each(function () {
4337
4338                    // We always store the camelCased key
4339                    dataUser.set(this, key, value);
4340                });
4341            }, null, value, arguments.length > 1, null, true);
4342        },
4343
4344        removeData: function (key) {
4345            return this.each(function () {
4346                dataUser.remove(this, key);
4347            });
4348        }
4349    });
4350
4351
4352    jQuery.extend({
4353        queue: function (elem, type, data) {
4354            var queue;
4355
4356            if (elem) {
4357                type = (type || "fx") + "queue";
4358                queue = dataPriv.get(elem, type);
4359
4360                // Speed up dequeue by getting out quickly if this is just a lookup
4361                if (data) {
4362                    if (!queue || Array.isArray(data)) {
4363                        queue = dataPriv.access(elem, type, jQuery.makeArray(data));
4364                    } else {
4365                        queue.push(data);
4366                    }
4367                }
4368                return queue || [];
4369            }
4370        },
4371
4372        dequeue: function (elem, type) {
4373            type = type || "fx";
4374
4375            var queue = jQuery.queue(elem, type),
4376                startLength = queue.length,
4377                fn = queue.shift(),
4378                hooks = jQuery._queueHooks(elem, type),
4379                next = function () {
4380                    jQuery.dequeue(elem, type);
4381                };
4382
4383            // If the fx queue is dequeued, always remove the progress sentinel
4384            if (fn === "inprogress") {
4385                fn = queue.shift();
4386                startLength--;
4387            }
4388
4389            if (fn) {
4390
4391                // Add a progress sentinel to prevent the fx queue from being
4392                // automatically dequeued
4393                if (type === "fx") {
4394                    queue.unshift("inprogress");
4395                }
4396
4397                // Clear up the last queue stop function
4398                delete hooks.stop;
4399                fn.call(elem, next, hooks);
4400            }
4401
4402            if (!startLength && hooks) {
4403                hooks.empty.fire();
4404            }
4405        },
4406
4407        // Not public - generate a queueHooks object, or return the current one
4408        _queueHooks: function (elem, type) {
4409            var key = type + "queueHooks";
4410            return dataPriv.get(elem, key) || dataPriv.access(elem, key, {
4411                empty: jQuery.Callbacks("once memory").add(function () {
4412                    dataPriv.remove(elem, [type + "queue", key]);
4413                })
4414            });
4415        }
4416    });
4417
4418    jQuery.fn.extend({
4419        queue: function (type, data) {
4420            var setter = 2;
4421
4422            if (typeof type !== "string") {
4423                data = type;
4424                type = "fx";
4425                setter--;
4426            }
4427
4428            if (arguments.length < setter) {
4429                return jQuery.queue(this[0], type);
4430            }
4431
4432            return data === undefined ?
4433                this :
4434                this.each(function () {
4435                    var queue = jQuery.queue(this, type, data);
4436
4437                    // Ensure a hooks for this queue
4438                    jQuery._queueHooks(this, type);
4439
4440                    if (type === "fx" && queue[0] !== "inprogress") {
4441                        jQuery.dequeue(this, type);
4442                    }
4443                });
4444        },
4445        dequeue: function (type) {
4446            return this.each(function () {
4447                jQuery.dequeue(this, type);
4448            });
4449        },
4450        clearQueue: function (type) {
4451            return this.queue(type || "fx", []);
4452        },
4453
4454        // Get a promise resolved when queues of a certain type
4455        // are emptied (fx is the type by default)
4456        promise: function (type, obj) {
4457            var tmp,
4458                count = 1,
4459                defer = jQuery.Deferred(),
4460                elements = this,
4461                i = this.length,
4462                resolve = function () {
4463                    if (!(--count)) {
4464                        defer.resolveWith(elements, [elements]);
4465                    }
4466                };
4467
4468            if (typeof type !== "string") {
4469                obj = type;
4470                type = undefined;
4471            }
4472            type = type || "fx";
4473
4474            while (i--) {
4475                tmp = dataPriv.get(elements[i], type + "queueHooks");
4476                if (tmp && tmp.empty) {
4477                    count++;
4478                    tmp.empty.add(resolve);
4479                }
4480            }
4481            resolve();
4482            return defer.promise(obj);
4483        }
4484    });
4485    var pnum = (/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/).source;
4486
4487    var rcssNum = new RegExp("^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i");
4488
4489
4490    var cssExpand = ["Top", "Right", "Bottom", "Left"];
4491
4492    var isHiddenWithinTree = function (elem, el) {
4493
4494        // isHiddenWithinTree might be called from jQuery#filter function;
4495        // in that case, element will be second argument
4496        elem = el || elem;
4497
4498        // Inline style trumps all
4499        return elem.style.display === "none" ||
4500            elem.style.display === "" &&
4501
4502            // Otherwise, check computed style
4503            // Support: Firefox <=43 - 45
4504            // Disconnected elements can have computed display: none, so first confirm that elem is
4505            // in the document.
4506            jQuery.contains(elem.ownerDocument, elem) &&
4507
4508            jQuery.css(elem, "display") === "none";
4509    };
4510
4511    var swap = function (elem, options, callback, args) {
4512        var ret, name,
4513            old = {};
4514
4515        // Remember the old values, and insert the new ones
4516        for (name in options) {
4517            old[name] = elem.style[name];
4518            elem.style[name] = options[name];
4519        }
4520
4521        ret = callback.apply(elem, args || []);
4522
4523        // Revert the old values
4524        for (name in options) {
4525            elem.style[name] = old[name];
4526        }
4527
4528        return ret;
4529    };
4530
4531
4532    function adjustCSS(elem, prop, valueParts, tween) {
4533        var adjusted,
4534            scale = 1,
4535            maxIterations = 20,
4536            currentValue = tween ?
4537                function () {
4538                    return tween.cur();
4539                } :
4540                function () {
4541                    return jQuery.css(elem, prop, "");
4542                },
4543            initial = currentValue(),
4544            unit = valueParts && valueParts[3] || (jQuery.cssNumber[prop] ? "" : "px"),
4545
4546            // Starting value computation is required for potential unit mismatches
4547            initialInUnit = (jQuery.cssNumber[prop] || unit !== "px" && +initial) &&
4548                rcssNum.exec(jQuery.css(elem, prop));
4549
4550        if (initialInUnit && initialInUnit[3] !== unit) {
4551
4552            // Trust units reported by jQuery.css
4553            unit = unit || initialInUnit[3];
4554
4555            // Make sure we update the tween properties later on
4556            valueParts = valueParts || [];
4557
4558            // Iteratively approximate from a nonzero starting point
4559            initialInUnit = +initial || 1;
4560
4561            do {
4562
4563                // If previous iteration zeroed out, double until we get *something*.
4564                // Use string for doubling so we don't accidentally see scale as unchanged below
4565                scale = scale || ".5";
4566
4567                // Adjust and apply
4568                initialInUnit = initialInUnit / scale;
4569                jQuery.style(elem, prop, initialInUnit + unit);
4570
4571                // Update scale, tolerating zero or NaN from tween.cur()
4572                // Break the loop if scale is unchanged or perfect, or if we've just had enough.
4573            } while (
4574                scale !== (scale = currentValue() / initial) && scale !== 1 && --maxIterations
4575                );
4576        }
4577
4578        if (valueParts) {
4579            initialInUnit = +initialInUnit || +initial || 0;
4580
4581            // Apply relative offset (+=/-=) if specified
4582            adjusted = valueParts[1] ?
4583                initialInUnit + (valueParts[1] + 1) * valueParts[2] :
4584                +valueParts[2];
4585            if (tween) {
4586                tween.unit = unit;
4587                tween.start = initialInUnit;
4588                tween.end = adjusted;
4589            }
4590        }
4591        return adjusted;
4592    }
4593
4594
4595    var defaultDisplayMap = {};
4596
4597    function getDefaultDisplay(elem) {
4598        var temp,
4599            doc = elem.ownerDocument,
4600            nodeName = elem.nodeName,
4601            display = defaultDisplayMap[nodeName];
4602
4603        if (display) {
vendor: 4,740 bytes, lines 4604-4758
4604            return display;
4605        }
4606
4607        temp = doc.body.appendChild(doc.createElement(nodeName));
4608        display = jQuery.css(temp, "display");
4609
4610        temp.parentNode.removeChild(temp);
4611
4612        if (display === "none") {
4613            display = "block";
4614        }
4615        defaultDisplayMap[nodeName] = display;
4616
4617        return display;
4618    }
4619
4620    function showHide(elements, show) {
4621        var display, elem,
4622            values = [],
4623            index = 0,
4624            length = elements.length;
4625
4626        // Determine new display value for elements that need to change
4627        for (; index < length; index++) {
4628            elem = elements[index];
4629            if (!elem.style) {
4630                continue;
4631            }
4632
4633            display = elem.style.display;
4634            if (show) {
4635
4636                // Since we force visibility upon cascade-hidden elements, an immediate (and slow)
4637                // check is required in this first loop unless we have a nonempty display value (either
4638                // inline or about-to-be-restored)
4639                if (display === "none") {
4640                    values[index] = dataPriv.get(elem, "display") || null;
4641                    if (!values[index]) {
4642                        elem.style.display = "";
4643                    }
4644                }
4645                if (elem.style.display === "" && isHiddenWithinTree(elem)) {
4646                    values[index] = getDefaultDisplay(elem);
4647                }
4648            } else {
4649                if (display !== "none") {
4650                    values[index] = "none";
4651
4652                    // Remember what we're overwriting
4653                    dataPriv.set(elem, "display", display);
4654                }
4655            }
4656        }
4657
4658        // Set the display of the elements in a second loop to avoid constant reflow
4659        for (index = 0; index < length; index++) {
4660            if (values[index] != null) {
4661                elements[index].style.display = values[index];
4662            }
4663        }
4664
4665        return elements;
4666    }
4667
4668    jQuery.fn.extend({
4669        show: function () {
4670            return showHide(this, true);
4671        },
4672        hide: function () {
4673            return showHide(this);
4674        },
4675        toggle: function (state) {
4676            if (typeof state === "boolean") {
4677                return state ? this.show() : this.hide();
4678            }
4679
4680            return this.each(function () {
4681                if (isHiddenWithinTree(this)) {
4682                    jQuery(this).show();
4683                } else {
4684                    jQuery(this).hide();
4685                }
4686            });
4687        }
4688    });
4689    var rcheckableType = (/^(?:checkbox|radio)$/i);
4690
4691    var rtagName = (/<([a-z][^\/\0>\x20\t\r\n\f]+)/i);
4692
4693    var rscriptType = (/^$|\/(?:java|ecma)script/i);
4694
4695
4696// We have to close these tags to support XHTML (#13200)
4697    var wrapMap = {
4698
4699        // Support: IE <=9 only
4700        option: [1, "<select multiple='multiple'>", "</select>"],
4701
4702        // XHTML parsers do not magically insert elements in the
4703        // same way that tag soup parsers do. So we cannot shorten
4704        // this by omitting <tbody> or other required elements.
4705        thead: [1, "<table>", "</table>"],
4706        col: [2, "<table><colgroup>", "</colgroup></table>"],
4707        tr: [2, "<table><tbody>", "</tbody></table>"],
4708        td: [3, "<table><tbody><tr>", "</tr></tbody></table>"],
4709
4710        _default: [0, "", ""]
4711    };
4712
4713// Support: IE <=9 only
4714    wrapMap.optgroup = wrapMap.option;
4715
4716    wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
4717    wrapMap.th = wrapMap.td;
4718
4719
4720    function getAll(context, tag) {
4721
4722        // Support: IE <=9 - 11 only
4723        // Use typeof to avoid zero-argument method invocation on host objects (#15151)
4724        var ret;
4725
4726        if (typeof context.getElementsByTagName !== "undefined") {
4727            ret = context.getElementsByTagName(tag || "*");
4728
4729        } else if (typeof context.querySelectorAll !== "undefined") {
4730            ret = context.querySelectorAll(tag || "*");
4731
4732        } else {
4733            ret = [];
4734        }
4735
4736        if (tag === undefined || tag && nodeName(context, tag)) {
4737            return jQuery.merge([context], ret);
4738        }
4739
4740        return ret;
4741    }
4742
4743
4744// Mark scripts as having already been evaluated
4745    function setGlobalEval(elems, refElements) {
4746        var i = 0,
4747            l = elems.length;
4748
4749        for (; i < l; i++) {
4750            dataPriv.set(
4751                elems[i],
4752                "globalEval",
4753                !refElements || dataPriv.get(refElements[i], "globalEval")
4754            );
4755        }
4756    }
4757
4758
vendor: 16,200 bytes, lines 4759-5194
4759    var rhtml = /<|&#?\w+;/;
4760
4761    function buildFragment(elems, context, scripts, selection, ignored) {
4762        var elem, tmp, tag, wrap, contains, j,
4763            fragment = context.createDocumentFragment(),
4764            nodes = [],
4765            i = 0,
4766            l = elems.length;
4767
4768        for (; i < l; i++) {
4769            elem = elems[i];
4770
4771            if (elem || elem === 0) {
4772
4773                // Add nodes directly
4774                if (jQuery.type(elem) === "object") {
4775
4776                    // Support: Android <=4.0 only, PhantomJS 1 only
4777                    // push.apply(_, arraylike) throws on ancient WebKit
4778                    jQuery.merge(nodes, elem.nodeType ? [elem] : elem);
4779
4780                    // Convert non-html into a text node
4781                } else if (!rhtml.test(elem)) {
4782                    nodes.push(context.createTextNode(elem));
4783
4784                    // Convert html into DOM nodes
4785                } else {
4786                    tmp = tmp || fragment.appendChild(context.createElement("div"));
4787
4788                    // Deserialize a standard representation
4789                    tag = (rtagName.exec(elem) || ["", ""])[1].toLowerCase();
4790                    wrap = wrapMap[tag] || wrapMap._default;
4791                    tmp.innerHTML = wrap[1] + jQuery.htmlPrefilter(elem) + wrap[2];
4792
4793                    // Descend through wrappers to the right content
4794                    j = wrap[0];
4795                    while (j--) {
4796                        tmp = tmp.lastChild;
4797                    }
4798
4799                    // Support: Android <=4.0 only, PhantomJS 1 only
4800                    // push.apply(_, arraylike) throws on ancient WebKit
4801                    jQuery.merge(nodes, tmp.childNodes);
4802
4803                    // Remember the top-level container
4804                    tmp = fragment.firstChild;
4805
4806                    // Ensure the created nodes are orphaned (#12392)
4807                    tmp.textContent = "";
4808                }
4809            }
4810        }
4811
4812        // Remove wrapper from fragment
4813        fragment.textContent = "";
4814
4815        i = 0;
4816        while ((elem = nodes[i++])) {
4817
4818            // Skip elements already in the context collection (trac-4087)
4819            if (selection && jQuery.inArray(elem, selection) > -1) {
4820                if (ignored) {
4821                    ignored.push(elem);
4822                }
4823                continue;
4824            }
4825
4826            contains = jQuery.contains(elem.ownerDocument, elem);
4827
4828            // Append to fragment
4829            tmp = getAll(fragment.appendChild(elem), "script");
4830
4831            // Preserve script evaluation history
4832            if (contains) {
4833                setGlobalEval(tmp);
4834            }
4835
4836            // Capture executables
4837            if (scripts) {
4838                j = 0;
4839                while ((elem = tmp[j++])) {
4840                    if (rscriptType.test(elem.type || "")) {
4841                        scripts.push(elem);
4842                    }
4843                }
4844            }
4845        }
4846
4847        return fragment;
4848    }
4849
4850
4851    (function () {
4852        var fragment = document.createDocumentFragment(),
4853            div = fragment.appendChild(document.createElement("div")),
4854            input = document.createElement("input");
4855
4856        // Support: Android 4.0 - 4.3 only
4857        // Check state lost if the name is set (#11217)
4858        // Support: Windows Web Apps (WWA)
4859        // `name` and `type` must use .setAttribute for WWA (#14901)
4860        input.setAttribute("type", "radio");
4861        input.setAttribute("checked", "checked");
4862        input.setAttribute("name", "t");
4863
4864        div.appendChild(input);
4865
4866        // Support: Android <=4.1 only
4867        // Older WebKit doesn't clone checked state correctly in fragments
4868        support.checkClone = div.cloneNode(true).cloneNode(true).lastChild.checked;
4869
4870        // Support: IE <=11 only
4871        // Make sure textarea (and checkbox) defaultValue is properly cloned
4872        div.innerHTML = "<textarea>x</textarea>";
4873        support.noCloneChecked = !!div.cloneNode(true).lastChild.defaultValue;
4874    })();
4875    var documentElement = document.documentElement;
4876
4877
4878    var
4879        rkeyEvent = /^key/,
4880        rmouseEvent = /^(?:mouse|pointer|contextmenu|drag|drop)|click/,
4881        rtypenamespace = /^([^.]*)(?:\.(.+)|)/;
4882
4883    function returnTrue() {
4884        return true;
4885    }
4886
4887    function returnFalse() {
4888        return false;
4889    }
4890
4891// Support: IE <=9 only
4892// See #13393 for more info
4893    function safeActiveElement() {
4894        try {
4895            return document.activeElement;
4896        } catch (err) {
4897        }
4898    }
4899
4900    function on(elem, types, selector, data, fn, one) {
4901        var origFn, type;
4902
4903        // Types can be a map of types/handlers
4904        if (typeof types === "object") {
4905
4906            // ( types-Object, selector, data )
4907            if (typeof selector !== "string") {
4908
4909                // ( types-Object, data )
4910                data = data || selector;
4911                selector = undefined;
4912            }
4913            for (type in types) {
4914                on(elem, type, selector, data, types[type], one);
4915            }
4916            return elem;
4917        }
4918
4919        if (data == null && fn == null) {
4920
4921            // ( types, fn )
4922            fn = selector;
4923            data = selector = undefined;
4924        } else if (fn == null) {
4925            if (typeof selector === "string") {
4926
4927                // ( types, selector, fn )
4928                fn = data;
4929                data = undefined;
4930            } else {
4931
4932                // ( types, data, fn )
4933                fn = data;
4934                data = selector;
4935                selector = undefined;
4936            }
4937        }
4938        if (fn === false) {
4939            fn = returnFalse;
4940        } else if (!fn) {
4941            return elem;
4942        }
4943
4944        if (one === 1) {
4945            origFn = fn;
4946            fn = function (event) {
4947
4948                // Can use an empty set, since event contains the info
4949                jQuery().off(event);
4950                return origFn.apply(this, arguments);
4951            };
4952
4953            // Use same guid so caller can remove using origFn
4954            fn.guid = origFn.guid || (origFn.guid = jQuery.guid++);
4955        }
4956        return elem.each(function () {
4957            jQuery.event.add(this, types, fn, data, selector);
4958        });
4959    }
4960
4961    /*
4962* Helper functions for managing events -- not part of the public interface.
4963* Props to Dean Edwards' addEvent library for many of the ideas.
4964*/
4965    jQuery.event = {
4966
4967        global: {},
4968
4969        add: function (elem, types, handler, data, selector) {
4970
4971            var handleObjIn, eventHandle, tmp,
4972                events, t, handleObj,
4973                special, handlers, type, namespaces, origType,
4974                elemData = dataPriv.get(elem);
4975
4976            // Don't attach events to noData or text/comment nodes (but allow plain objects)
4977            if (!elemData) {
4978                return;
4979            }
4980
4981            // Caller can pass in an object of custom data in lieu of the handler
4982            if (handler.handler) {
4983                handleObjIn = handler;
4984                handler = handleObjIn.handler;
4985                selector = handleObjIn.selector;
4986            }
4987
4988            // Ensure that invalid selectors throw exceptions at attach time
4989            // Evaluate against documentElement in case elem is a non-element node (e.g., document)
4990            if (selector) {
4991                jQuery.find.matchesSelector(documentElement, selector);
4992            }
4993
4994            // Make sure that the handler has a unique ID, used to find/remove it later
4995            if (!handler.guid) {
4996                handler.guid = jQuery.guid++;
4997            }
4998
4999            // Init the element's event structure and main handler, if this is the first
5000            if (!(events = elemData.events)) {
5001                events = elemData.events = {};
5002            }
5003            if (!(eventHandle = elemData.handle)) {
5004                eventHandle = elemData.handle = function (e) {
5005
5006                    // Discard the second event of a jQuery.event.trigger() and
5007                    // when an event is called after a page has unloaded
5008                    return typeof jQuery !== "undefined" && jQuery.event.triggered !== e.type ?
5009                        jQuery.event.dispatch.apply(elem, arguments) : undefined;
5010                };
5011            }
5012
5013            // Handle multiple events separated by a space
5014            types = (types || "").match(rnothtmlwhite) || [""];
5015            t = types.length;
5016            while (t--) {
5017                tmp = rtypenamespace.exec(types[t]) || [];
5018                type = origType = tmp[1];
5019                namespaces = (tmp[2] || "").split(".").sort();
5020
5021                // There *must* be a type, no attaching namespace-only handlers
5022                if (!type) {
5023                    continue;
5024                }
5025
5026                // If event changes its type, use the special event handlers for the changed type
5027                special = jQuery.event.special[type] || {};
5028
5029                // If selector defined, determine special event api type, otherwise given type
5030                type = (selector ? special.delegateType : special.bindType) || type;
5031
5032                // Update special based on newly reset type
5033                special = jQuery.event.special[type] || {};
5034
5035                // handleObj is passed to all event handlers
5036                handleObj = jQuery.extend({
5037                    type: type,
5038                    origType: origType,
5039                    data: data,
5040                    handler: handler,
5041                    guid: handler.guid,
5042                    selector: selector,
5043                    needsContext: selector && jQuery.expr.match.needsContext.test(selector),
5044                    namespace: namespaces.join(".")
5045                }, handleObjIn);
5046
5047                // Init the event handler queue if we're the first
5048                if (!(handlers = events[type])) {
5049                    handlers = events[type] = [];
5050                    handlers.delegateCount = 0;
5051
5052                    // Only use addEventListener if the special events handler returns false
5053                    if (!special.setup ||
5054                        special.setup.call(elem, data, namespaces, eventHandle) === false) {
5055
5056                        if (elem.addEventListener) {
5057                            elem.addEventListener(type, eventHandle);
5058                        }
5059                    }
5060                }
5061
5062                if (special.add) {
5063                    special.add.call(elem, handleObj);
5064
5065                    if (!handleObj.handler.guid) {
5066                        handleObj.handler.guid = handler.guid;
5067                    }
5068                }
5069
5070                // Add to the element's handler list, delegates in front
5071                if (selector) {
5072                    handlers.splice(handlers.delegateCount++, 0, handleObj);
5073                } else {
5074                    handlers.push(handleObj);
5075                }
5076
5077                // Keep track of which events have ever been used, for event optimization
5078                jQuery.event.global[type] = true;
5079            }
5080
5081        },
5082
5083        // Detach an event or set of events from an element
5084        remove: function (elem, types, handler, selector, mappedTypes) {
5085
5086            var j, origCount, tmp,
5087                events, t, handleObj,
5088                special, handlers, type, namespaces, origType,
5089                elemData = dataPriv.hasData(elem) && dataPriv.get(elem);
5090
5091            if (!elemData || !(events = elemData.events)) {
5092                return;
5093            }
5094
5095            // Once for each type.namespace in types; type may be omitted
5096            types = (types || "").match(rnothtmlwhite) || [""];
5097            t = types.length;
5098            while (t--) {
5099                tmp = rtypenamespace.exec(types[t]) || [];
5100                type = origType = tmp[1];
5101                namespaces = (tmp[2] || "").split(".").sort();
5102
5103                // Unbind all events (on this namespace, if provided) for the element
5104                if (!type) {
5105                    for (type in events) {
5106                        jQuery.event.remove(elem, type + types[t], handler, selector, true);
5107                    }
5108                    continue;
5109                }
5110
5111                special = jQuery.event.special[type] || {};
5112                type = (selector ? special.delegateType : special.bindType) || type;
5113                handlers = events[type] || [];
5114                tmp = tmp[2] &&
5115                    new RegExp("(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)");
5116
5117                // Remove matching events
5118                origCount = j = handlers.length;
5119                while (j--) {
5120                    handleObj = handlers[j];
5121
5122                    if ((mappedTypes || origType === handleObj.origType) &&
5123                        (!handler || handler.guid === handleObj.guid) &&
5124                        (!tmp || tmp.test(handleObj.namespace)) &&
5125                        (!selector || selector === handleObj.selector ||
5126                            selector === "**" && handleObj.selector)) {
5127                        handlers.splice(j, 1);
5128
5129                        if (handleObj.selector) {
5130                            handlers.delegateCount--;
5131                        }
5132                        if (special.remove) {
5133                            special.remove.call(elem, handleObj);
5134                        }
5135                    }
5136                }
5137
5138                // Remove generic event handler if we removed something and no more handlers exist
5139                // (avoids potential for endless recursion during removal of special event handlers)
5140                if (origCount && !handlers.length) {
5141                    if (!special.teardown ||
5142                        special.teardown.call(elem, namespaces, elemData.handle) === false) {
5143
5144                        jQuery.removeEvent(elem, type, elemData.handle);
5145                    }
5146
5147                    delete events[type];
5148                }
5149            }
5150
5151            // Remove data and the expando if it's no longer used
5152            if (jQuery.isEmptyObject(events)) {
5153                dataPriv.remove(elem, "handle events");
5154            }
5155        },
5156
5157        dispatch: function (nativeEvent) {
5158
5159            // Make a writable jQuery.Event from the native event object
5160            var event = jQuery.event.fix(nativeEvent);
5161
5162            var i, j, ret, matched, handleObj, handlerQueue,
5163                args = new Array(arguments.length),
5164                handlers = (dataPriv.get(this, "events") || {})[event.type] || [],
5165                special = jQuery.event.special[event.type] || {};
5166
5167            // Use the fix-ed jQuery.Event rather than the (read-only) native event
5168            args[0] = event;
5169
5170            for (i = 1; i < arguments.length; i++) {
5171                args[i] = arguments[i];
5172            }
5173
5174            event.delegateTarget = this;
5175
5176            // Call the preDispatch hook for the mapped type, and let it bail if desired
5177            if (special.preDispatch && special.preDispatch.call(this, event) === false) {
5178                return;
5179            }
5180
5181            // Determine handlers
5182            handlerQueue = jQuery.event.handlers.call(this, event, handlers);
5183
5184            // Run delegates first; they may want to stop propagation beneath us
5185            i = 0;
5186            while ((matched = handlerQueue[i++]) && !event.isPropagationStopped()) {
5187                event.currentTarget = matched.elem;
5188
5189                j = 0;
5190                while ((handleObj = matched.handlers[j++]) &&
5191                !event.isImmediatePropagationStopped()) {
5192
5193                    // Triggered event must either 1) have no namespace, or 2) have namespace(s)
5194                    // a subset or equal to those in the bound event (both can have no namespace).
vendor: 14,375 bytes, lines 5195-5606
5195                    if (!event.rnamespace || event.rnamespace.test(handleObj.namespace)) {
5196
5197                        event.handleObj = handleObj;
5198                        event.data = handleObj.data;
5199
5200                        ret = ((jQuery.event.special[handleObj.origType] || {}).handle ||
5201                            handleObj.handler).apply(matched.elem, args);
5202
5203                        if (ret !== undefined) {
5204                            if ((event.result = ret) === false) {
5205                                event.preventDefault();
5206                                event.stopPropagation();
5207                            }
5208                        }
5209                    }
5210                }
5211            }
5212
5213            // Call the postDispatch hook for the mapped type
5214            if (special.postDispatch) {
5215                special.postDispatch.call(this, event);
5216            }
5217
5218            return event.result;
5219        },
5220
5221        handlers: function (event, handlers) {
5222            var i, handleObj, sel, matchedHandlers, matchedSelectors,
5223                handlerQueue = [],
5224                delegateCount = handlers.delegateCount,
5225                cur = event.target;
5226
5227            // Find delegate handlers
5228            if (delegateCount &&
5229
5230                // Support: IE <=9
5231                // Black-hole SVG <use> instance trees (trac-13180)
5232                cur.nodeType &&
5233
5234                // Support: Firefox <=42
5235                // Suppress spec-violating clicks indicating a non-primary pointer button (trac-3861)
5236                // https://www.w3.org/TR/DOM-Level-3-Events/#event-type-click
5237                // Support: IE 11 only
5238                // ...but not arrow key "clicks" of radio inputs, which can have `button` -1 (gh-2343)
5239                !(event.type === "click" && event.button >= 1)) {
5240
5241                for (; cur !== this; cur = cur.parentNode || this) {
5242
5243                    // Don't check non-elements (#13208)
5244                    // Don't process clicks on disabled elements (#6911, #8165, #11382, #11764)
5245                    if (cur.nodeType === 1 && !(event.type === "click" && cur.disabled === true)) {
5246                        matchedHandlers = [];
5247                        matchedSelectors = {};
5248                        for (i = 0; i < delegateCount; i++) {
5249                            handleObj = handlers[i];
5250
5251                            // Don't conflict with Object.prototype properties (#13203)
5252                            sel = handleObj.selector + " ";
5253
5254                            if (matchedSelectors[sel] === undefined) {
5255                                matchedSelectors[sel] = handleObj.needsContext ?
5256                                    jQuery(sel, this).index(cur) > -1 :
5257                                    jQuery.find(sel, this, null, [cur]).length;
5258                            }
5259                            if (matchedSelectors[sel]) {
5260                                matchedHandlers.push(handleObj);
5261                            }
5262                        }
5263                        if (matchedHandlers.length) {
5264                            handlerQueue.push({elem: cur, handlers: matchedHandlers});
5265                        }
5266                    }
5267                }
5268            }
5269
5270            // Add the remaining (directly-bound) handlers
5271            cur = this;
5272            if (delegateCount < handlers.length) {
5273                handlerQueue.push({elem: cur, handlers: handlers.slice(delegateCount)});
5274            }
5275
5276            return handlerQueue;
5277        },
5278
5279        addProp: function (name, hook) {
5280            Object.defineProperty(jQuery.Event.prototype, name, {
5281                enumerable: true,
5282                configurable: true,
5283
5284                get: jQuery.isFunction(hook) ?
5285                    function () {
5286                        if (this.originalEvent) {
5287                            return hook(this.originalEvent);
5288                        }
5289                    } :
5290                    function () {
5291                        if (this.originalEvent) {
5292                            return this.originalEvent[name];
5293                        }
5294                    },
5295
5296                set: function (value) {
5297                    Object.defineProperty(this, name, {
5298                        enumerable: true,
5299                        configurable: true,
5300                        writable: true,
5301                        value: value
5302                    });
5303                }
5304            });
5305        },
5306
5307        fix: function (originalEvent) {
5308            return originalEvent[jQuery.expando] ?
5309                originalEvent :
5310                new jQuery.Event(originalEvent);
5311        },
5312
5313        special: {
5314            load: {
5315
5316                // Prevent triggered image.load events from bubbling to window.load
5317                noBubble: true
5318            },
5319            focus: {
5320
5321                // Fire native event if possible so blur/focus sequence is correct
5322                trigger: function () {
5323                    if (this !== safeActiveElement() && this.focus) {
5324                        this.focus();
5325                        return false;
5326                    }
5327                },
5328                delegateType: "focusin"
5329            },
5330            blur: {
5331                trigger: function () {
5332                    if (this === safeActiveElement() && this.blur) {
5333                        this.blur();
5334                        return false;
5335                    }
5336                },
5337                delegateType: "focusout"
5338            },
5339            click: {
5340
5341                // For checkbox, fire native event so checked state will be right
5342                trigger: function () {
5343                    if (this.type === "checkbox" && this.click && nodeName(this, "input")) {
5344                        this.click();
5345                        return false;
5346                    }
5347                },
5348
5349                // For cross-browser consistency, don't fire native .click() on links
5350                _default: function (event) {
5351                    return nodeName(event.target, "a");
5352                }
5353            },
5354
5355            beforeunload: {
5356                postDispatch: function (event) {
5357
5358                    // Support: Firefox 20+
5359                    // Firefox doesn't alert if the returnValue field is not set.
5360                    if (event.result !== undefined && event.originalEvent) {
5361                        event.originalEvent.returnValue = event.result;
5362                    }
5363                }
5364            }
5365        }
5366    };
5367
5368    jQuery.removeEvent = function (elem, type, handle) {
5369
5370        // This "if" is needed for plain objects
5371        if (elem.removeEventListener) {
5372            elem.removeEventListener(type, handle);
5373        }
5374    };
5375
5376    jQuery.Event = function (src, props) {
5377
5378        // Allow instantiation without the 'new' keyword
5379        if (!(this instanceof jQuery.Event)) {
5380            return new jQuery.Event(src, props);
5381        }
5382
5383        // Event object
5384        if (src && src.type) {
5385            this.originalEvent = src;
5386            this.type = src.type;
5387
5388            // Events bubbling up the document may have been marked as prevented
5389            // by a handler lower down the tree; reflect the correct value.
5390            this.isDefaultPrevented = src.defaultPrevented ||
5391            src.defaultPrevented === undefined &&
5392
5393            // Support: Android <=2.3 only
5394            src.returnValue === false ?
5395                returnTrue :
5396                returnFalse;
5397
5398            // Create target properties
5399            // Support: Safari <=6 - 7 only
5400            // Target should not be a text node (#504, #13143)
5401            this.target = (src.target && src.target.nodeType === 3) ?
5402                src.target.parentNode :
5403                src.target;
5404
5405            this.currentTarget = src.currentTarget;
5406            this.relatedTarget = src.relatedTarget;
5407
5408            // Event type
5409        } else {
5410            this.type = src;
5411        }
5412
5413        // Put explicitly provided properties onto the event object
5414        if (props) {
5415            jQuery.extend(this, props);
5416        }
5417
5418        // Create a timestamp if incoming event doesn't have one
5419        this.timeStamp = src && src.timeStamp || jQuery.now();
5420
5421        // Mark it as fixed
5422        this[jQuery.expando] = true;
5423    };
5424
5425// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding
5426// https://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
5427    jQuery.Event.prototype = {
5428        constructor: jQuery.Event,
5429        isDefaultPrevented: returnFalse,
5430        isPropagationStopped: returnFalse,
5431        isImmediatePropagationStopped: returnFalse,
5432        isSimulated: false,
5433
5434        preventDefault: function () {
5435            var e = this.originalEvent;
5436
5437            this.isDefaultPrevented = returnTrue;
5438
5439            if (e && !this.isSimulated) {
5440                e.preventDefault();
5441            }
5442        },
5443        stopPropagation: function () {
5444            var e = this.originalEvent;
5445
5446            this.isPropagationStopped = returnTrue;
5447
5448            if (e && !this.isSimulated) {
5449                e.stopPropagation();
5450            }
5451        },
5452        stopImmediatePropagation: function () {
5453            var e = this.originalEvent;
5454
5455            this.isImmediatePropagationStopped = returnTrue;
5456
5457            if (e && !this.isSimulated) {
5458                e.stopImmediatePropagation();
5459            }
5460
5461            this.stopPropagation();
5462        }
5463    };
5464
5465// Includes all common event props including KeyEvent and MouseEvent specific props
5466    jQuery.each({
5467        altKey: true,
5468        bubbles: true,
5469        cancelable: true,
5470        changedTouches: true,
5471        ctrlKey: true,
5472        detail: true,
5473        eventPhase: true,
5474        metaKey: true,
5475        pageX: true,
5476        pageY: true,
5477        shiftKey: true,
5478        view: true,
5479        "char": true,
5480        charCode: true,
5481        key: true,
5482        keyCode: true,
5483        button: true,
5484        buttons: true,
5485        clientX: true,
5486        clientY: true,
5487        offsetX: true,
5488        offsetY: true,
5489        pointerId: true,
5490        pointerType: true,
5491        screenX: true,
5492        screenY: true,
5493        targetTouches: true,
5494        toElement: true,
5495        touches: true,
5496
5497        which: function (event) {
5498            var button = event.button;
5499
5500            // Add which for key events
5501            if (event.which == null && rkeyEvent.test(event.type)) {
5502                return event.charCode != null ? event.charCode : event.keyCode;
5503            }
5504
5505            // Add which for click: 1 === left; 2 === middle; 3 === right
5506            if (!event.which && button !== undefined && rmouseEvent.test(event.type)) {
5507                if (button & 1) {
5508                    return 1;
5509                }
5510
5511                if (button & 2) {
5512                    return 3;
5513                }
5514
5515                if (button & 4) {
5516                    return 2;
5517                }
5518
5519                return 0;
5520            }
5521
5522            return event.which;
5523        }
5524    }, jQuery.event.addProp);
5525
5526// Create mouseenter/leave events using mouseover/out and event-time checks
5527// so that event delegation works in jQuery.
5528// Do the same for pointerenter/pointerleave and pointerover/pointerout
5529//
5530// Support: Safari 7 only
5531// Safari sends mouseenter too often; see:
5532// https://bugs.chromium.org/p/chromium/issues/detail?id=470258
5533// for the description of the bug (it existed in older Chrome versions as well).
5534    jQuery.each({
5535        mouseenter: "mouseover",
5536        mouseleave: "mouseout",
5537        pointerenter: "pointerover",
5538        pointerleave: "pointerout"
5539    }, function (orig, fix) {
5540        jQuery.event.special[orig] = {
5541            delegateType: fix,
5542            bindType: fix,
5543
5544            handle: function (event) {
5545                var ret,
5546                    target = this,
5547                    related = event.relatedTarget,
5548                    handleObj = event.handleObj;
5549
5550                // For mouseenter/leave call the handler if related is outside the target.
5551                // NB: No relatedTarget if the mouse left/entered the browser window
5552                if (!related || (related !== target && !jQuery.contains(target, related))) {
5553                    event.type = handleObj.origType;
5554                    ret = handleObj.handler.apply(this, arguments);
5555                    event.type = fix;
5556                }
5557                return ret;
5558            }
5559        };
5560    });
5561
5562    jQuery.fn.extend({
5563
5564        on: function (types, selector, data, fn) {
5565            return on(this, types, selector, data, fn);
5566        },
5567        one: function (types, selector, data, fn) {
5568            return on(this, types, selector, data, fn, 1);
5569        },
5570        off: function (types, selector, fn) {
5571            var handleObj, type;
5572            if (types && types.preventDefault && types.handleObj) {
5573
5574                // ( event )	dispatched jQuery.Event
5575                handleObj = types.handleObj;
5576                jQuery(types.delegateTarget).off(
5577                    handleObj.namespace ?
5578                        handleObj.origType + "." + handleObj.namespace :
5579                        handleObj.origType,
5580                    handleObj.selector,
5581                    handleObj.handler
5582                );
5583                return this;
5584            }
5585            if (typeof types === "object") {
5586
5587                // ( types-object [, selector] )
5588                for (type in types) {
5589                    this.off(type, selector, types[type]);
5590                }
5591                return this;
5592            }
5593            if (selector === false || typeof selector === "function") {
5594
5595                // ( types [, fn] )
5596                fn = selector;
5597                selector = undefined;
5598            }
5599            if (fn === false) {
5600                fn = returnFalse;
5601            }
5602            return this.each(function () {
5603                jQuery.event.remove(this, types, fn, selector);
5604            });
5605        }
5606    });
vendor: 9,929 bytes, lines 5607-5882
5607
5608
5609    var
5610
5611        /* eslint-disable max-len */
5612
5613        // See https://github.com/eslint/eslint/issues/3229
5614        rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([a-z][^\/\0>\x20\t\r\n\f]*)[^>]*)\/>/gi,
5615
5616        /* eslint-enable */
5617
5618        // Support: IE <=10 - 11, Edge 12 - 13
5619        // In IE/Edge using regex groups here causes severe slowdowns.
5620        // See https://connect.microsoft.com/IE/feedback/details/1736512/
5621        rnoInnerhtml = /<script|<style|<link/i,
5622
5623        // checked="checked" or checked
5624        rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i,
5625        rscriptTypeMasked = /^true\/(.*)/,
5626        rcleanScript = /^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g;
5627
5628// Prefer a tbody over its parent table for containing new rows
5629    function manipulationTarget(elem, content) {
5630        if (nodeName(elem, "table") &&
5631            nodeName(content.nodeType !== 11 ? content : content.firstChild, "tr")) {
5632
5633            return jQuery(">tbody", elem)[0] || elem;
5634        }
5635
5636        return elem;
5637    }
5638
5639// Replace/restore the type attribute of script elements for safe DOM manipulation
5640    function disableScript(elem) {
5641        elem.type = (elem.getAttribute("type") !== null) + "/" + elem.type;
5642        return elem;
5643    }
5644
5645    function restoreScript(elem) {
5646        var match = rscriptTypeMasked.exec(elem.type);
5647
5648        if (match) {
5649            elem.type = match[1];
5650        } else {
5651            elem.removeAttribute("type");
5652        }
5653
5654        return elem;
5655    }
5656
5657    function cloneCopyEvent(src, dest) {
5658        var i, l, type, pdataOld, pdataCur, udataOld, udataCur, events;
5659
5660        if (dest.nodeType !== 1) {
5661            return;
5662        }
5663
5664        // 1. Copy private data: events, handlers, etc.
5665        if (dataPriv.hasData(src)) {
5666            pdataOld = dataPriv.access(src);
5667            pdataCur = dataPriv.set(dest, pdataOld);
5668            events = pdataOld.events;
5669
5670            if (events) {
5671                delete pdataCur.handle;
5672                pdataCur.events = {};
5673
5674                for (type in events) {
5675                    for (i = 0, l = events[type].length; i < l; i++) {
5676                        jQuery.event.add(dest, type, events[type][i]);
5677                    }
5678                }
5679            }
5680        }
5681
5682        // 2. Copy user data
5683        if (dataUser.hasData(src)) {
5684            udataOld = dataUser.access(src);
5685            udataCur = jQuery.extend({}, udataOld);
5686
5687            dataUser.set(dest, udataCur);
5688        }
5689    }
5690
5691// Fix IE bugs, see support tests
5692    function fixInput(src, dest) {
5693        var nodeName = dest.nodeName.toLowerCase();
5694
5695        // Fails to persist the checked state of a cloned checkbox or radio button.
5696        if (nodeName === "input" && rcheckableType.test(src.type)) {
5697            dest.checked = src.checked;
5698
5699            // Fails to return the selected option to the default selected state when cloning options
5700        } else if (nodeName === "input" || nodeName === "textarea") {
5701            dest.defaultValue = src.defaultValue;
5702        }
5703    }
5704
5705    function domManip(collection, args, callback, ignored) {
5706
5707        // Flatten any nested arrays
5708        args = concat.apply([], args);
5709
5710        var fragment, first, scripts, hasScripts, node, doc,
5711            i = 0,
5712            l = collection.length,
5713            iNoClone = l - 1,
5714            value = args[0],
5715            isFunction = jQuery.isFunction(value);
5716
5717        // We can't cloneNode fragments that contain checked, in WebKit
5718        if (isFunction ||
5719            (l > 1 && typeof value === "string" &&
5720                !support.checkClone && rchecked.test(value))) {
5721            return collection.each(function (index) {
5722                var self = collection.eq(index);
5723                if (isFunction) {
5724                    args[0] = value.call(this, index, self.html());
5725                }
5726                domManip(self, args, callback, ignored);
5727            });
5728        }
5729
5730        if (l) {
5731            fragment = buildFragment(args, collection[0].ownerDocument, false, collection, ignored);
5732            first = fragment.firstChild;
5733
5734            if (fragment.childNodes.length === 1) {
5735                fragment = first;
5736            }
5737
5738            // Require either new content or an interest in ignored elements to invoke the callback
5739            if (first || ignored) {
5740                scripts = jQuery.map(getAll(fragment, "script"), disableScript);
5741                hasScripts = scripts.length;
5742
5743                // Use the original fragment for the last item
5744                // instead of the first because it can end up
5745                // being emptied incorrectly in certain situations (#8070).
5746                for (; i < l; i++) {
5747                    node = fragment;
5748
5749                    if (i !== iNoClone) {
5750                        node = jQuery.clone(node, true, true);
5751
5752                        // Keep references to cloned scripts for later restoration
5753                        if (hasScripts) {
5754
5755                            // Support: Android <=4.0 only, PhantomJS 1 only
5756                            // push.apply(_, arraylike) throws on ancient WebKit
5757                            jQuery.merge(scripts, getAll(node, "script"));
5758                        }
5759                    }
5760
5761                    callback.call(collection[i], node, i);
5762                }
5763
5764                if (hasScripts) {
5765                    doc = scripts[scripts.length - 1].ownerDocument;
5766
5767                    // Reenable scripts
5768                    jQuery.map(scripts, restoreScript);
5769
5770                    // Evaluate executable scripts on first document insertion
5771                    for (i = 0; i < hasScripts; i++) {
5772                        node = scripts[i];
5773                        if (rscriptType.test(node.type || "") &&
5774                            !dataPriv.access(node, "globalEval") &&
5775                            jQuery.contains(doc, node)) {
5776
5777                            if (node.src) {
5778
5779                                // Optional AJAX dependency, but won't run scripts if not present
5780                                if (jQuery._evalUrl) {
5781                                    jQuery._evalUrl(node.src);
5782                                }
5783                            } else {
5784                                DOMEval(node.textContent.replace(rcleanScript, ""), doc);
5785                            }
5786                        }
5787                    }
5788                }
5789            }
5790        }
5791
5792        return collection;
5793    }
5794
5795    function remove(elem, selector, keepData) {
5796        var node,
5797            nodes = selector ? jQuery.filter(selector, elem) : elem,
5798            i = 0;
5799
5800        for (; (node = nodes[i]) != null; i++) {
5801            if (!keepData && node.nodeType === 1) {
5802                jQuery.cleanData(getAll(node));
5803            }
5804
5805            if (node.parentNode) {
5806                if (keepData && jQuery.contains(node.ownerDocument, node)) {
5807                    setGlobalEval(getAll(node, "script"));
5808                }
5809                node.parentNode.removeChild(node);
5810            }
5811        }
5812
5813        return elem;
5814    }
5815
5816    jQuery.extend({
5817        htmlPrefilter: function (html) {
5818            return html.replace(rxhtmlTag, "<$1></$2>");
5819        },
5820
5821        clone: function (elem, dataAndEvents, deepDataAndEvents) {
5822            var i, l, srcElements, destElements,
5823                clone = elem.cloneNode(true),
5824                inPage = jQuery.contains(elem.ownerDocument, elem);
5825
5826            // Fix IE cloning issues
5827            if (!support.noCloneChecked && (elem.nodeType === 1 || elem.nodeType === 11) &&
5828                !jQuery.isXMLDoc(elem)) {
5829
5830                // We eschew Sizzle here for performance reasons: https://jsperf.com/getall-vs-sizzle/2
5831                destElements = getAll(clone);
5832                srcElements = getAll(elem);
5833
5834                for (i = 0, l = srcElements.length; i < l; i++) {
5835                    fixInput(srcElements[i], destElements[i]);
5836                }
5837            }
5838
5839            // Copy the events from the original to the clone
5840            if (dataAndEvents) {
5841                if (deepDataAndEvents) {
5842                    srcElements = srcElements || getAll(elem);
5843                    destElements = destElements || getAll(clone);
5844
5845                    for (i = 0, l = srcElements.length; i < l; i++) {
5846                        cloneCopyEvent(srcElements[i], destElements[i]);
5847                    }
5848                } else {
5849                    cloneCopyEvent(elem, clone);
5850                }
5851            }
5852
5853            // Preserve script evaluation history
5854            destElements = getAll(clone, "script");
5855            if (destElements.length > 0) {
5856                setGlobalEval(destElements, !inPage && getAll(elem, "script"));
5857            }
5858
5859            // Return the cloned set
5860            return clone;
5861        },
5862
5863        cleanData: function (elems) {
5864            var data, elem, type,
5865                special = jQuery.event.special,
5866                i = 0;
5867
5868            for (; (elem = elems[i]) !== undefined; i++) {
5869                if (acceptData(elem)) {
5870                    if ((data = elem[dataPriv.expando])) {
5871                        if (data.events) {
5872                            for (type in data.events) {
5873                                if (special[type]) {
5874                                    jQuery.event.remove(elem, type);
5875
5876                                    // This is a shortcut to avoid jQuery.event.remove's overhead
5877                                } else {
5878                                    jQuery.removeEvent(elem, type, data.handle);
5879                                }
5880                            }
5881                        }
5882
vendor: 5,412 bytes, lines 5883-6037
5883                        // Support: Chrome <=35 - 45+
5884                        // Assign undefined instead of using delete, see Data#remove
5885                        elem[dataPriv.expando] = undefined;
5886                    }
5887                    if (elem[dataUser.expando]) {
5888
5889                        // Support: Chrome <=35 - 45+
5890                        // Assign undefined instead of using delete, see Data#remove
5891                        elem[dataUser.expando] = undefined;
5892                    }
5893                }
5894            }
5895        }
5896    });
5897
5898    jQuery.fn.extend({
5899        detach: function (selector) {
5900            return remove(this, selector, true);
5901        },
5902
5903        remove: function (selector) {
5904            return remove(this, selector);
5905        },
5906
5907        text: function (value) {
5908            return access(this, function (value) {
5909                return value === undefined ?
5910                    jQuery.text(this) :
5911                    this.empty().each(function () {
5912                        if (this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9) {
5913                            this.textContent = value;
5914                        }
5915                    });
5916            }, null, value, arguments.length);
5917        },
5918
5919        append: function () {
5920            return domManip(this, arguments, function (elem) {
5921                if (this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9) {
5922                    var target = manipulationTarget(this, elem);
5923                    target.appendChild(elem);
5924                }
5925            });
5926        },
5927
5928        prepend: function () {
5929            return domManip(this, arguments, function (elem) {
5930                if (this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9) {
5931                    var target = manipulationTarget(this, elem);
5932                    target.insertBefore(elem, target.firstChild);
5933                }
5934            });
5935        },
5936
5937        before: function () {
5938            return domManip(this, arguments, function (elem) {
5939                if (this.parentNode) {
5940                    this.parentNode.insertBefore(elem, this);
5941                }
5942            });
5943        },
5944
5945        after: function () {
5946            return domManip(this, arguments, function (elem) {
5947                if (this.parentNode) {
5948                    this.parentNode.insertBefore(elem, this.nextSibling);
5949                }
5950            });
5951        },
5952
5953        empty: function () {
5954            var elem,
5955                i = 0;
5956
5957            for (; (elem = this[i]) != null; i++) {
5958                if (elem.nodeType === 1) {
5959
5960                    // Prevent memory leaks
5961                    jQuery.cleanData(getAll(elem, false));
5962
5963                    // Remove any remaining nodes
5964                    elem.textContent = "";
5965                }
5966            }
5967
5968            return this;
5969        },
5970
5971        clone: function (dataAndEvents, deepDataAndEvents) {
5972            dataAndEvents = dataAndEvents == null ? false : dataAndEvents;
5973            deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;
5974
5975            return this.map(function () {
5976                return jQuery.clone(this, dataAndEvents, deepDataAndEvents);
5977            });
5978        },
5979
5980        html: function (value) {
5981            return access(this, function (value) {
5982                var elem = this[0] || {},
5983                    i = 0,
5984                    l = this.length;
5985
5986                if (value === undefined && elem.nodeType === 1) {
5987                    return elem.innerHTML;
5988                }
5989
5990                // See if we can take a shortcut and just use innerHTML
5991                if (typeof value === "string" && !rnoInnerhtml.test(value) &&
5992                    !wrapMap[(rtagName.exec(value) || ["", ""])[1].toLowerCase()]) {
5993
5994                    value = jQuery.htmlPrefilter(value);
5995
5996                    try {
5997                        for (; i < l; i++) {
5998                            elem = this[i] || {};
5999
6000                            // Remove element nodes and prevent memory leaks
6001                            if (elem.nodeType === 1) {
6002                                jQuery.cleanData(getAll(elem, false));
6003                                elem.innerHTML = value;
6004                            }
6005                        }
6006
6007                        elem = 0;
6008
6009                        // If using innerHTML throws an exception, use the fallback method
6010                    } catch (e) {
6011                    }
6012                }
6013
6014                if (elem) {
6015                    this.empty().append(value);
6016                }
6017            }, null, value, arguments.length);
6018        },
6019
6020        replaceWith: function () {
6021            var ignored = [];
6022
6023            // Make the changes, replacing each non-ignored context element with the new content
6024            return domManip(this, arguments, function (elem) {
6025                var parent = this.parentNode;
6026
6027                if (jQuery.inArray(this, ignored) < 0) {
6028                    jQuery.cleanData(getAll(this));
6029                    if (parent) {
6030                        parent.replaceChild(elem, this);
6031                    }
6032                }
6033
6034                // Force callback invocation
6035            }, ignored);
6036        }
6037    });
vendor: 4,434 bytes, lines 6038-6164
6038
6039    jQuery.each({
6040        appendTo: "append",
6041        prependTo: "prepend",
6042        insertBefore: "before",
6043        insertAfter: "after",
6044        replaceAll: "replaceWith"
6045    }, function (name, original) {
6046        jQuery.fn[name] = function (selector) {
6047            var elems,
6048                ret = [],
6049                insert = jQuery(selector),
6050                last = insert.length - 1,
6051                i = 0;
6052
6053            for (; i <= last; i++) {
6054                elems = i === last ? this : this.clone(true);
6055                jQuery(insert[i])[original](elems);
6056
6057                // Support: Android <=4.0 only, PhantomJS 1 only
6058                // .get() because push.apply(_, arraylike) throws on ancient WebKit
6059                push.apply(ret, elems.get());
6060            }
6061
6062            return this.pushStack(ret);
6063        };
6064    });
6065    var rmargin = (/^margin/);
6066
6067    var rnumnonpx = new RegExp("^(" + pnum + ")(?!px)[a-z%]+$", "i");
6068
6069    var getStyles = function (elem) {
6070
6071        // Support: IE <=11 only, Firefox <=30 (#15098, #14150)
6072        // IE throws on elements created in popups
6073        // FF meanwhile throws on frame elements through "defaultView.getComputedStyle"
6074        var view = elem.ownerDocument.defaultView;
6075
6076        if (!view || !view.opener) {
6077            view = window;
6078        }
6079
6080        return view.getComputedStyle(elem);
6081    };
6082
6083
6084    (function () {
6085
6086        // Executing both pixelPosition & boxSizingReliable tests require only one layout
6087        // so they're executed at the same time to save the second computation.
6088        function computeStyleTests() {
6089
6090            // This is a singleton, we need to execute it only once
6091            if (!div) {
6092                return;
6093            }
6094
6095            div.style.cssText =
6096                "box-sizing:border-box;" +
6097                "position:relative;display:block;" +
6098                "margin:auto;border:1px;padding:1px;" +
6099                "top:1%;width:50%";
6100            div.innerHTML = "";
6101            documentElement.appendChild(container);
6102
6103            var divStyle = window.getComputedStyle(div);
6104            pixelPositionVal = divStyle.top !== "1%";
6105
6106            // Support: Android 4.0 - 4.3 only, Firefox <=3 - 44
6107            reliableMarginLeftVal = divStyle.marginLeft === "2px";
6108            boxSizingReliableVal = divStyle.width === "4px";
6109
6110            // Support: Android 4.0 - 4.3 only
6111            // Some styles come back with percentage values, even though they shouldn't
6112            div.style.marginRight = "50%";
6113            pixelMarginRightVal = divStyle.marginRight === "4px";
6114
6115            documentElement.removeChild(container);
6116
6117            // Nullify the div so it wouldn't be stored in the memory and
6118            // it will also be a sign that checks already performed
6119            div = null;
6120        }
6121
6122        var pixelPositionVal, boxSizingReliableVal, pixelMarginRightVal, reliableMarginLeftVal,
6123            container = document.createElement("div"),
6124            div = document.createElement("div");
6125
6126        // Finish early in limited (non-browser) environments
6127        if (!div.style) {
6128            return;
6129        }
6130
6131        // Support: IE <=9 - 11 only
6132        // Style of cloned element affects source element cloned (#8908)
6133        div.style.backgroundClip = "content-box";
6134        div.cloneNode(true).style.backgroundClip = "";
6135        support.clearCloneStyle = div.style.backgroundClip === "content-box";
6136
6137        container.style.cssText = "border:0;width:8px;height:0;top:0;left:-9999px;" +
6138            "padding:0;margin-top:1px;position:absolute";
6139        container.appendChild(div);
6140
6141        jQuery.extend(support, {
6142            pixelPosition: function () {
6143                computeStyleTests();
6144                return pixelPositionVal;
6145            },
6146            boxSizingReliable: function () {
6147                computeStyleTests();
6148                return boxSizingReliableVal;
6149            },
6150            pixelMarginRight: function () {
6151                computeStyleTests();
6152                return pixelMarginRightVal;
6153            },
6154            reliableMarginLeft: function () {
6155                computeStyleTests();
6156                return reliableMarginLeftVal;
6157            }
6158        });
6159    })();
6160
6161
6162    function curCSS(elem, name, computed) {
6163        var width, minWidth, maxWidth, ret,
6164
vendor: 13,128 bytes, lines 6165-6532
6165            // Support: Firefox 51+
6166            // Retrieving style before computed somehow
6167            // fixes an issue with getting wrong values
6168            // on detached elements
6169            style = elem.style;
6170
6171        computed = computed || getStyles(elem);
6172
6173        // getPropertyValue is needed for:
6174        // .css('filter') (IE 9 only, #12537)
6175        // .css('--customProperty) (#3144)
6176        if (computed) {
6177            ret = computed.getPropertyValue(name) || computed[name];
6178
6179            if (ret === "" && !jQuery.contains(elem.ownerDocument, elem)) {
6180                ret = jQuery.style(elem, name);
6181            }
6182
6183            // A tribute to the "awesome hack by Dean Edwards"
6184            // Android Browser returns percentage for some values,
6185            // but width seems to be reliably pixels.
6186            // This is against the CSSOM draft spec:
6187            // https://drafts.csswg.org/cssom/#resolved-values
6188            if (!support.pixelMarginRight() && rnumnonpx.test(ret) && rmargin.test(name)) {
6189
6190                // Remember the original values
6191                width = style.width;
6192                minWidth = style.minWidth;
6193                maxWidth = style.maxWidth;
6194
6195                // Put in the new values to get a computed value out
6196                style.minWidth = style.maxWidth = style.width = ret;
6197                ret = computed.width;
6198
6199                // Revert the changed values
6200                style.width = width;
6201                style.minWidth = minWidth;
6202                style.maxWidth = maxWidth;
6203            }
6204        }
6205
6206        return ret !== undefined ?
6207
6208            // Support: IE <=9 - 11 only
6209            // IE returns zIndex value as an integer.
6210            ret + "" :
6211            ret;
6212    }
6213
6214
6215    function addGetHookIf(conditionFn, hookFn) {
6216
6217        // Define the hook, we'll check on the first run if it's really needed.
6218        return {
6219            get: function () {
6220                if (conditionFn()) {
6221
6222                    // Hook not needed (or it's not possible to use it due
6223                    // to missing dependency), remove it.
6224                    delete this.get;
6225                    return;
6226                }
6227
6228                // Hook needed; redefine it so that the support test is not executed again.
6229                return (this.get = hookFn).apply(this, arguments);
6230            }
6231        };
6232    }
6233
6234
6235    var
6236
6237        // Swappable if display is none or starts with table
6238        // except "table", "table-cell", or "table-caption"
6239        // See here for display values: https://developer.mozilla.org/en-US/docs/CSS/display
6240        rdisplayswap = /^(none|table(?!-c[ea]).+)/,
6241        rcustomProp = /^--/,
6242        cssShow = {position: "absolute", visibility: "hidden", display: "block"},
6243        cssNormalTransform = {
6244            letterSpacing: "0",
6245            fontWeight: "400"
6246        },
6247
6248        cssPrefixes = ["Webkit", "Moz", "ms"],
6249        emptyStyle = document.createElement("div").style;
6250
6251// Return a css property mapped to a potentially vendor prefixed property
6252    function vendorPropName(name) {
6253
6254        // Shortcut for names that are not vendor prefixed
6255        if (name in emptyStyle) {
6256            return name;
6257        }
6258
6259        // Check for vendor prefixed names
6260        var capName = name[0].toUpperCase() + name.slice(1),
6261            i = cssPrefixes.length;
6262
6263        while (i--) {
6264            name = cssPrefixes[i] + capName;
6265            if (name in emptyStyle) {
6266                return name;
6267            }
6268        }
6269    }
6270
6271// Return a property mapped along what jQuery.cssProps suggests or to
6272// a vendor prefixed property.
6273    function finalPropName(name) {
6274        var ret = jQuery.cssProps[name];
6275        if (!ret) {
6276            ret = jQuery.cssProps[name] = vendorPropName(name) || name;
6277        }
6278        return ret;
6279    }
6280
6281    function setPositiveNumber(elem, value, subtract) {
6282
6283        // Any relative (+/-) values have already been
6284        // normalized at this point
6285        var matches = rcssNum.exec(value);
6286        return matches ?
6287
6288            // Guard against undefined "subtract", e.g., when used as in cssHooks
6289            Math.max(0, matches[2] - (subtract || 0)) + (matches[3] || "px") :
6290            value;
6291    }
6292
6293    function augmentWidthOrHeight(elem, name, extra, isBorderBox, styles) {
6294        var i,
6295            val = 0;
6296
6297        // If we already have the right measurement, avoid augmentation
6298        if (extra === (isBorderBox ? "border" : "content")) {
6299            i = 4;
6300
6301            // Otherwise initialize for horizontal or vertical properties
6302        } else {
6303            i = name === "width" ? 1 : 0;
6304        }
6305
6306        for (; i < 4; i += 2) {
6307
6308            // Both box models exclude margin, so add it if we want it
6309            if (extra === "margin") {
6310                val += jQuery.css(elem, extra + cssExpand[i], true, styles);
6311            }
6312
6313            if (isBorderBox) {
6314
6315                // border-box includes padding, so remove it if we want content
6316                if (extra === "content") {
6317                    val -= jQuery.css(elem, "padding" + cssExpand[i], true, styles);
6318                }
6319
6320                // At this point, extra isn't border nor margin, so remove border
6321                if (extra !== "margin") {
6322                    val -= jQuery.css(elem, "border" + cssExpand[i] + "Width", true, styles);
6323                }
6324            } else {
6325
6326                // At this point, extra isn't content, so add padding
6327                val += jQuery.css(elem, "padding" + cssExpand[i], true, styles);
6328
6329                // At this point, extra isn't content nor padding, so add border
6330                if (extra !== "padding") {
6331                    val += jQuery.css(elem, "border" + cssExpand[i] + "Width", true, styles);
6332                }
6333            }
6334        }
6335
6336        return val;
6337    }
6338
6339    function getWidthOrHeight(elem, name, extra) {
6340
6341        // Start with computed style
6342        var valueIsBorderBox,
6343            styles = getStyles(elem),
6344            val = curCSS(elem, name, styles),
6345            isBorderBox = jQuery.css(elem, "boxSizing", false, styles) === "border-box";
6346
6347        // Computed unit is not pixels. Stop here and return.
6348        if (rnumnonpx.test(val)) {
6349            return val;
6350        }
6351
6352        // Check for style in case a browser which returns unreliable values
6353        // for getComputedStyle silently falls back to the reliable elem.style
6354        valueIsBorderBox = isBorderBox &&
6355            (support.boxSizingReliable() || val === elem.style[name]);
6356
6357        // Fall back to offsetWidth/Height when value is "auto"
6358        // This happens for inline elements with no explicit setting (gh-3571)
6359        if (val === "auto") {
6360            val = elem["offset" + name[0].toUpperCase() + name.slice(1)];
6361        }
6362
6363        // Normalize "", auto, and prepare for extra
6364        val = parseFloat(val) || 0;
6365
6366        // Use the active box-sizing model to add/subtract irrelevant styles
6367        return (val +
6368            augmentWidthOrHeight(
6369                elem,
6370                name,
6371                extra || (isBorderBox ? "border" : "content"),
6372                valueIsBorderBox,
6373                styles
6374            )
6375        ) + "px";
6376    }
6377
6378    jQuery.extend({
6379
6380        // Add in style property hooks for overriding the default
6381        // behavior of getting and setting a style property
6382        cssHooks: {
6383            opacity: {
6384                get: function (elem, computed) {
6385                    if (computed) {
6386
6387                        // We should always get a number back from opacity
6388                        var ret = curCSS(elem, "opacity");
6389                        return ret === "" ? "1" : ret;
6390                    }
6391                }
6392            }
6393        },
6394
6395        // Don't automatically add "px" to these possibly-unitless properties
6396        cssNumber: {
6397            "animationIterationCount": true,
6398            "columnCount": true,
6399            "fillOpacity": true,
6400            "flexGrow": true,
6401            "flexShrink": true,
6402            "fontWeight": true,
6403            "lineHeight": true,
6404            "opacity": true,
6405            "order": true,
6406            "orphans": true,
6407            "widows": true,
6408            "zIndex": true,
6409            "zoom": true
6410        },
6411
6412        // Add in properties whose names you wish to fix before
6413        // setting or getting the value
6414        cssProps: {
6415            "float": "cssFloat"
6416        },
6417
6418        // Get and set the style property on a DOM Node
6419        style: function (elem, name, value, extra) {
6420
6421            // Don't set styles on text and comment nodes
6422            if (!elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style) {
6423                return;
6424            }
6425
6426            // Make sure that we're working with the right name
6427            var ret, type, hooks,
6428                origName = jQuery.camelCase(name),
6429                isCustomProp = rcustomProp.test(name),
6430                style = elem.style;
6431
6432            // Make sure that we're working with the right name. We don't
6433            // want to query the value if it is a CSS custom property
6434            // since they are user-defined.
6435            if (!isCustomProp) {
6436                name = finalPropName(origName);
6437            }
6438
6439            // Gets hook for the prefixed version, then unprefixed version
6440            hooks = jQuery.cssHooks[name] || jQuery.cssHooks[origName];
6441
6442            // Check if we're setting a value
6443            if (value !== undefined) {
6444                type = typeof value;
6445
6446                // Convert "+=" or "-=" to relative numbers (#7345)
6447                if (type === "string" && (ret = rcssNum.exec(value)) && ret[1]) {
6448                    value = adjustCSS(elem, name, ret);
6449
6450                    // Fixes bug #9237
6451                    type = "number";
6452                }
6453
6454                // Make sure that null and NaN values aren't set (#7116)
6455                if (value == null || value !== value) {
6456                    return;
6457                }
6458
6459                // If a number was passed in, add the unit (except for certain CSS properties)
6460                if (type === "number") {
6461                    value += ret && ret[3] || (jQuery.cssNumber[origName] ? "" : "px");
6462                }
6463
6464                // background-* props affect original clone's values
6465                if (!support.clearCloneStyle && value === "" && name.indexOf("background") === 0) {
6466                    style[name] = "inherit";
6467                }
6468
6469                // If a hook was provided, use that value, otherwise just set the specified value
6470                if (!hooks || !("set" in hooks) ||
6471                    (value = hooks.set(elem, value, extra)) !== undefined) {
6472
6473                    if (isCustomProp) {
6474                        style.setProperty(name, value);
6475                    } else {
6476                        style[name] = value;
6477                    }
6478                }
6479
6480            } else {
6481
6482                // If a hook was provided get the non-computed value from there
6483                if (hooks && "get" in hooks &&
6484                    (ret = hooks.get(elem, false, extra)) !== undefined) {
6485
6486                    return ret;
6487                }
6488
6489                // Otherwise just get the value from the style object
6490                return style[name];
6491            }
6492        },
6493
6494        css: function (elem, name, extra, styles) {
6495            var val, num, hooks,
6496                origName = jQuery.camelCase(name),
6497                isCustomProp = rcustomProp.test(name);
6498
6499            // Make sure that we're working with the right name. We don't
6500            // want to modify the value if it is a CSS custom property
6501            // since they are user-defined.
6502            if (!isCustomProp) {
6503                name = finalPropName(origName);
6504            }
6505
6506            // Try prefixed name followed by the unprefixed name
6507            hooks = jQuery.cssHooks[name] || jQuery.cssHooks[origName];
6508
6509            // If a hook was provided get the computed value from there
6510            if (hooks && "get" in hooks) {
6511                val = hooks.get(elem, true, extra);
6512            }
6513
6514            // Otherwise, if a way to get the computed value exists, use that
6515            if (val === undefined) {
6516                val = curCSS(elem, name, styles);
6517            }
6518
6519            // Convert "normal" to computed value
6520            if (val === "normal" && name in cssNormalTransform) {
6521                val = cssNormalTransform[name];
6522            }
6523
6524            // Make numeric if forced or a qualifier was provided and val looks numeric
6525            if (extra === "" || extra) {
6526                num = parseFloat(val);
6527                return extra === true || isFinite(num) ? num || 0 : val;
6528            }
6529
6530            return val;
6531        }
6532    });
vendor: 4,148 bytes, lines 6533-6645
6533
6534    jQuery.each(["height", "width"], function (i, name) {
6535        jQuery.cssHooks[name] = {
6536            get: function (elem, computed, extra) {
6537                if (computed) {
6538
6539                    // Certain elements can have dimension info if we invisibly show them
6540                    // but it must have a current display style that would benefit
6541                    return rdisplayswap.test(jQuery.css(elem, "display")) &&
6542
6543                    // Support: Safari 8+
6544                    // Table columns in Safari have non-zero offsetWidth & zero
6545                    // getBoundingClientRect().width unless display is changed.
6546                    // Support: IE <=11 only
6547                    // Running getBoundingClientRect on a disconnected node
6548                    // in IE throws an error.
6549                    (!elem.getClientRects().length || !elem.getBoundingClientRect().width) ?
6550                        swap(elem, cssShow, function () {
6551                            return getWidthOrHeight(elem, name, extra);
6552                        }) :
6553                        getWidthOrHeight(elem, name, extra);
6554                }
6555            },
6556
6557            set: function (elem, value, extra) {
6558                var matches,
6559                    styles = extra && getStyles(elem),
6560                    subtract = extra && augmentWidthOrHeight(
6561                        elem,
6562                        name,
6563                        extra,
6564                        jQuery.css(elem, "boxSizing", false, styles) === "border-box",
6565                        styles
6566                    );
6567
6568                // Convert to pixels if value adjustment is needed
6569                if (subtract && (matches = rcssNum.exec(value)) &&
6570                    (matches[3] || "px") !== "px") {
6571
6572                    elem.style[name] = value;
6573                    value = jQuery.css(elem, name);
6574                }
6575
6576                return setPositiveNumber(elem, value, subtract);
6577            }
6578        };
6579    });
6580
6581    jQuery.cssHooks.marginLeft = addGetHookIf(support.reliableMarginLeft,
6582        function (elem, computed) {
6583            if (computed) {
6584                return (parseFloat(curCSS(elem, "marginLeft")) ||
6585                    elem.getBoundingClientRect().left -
6586                    swap(elem, {marginLeft: 0}, function () {
6587                        return elem.getBoundingClientRect().left;
6588                    })
6589                ) + "px";
6590            }
6591        }
6592    );
6593
6594// These hooks are used by animate to expand properties
6595    jQuery.each({
6596        margin: "",
6597        padding: "",
6598        border: "Width"
6599    }, function (prefix, suffix) {
6600        jQuery.cssHooks[prefix + suffix] = {
6601            expand: function (value) {
6602                var i = 0,
6603                    expanded = {},
6604
6605                    // Assumes a single number if not a string
6606                    parts = typeof value === "string" ? value.split(" ") : [value];
6607
6608                for (; i < 4; i++) {
6609                    expanded[prefix + cssExpand[i] + suffix] =
6610                        parts[i] || parts[i - 2] || parts[0];
6611                }
6612
6613                return expanded;
6614            }
6615        };
6616
6617        if (!rmargin.test(prefix)) {
6618            jQuery.cssHooks[prefix + suffix].set = setPositiveNumber;
6619        }
6620    });
6621
6622    jQuery.fn.extend({
6623        css: function (name, value) {
6624            return access(this, function (elem, name, value) {
6625                var styles, len,
6626                    map = {},
6627                    i = 0;
6628
6629                if (Array.isArray(name)) {
6630                    styles = getStyles(elem);
6631                    len = name.length;
6632
6633                    for (; i < len; i++) {
6634                        map[name[i]] = jQuery.css(elem, name[i], false, styles);
6635                    }
6636
6637                    return map;
6638                }
6639
6640                return value !== undefined ?
6641                    jQuery.style(elem, name, value) :
6642                    jQuery.css(elem, name);
6643            }, name, value, arguments.length > 1);
6644        }
6645    });
vendor: 8,446 bytes, lines 6646-6890
6646
6647
6648    function Tween(elem, options, prop, end, easing) {
6649        return new Tween.prototype.init(elem, options, prop, end, easing);
6650    }
6651
6652    jQuery.Tween = Tween;
6653
6654    Tween.prototype = {
6655        constructor: Tween,
6656        init: function (elem, options, prop, end, easing, unit) {
6657            this.elem = elem;
6658            this.prop = prop;
6659            this.easing = easing || jQuery.easing._default;
6660            this.options = options;
6661            this.start = this.now = this.cur();
6662            this.end = end;
6663            this.unit = unit || (jQuery.cssNumber[prop] ? "" : "px");
6664        },
6665        cur: function () {
6666            var hooks = Tween.propHooks[this.prop];
6667
6668            return hooks && hooks.get ?
6669                hooks.get(this) :
6670                Tween.propHooks._default.get(this);
6671        },
6672        run: function (percent) {
6673            var eased,
6674                hooks = Tween.propHooks[this.prop];
6675
6676            if (this.options.duration) {
6677                this.pos = eased = jQuery.easing[this.easing](
6678                    percent, this.options.duration * percent, 0, 1, this.options.duration
6679                );
6680            } else {
6681                this.pos = eased = percent;
6682            }
6683            this.now = (this.end - this.start) * eased + this.start;
6684
6685            if (this.options.step) {
6686                this.options.step.call(this.elem, this.now, this);
6687            }
6688
6689            if (hooks && hooks.set) {
6690                hooks.set(this);
6691            } else {
6692                Tween.propHooks._default.set(this);
6693            }
6694            return this;
6695        }
6696    };
6697
6698    Tween.prototype.init.prototype = Tween.prototype;
6699
6700    Tween.propHooks = {
6701        _default: {
6702            get: function (tween) {
6703                var result;
6704
6705                // Use a property on the element directly when it is not a DOM element,
6706                // or when there is no matching style property that exists.
6707                if (tween.elem.nodeType !== 1 ||
6708                    tween.elem[tween.prop] != null && tween.elem.style[tween.prop] == null) {
6709                    return tween.elem[tween.prop];
6710                }
6711
6712                // Passing an empty string as a 3rd parameter to .css will automatically
6713                // attempt a parseFloat and fallback to a string if the parse fails.
6714                // Simple values such as "10px" are parsed to Float;
6715                // complex values such as "rotate(1rad)" are returned as-is.
6716                result = jQuery.css(tween.elem, tween.prop, "");
6717
6718                // Empty strings, null, undefined and "auto" are converted to 0.
6719                return !result || result === "auto" ? 0 : result;
6720            },
6721            set: function (tween) {
6722
6723                // Use step hook for back compat.
6724                // Use cssHook if its there.
6725                // Use .style if available and use plain properties where available.
6726                if (jQuery.fx.step[tween.prop]) {
6727                    jQuery.fx.step[tween.prop](tween);
6728                } else if (tween.elem.nodeType === 1 &&
6729                    (tween.elem.style[jQuery.cssProps[tween.prop]] != null ||
6730                        jQuery.cssHooks[tween.prop])) {
6731                    jQuery.style(tween.elem, tween.prop, tween.now + tween.unit);
6732                } else {
6733                    tween.elem[tween.prop] = tween.now;
6734                }
6735            }
6736        }
6737    };
6738
6739// Support: IE <=9 only
6740// Panic based approach to setting things on disconnected nodes
6741    Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = {
6742        set: function (tween) {
6743            if (tween.elem.nodeType && tween.elem.parentNode) {
6744                tween.elem[tween.prop] = tween.now;
6745            }
6746        }
6747    };
6748
6749    jQuery.easing = {
6750        linear: function (p) {
6751            return p;
6752        },
6753        swing: function (p) {
6754            return 0.5 - Math.cos(p * Math.PI) / 2;
6755        },
6756        _default: "swing"
6757    };
6758
6759    jQuery.fx = Tween.prototype.init;
6760
6761// Back compat <1.8 extension point
6762    jQuery.fx.step = {};
6763
6764
6765    var
6766        fxNow, inProgress,
6767        rfxtypes = /^(?:toggle|show|hide)$/,
6768        rrun = /queueHooks$/;
6769
6770    function schedule() {
6771        if (inProgress) {
6772            if (document.hidden === false && window.requestAnimationFrame) {
6773                window.requestAnimationFrame(schedule);
6774            } else {
6775                window.setTimeout(schedule, jQuery.fx.interval);
6776            }
6777
6778            jQuery.fx.tick();
6779        }
6780    }
6781
6782// Animations created synchronously will run synchronously
6783    function createFxNow() {
6784        window.setTimeout(function () {
6785            fxNow = undefined;
6786        });
6787        return (fxNow = jQuery.now());
6788    }
6789
6790// Generate parameters to create a standard animation
6791    function genFx(type, includeWidth) {
6792        var which,
6793            i = 0,
6794            attrs = {height: type};
6795
6796        // If we include width, step value is 1 to do all cssExpand values,
6797        // otherwise step value is 2 to skip over Left and Right
6798        includeWidth = includeWidth ? 1 : 0;
6799        for (; i < 4; i += 2 - includeWidth) {
6800            which = cssExpand[i];
6801            attrs["margin" + which] = attrs["padding" + which] = type;
6802        }
6803
6804        if (includeWidth) {
6805            attrs.opacity = attrs.width = type;
6806        }
6807
6808        return attrs;
6809    }
6810
6811    function createTween(value, prop, animation) {
6812        var tween,
6813            collection = (Animation.tweeners[prop] || []).concat(Animation.tweeners["*"]),
6814            index = 0,
6815            length = collection.length;
6816        for (; index < length; index++) {
6817            if ((tween = collection[index].call(animation, prop, value))) {
6818
6819                // We're done with this property
6820                return tween;
6821            }
6822        }
6823    }
6824
6825    function defaultPrefilter(elem, props, opts) {
6826        var prop, value, toggle, hooks, oldfire, propTween, restoreDisplay, display,
6827            isBox = "width" in props || "height" in props,
6828            anim = this,
6829            orig = {},
6830            style = elem.style,
6831            hidden = elem.nodeType && isHiddenWithinTree(elem),
6832            dataShow = dataPriv.get(elem, "fxshow");
6833
6834        // Queue-skipping animations hijack the fx hooks
6835        if (!opts.queue) {
6836            hooks = jQuery._queueHooks(elem, "fx");
6837            if (hooks.unqueued == null) {
6838                hooks.unqueued = 0;
6839                oldfire = hooks.empty.fire;
6840                hooks.empty.fire = function () {
6841                    if (!hooks.unqueued) {
6842                        oldfire();
6843                    }
6844                };
6845            }
6846            hooks.unqueued++;
6847
6848            anim.always(function () {
6849
6850                // Ensure the complete handler is called before this completes
6851                anim.always(function () {
6852                    hooks.unqueued--;
6853                    if (!jQuery.queue(elem, "fx").length) {
6854                        hooks.empty.fire();
6855                    }
6856                });
6857            });
6858        }
6859
6860        // Detect show/hide animations
6861        for (prop in props) {
6862            value = props[prop];
6863            if (rfxtypes.test(value)) {
6864                delete props[prop];
6865                toggle = toggle || value === "toggle";
6866                if (value === (hidden ? "hide" : "show")) {
6867
6868                    // Pretend to be hidden if this is a "show" and
6869                    // there is still data from a stopped show/hide
6870                    if (value === "show" && dataShow && dataShow[prop] !== undefined) {
6871                        hidden = true;
6872
6873                        // Ignore all other no-op show/hide data
6874                    } else {
6875                        continue;
6876                    }
6877                }
6878                orig[prop] = dataShow && dataShow[prop] || jQuery.style(elem, prop);
6879            }
6880        }
6881
6882        // Bail out if this is a no-op like .hide().hide()
6883        propTween = !jQuery.isEmptyObject(props);
6884        if (!propTween && jQuery.isEmptyObject(orig)) {
6885            return;
6886        }
6887
6888        // Restrict "overflow" and "display" styles during box animations
6889        if (isBox && elem.nodeType === 1) {
6890
vendor: 4,256 bytes, lines 6891-7001
6891            // Support: IE <=9 - 11, Edge 12 - 13
6892            // Record all 3 overflow attributes because IE does not infer the shorthand
6893            // from identically-valued overflowX and overflowY
6894            opts.overflow = [style.overflow, style.overflowX, style.overflowY];
6895
6896            // Identify a display type, preferring old show/hide data over the CSS cascade
6897            restoreDisplay = dataShow && dataShow.display;
6898            if (restoreDisplay == null) {
6899                restoreDisplay = dataPriv.get(elem, "display");
6900            }
6901            display = jQuery.css(elem, "display");
6902            if (display === "none") {
6903                if (restoreDisplay) {
6904                    display = restoreDisplay;
6905                } else {
6906
6907                    // Get nonempty value(s) by temporarily forcing visibility
6908                    showHide([elem], true);
6909                    restoreDisplay = elem.style.display || restoreDisplay;
6910                    display = jQuery.css(elem, "display");
6911                    showHide([elem]);
6912                }
6913            }
6914
6915            // Animate inline elements as inline-block
6916            if (display === "inline" || display === "inline-block" && restoreDisplay != null) {
6917                if (jQuery.css(elem, "float") === "none") {
6918
6919                    // Restore the original display value at the end of pure show/hide animations
6920                    if (!propTween) {
6921                        anim.done(function () {
6922                            style.display = restoreDisplay;
6923                        });
6924                        if (restoreDisplay == null) {
6925                            display = style.display;
6926                            restoreDisplay = display === "none" ? "" : display;
6927                        }
6928                    }
6929                    style.display = "inline-block";
6930                }
6931            }
6932        }
6933
6934        if (opts.overflow) {
6935            style.overflow = "hidden";
6936            anim.always(function () {
6937                style.overflow = opts.overflow[0];
6938                style.overflowX = opts.overflow[1];
6939                style.overflowY = opts.overflow[2];
6940            });
6941        }
6942
6943        // Implement show/hide animations
6944        propTween = false;
6945        for (prop in orig) {
6946
6947            // General show/hide setup for this element animation
6948            if (!propTween) {
6949                if (dataShow) {
6950                    if ("hidden" in dataShow) {
6951                        hidden = dataShow.hidden;
6952                    }
6953                } else {
6954                    dataShow = dataPriv.access(elem, "fxshow", {display: restoreDisplay});
6955                }
6956
6957                // Store hidden/visible for toggle so `.stop().toggle()` "reverses"
6958                if (toggle) {
6959                    dataShow.hidden = !hidden;
6960                }
6961
6962                // Show elements before animating them
6963                if (hidden) {
6964                    showHide([elem], true);
6965                }
6966
6967                /* eslint-disable no-loop-func */
6968
6969                anim.done(function () {
6970
6971                    /* eslint-enable no-loop-func */
6972
6973                    // The final step of a "hide" animation is actually hiding the element
6974                    if (!hidden) {
6975                        showHide([elem]);
6976                    }
6977                    dataPriv.remove(elem, "fxshow");
6978                    for (prop in orig) {
6979                        jQuery.style(elem, prop, orig[prop]);
6980                    }
6981                });
6982            }
6983
6984            // Per-property setup
6985            propTween = createTween(hidden ? dataShow[prop] : 0, prop, anim);
6986            if (!(prop in dataShow)) {
6987                dataShow[prop] = propTween.start;
6988                if (hidden) {
6989                    propTween.end = propTween.start;
6990                    propTween.start = 0;
6991                }
6992            }
6993        }
6994    }
6995
6996    function propFilter(props, specialEasing) {
6997        var index, name, easing, value, hooks;
6998
6999        // camelCase, specialEasing and expand cssHook pass
7000        for (index in props) {
7001            name = jQuery.camelCase(index);
vendor: 5,587 bytes, lines 7002-7145
7002            easing = specialEasing[name];
7003            value = props[index];
7004            if (Array.isArray(value)) {
7005                easing = value[1];
7006                value = props[index] = value[0];
7007            }
7008
7009            if (index !== name) {
7010                props[name] = value;
7011                delete props[index];
7012            }
7013
7014            hooks = jQuery.cssHooks[name];
7015            if (hooks && "expand" in hooks) {
7016                value = hooks.expand(value);
7017                delete props[name];
7018
7019                // Not quite $.extend, this won't overwrite existing keys.
7020                // Reusing 'index' because we have the correct "name"
7021                for (index in value) {
7022                    if (!(index in props)) {
7023                        props[index] = value[index];
7024                        specialEasing[index] = easing;
7025                    }
7026                }
7027            } else {
7028                specialEasing[name] = easing;
7029            }
7030        }
7031    }
7032
7033    function Animation(elem, properties, options) {
7034        var result,
7035            stopped,
7036            index = 0,
7037            length = Animation.prefilters.length,
7038            deferred = jQuery.Deferred().always(function () {
7039
7040                // Don't match elem in the :animated selector
7041                delete tick.elem;
7042            }),
7043            tick = function () {
7044                if (stopped) {
7045                    return false;
7046                }
7047                var currentTime = fxNow || createFxNow(),
7048                    remaining = Math.max(0, animation.startTime + animation.duration - currentTime),
7049
7050                    // Support: Android 2.3 only
7051                    // Archaic crash bug won't allow us to use `1 - ( 0.5 || 0 )` (#12497)
7052                    temp = remaining / animation.duration || 0,
7053                    percent = 1 - temp,
7054                    index = 0,
7055                    length = animation.tweens.length;
7056
7057                for (; index < length; index++) {
7058                    animation.tweens[index].run(percent);
7059                }
7060
7061                deferred.notifyWith(elem, [animation, percent, remaining]);
7062
7063                // If there's more to do, yield
7064                if (percent < 1 && length) {
7065                    return remaining;
7066                }
7067
7068                // If this was an empty animation, synthesize a final progress notification
7069                if (!length) {
7070                    deferred.notifyWith(elem, [animation, 1, 0]);
7071                }
7072
7073                // Resolve the animation and report its conclusion
7074                deferred.resolveWith(elem, [animation]);
7075                return false;
7076            },
7077            animation = deferred.promise({
7078                elem: elem,
7079                props: jQuery.extend({}, properties),
7080                opts: jQuery.extend(true, {
7081                    specialEasing: {},
7082                    easing: jQuery.easing._default
7083                }, options),
7084                originalProperties: properties,
7085                originalOptions: options,
7086                startTime: fxNow || createFxNow(),
7087                duration: options.duration,
7088                tweens: [],
7089                createTween: function (prop, end) {
7090                    var tween = jQuery.Tween(elem, animation.opts, prop, end,
7091                        animation.opts.specialEasing[prop] || animation.opts.easing);
7092                    animation.tweens.push(tween);
7093                    return tween;
7094                },
7095                stop: function (gotoEnd) {
7096                    var index = 0,
7097
7098                        // If we are going to the end, we want to run all the tweens
7099                        // otherwise we skip this part
7100                        length = gotoEnd ? animation.tweens.length : 0;
7101                    if (stopped) {
7102                        return this;
7103                    }
7104                    stopped = true;
7105                    for (; index < length; index++) {
7106                        animation.tweens[index].run(1);
7107                    }
7108
7109                    // Resolve when we played the last frame; otherwise, reject
7110                    if (gotoEnd) {
7111                        deferred.notifyWith(elem, [animation, 1, 0]);
7112                        deferred.resolveWith(elem, [animation, gotoEnd]);
7113                    } else {
7114                        deferred.rejectWith(elem, [animation, gotoEnd]);
7115                    }
7116                    return this;
7117                }
7118            }),
7119            props = animation.props;
7120
7121        propFilter(props, animation.opts.specialEasing);
7122
7123        for (; index < length; index++) {
7124            result = Animation.prefilters[index].call(animation, elem, props, animation.opts);
7125            if (result) {
7126                if (jQuery.isFunction(result.stop)) {
7127                    jQuery._queueHooks(animation.elem, animation.opts.queue).stop =
7128                        jQuery.proxy(result.stop, result);
7129                }
7130                return result;
7131            }
7132        }
7133
7134        jQuery.map(props, createTween, animation);
7135
7136        if (jQuery.isFunction(animation.opts.start)) {
7137            animation.opts.start.call(elem, animation);
7138        }
7139
7140        // Attach callbacks from options
7141        animation
7142            .progress(animation.opts.progress)
7143            .done(animation.opts.done, animation.opts.complete)
7144            .fail(animation.opts.fail)
7145            .always(animation.opts.always);
vendor: 7,423 bytes, lines 7146-7363
7146
7147        jQuery.fx.timer(
7148            jQuery.extend(tick, {
7149                elem: elem,
7150                anim: animation,
7151                queue: animation.opts.queue
7152            })
7153        );
7154
7155        return animation;
7156    }
7157
7158    jQuery.Animation = jQuery.extend(Animation, {
7159
7160        tweeners: {
7161            "*": [function (prop, value) {
7162                var tween = this.createTween(prop, value);
7163                adjustCSS(tween.elem, prop, rcssNum.exec(value), tween);
7164                return tween;
7165            }]
7166        },
7167
7168        tweener: function (props, callback) {
7169            if (jQuery.isFunction(props)) {
7170                callback = props;
7171                props = ["*"];
7172            } else {
7173                props = props.match(rnothtmlwhite);
7174            }
7175
7176            var prop,
7177                index = 0,
7178                length = props.length;
7179
7180            for (; index < length; index++) {
7181                prop = props[index];
7182                Animation.tweeners[prop] = Animation.tweeners[prop] || [];
7183                Animation.tweeners[prop].unshift(callback);
7184            }
7185        },
7186
7187        prefilters: [defaultPrefilter],
7188
7189        prefilter: function (callback, prepend) {
7190            if (prepend) {
7191                Animation.prefilters.unshift(callback);
7192            } else {
7193                Animation.prefilters.push(callback);
7194            }
7195        }
7196    });
7197
7198    jQuery.speed = function (speed, easing, fn) {
7199        var opt = speed && typeof speed === "object" ? jQuery.extend({}, speed) : {
7200            complete: fn || !fn && easing ||
7201                jQuery.isFunction(speed) && speed,
7202            duration: speed,
7203            easing: fn && easing || easing && !jQuery.isFunction(easing) && easing
7204        };
7205
7206        // Go to the end state if fx are off
7207        if (jQuery.fx.off) {
7208            opt.duration = 0;
7209
7210        } else {
7211            if (typeof opt.duration !== "number") {
7212                if (opt.duration in jQuery.fx.speeds) {
7213                    opt.duration = jQuery.fx.speeds[opt.duration];
7214
7215                } else {
7216                    opt.duration = jQuery.fx.speeds._default;
7217                }
7218            }
7219        }
7220
7221        // Normalize opt.queue - true/undefined/null -> "fx"
7222        if (opt.queue == null || opt.queue === true) {
7223            opt.queue = "fx";
7224        }
7225
7226        // Queueing
7227        opt.old = opt.complete;
7228
7229        opt.complete = function () {
7230            if (jQuery.isFunction(opt.old)) {
7231                opt.old.call(this);
7232            }
7233
7234            if (opt.queue) {
7235                jQuery.dequeue(this, opt.queue);
7236            }
7237        };
7238
7239        return opt;
7240    };
7241
7242    jQuery.fn.extend({
7243        fadeTo: function (speed, to, easing, callback) {
7244
7245            // Show any hidden elements after setting opacity to 0
7246            return this.filter(isHiddenWithinTree).css("opacity", 0).show()
7247
7248                // Animate to the value specified
7249                .end().animate({opacity: to}, speed, easing, callback);
7250        },
7251        animate: function (prop, speed, easing, callback) {
7252            var empty = jQuery.isEmptyObject(prop),
7253                optall = jQuery.speed(speed, easing, callback),
7254                doAnimation = function () {
7255
7256                    // Operate on a copy of prop so per-property easing won't be lost
7257                    var anim = Animation(this, jQuery.extend({}, prop), optall);
7258
7259                    // Empty animations, or finishing resolves immediately
7260                    if (empty || dataPriv.get(this, "finish")) {
7261                        anim.stop(true);
7262                    }
7263                };
7264            doAnimation.finish = doAnimation;
7265
7266            return empty || optall.queue === false ?
7267                this.each(doAnimation) :
7268                this.queue(optall.queue, doAnimation);
7269        },
7270        stop: function (type, clearQueue, gotoEnd) {
7271            var stopQueue = function (hooks) {
7272                var stop = hooks.stop;
7273                delete hooks.stop;
7274                stop(gotoEnd);
7275            };
7276
7277            if (typeof type !== "string") {
7278                gotoEnd = clearQueue;
7279                clearQueue = type;
7280                type = undefined;
7281            }
7282            if (clearQueue && type !== false) {
7283                this.queue(type || "fx", []);
7284            }
7285
7286            return this.each(function () {
7287                var dequeue = true,
7288                    index = type != null && type + "queueHooks",
7289                    timers = jQuery.timers,
7290                    data = dataPriv.get(this);
7291
7292                if (index) {
7293                    if (data[index] && data[index].stop) {
7294                        stopQueue(data[index]);
7295                    }
7296                } else {
7297                    for (index in data) {
7298                        if (data[index] && data[index].stop && rrun.test(index)) {
7299                            stopQueue(data[index]);
7300                        }
7301                    }
7302                }
7303
7304                for (index = timers.length; index--;) {
7305                    if (timers[index].elem === this &&
7306                        (type == null || timers[index].queue === type)) {
7307
7308                        timers[index].anim.stop(gotoEnd);
7309                        dequeue = false;
7310                        timers.splice(index, 1);
7311                    }
7312                }
7313
7314                // Start the next in the queue if the last step wasn't forced.
7315                // Timers currently will call their complete callbacks, which
7316                // will dequeue but only if they were gotoEnd.
7317                if (dequeue || !gotoEnd) {
7318                    jQuery.dequeue(this, type);
7319                }
7320            });
7321        },
7322        finish: function (type) {
7323            if (type !== false) {
7324                type = type || "fx";
7325            }
7326            return this.each(function () {
7327                var index,
7328                    data = dataPriv.get(this),
7329                    queue = data[type + "queue"],
7330                    hooks = data[type + "queueHooks"],
7331                    timers = jQuery.timers,
7332                    length = queue ? queue.length : 0;
7333
7334                // Enable finishing flag on private data
7335                data.finish = true;
7336
7337                // Empty the queue first
7338                jQuery.queue(this, type, []);
7339
7340                if (hooks && hooks.stop) {
7341                    hooks.stop.call(this, true);
7342                }
7343
7344                // Look for any active animations, and finish them
7345                for (index = timers.length; index--;) {
7346                    if (timers[index].elem === this && timers[index].queue === type) {
7347                        timers[index].anim.stop(true);
7348                        timers.splice(index, 1);
7349                    }
7350                }
7351
7352                // Look for any animations in the old queue and finish them
7353                for (index = 0; index < length; index++) {
7354                    if (queue[index] && queue[index].finish) {
7355                        queue[index].finish.call(this);
7356                    }
7357                }
7358
7359                // Turn off finishing flag
7360                delete data.finish;
7361            });
7362        }
7363    });
vendor: 11,592 bytes, lines 7364-7739
7364
7365    jQuery.each(["toggle", "show", "hide"], function (i, name) {
7366        var cssFn = jQuery.fn[name];
7367        jQuery.fn[name] = function (speed, easing, callback) {
7368            return speed == null || typeof speed === "boolean" ?
7369                cssFn.apply(this, arguments) :
7370                this.animate(genFx(name, true), speed, easing, callback);
7371        };
7372    });
7373
7374// Generate shortcuts for custom animations
7375    jQuery.each({
7376        slideDown: genFx("show"),
7377        slideUp: genFx("hide"),
7378        slideToggle: genFx("toggle"),
7379        fadeIn: {opacity: "show"},
7380        fadeOut: {opacity: "hide"},
7381        fadeToggle: {opacity: "toggle"}
7382    }, function (name, props) {
7383        jQuery.fn[name] = function (speed, easing, callback) {
7384            return this.animate(props, speed, easing, callback);
7385        };
7386    });
7387
7388    jQuery.timers = [];
7389    jQuery.fx.tick = function () {
7390        var timer,
7391            i = 0,
7392            timers = jQuery.timers;
7393
7394        fxNow = jQuery.now();
7395
7396        for (; i < timers.length; i++) {
7397            timer = timers[i];
7398
7399            // Run the timer and safely remove it when done (allowing for external removal)
7400            if (!timer() && timers[i] === timer) {
7401                timers.splice(i--, 1);
7402            }
7403        }
7404
7405        if (!timers.length) {
7406            jQuery.fx.stop();
7407        }
7408        fxNow = undefined;
7409    };
7410
7411    jQuery.fx.timer = function (timer) {
7412        jQuery.timers.push(timer);
7413        jQuery.fx.start();
7414    };
7415
7416    jQuery.fx.interval = 13;
7417    jQuery.fx.start = function () {
7418        if (inProgress) {
7419            return;
7420        }
7421
7422        inProgress = true;
7423        schedule();
7424    };
7425
7426    jQuery.fx.stop = function () {
7427        inProgress = null;
7428    };
7429
7430    jQuery.fx.speeds = {
7431        slow: 600,
7432        fast: 200,
7433
7434        // Default speed
7435        _default: 400
7436    };
7437
7438
7439// Based off of the plugin by Clint Helfers, with permission.
7440// https://web.archive.org/web/20100324014747/http://blindsignals.com/index.php/2009/07/jquery-delay/
7441    jQuery.fn.delay = function (time, type) {
7442        time = jQuery.fx ? jQuery.fx.speeds[time] || time : time;
7443        type = type || "fx";
7444
7445        return this.queue(type, function (next, hooks) {
7446            var timeout = window.setTimeout(next, time);
7447            hooks.stop = function () {
7448                window.clearTimeout(timeout);
7449            };
7450        });
7451    };
7452
7453
7454    (function () {
7455        var input = document.createElement("input"),
7456            select = document.createElement("select"),
7457            opt = select.appendChild(document.createElement("option"));
7458
7459        input.type = "checkbox";
7460
7461        // Support: Android <=4.3 only
7462        // Default value for a checkbox should be "on"
7463        support.checkOn = input.value !== "";
7464
7465        // Support: IE <=11 only
7466        // Must access selectedIndex to make default options select
7467        support.optSelected = opt.selected;
7468
7469        // Support: IE <=11 only
7470        // An input loses its value after becoming a radio
7471        input = document.createElement("input");
7472        input.value = "t";
7473        input.type = "radio";
7474        support.radioValue = input.value === "t";
7475    })();
7476
7477
7478    var boolHook,
7479        attrHandle = jQuery.expr.attrHandle;
7480
7481    jQuery.fn.extend({
7482        attr: function (name, value) {
7483            return access(this, jQuery.attr, name, value, arguments.length > 1);
7484        },
7485
7486        removeAttr: function (name) {
7487            return this.each(function () {
7488                jQuery.removeAttr(this, name);
7489            });
7490        }
7491    });
7492
7493    jQuery.extend({
7494        attr: function (elem, name, value) {
7495            var ret, hooks,
7496                nType = elem.nodeType;
7497
7498            // Don't get/set attributes on text, comment and attribute nodes
7499            if (nType === 3 || nType === 8 || nType === 2) {
7500                return;
7501            }
7502
7503            // Fallback to prop when attributes are not supported
7504            if (typeof elem.getAttribute === "undefined") {
7505                return jQuery.prop(elem, name, value);
7506            }
7507
7508            // Attribute hooks are determined by the lowercase version
7509            // Grab necessary hook if one is defined
7510            if (nType !== 1 || !jQuery.isXMLDoc(elem)) {
7511                hooks = jQuery.attrHooks[name.toLowerCase()] ||
7512                    (jQuery.expr.match.bool.test(name) ? boolHook : undefined);
7513            }
7514
7515            if (value !== undefined) {
7516                if (value === null) {
7517                    jQuery.removeAttr(elem, name);
7518                    return;
7519                }
7520
7521                if (hooks && "set" in hooks &&
7522                    (ret = hooks.set(elem, value, name)) !== undefined) {
7523                    return ret;
7524                }
7525
7526                elem.setAttribute(name, value + "");
7527                return value;
7528            }
7529
7530            if (hooks && "get" in hooks && (ret = hooks.get(elem, name)) !== null) {
7531                return ret;
7532            }
7533
7534            ret = jQuery.find.attr(elem, name);
7535
7536            // Non-existent attributes return null, we normalize to undefined
7537            return ret == null ? undefined : ret;
7538        },
7539
7540        attrHooks: {
7541            type: {
7542                set: function (elem, value) {
7543                    if (!support.radioValue && value === "radio" &&
7544                        nodeName(elem, "input")) {
7545                        var val = elem.value;
7546                        elem.setAttribute("type", value);
7547                        if (val) {
7548                            elem.value = val;
7549                        }
7550                        return value;
7551                    }
7552                }
7553            }
7554        },
7555
7556        removeAttr: function (elem, value) {
7557            var name,
7558                i = 0,
7559
7560                // Attribute names can contain non-HTML whitespace characters
7561                // https://html.spec.whatwg.org/multipage/syntax.html#attributes-2
7562                attrNames = value && value.match(rnothtmlwhite);
7563
7564            if (attrNames && elem.nodeType === 1) {
7565                while ((name = attrNames[i++])) {
7566                    elem.removeAttribute(name);
7567                }
7568            }
7569        }
7570    });
7571
7572// Hooks for boolean attributes
7573    boolHook = {
7574        set: function (elem, value, name) {
7575            if (value === false) {
7576
7577                // Remove boolean attributes when set to false
7578                jQuery.removeAttr(elem, name);
7579            } else {
7580                elem.setAttribute(name, name);
7581            }
7582            return name;
7583        }
7584    };
7585
7586    jQuery.each(jQuery.expr.match.bool.source.match(/\w+/g), function (i, name) {
7587        var getter = attrHandle[name] || jQuery.find.attr;
7588
7589        attrHandle[name] = function (elem, name, isXML) {
7590            var ret, handle,
7591                lowercaseName = name.toLowerCase();
7592
7593            if (!isXML) {
7594
7595                // Avoid an infinite loop by temporarily removing this function from the getter
7596                handle = attrHandle[lowercaseName];
7597                attrHandle[lowercaseName] = ret;
7598                ret = getter(elem, name, isXML) != null ?
7599                    lowercaseName :
7600                    null;
7601                attrHandle[lowercaseName] = handle;
7602            }
7603            return ret;
7604        };
7605    });
7606
7607
7608    var rfocusable = /^(?:input|select|textarea|button)$/i,
7609        rclickable = /^(?:a|area)$/i;
7610
7611    jQuery.fn.extend({
7612        prop: function (name, value) {
7613            return access(this, jQuery.prop, name, value, arguments.length > 1);
7614        },
7615
7616        removeProp: function (name) {
7617            return this.each(function () {
7618                delete this[jQuery.propFix[name] || name];
7619            });
7620        }
7621    });
7622
7623    jQuery.extend({
7624        prop: function (elem, name, value) {
7625            var ret, hooks,
7626                nType = elem.nodeType;
7627
7628            // Don't get/set properties on text, comment and attribute nodes
7629            if (nType === 3 || nType === 8 || nType === 2) {
7630                return;
7631            }
7632
7633            if (nType !== 1 || !jQuery.isXMLDoc(elem)) {
7634
7635                // Fix name and attach hooks
7636                name = jQuery.propFix[name] || name;
7637                hooks = jQuery.propHooks[name];
7638            }
7639
7640            if (value !== undefined) {
7641                if (hooks && "set" in hooks &&
7642                    (ret = hooks.set(elem, value, name)) !== undefined) {
7643                    return ret;
7644                }
7645
7646                return (elem[name] = value);
7647            }
7648
7649            if (hooks && "get" in hooks && (ret = hooks.get(elem, name)) !== null) {
7650                return ret;
7651            }
7652
7653            return elem[name];
7654        },
7655
7656        propHooks: {
7657            tabIndex: {
7658                get: function (elem) {
7659
7660                    // Support: IE <=9 - 11 only
7661                    // elem.tabIndex doesn't always return the
7662                    // correct value when it hasn't been explicitly set
7663                    // https://web.archive.org/web/20141116233347/http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/
7664                    // Use proper attribute retrieval(#12072)
7665                    var tabindex = jQuery.find.attr(elem, "tabindex");
7666
7667                    if (tabindex) {
7668                        return parseInt(tabindex, 10);
7669                    }
7670
7671                    if (
7672                        rfocusable.test(elem.nodeName) ||
7673                        rclickable.test(elem.nodeName) &&
7674                        elem.href
7675                    ) {
7676                        return 0;
7677                    }
7678
7679                    return -1;
7680                }
7681            }
7682        },
7683
7684        propFix: {
7685            "for": "htmlFor",
7686            "class": "className"
7687        }
7688    });
7689
7690// Support: IE <=11 only
7691// Accessing the selectedIndex property
7692// forces the browser to respect setting selected
7693// on the option
7694// The getter ensures a default option is selected
7695// when in an optgroup
7696// eslint rule "no-unused-expressions" is disabled for this code
7697// since it considers such accessions noop
7698    if (!support.optSelected) {
7699        jQuery.propHooks.selected = {
7700            get: function (elem) {
7701
7702                /* eslint no-unused-expressions: "off" */
7703
7704                var parent = elem.parentNode;
7705                if (parent && parent.parentNode) {
7706                    parent.parentNode.selectedIndex;
7707                }
7708                return null;
7709            },
7710            set: function (elem) {
7711
7712                /* eslint no-unused-expressions: "off" */
7713
7714                var parent = elem.parentNode;
7715                if (parent) {
7716                    parent.selectedIndex;
7717
7718                    if (parent.parentNode) {
7719                        parent.parentNode.selectedIndex;
7720                    }
7721                }
7722            }
7723        };
7724    }
7725
7726    jQuery.each([
7727        "tabIndex",
7728        "readOnly",
7729        "maxLength",
7730        "cellSpacing",
7731        "cellPadding",
7732        "rowSpan",
7733        "colSpan",
7734        "useMap",
7735        "frameBorder",
7736        "contentEditable"
7737    ], function () {
7738        jQuery.propFix[this.toLowerCase()] = this;
7739    });
vendor: 6,258 bytes, lines 7740-7911
7740
7741
7742    // Strip and collapse whitespace according to HTML spec
7743    // https://html.spec.whatwg.org/multipage/infrastructure.html#strip-and-collapse-whitespace
7744    function stripAndCollapse(value) {
7745        var tokens = value.match(rnothtmlwhite) || [];
7746        return tokens.join(" ");
7747    }
7748
7749
7750    function getClass(elem) {
7751        return elem.getAttribute && elem.getAttribute("class") || "";
7752    }
7753
7754    jQuery.fn.extend({
7755        addClass: function (value) {
7756            var classes, elem, cur, curValue, clazz, j, finalValue,
7757                i = 0;
7758
7759            if (jQuery.isFunction(value)) {
7760                return this.each(function (j) {
7761                    jQuery(this).addClass(value.call(this, j, getClass(this)));
7762                });
7763            }
7764
7765            if (typeof value === "string" && value) {
7766                classes = value.match(rnothtmlwhite) || [];
7767
7768                while ((elem = this[i++])) {
7769                    curValue = getClass(elem);
7770                    cur = elem.nodeType === 1 && (" " + stripAndCollapse(curValue) + " ");
7771
7772                    if (cur) {
7773                        j = 0;
7774                        while ((clazz = classes[j++])) {
7775                            if (cur.indexOf(" " + clazz + " ") < 0) {
7776                                cur += clazz + " ";
7777                            }
7778                        }
7779
7780                        // Only assign if different to avoid unneeded rendering.
7781                        finalValue = stripAndCollapse(cur);
7782                        if (curValue !== finalValue) {
7783                            elem.setAttribute("class", finalValue);
7784                        }
7785                    }
7786                }
7787            }
7788
7789            return this;
7790        },
7791
7792        removeClass: function (value) {
7793            var classes, elem, cur, curValue, clazz, j, finalValue,
7794                i = 0;
7795
7796            if (jQuery.isFunction(value)) {
7797                return this.each(function (j) {
7798                    jQuery(this).removeClass(value.call(this, j, getClass(this)));
7799                });
7800            }
7801
7802            if (!arguments.length) {
7803                return this.attr("class", "");
7804            }
7805
7806            if (typeof value === "string" && value) {
7807                classes = value.match(rnothtmlwhite) || [];
7808
7809                while ((elem = this[i++])) {
7810                    curValue = getClass(elem);
7811
7812                    // This expression is here for better compressibility (see addClass)
7813                    cur = elem.nodeType === 1 && (" " + stripAndCollapse(curValue) + " ");
7814
7815                    if (cur) {
7816                        j = 0;
7817                        while ((clazz = classes[j++])) {
7818
7819                            // Remove *all* instances
7820                            while (cur.indexOf(" " + clazz + " ") > -1) {
7821                                cur = cur.replace(" " + clazz + " ", " ");
7822                            }
7823                        }
7824
7825                        // Only assign if different to avoid unneeded rendering.
7826                        finalValue = stripAndCollapse(cur);
7827                        if (curValue !== finalValue) {
7828                            elem.setAttribute("class", finalValue);
7829                        }
7830                    }
7831                }
7832            }
7833
7834            return this;
7835        },
7836
7837        toggleClass: function (value, stateVal) {
7838            var type = typeof value;
7839
7840            if (typeof stateVal === "boolean" && type === "string") {
7841                return stateVal ? this.addClass(value) : this.removeClass(value);
7842            }
7843
7844            if (jQuery.isFunction(value)) {
7845                return this.each(function (i) {
7846                    jQuery(this).toggleClass(
7847                        value.call(this, i, getClass(this), stateVal),
7848                        stateVal
7849                    );
7850                });
7851            }
7852
7853            return this.each(function () {
7854                var className, i, self, classNames;
7855
7856                if (type === "string") {
7857
7858                    // Toggle individual class names
7859                    i = 0;
7860                    self = jQuery(this);
7861                    classNames = value.match(rnothtmlwhite) || [];
7862
7863                    while ((className = classNames[i++])) {
7864
7865                        // Check each className given, space separated list
7866                        if (self.hasClass(className)) {
7867                            self.removeClass(className);
7868                        } else {
7869                            self.addClass(className);
7870                        }
7871                    }
7872
7873                    // Toggle whole class name
7874                } else if (value === undefined || type === "boolean") {
7875                    className = getClass(this);
7876                    if (className) {
7877
7878                        // Store className if set
7879                        dataPriv.set(this, "__className__", className);
7880                    }
7881
7882                    // If the element has a class name or if we're passed `false`,
7883                    // then remove the whole classname (if there was one, the above saved it).
7884                    // Otherwise bring back whatever was previously saved (if anything),
7885                    // falling back to the empty string if nothing was stored.
7886                    if (this.setAttribute) {
7887                        this.setAttribute("class",
7888                            className || value === false ?
7889                                "" :
7890                                dataPriv.get(this, "__className__") || ""
7891                        );
7892                    }
7893                }
7894            });
7895        },
7896
7897        hasClass: function (selector) {
7898            var className, elem,
7899                i = 0;
7900
7901            className = " " + selector + " ";
7902            while ((elem = this[i++])) {
7903                if (elem.nodeType === 1 &&
7904                    (" " + stripAndCollapse(getClass(elem)) + " ").indexOf(className) > -1) {
7905                    return true;
7906                }
7907            }
7908
7909            return false;
7910        }
7911    });
vendor: 5,632 bytes, lines 7912-8074
7912
7913
7914    var rreturn = /\r/g;
7915
7916    jQuery.fn.extend({
7917        val: function (value) {
7918            var hooks, ret, isFunction,
7919                elem = this[0];
7920
7921            if (!arguments.length) {
7922                if (elem) {
7923                    hooks = jQuery.valHooks[elem.type] ||
7924                        jQuery.valHooks[elem.nodeName.toLowerCase()];
7925
7926                    if (hooks &&
7927                        "get" in hooks &&
7928                        (ret = hooks.get(elem, "value")) !== undefined
7929                    ) {
7930                        return ret;
7931                    }
7932
7933                    ret = elem.value;
7934
7935                    // Handle most common string cases
7936                    if (typeof ret === "string") {
7937                        return ret.replace(rreturn, "");
7938                    }
7939
7940                    // Handle cases where value is null/undef or number
7941                    return ret == null ? "" : ret;
7942                }
7943
7944                return;
7945            }
7946
7947            isFunction = jQuery.isFunction(value);
7948
7949            return this.each(function (i) {
7950                var val;
7951
7952                if (this.nodeType !== 1) {
7953                    return;
7954                }
7955
7956                if (isFunction) {
7957                    val = value.call(this, i, jQuery(this).val());
7958                } else {
7959                    val = value;
7960                }
7961
7962                // Treat null/undefined as ""; convert numbers to string
7963                if (val == null) {
7964                    val = "";
7965
7966                } else if (typeof val === "number") {
7967                    val += "";
7968
7969                } else if (Array.isArray(val)) {
7970                    val = jQuery.map(val, function (value) {
7971                        return value == null ? "" : value + "";
7972                    });
7973                }
7974
7975                hooks = jQuery.valHooks[this.type] || jQuery.valHooks[this.nodeName.toLowerCase()];
7976
7977                // If set returns undefined, fall back to normal setting
7978                if (!hooks || !("set" in hooks) || hooks.set(this, val, "value") === undefined) {
7979                    this.value = val;
7980                }
7981            });
7982        }
7983    });
7984
7985    jQuery.extend({
7986        valHooks: {
7987            option: {
7988                get: function (elem) {
7989
7990                    var val = jQuery.find.attr(elem, "value");
7991                    return val != null ?
7992                        val :
7993
7994                        // Support: IE <=10 - 11 only
7995                        // option.text throws exceptions (#14686, #14858)
7996                        // Strip and collapse whitespace
7997                        // https://html.spec.whatwg.org/#strip-and-collapse-whitespace
7998                        stripAndCollapse(jQuery.text(elem));
7999                }
8000            },
8001            select: {
8002                get: function (elem) {
8003                    var value, option, i,
8004                        options = elem.options,
8005                        index = elem.selectedIndex,
8006                        one = elem.type === "select-one",
8007                        values = one ? null : [],
8008                        max = one ? index + 1 : options.length;
8009
8010                    if (index < 0) {
8011                        i = max;
8012
8013                    } else {
8014                        i = one ? index : 0;
8015                    }
8016
8017                    // Loop through all the selected options
8018                    for (; i < max; i++) {
8019                        option = options[i];
8020
8021                        // Support: IE <=9 only
8022                        // IE8-9 doesn't update selected after form reset (#2551)
8023                        if ((option.selected || i === index) &&
8024
8025                            // Don't return options that are disabled or in a disabled optgroup
8026                            !option.disabled &&
8027                            (!option.parentNode.disabled ||
8028                                !nodeName(option.parentNode, "optgroup"))) {
8029
8030                            // Get the specific value for the option
8031                            value = jQuery(option).val();
8032
8033                            // We don't need an array for one selects
8034                            if (one) {
8035                                return value;
8036                            }
8037
8038                            // Multi-Selects return an array
8039                            values.push(value);
8040                        }
8041                    }
8042
8043                    return values;
8044                },
8045
8046                set: function (elem, value) {
8047                    var optionSet, option,
8048                        options = elem.options,
8049                        values = jQuery.makeArray(value),
8050                        i = options.length;
8051
8052                    while (i--) {
8053                        option = options[i];
8054
8055                        /* eslint-disable no-cond-assign */
8056
8057                        if (option.selected =
8058                            jQuery.inArray(jQuery.valHooks.option.get(option), values) > -1
8059                        ) {
8060                            optionSet = true;
8061                        }
8062
8063                        /* eslint-enable no-cond-assign */
8064                    }
8065
8066                    // Force browsers to behave consistently when non-matching value is set
8067                    if (!optionSet) {
8068                        elem.selectedIndex = -1;
8069                    }
8070                    return values;
8071                }
8072            }
8073        }
8074    });
vendor: 9,460 bytes, lines 8075-8325
8075
8076// Radios and checkboxes getter/setter
8077    jQuery.each(["radio", "checkbox"], function () {
8078        jQuery.valHooks[this] = {
8079            set: function (elem, value) {
8080                if (Array.isArray(value)) {
8081                    return (elem.checked = jQuery.inArray(jQuery(elem).val(), value) > -1);
8082                }
8083            }
8084        };
8085        if (!support.checkOn) {
8086            jQuery.valHooks[this].get = function (elem) {
8087                return elem.getAttribute("value") === null ? "on" : elem.value;
8088            };
8089        }
8090    });
8091
8092
8093// Return jQuery for attributes-only inclusion
8094
8095
8096    var rfocusMorph = /^(?:focusinfocus|focusoutblur)$/;
8097
8098    jQuery.extend(jQuery.event, {
8099
8100        trigger: function (event, data, elem, onlyHandlers) {
8101
8102            var i, cur, tmp, bubbleType, ontype, handle, special,
8103                eventPath = [elem || document],
8104                type = hasOwn.call(event, "type") ? event.type : event,
8105                namespaces = hasOwn.call(event, "namespace") ? event.namespace.split(".") : [];
8106
8107            cur = tmp = elem = elem || document;
8108
8109            // Don't do events on text and comment nodes
8110            if (elem.nodeType === 3 || elem.nodeType === 8) {
8111                return;
8112            }
8113
8114            // focus/blur morphs to focusin/out; ensure we're not firing them right now
8115            if (rfocusMorph.test(type + jQuery.event.triggered)) {
8116                return;
8117            }
8118
8119            if (type.indexOf(".") > -1) {
8120
8121                // Namespaced trigger; create a regexp to match event type in handle()
8122                namespaces = type.split(".");
8123                type = namespaces.shift();
8124                namespaces.sort();
8125            }
8126            ontype = type.indexOf(":") < 0 && "on" + type;
8127
8128            // Caller can pass in a jQuery.Event object, Object, or just an event type string
8129            event = event[jQuery.expando] ?
8130                event :
8131                new jQuery.Event(type, typeof event === "object" && event);
8132
8133            // Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true)
8134            event.isTrigger = onlyHandlers ? 2 : 3;
8135            event.namespace = namespaces.join(".");
8136            event.rnamespace = event.namespace ?
8137                new RegExp("(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)") :
8138                null;
8139
8140            // Clean up the event in case it is being reused
8141            event.result = undefined;
8142            if (!event.target) {
8143                event.target = elem;
8144            }
8145
8146            // Clone any incoming data and prepend the event, creating the handler arg list
8147            data = data == null ?
8148                [event] :
8149                jQuery.makeArray(data, [event]);
8150
8151            // Allow special events to draw outside the lines
8152            special = jQuery.event.special[type] || {};
8153            if (!onlyHandlers && special.trigger && special.trigger.apply(elem, data) === false) {
8154                return;
8155            }
8156
8157            // Determine event propagation path in advance, per W3C events spec (#9951)
8158            // Bubble up to document, then to window; watch for a global ownerDocument var (#9724)
8159            if (!onlyHandlers && !special.noBubble && !jQuery.isWindow(elem)) {
8160
8161                bubbleType = special.delegateType || type;
8162                if (!rfocusMorph.test(bubbleType + type)) {
8163                    cur = cur.parentNode;
8164                }
8165                for (; cur; cur = cur.parentNode) {
8166                    eventPath.push(cur);
8167                    tmp = cur;
8168                }
8169
8170                // Only add window if we got to document (e.g., not plain obj or detached DOM)
8171                if (tmp === (elem.ownerDocument || document)) {
8172                    eventPath.push(tmp.defaultView || tmp.parentWindow || window);
8173                }
8174            }
8175
8176            // Fire handlers on the event path
8177            i = 0;
8178            while ((cur = eventPath[i++]) && !event.isPropagationStopped()) {
8179
8180                event.type = i > 1 ?
8181                    bubbleType :
8182                    special.bindType || type;
8183
8184                // jQuery handler
8185                handle = (dataPriv.get(cur, "events") || {})[event.type] &&
8186                    dataPriv.get(cur, "handle");
8187                if (handle) {
8188                    handle.apply(cur, data);
8189                }
8190
8191                // Native handler
8192                handle = ontype && cur[ontype];
8193                if (handle && handle.apply && acceptData(cur)) {
8194                    event.result = handle.apply(cur, data);
8195                    if (event.result === false) {
8196                        event.preventDefault();
8197                    }
8198                }
8199            }
8200            event.type = type;
8201
8202            // If nobody prevented the default action, do it now
8203            if (!onlyHandlers && !event.isDefaultPrevented()) {
8204
8205                if ((!special._default ||
8206                        special._default.apply(eventPath.pop(), data) === false) &&
8207                    acceptData(elem)) {
8208
8209                    // Call a native DOM method on the target with the same name as the event.
8210                    // Don't do default actions on window, that's where global variables be (#6170)
8211                    if (ontype && jQuery.isFunction(elem[type]) && !jQuery.isWindow(elem)) {
8212
8213                        // Don't re-trigger an onFOO event when we call its FOO() method
8214                        tmp = elem[ontype];
8215
8216                        if (tmp) {
8217                            elem[ontype] = null;
8218                        }
8219
8220                        // Prevent re-triggering of the same event, since we already bubbled it above
8221                        jQuery.event.triggered = type;
8222                        elem[type]();
8223                        jQuery.event.triggered = undefined;
8224
8225                        if (tmp) {
8226                            elem[ontype] = tmp;
8227                        }
8228                    }
8229                }
8230            }
8231
8232            return event.result;
8233        },
8234
8235        // Piggyback on a donor event to simulate a different one
8236        // Used only for `focus(in | out)` events
8237        simulate: function (type, elem, event) {
8238            var e = jQuery.extend(
8239                new jQuery.Event(),
8240                event,
8241                {
8242                    type: type,
8243                    isSimulated: true
8244                }
8245            );
8246
8247            jQuery.event.trigger(e, null, elem);
8248        }
8249
8250    });
8251
8252    jQuery.fn.extend({
8253
8254        trigger: function (type, data) {
8255            return this.each(function () {
8256                jQuery.event.trigger(type, data, this);
8257            });
8258        },
8259        triggerHandler: function (type, data) {
8260            var elem = this[0];
8261            if (elem) {
8262                return jQuery.event.trigger(type, data, elem, true);
8263            }
8264        }
8265    });
8266
8267
8268    jQuery.each(("blur focus focusin focusout resize scroll click dblclick " +
8269            "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " +
8270            "change select submit keydown keypress keyup contextmenu").split(" "),
8271        function (i, name) {
8272
8273            // Handle event binding
8274            jQuery.fn[name] = function (data, fn) {
8275                return arguments.length > 0 ?
8276                    this.on(name, null, data, fn) :
8277                    this.trigger(name);
8278            };
8279        });
8280
8281    jQuery.fn.extend({
8282        hover: function (fnOver, fnOut) {
8283            return this.mouseenter(fnOver).mouseleave(fnOut || fnOver);
8284        }
8285    });
8286
8287
8288    support.focusin = "onfocusin" in window;
8289
8290
8291// Support: Firefox <=44
8292// Firefox doesn't have focus(in | out) events
8293// Related ticket - https://bugzilla.mozilla.org/show_bug.cgi?id=687787
8294//
8295// Support: Chrome <=48 - 49, Safari <=9.0 - 9.1
8296// focus(in | out) events fire after focus & blur events,
8297// which is spec violation - http://www.w3.org/TR/DOM-Level-3-Events/#events-focusevent-event-order
8298// Related ticket - https://bugs.chromium.org/p/chromium/issues/detail?id=449857
8299    if (!support.focusin) {
8300        jQuery.each({focus: "focusin", blur: "focusout"}, function (orig, fix) {
8301
8302            // Attach a single capturing handler on the document while someone wants focusin/focusout
8303            var handler = function (event) {
8304                jQuery.event.simulate(fix, event.target, jQuery.event.fix(event));
8305            };
8306
8307            jQuery.event.special[fix] = {
8308                setup: function () {
8309                    var doc = this.ownerDocument || this,
8310                        attaches = dataPriv.access(doc, fix);
8311
8312                    if (!attaches) {
8313                        doc.addEventListener(orig, handler, true);
8314                    }
8315                    dataPriv.access(doc, fix, (attaches || 0) + 1);
8316                },
8317                teardown: function () {
8318                    var doc = this.ownerDocument || this,
8319                        attaches = dataPriv.access(doc, fix) - 1;
8320
8321                    if (!attaches) {
8322                        doc.removeEventListener(orig, handler, true);
8323                        dataPriv.remove(doc, fix);
8324
8325                    } else {
vendor: 4,900 bytes, lines 8326-8477
8326                        dataPriv.access(doc, fix, attaches);
8327                    }
8328                }
8329            };
8330        });
8331    }
8332    var location = window.location;
8333
8334    var nonce = jQuery.now();
8335
8336    var rquery = (/\?/);
8337
8338
8339// Cross-browser xml parsing
8340    jQuery.parseXML = function (data) {
8341        var xml;
8342        if (!data || typeof data !== "string") {
8343            return null;
8344        }
8345
8346        // Support: IE 9 - 11 only
8347        // IE throws on parseFromString with invalid input.
8348        try {
8349            xml = (new window.DOMParser()).parseFromString(data, "text/xml");
8350        } catch (e) {
8351            xml = undefined;
8352        }
8353
8354        if (!xml || xml.getElementsByTagName("parsererror").length) {
8355            jQuery.error("Invalid XML: " + data);
8356        }
8357        return xml;
8358    };
8359
8360
8361    var
8362        rbracket = /\[\]$/,
8363        rCRLF = /\r?\n/g,
8364        rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i,
8365        rsubmittable = /^(?:input|select|textarea|keygen)/i;
8366
8367    function buildParams(prefix, obj, traditional, add) {
8368        var name;
8369
8370        if (Array.isArray(obj)) {
8371
8372            // Serialize array item.
8373            jQuery.each(obj, function (i, v) {
8374                if (traditional || rbracket.test(prefix)) {
8375
8376                    // Treat each array item as a scalar.
8377                    add(prefix, v);
8378
8379                } else {
8380
8381                    // Item is non-scalar (array or object), encode its numeric index.
8382                    buildParams(
8383                        prefix + "[" + (typeof v === "object" && v != null ? i : "") + "]",
8384                        v,
8385                        traditional,
8386                        add
8387                    );
8388                }
8389            });
8390
8391        } else if (!traditional && jQuery.type(obj) === "object") {
8392
8393            // Serialize object item.
8394            for (name in obj) {
8395                buildParams(prefix + "[" + name + "]", obj[name], traditional, add);
8396            }
8397
8398        } else {
8399
8400            // Serialize scalar item.
8401            add(prefix, obj);
8402        }
8403    }
8404
8405// Serialize an array of form elements or a set of
8406// key/values into a query string
8407    jQuery.param = function (a, traditional) {
8408        var prefix,
8409            s = [],
8410            add = function (key, valueOrFunction) {
8411
8412                // If value is a function, invoke it and use its return value
8413                var value = jQuery.isFunction(valueOrFunction) ?
8414                    valueOrFunction() :
8415                    valueOrFunction;
8416
8417                s[s.length] = encodeURIComponent(key) + "=" +
8418                    encodeURIComponent(value == null ? "" : value);
8419            };
8420
8421        // If an array was passed in, assume that it is an array of form elements.
8422        if (Array.isArray(a) || (a.jquery && !jQuery.isPlainObject(a))) {
8423
8424            // Serialize the form elements
8425            jQuery.each(a, function () {
8426                add(this.name, this.value);
8427            });
8428
8429        } else {
8430
8431            // If traditional, encode the "old" way (the way 1.3.2 or older
8432            // did it), otherwise encode params recursively.
8433            for (prefix in a) {
8434                buildParams(prefix, a[prefix], traditional, add);
8435            }
8436        }
8437
8438        // Return the resulting serialization
8439        return s.join("&");
8440    };
8441
8442    jQuery.fn.extend({
8443        serialize: function () {
8444            return jQuery.param(this.serializeArray());
8445        },
8446        serializeArray: function () {
8447            return this.map(function () {
8448
8449                // Can add propHook for "elements" to filter or add form elements
8450                var elements = jQuery.prop(this, "elements");
8451                return elements ? jQuery.makeArray(elements) : this;
8452            })
8453                .filter(function () {
8454                    var type = this.type;
8455
8456                    // Use .is( ":disabled" ) so that fieldset[disabled] works
8457                    return this.name && !jQuery(this).is(":disabled") &&
8458                        rsubmittable.test(this.nodeName) && !rsubmitterTypes.test(type) &&
8459                        (this.checked || !rcheckableType.test(type));
8460                })
8461                .map(function (i, elem) {
8462                    var val = jQuery(this).val();
8463
8464                    if (val == null) {
8465                        return null;
8466                    }
8467
8468                    if (Array.isArray(val)) {
8469                        return jQuery.map(val, function (val) {
8470                            return {name: elem.name, value: val.replace(rCRLF, "\r\n")};
8471                        });
8472                    }
8473
8474                    return {name: elem.name, value: val.replace(rCRLF, "\r\n")};
8475                }).get();
8476        }
8477    });
vendor: 5,294 bytes, lines 8478-8628
8478
8479
8480    var
8481        r20 = /%20/g,
8482        rhash = /#.*$/,
8483        rantiCache = /([?&])_=[^&]*/,
8484        rheaders = /^(.*?):[ \t]*([^\r\n]*)$/mg,
8485
8486        // #7653, #8125, #8152: local protocol detection
8487        rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/,
8488        rnoContent = /^(?:GET|HEAD)$/,
8489        rprotocol = /^\/\//,
8490
8491        /* Prefilters
8492* 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example)
8493* 2) These are called:
8494*		- BEFORE asking for a transport
8495*		- AFTER param serialization (s.data is a string if s.processData is true)
8496* 3) key is the dataType
8497* 4) the catchall symbol "*" can be used
8498* 5) execution will start with transport dataType and THEN continue down to "*" if needed
8499*/
8500        prefilters = {},
8501
8502        /* Transports bindings
8503* 1) key is the dataType
8504* 2) the catchall symbol "*" can be used
8505* 3) selection will start with transport dataType and THEN go to "*" if needed
8506*/
8507        transports = {},
8508
8509        // Avoid comment-prolog char sequence (#10098); must appease lint and evade compression
8510        allTypes = "*/".concat("*"),
8511
8512        // Anchor tag for parsing the document origin
8513        originAnchor = document.createElement("a");
8514    originAnchor.href = location.href;
8515
8516// Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport
8517    function addToPrefiltersOrTransports(structure) {
8518
8519        // dataTypeExpression is optional and defaults to "*"
8520        return function (dataTypeExpression, func) {
8521
8522            if (typeof dataTypeExpression !== "string") {
8523                func = dataTypeExpression;
8524                dataTypeExpression = "*";
8525            }
8526
8527            var dataType,
8528                i = 0,
8529                dataTypes = dataTypeExpression.toLowerCase().match(rnothtmlwhite) || [];
8530
8531            if (jQuery.isFunction(func)) {
8532
8533                // For each dataType in the dataTypeExpression
8534                while ((dataType = dataTypes[i++])) {
8535
8536                    // Prepend if requested
8537                    if (dataType[0] === "+") {
8538                        dataType = dataType.slice(1) || "*";
8539                        (structure[dataType] = structure[dataType] || []).unshift(func);
8540
8541                        // Otherwise append
8542                    } else {
8543                        (structure[dataType] = structure[dataType] || []).push(func);
8544                    }
8545                }
8546            }
8547        };
8548    }
8549
8550// Base inspection function for prefilters and transports
8551    function inspectPrefiltersOrTransports(structure, options, originalOptions, jqXHR) {
8552
8553        var inspected = {},
8554            seekingTransport = (structure === transports);
8555
8556        function inspect(dataType) {
8557            var selected;
8558            inspected[dataType] = true;
8559            jQuery.each(structure[dataType] || [], function (_, prefilterOrFactory) {
8560                var dataTypeOrTransport = prefilterOrFactory(options, originalOptions, jqXHR);
8561                if (typeof dataTypeOrTransport === "string" &&
8562                    !seekingTransport && !inspected[dataTypeOrTransport]) {
8563
8564                    options.dataTypes.unshift(dataTypeOrTransport);
8565                    inspect(dataTypeOrTransport);
8566                    return false;
8567                } else if (seekingTransport) {
8568                    return !(selected = dataTypeOrTransport);
8569                }
8570            });
8571            return selected;
8572        }
8573
8574        return inspect(options.dataTypes[0]) || !inspected["*"] && inspect("*");
8575    }
8576
8577// A special extend for ajax options
8578// that takes "flat" options (not to be deep extended)
8579// Fixes #9887
8580    function ajaxExtend(target, src) {
8581        var key, deep,
8582            flatOptions = jQuery.ajaxSettings.flatOptions || {};
8583
8584        for (key in src) {
8585            if (src[key] !== undefined) {
8586                (flatOptions[key] ? target : (deep || (deep = {})))[key] = src[key];
8587            }
8588        }
8589        if (deep) {
8590            jQuery.extend(true, target, deep);
8591        }
8592
8593        return target;
8594    }
8595
8596    /* Handles responses to an ajax request:
8597* - finds the right dataType (mediates between content-type and expected dataType)
8598* - returns the corresponding response
8599*/
8600    function ajaxHandleResponses(s, jqXHR, responses) {
8601
8602        var ct, type, finalDataType, firstDataType,
8603            contents = s.contents,
8604            dataTypes = s.dataTypes;
8605
8606        // Remove auto dataType and get content-type in the process
8607        while (dataTypes[0] === "*") {
8608            dataTypes.shift();
8609            if (ct === undefined) {
8610                ct = s.mimeType || jqXHR.getResponseHeader("Content-Type");
8611            }
8612        }
8613
8614        // Check if we're dealing with a known content-type
8615        if (ct) {
8616            for (type in contents) {
8617                if (contents[type] && contents[type].test(ct)) {
8618                    dataTypes.unshift(type);
8619                    break;
8620                }
8621            }
8622        }
8623
8624        // Check to see if we have a response for the expected dataType
8625        if (dataTypes[0] in responses) {
8626            finalDataType = dataTypes[0];
8627        } else {
8628
vendor: 5,255 bytes, lines 8629-8778
8629            // Try convertible dataTypes
8630            for (type in responses) {
8631                if (!dataTypes[0] || s.converters[type + " " + dataTypes[0]]) {
8632                    finalDataType = type;
8633                    break;
8634                }
8635                if (!firstDataType) {
8636                    firstDataType = type;
8637                }
8638            }
8639
8640            // Or just use first one
8641            finalDataType = finalDataType || firstDataType;
8642        }
8643
8644        // If we found a dataType
8645        // We add the dataType to the list if needed
8646        // and return the corresponding response
8647        if (finalDataType) {
8648            if (finalDataType !== dataTypes[0]) {
8649                dataTypes.unshift(finalDataType);
8650            }
8651            return responses[finalDataType];
8652        }
8653    }
8654
8655    /* Chain conversions given the request and the original response
8656* Also sets the responseXXX fields on the jqXHR instance
8657*/
8658    function ajaxConvert(s, response, jqXHR, isSuccess) {
8659        var conv2, current, conv, tmp, prev,
8660            converters = {},
8661
8662            // Work with a copy of dataTypes in case we need to modify it for conversion
8663            dataTypes = s.dataTypes.slice();
8664
8665        // Create converters map with lowercased keys
8666        if (dataTypes[1]) {
8667            for (conv in s.converters) {
8668                converters[conv.toLowerCase()] = s.converters[conv];
8669            }
8670        }
8671
8672        current = dataTypes.shift();
8673
8674        // Convert to each sequential dataType
8675        while (current) {
8676
8677            if (s.responseFields[current]) {
8678                jqXHR[s.responseFields[current]] = response;
8679            }
8680
8681            // Apply the dataFilter if provided
8682            if (!prev && isSuccess && s.dataFilter) {
8683                response = s.dataFilter(response, s.dataType);
8684            }
8685
8686            prev = current;
8687            current = dataTypes.shift();
8688
8689            if (current) {
8690
8691                // There's only work to do if current dataType is non-auto
8692                if (current === "*") {
8693
8694                    current = prev;
8695
8696                    // Convert response if prev dataType is non-auto and differs from current
8697                } else if (prev !== "*" && prev !== current) {
8698
8699                    // Seek a direct converter
8700                    conv = converters[prev + " " + current] || converters["* " + current];
8701
8702                    // If none found, seek a pair
8703                    if (!conv) {
8704                        for (conv2 in converters) {
8705
8706                            // If conv2 outputs current
8707                            tmp = conv2.split(" ");
8708                            if (tmp[1] === current) {
8709
8710                                // If prev can be converted to accepted input
8711                                conv = converters[prev + " " + tmp[0]] ||
8712                                    converters["* " + tmp[0]];
8713                                if (conv) {
8714
8715                                    // Condense equivalence converters
8716                                    if (conv === true) {
8717                                        conv = converters[conv2];
8718
8719                                        // Otherwise, insert the intermediate dataType
8720                                    } else if (converters[conv2] !== true) {
8721                                        current = tmp[0];
8722                                        dataTypes.unshift(tmp[1]);
8723                                    }
8724                                    break;
8725                                }
8726                            }
8727                        }
8728                    }
8729
8730                    // Apply converter (if not an equivalence)
8731                    if (conv !== true) {
8732
8733                        // Unless errors are allowed to bubble, catch and return them
8734                        if (conv && s.throws) {
8735                            response = conv(response);
8736                        } else {
8737                            try {
8738                                response = conv(response);
8739                            } catch (e) {
8740                                return {
8741                                    state: "parsererror",
8742                                    error: conv ? e : "No conversion from " + prev + " to " + current
8743                                };
8744                            }
8745                        }
8746                    }
8747                }
8748            }
8749        }
8750
8751        return {state: "success", data: response};
8752    }
8753
8754    jQuery.extend({
8755
8756        // Counter for holding the number of active queries
8757        active: 0,
8758
8759        // Last-Modified header cache for next request
8760        lastModified: {},
8761        etag: {},
8762
8763        ajaxSettings: {
8764            url: location.href,
8765            type: "GET",
8766            isLocal: rlocalProtocol.test(location.protocol),
8767            global: true,
8768            processData: true,
8769            async: true,
8770            contentType: "application/x-www-form-urlencoded; charset=UTF-8",
8771
8772            /*
8773	timeout: 0,
8774	data: null,
8775	dataType: null,
8776	username: null,
8777	password: null,
8778	cache: null,
vendor: 22,825 bytes, lines 8779-9418
8779	throws: false,
8780	traditional: false,
8781	headers: {},
8782	*/
8783
8784            accepts: {
8785                "*": allTypes,
8786                text: "text/plain",
8787                html: "text/html",
8788                xml: "application/xml, text/xml",
8789                json: "application/json, text/javascript"
8790            },
8791
8792            contents: {
8793                xml: /\bxml\b/,
8794                html: /\bhtml/,
8795                json: /\bjson\b/
8796            },
8797
8798            responseFields: {
8799                xml: "responseXML",
8800                text: "responseText",
8801                json: "responseJSON"
8802            },
8803
8804            // Data converters
8805            // Keys separate source (or catchall "*") and destination types with a single space
8806            converters: {
8807
8808                // Convert anything to text
8809                "* text": String,
8810
8811                // Text to html (true = no transformation)
8812                "text html": true,
8813
8814                // Evaluate text as a json expression
8815                "text json": JSON.parse,
8816
8817                // Parse text as xml
8818                "text xml": jQuery.parseXML
8819            },
8820
8821            // For options that shouldn't be deep extended:
8822            // you can add your own custom options here if
8823            // and when you create one that shouldn't be
8824            // deep extended (see ajaxExtend)
8825            flatOptions: {
8826                url: true,
8827                context: true
8828            }
8829        },
8830
8831        // Creates a full fledged settings object into target
8832        // with both ajaxSettings and settings fields.
8833        // If target is omitted, writes into ajaxSettings.
8834        ajaxSetup: function (target, settings) {
8835            return settings ?
8836
8837                // Building a settings object
8838                ajaxExtend(ajaxExtend(target, jQuery.ajaxSettings), settings) :
8839
8840                // Extending ajaxSettings
8841                ajaxExtend(jQuery.ajaxSettings, target);
8842        },
8843
8844        ajaxPrefilter: addToPrefiltersOrTransports(prefilters),
8845        ajaxTransport: addToPrefiltersOrTransports(transports),
8846
8847        // Main method
8848        ajax: function (url, options) {
8849
8850            // If url is an object, simulate pre-1.5 signature
8851            if (typeof url === "object") {
8852                options = url;
8853                url = undefined;
8854            }
8855
8856            // Force options to be an object
8857            options = options || {};
8858
8859            var transport,
8860
8861                // URL without anti-cache param
8862                cacheURL,
8863
8864                // Response headers
8865                responseHeadersString,
8866                responseHeaders,
8867
8868                // timeout handle
8869                timeoutTimer,
8870
8871                // Url cleanup var
8872                urlAnchor,
8873
8874                // Request state (becomes false upon send and true upon completion)
8875                completed,
8876
8877                // To know if global events are to be dispatched
8878                fireGlobals,
8879
8880                // Loop variable
8881                i,
8882
8883                // uncached part of the url
8884                uncached,
8885
8886                // Create the final options object
8887                s = jQuery.ajaxSetup({}, options),
8888
8889                // Callbacks context
8890                callbackContext = s.context || s,
8891
8892                // Context for global events is callbackContext if it is a DOM node or jQuery collection
8893                globalEventContext = s.context &&
8894                (callbackContext.nodeType || callbackContext.jquery) ?
8895                    jQuery(callbackContext) :
8896                    jQuery.event,
8897
8898                // Deferreds
8899                deferred = jQuery.Deferred(),
8900                completeDeferred = jQuery.Callbacks("once memory"),
8901
8902                // Status-dependent callbacks
8903                statusCode = s.statusCode || {},
8904
8905                // Headers (they are sent all at once)
8906                requestHeaders = {},
8907                requestHeadersNames = {},
8908
8909                // Default abort message
8910                strAbort = "canceled",
8911
8912                // Fake xhr
8913                jqXHR = {
8914                    readyState: 0,
8915
8916                    // Builds headers hashtable if needed
8917                    getResponseHeader: function (key) {
8918                        var match;
8919                        if (completed) {
8920                            if (!responseHeaders) {
8921                                responseHeaders = {};
8922                                while ((match = rheaders.exec(responseHeadersString))) {
8923                                    responseHeaders[match[1].toLowerCase()] = match[2];
8924                                }
8925                            }
8926                            match = responseHeaders[key.toLowerCase()];
8927                        }
8928                        return match == null ? null : match;
8929                    },
8930
8931                    // Raw string
8932                    getAllResponseHeaders: function () {
8933                        return completed ? responseHeadersString : null;
8934                    },
8935
8936                    // Caches the header
8937                    setRequestHeader: function (name, value) {
8938                        if (completed == null) {
8939                            name = requestHeadersNames[name.toLowerCase()] =
8940                                requestHeadersNames[name.toLowerCase()] || name;
8941                            requestHeaders[name] = value;
8942                        }
8943                        return this;
8944                    },
8945
8946                    // Overrides response content-type header
8947                    overrideMimeType: function (type) {
8948                        if (completed == null) {
8949                            s.mimeType = type;
8950                        }
8951                        return this;
8952                    },
8953
8954                    // Status-dependent callbacks
8955                    statusCode: function (map) {
8956                        var code;
8957                        if (map) {
8958                            if (completed) {
8959
8960                                // Execute the appropriate callbacks
8961                                jqXHR.always(map[jqXHR.status]);
8962                            } else {
8963
8964                                // Lazy-add the new callbacks in a way that preserves old ones
8965                                for (code in map) {
8966                                    statusCode[code] = [statusCode[code], map[code]];
8967                                }
8968                            }
8969                        }
8970                        return this;
8971                    },
8972
8973                    // Cancel the request
8974                    abort: function (statusText) {
8975                        var finalText = statusText || strAbort;
8976                        if (transport) {
8977                            transport.abort(finalText);
8978                        }
8979                        done(0, finalText);
8980                        return this;
8981                    }
8982                };
8983
8984            // Attach deferreds
8985            deferred.promise(jqXHR);
8986
8987            // Add protocol if not provided (prefilters might expect it)
8988            // Handle falsy url in the settings object (#10093: consistency with old signature)
8989            // We also use the url parameter if available
8990            s.url = ((url || s.url || location.href) + "")
8991                .replace(rprotocol, location.protocol + "//");
8992
8993            // Alias method option to type as per ticket #12004
8994            s.type = options.method || options.type || s.method || s.type;
8995
8996            // Extract dataTypes list
8997            s.dataTypes = (s.dataType || "*").toLowerCase().match(rnothtmlwhite) || [""];
8998
8999            // A cross-domain request is in order when the origin doesn't match the current origin.
9000            if (s.crossDomain == null) {
9001                urlAnchor = document.createElement("a");
9002
9003                // Support: IE <=8 - 11, Edge 12 - 13
9004                // IE throws exception on accessing the href property if url is malformed,
9005                // e.g. http://example.com:80x/
9006                try {
9007                    urlAnchor.href = s.url;
9008
9009                    // Support: IE <=8 - 11 only
9010                    // Anchor's host property isn't correctly set when s.url is relative
9011                    urlAnchor.href = urlAnchor.href;
9012                    s.crossDomain = originAnchor.protocol + "//" + originAnchor.host !==
9013                        urlAnchor.protocol + "//" + urlAnchor.host;
9014                } catch (e) {
9015
9016                    // If there is an error parsing the URL, assume it is crossDomain,
9017                    // it can be rejected by the transport if it is invalid
9018                    s.crossDomain = true;
9019                }
9020            }
9021
9022            // Convert data if not already a string
9023            if (s.data && s.processData && typeof s.data !== "string") {
9024                s.data = jQuery.param(s.data, s.traditional);
9025            }
9026
9027            // Apply prefilters
9028            inspectPrefiltersOrTransports(prefilters, s, options, jqXHR);
9029
9030            // If request was aborted inside a prefilter, stop there
9031            if (completed) {
9032                return jqXHR;
9033            }
9034
9035            // We can fire global events as of now if asked to
9036            // Don't fire events if jQuery.event is undefined in an AMD-usage scenario (#15118)
9037            fireGlobals = jQuery.event && s.global;
9038
9039            // Watch for a new set of requests
9040            if (fireGlobals && jQuery.active++ === 0) {
9041                jQuery.event.trigger("ajaxStart");
9042            }
9043
9044            // Uppercase the type
9045            s.type = s.type.toUpperCase();
9046
9047            // Determine if request has content
9048            s.hasContent = !rnoContent.test(s.type);
9049
9050            // Save the URL in case we're toying with the If-Modified-Since
9051            // and/or If-None-Match header later on
9052            // Remove hash to simplify url manipulation
9053            cacheURL = s.url.replace(rhash, "");
9054
9055            // More options handling for requests with no content
9056            if (!s.hasContent) {
9057
9058                // Remember the hash so we can put it back
9059                uncached = s.url.slice(cacheURL.length);
9060
9061                // If data is available, append data to url
9062                if (s.data) {
9063                    cacheURL += (rquery.test(cacheURL) ? "&" : "?") + s.data;
9064
9065                    // #9682: remove data so that it's not used in an eventual retry
9066                    delete s.data;
9067                }
9068
9069                // Add or update anti-cache param if needed
9070                if (s.cache === false) {
9071                    cacheURL = cacheURL.replace(rantiCache, "$1");
9072                    uncached = (rquery.test(cacheURL) ? "&" : "?") + "_=" + (nonce++) + uncached;
9073                }
9074
9075                // Put hash and anti-cache on the URL that will be requested (gh-1732)
9076                s.url = cacheURL + uncached;
9077
9078                // Change '%20' to '+' if this is encoded form body content (gh-2658)
9079            } else if (s.data && s.processData &&
9080                (s.contentType || "").indexOf("application/x-www-form-urlencoded") === 0) {
9081                s.data = s.data.replace(r20, "+");
9082            }
9083
9084            // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
9085            if (s.ifModified) {
9086                if (jQuery.lastModified[cacheURL]) {
9087                    jqXHR.setRequestHeader("If-Modified-Since", jQuery.lastModified[cacheURL]);
9088                }
9089                if (jQuery.etag[cacheURL]) {
9090                    jqXHR.setRequestHeader("If-None-Match", jQuery.etag[cacheURL]);
9091                }
9092            }
9093
9094            // Set the correct header, if data is being sent
9095            if (s.data && s.hasContent && s.contentType !== false || options.contentType) {
9096                jqXHR.setRequestHeader("Content-Type", s.contentType);
9097            }
9098
9099            // Set the Accepts header for the server, depending on the dataType
9100            jqXHR.setRequestHeader(
9101                "Accept",
9102                s.dataTypes[0] && s.accepts[s.dataTypes[0]] ?
9103                    s.accepts[s.dataTypes[0]] +
9104                    (s.dataTypes[0] !== "*" ? ", " + allTypes + "; q=0.01" : "") :
9105                    s.accepts["*"]
9106            );
9107
9108            // Check for headers option
9109            for (i in s.headers) {
9110                jqXHR.setRequestHeader(i, s.headers[i]);
9111            }
9112
9113            // Allow custom headers/mimetypes and early abort
9114            if (s.beforeSend &&
9115                (s.beforeSend.call(callbackContext, jqXHR, s) === false || completed)) {
9116
9117                // Abort if not done already and return
9118                return jqXHR.abort();
9119            }
9120
9121            // Aborting is no longer a cancellation
9122            strAbort = "abort";
9123
9124            // Install callbacks on deferreds
9125            completeDeferred.add(s.complete);
9126            jqXHR.done(s.success);
9127            jqXHR.fail(s.error);
9128
9129            // Get transport
9130            transport = inspectPrefiltersOrTransports(transports, s, options, jqXHR);
9131
9132            // If no transport, we auto-abort
9133            if (!transport) {
9134                done(-1, "No Transport");
9135            } else {
9136                jqXHR.readyState = 1;
9137
9138                // Send global event
9139                if (fireGlobals) {
9140                    globalEventContext.trigger("ajaxSend", [jqXHR, s]);
9141                }
9142
9143                // If request was aborted inside ajaxSend, stop there
9144                if (completed) {
9145                    return jqXHR;
9146                }
9147
9148                // Timeout
9149                if (s.async && s.timeout > 0) {
9150                    timeoutTimer = window.setTimeout(function () {
9151                        jqXHR.abort("timeout");
9152                    }, s.timeout);
9153                }
9154
9155                try {
9156                    completed = false;
9157                    transport.send(requestHeaders, done);
9158                } catch (e) {
9159
9160                    // Rethrow post-completion exceptions
9161                    if (completed) {
9162                        throw e;
9163                    }
9164
9165                    // Propagate others as results
9166                    done(-1, e);
9167                }
9168            }
9169
9170            // Callback for when everything is done
9171            function done(status, nativeStatusText, responses, headers) {
9172                var isSuccess, success, error, response, modified,
9173                    statusText = nativeStatusText;
9174
9175                // Ignore repeat invocations
9176                if (completed) {
9177                    return;
9178                }
9179
9180                completed = true;
9181
9182                // Clear timeout if it exists
9183                if (timeoutTimer) {
9184                    window.clearTimeout(timeoutTimer);
9185                }
9186
9187                // Dereference transport for early garbage collection
9188                // (no matter how long the jqXHR object will be used)
9189                transport = undefined;
9190
9191                // Cache response headers
9192                responseHeadersString = headers || "";
9193
9194                // Set readyState
9195                jqXHR.readyState = status > 0 ? 4 : 0;
9196
9197                // Determine if successful
9198                isSuccess = status >= 200 && status < 300 || status === 304;
9199
9200                // Get response data
9201                if (responses) {
9202                    response = ajaxHandleResponses(s, jqXHR, responses);
9203                }
9204
9205                // Convert no matter what (that way responseXXX fields are always set)
9206                response = ajaxConvert(s, response, jqXHR, isSuccess);
9207
9208                // If successful, handle type chaining
9209                if (isSuccess) {
9210
9211                    // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
9212                    if (s.ifModified) {
9213                        modified = jqXHR.getResponseHeader("Last-Modified");
9214                        if (modified) {
9215                            jQuery.lastModified[cacheURL] = modified;
9216                        }
9217                        modified = jqXHR.getResponseHeader("etag");
9218                        if (modified) {
9219                            jQuery.etag[cacheURL] = modified;
9220                        }
9221                    }
9222
9223                    // if no content
9224                    if (status === 204 || s.type === "HEAD") {
9225                        statusText = "nocontent";
9226
9227                        // if not modified
9228                    } else if (status === 304) {
9229                        statusText = "notmodified";
9230
9231                        // If we have data, let's convert it
9232                    } else {
9233                        statusText = response.state;
9234                        success = response.data;
9235                        error = response.error;
9236                        isSuccess = !error;
9237                    }
9238                } else {
9239
9240                    // Extract error from statusText and normalize for non-aborts
9241                    error = statusText;
9242                    if (status || !statusText) {
9243                        statusText = "error";
9244                        if (status < 0) {
9245                            status = 0;
9246                        }
9247                    }
9248                }
9249
9250                // Set data for the fake xhr object
9251                jqXHR.status = status;
9252                jqXHR.statusText = (nativeStatusText || statusText) + "";
9253
9254                // Success/Error
9255                if (isSuccess) {
9256                    deferred.resolveWith(callbackContext, [success, statusText, jqXHR]);
9257                } else {
9258                    deferred.rejectWith(callbackContext, [jqXHR, statusText, error]);
9259                }
9260
9261                // Status-dependent callbacks
9262                jqXHR.statusCode(statusCode);
9263                statusCode = undefined;
9264
9265                if (fireGlobals) {
9266                    globalEventContext.trigger(isSuccess ? "ajaxSuccess" : "ajaxError",
9267                        [jqXHR, s, isSuccess ? success : error]);
9268                }
9269
9270                // Complete
9271                completeDeferred.fireWith(callbackContext, [jqXHR, statusText]);
9272
9273                if (fireGlobals) {
9274                    globalEventContext.trigger("ajaxComplete", [jqXHR, s]);
9275
9276                    // Handle the global AJAX counter
9277                    if (!(--jQuery.active)) {
9278                        jQuery.event.trigger("ajaxStop");
9279                    }
9280                }
9281            }
9282
9283            return jqXHR;
9284        },
9285
9286        getJSON: function (url, data, callback) {
9287            return jQuery.get(url, data, callback, "json");
9288        },
9289
9290        getScript: function (url, callback) {
9291            return jQuery.get(url, undefined, callback, "script");
9292        }
9293    });
9294
9295    jQuery.each(["get", "post"], function (i, method) {
9296        jQuery[method] = function (url, data, callback, type) {
9297
9298            // Shift arguments if data argument was omitted
9299            if (jQuery.isFunction(data)) {
9300                type = type || callback;
9301                callback = data;
9302                data = undefined;
9303            }
9304
9305            // The url can be an options object (which then must have .url)
9306            return jQuery.ajax(jQuery.extend({
9307                url: url,
9308                type: method,
9309                dataType: type,
9310                data: data,
9311                success: callback
9312            }, jQuery.isPlainObject(url) && url));
9313        };
9314    });
9315
9316
9317    jQuery._evalUrl = function (url) {
9318        return jQuery.ajax({
9319            url: url,
9320
9321            // Make this explicit, since user can override this through ajaxSetup (#11264)
9322            type: "GET",
9323            dataType: "script",
9324            cache: true,
9325            async: false,
9326            global: false,
9327            "throws": true
9328        });
9329    };
9330
9331
9332    jQuery.fn.extend({
9333        wrapAll: function (html) {
9334            var wrap;
9335
9336            if (this[0]) {
9337                if (jQuery.isFunction(html)) {
9338                    html = html.call(this[0]);
9339                }
9340
9341                // The elements to wrap the target around
9342                wrap = jQuery(html, this[0].ownerDocument).eq(0).clone(true);
9343
9344                if (this[0].parentNode) {
9345                    wrap.insertBefore(this[0]);
9346                }
9347
9348                wrap.map(function () {
9349                    var elem = this;
9350
9351                    while (elem.firstElementChild) {
9352                        elem = elem.firstElementChild;
9353                    }
9354
9355                    return elem;
9356                }).append(this);
9357            }
9358
9359            return this;
9360        },
9361
9362        wrapInner: function (html) {
9363            if (jQuery.isFunction(html)) {
9364                return this.each(function (i) {
9365                    jQuery(this).wrapInner(html.call(this, i));
9366                });
9367            }
9368
9369            return this.each(function () {
9370                var self = jQuery(this),
9371                    contents = self.contents();
9372
9373                if (contents.length) {
9374                    contents.wrapAll(html);
9375
9376                } else {
9377                    self.append(html);
9378                }
9379            });
9380        },
9381
9382        wrap: function (html) {
9383            var isFunction = jQuery.isFunction(html);
9384
9385            return this.each(function (i) {
9386                jQuery(this).wrapAll(isFunction ? html.call(this, i) : html);
9387            });
9388        },
9389
9390        unwrap: function (selector) {
9391            this.parent(selector).not("body").each(function () {
9392                jQuery(this).replaceWith(this.childNodes);
9393            });
9394            return this;
9395        }
9396    });
9397
9398
9399    jQuery.expr.pseudos.hidden = function (elem) {
9400        return !jQuery.expr.pseudos.visible(elem);
9401    };
9402    jQuery.expr.pseudos.visible = function (elem) {
9403        return !!(elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length);
9404    };
9405
9406
9407    jQuery.ajaxSettings.xhr = function () {
9408        try {
9409            return new window.XMLHttpRequest();
9410        } catch (e) {
9411        }
9412    };
9413
9414    var xhrSuccessStatus = {
9415
9416            // File protocol always yields status code 0, assume 200
9417            0: 200,
9418
vendor: 6,194 bytes, lines 9419-9551
9419            // Support: IE <=9 only
9420            // #1450: sometimes IE returns 1223 when it should be 204
9421            1223: 204
9422        },
9423        xhrSupported = jQuery.ajaxSettings.xhr();
9424
9425    support.cors = !!xhrSupported && ("withCredentials" in xhrSupported);
9426    support.ajax = xhrSupported = !!xhrSupported;
9427
9428    jQuery.ajaxTransport(function (options) {
9429        var callback, errorCallback;
9430
9431        // Cross domain only allowed if supported through XMLHttpRequest
9432        if (support.cors || xhrSupported && !options.crossDomain) {
9433            return {
9434                send: function (headers, complete) {
9435                    var i,
9436                        xhr = options.xhr();
9437
9438                    xhr.open(
9439                        options.type,
9440                        options.url,
9441                        options.async,
9442                        options.username,
9443                        options.password
9444                    );
9445
9446                    // Apply custom fields if provided
9447                    if (options.xhrFields) {
9448                        for (i in options.xhrFields) {
9449                            xhr[i] = options.xhrFields[i];
9450                        }
9451                    }
9452
9453                    // Override mime type if needed
9454                    if (options.mimeType && xhr.overrideMimeType) {
9455                        xhr.overrideMimeType(options.mimeType);
9456                    }
9457
9458                    // X-Requested-With header
9459                    // For cross-domain requests, seeing as conditions for a preflight are
9460                    // akin to a jigsaw puzzle, we simply never set it to be sure.
9461                    // (it can always be set on a per-request basis or even using ajaxSetup)
9462                    // For same-domain requests, won't change header if already provided.
9463                    if (!options.crossDomain && !headers["X-Requested-With"]) {
9464                        headers["X-Requested-With"] = "XMLHttpRequest";
9465                    }
9466
9467                    // Set headers
9468                    for (i in headers) {
9469                        xhr.setRequestHeader(i, headers[i]);
9470                    }
9471
9472                    // Callback
9473                    callback = function (type) {
9474                        return function () {
9475                            if (callback) {
9476                                callback = errorCallback = xhr.onload =
9477                                    xhr.onerror = xhr.onabort = xhr.onreadystatechange = null;
9478
9479                                if (type === "abort") {
9480                                    xhr.abort();
9481                                } else if (type === "error") {
9482
9483                                    // Support: IE <=9 only
9484                                    // On a manual native abort, IE9 throws
9485                                    // errors on any property access that is not readyState
9486                                    if (typeof xhr.status !== "number") {
9487                                        complete(0, "error");
9488                                    } else {
9489                                        complete(
9490                                            // File: protocol always yields status 0; see #8605, #14207
9491                                            xhr.status,
9492                                            xhr.statusText
9493                                        );
9494                                    }
9495                                } else {
9496                                    complete(
9497                                        xhrSuccessStatus[xhr.status] || xhr.status,
9498                                        xhr.statusText,
9499
9500                                        // Support: IE <=9 only
9501                                        // IE9 has no XHR2 but throws on binary (trac-11426)
9502                                        // For XHR2 non-text, let the caller handle it (gh-2498)
9503                                        (xhr.responseType || "text") !== "text" ||
9504                                        typeof xhr.responseText !== "string" ?
9505                                            {binary: xhr.response} :
9506                                            {text: xhr.responseText},
9507                                        xhr.getAllResponseHeaders()
9508                                    );
9509                                }
9510                            }
9511                        };
9512                    };
9513
9514                    // Listen to events
9515                    xhr.onload = callback();
9516                    errorCallback = xhr.onerror = callback("error");
9517
9518                    // Support: IE 9 only
9519                    // Use onreadystatechange to replace onabort
9520                    // to handle uncaught aborts
9521                    if (xhr.onabort !== undefined) {
9522                        xhr.onabort = errorCallback;
9523                    } else {
9524                        xhr.onreadystatechange = function () {
9525
9526                            // Check readyState before timeout as it changes
9527                            if (xhr.readyState === 4) {
9528
9529                                // Allow onerror to be called first,
9530                                // but that will not handle a native abort
9531                                // Also, save errorCallback to a variable
9532                                // as xhr.onerror cannot be accessed
9533                                window.setTimeout(function () {
9534                                    if (callback) {
9535                                        errorCallback();
9536                                    }
9537                                });
9538                            }
9539                        };
9540                    }
9541
9542                    // Create the abort callback
9543                    callback = callback("abort");
9544
9545                    try {
9546
9547                        // Do send the request (this may raise an exception)
9548                        xhr.send(options.hasContent && options.data || null);
9549                    } catch (e) {
9550
9551                        // #14683: Only rethrow if this hasn't been n
vendor: 10,557 bytes, lines 9551-9861
9551otified as an error yet
9552                        if (callback) {
9553                            throw e;
9554                        }
9555                    }
9556                },
9557
9558                abort: function () {
9559                    if (callback) {
9560                        callback();
9561                    }
9562                }
9563            };
9564        }
9565    });
9566
9567
9568// Prevent auto-execution of scripts when no explicit dataType was provided (See gh-2432)
9569    jQuery.ajaxPrefilter(function (s) {
9570        if (s.crossDomain) {
9571            s.contents.script = false;
9572        }
9573    });
9574
9575// Install script dataType
9576    jQuery.ajaxSetup({
9577        accepts: {
9578            script: "text/javascript, application/javascript, " +
9579                "application/ecmascript, application/x-ecmascript"
9580        },
9581        contents: {
9582            script: /\b(?:java|ecma)script\b/
9583        },
9584        converters: {
9585            "text script": function (text) {
9586                jQuery.globalEval(text);
9587                return text;
9588            }
9589        }
9590    });
9591
9592// Handle cache's special case and crossDomain
9593    jQuery.ajaxPrefilter("script", function (s) {
9594        if (s.cache === undefined) {
9595            s.cache = false;
9596        }
9597        if (s.crossDomain) {
9598            s.type = "GET";
9599        }
9600    });
9601
9602// Bind script tag hack transport
9603    jQuery.ajaxTransport("script", function (s) {
9604
9605        // This transport only deals with cross domain requests
9606        if (s.crossDomain) {
9607            var script, callback;
9608            return {
9609                send: function (_, complete) {
9610                    script = jQuery("<script>").prop({
9611                        charset: s.scriptCharset,
9612                        src: s.url
9613                    }).on(
9614                        "load error",
9615                        callback = function (evt) {
9616                            script.remove();
9617                            callback = null;
9618                            if (evt) {
9619                                complete(evt.type === "error" ? 404 : 200, evt.type);
9620                            }
9621                        }
9622                    );
9623
9624                    // Use native DOM manipulation to avoid our domManip AJAX trickery
9625                    document.head.appendChild(script[0]);
9626                },
9627                abort: function () {
9628                    if (callback) {
9629                        callback();
9630                    }
9631                }
9632            };
9633        }
9634    });
9635
9636
9637    var oldCallbacks = [],
9638        rjsonp = /(=)\?(?=&|$)|\?\?/;
9639
9640// Default jsonp settings
9641    jQuery.ajaxSetup({
9642        jsonp: "callback",
9643        jsonpCallback: function () {
9644            var callback = oldCallbacks.pop() || (jQuery.expando + "_" + (nonce++));
9645            this[callback] = true;
9646            return callback;
9647        }
9648    });
9649
9650// Detect, normalize options and install callbacks for jsonp requests
9651    jQuery.ajaxPrefilter("json jsonp", function (s, originalSettings, jqXHR) {
9652
9653        var callbackName, overwritten, responseContainer,
9654            jsonProp = s.jsonp !== false && (rjsonp.test(s.url) ?
9655                    "url" :
9656                    typeof s.data === "string" &&
9657                    (s.contentType || "")
9658                        .indexOf("application/x-www-form-urlencoded") === 0 &&
9659                    rjsonp.test(s.data) && "data"
9660            );
9661
9662        // Handle iff the expected data type is "jsonp" or we have a parameter to set
9663        if (jsonProp || s.dataTypes[0] === "jsonp") {
9664
9665            // Get callback name, remembering preexisting value associated with it
9666            callbackName = s.jsonpCallback = jQuery.isFunction(s.jsonpCallback) ?
9667                s.jsonpCallback() :
9668                s.jsonpCallback;
9669
9670            // Insert callback into url or form data
9671            if (jsonProp) {
9672                s[jsonProp] = s[jsonProp].replace(rjsonp, "$1" + callbackName);
9673            } else if (s.jsonp !== false) {
9674                s.url += (rquery.test(s.url) ? "&" : "?") + s.jsonp + "=" + callbackName;
9675            }
9676
9677            // Use data converter to retrieve json after script execution
9678            s.converters["script json"] = function () {
9679                if (!responseContainer) {
9680                    jQuery.error(callbackName + " was not called");
9681                }
9682                return responseContainer[0];
9683            };
9684
9685            // Force json dataType
9686            s.dataTypes[0] = "json";
9687
9688            // Install callback
9689            overwritten = window[callbackName];
9690            window[callbackName] = function () {
9691                responseContainer = arguments;
9692            };
9693
9694            // Clean-up function (fires after converters)
9695            jqXHR.always(function () {
9696
9697                // If previous value didn't exist - remove it
9698                if (overwritten === undefined) {
9699                    jQuery(window).removeProp(callbackName);
9700
9701                    // Otherwise restore preexisting value
9702                } else {
9703                    window[callbackName] = overwritten;
9704                }
9705
9706                // Save back as free
9707                if (s[callbackName]) {
9708
9709                    // Make sure that re-using the options doesn't screw things around
9710                    s.jsonpCallback = originalSettings.jsonpCallback;
9711
9712                    // Save the callback name for future use
9713                    oldCallbacks.push(callbackName);
9714                }
9715
9716                // Call if it was a function and we have a response
9717                if (responseContainer && jQuery.isFunction(overwritten)) {
9718                    overwritten(responseContainer[0]);
9719                }
9720
9721                responseContainer = overwritten = undefined;
9722            });
9723
9724            // Delegate to script
9725            return "script";
9726        }
9727    });
9728
9729
9730// Support: Safari 8 only
9731// In Safari 8 documents created via document.implementation.createHTMLDocument
9732// collapse sibling forms: the second one becomes a child of the first one.
9733// Because of that, this security measure has to be disabled in Safari 8.
9734// https://bugs.webkit.org/show_bug.cgi?id=137337
9735    support.createHTMLDocument = (function () {
9736        var body = document.implementation.createHTMLDocument("").body;
9737        body.innerHTML = "<form></form><form></form>";
9738        return body.childNodes.length === 2;
9739    })();
9740
9741
9742// Argument "data" should be string of html
9743// context (optional): If specified, the fragment will be created in this context,
9744// defaults to document
9745// keepScripts (optional): If true, will include scripts passed in the html string
9746    jQuery.parseHTML = function (data, context, keepScripts) {
9747        if (typeof data !== "string") {
9748            return [];
9749        }
9750        if (typeof context === "boolean") {
9751            keepScripts = context;
9752            context = false;
9753        }
9754
9755        var base, parsed, scripts;
9756
9757        if (!context) {
9758
9759            // Stop scripts or inline event handlers from being executed immediately
9760            // by using document.implementation
9761            if (support.createHTMLDocument) {
9762                context = document.implementation.createHTMLDocument("");
9763
9764                // Set the base href for the created document
9765                // so any parsed elements with URLs
9766                // are based on the document's URL (gh-2965)
9767                base = context.createElement("base");
9768                base.href = document.location.href;
9769                context.head.appendChild(base);
9770            } else {
9771                context = document;
9772            }
9773        }
9774
9775        parsed = rsingleTag.exec(data);
9776        scripts = !keepScripts && [];
9777
9778        // Single tag
9779        if (parsed) {
9780            return [context.createElement(parsed[1])];
9781        }
9782
9783        parsed = buildFragment([data], context, scripts);
9784
9785        if (scripts && scripts.length) {
9786            jQuery(scripts).remove();
9787        }
9788
9789        return jQuery.merge([], parsed.childNodes);
9790    };
9791
9792
9793    /**
9794     * Load a url into a page
9795     */
9796    jQuery.fn.load = function (url, params, callback) {
9797        var selector, type, response,
9798            self = this,
9799            off = url.indexOf(" ");
9800
9801        if (off > -1) {
9802            selector = stripAndCollapse(url.slice(off));
9803            url = url.slice(0, off);
9804        }
9805
9806        // If it's a function
9807        if (jQuery.isFunction(params)) {
9808
9809            // We assume that it's the callback
9810            callback = params;
9811            params = undefined;
9812
9813            // Otherwise, build a param string
9814        } else if (params && typeof params === "object") {
9815            type = "POST";
9816        }
9817
9818        // If we have elements to modify, make the request
9819        if (self.length > 0) {
9820            jQuery.ajax({
9821                url: url,
9822
9823                // If "type" variable is undefined, then "GET" method will be used.
9824                // Make value of this field explicit since
9825                // user can override it through ajaxSetup method
9826                type: type || "GET",
9827                dataType: "html",
9828                data: params
9829            }).done(function (responseText) {
9830
9831                // Save response for use in complete callback
9832                response = arguments;
9833
9834                self.html(selector ?
9835
9836                    // If a selector was specified, locate the right elements in a dummy div
9837                    // Exclude scripts to avoid IE 'Permission Denied' errors
9838                    jQuery("<div>").append(jQuery.parseHTML(responseText)).find(selector) :
9839
9840                    // Otherwise use the full result
9841                    responseText);
9842
9843                // If the request succeeds, this function gets "data", "status", "jqXHR"
9844                // but they are ignored because response was set above.
9845                // If it fails, this function gets "jqXHR", "status", "error"
9846            }).always(callback && function (jqXHR, status) {
9847                self.each(function () {
9848                    callback.apply(this, response || [jqXHR.responseText, status, jqXHR]);
9849                });
9850            });
9851        }
9852
9853        return this;
9854    };
9855
9856
9857// Attach a bunch of functions for handling common AJAX events
9858    jQuery.each([
9859        "ajaxStart",
9860        "ajaxStop",
9861        "ajaxComplete",
vendor: 6,137 bytes, lines 9862-10032
9862        "ajaxError",
9863        "ajaxSuccess",
9864        "ajaxSend"
9865    ], function (i, type) {
9866        jQuery.fn[type] = function (fn) {
9867            return this.on(type, fn);
9868        };
9869    });
9870
9871
9872    jQuery.expr.pseudos.animated = function (elem) {
9873        return jQuery.grep(jQuery.timers, function (fn) {
9874            return elem === fn.elem;
9875        }).length;
9876    };
9877
9878
9879    jQuery.offset = {
9880        setOffset: function (elem, options, i) {
9881            var curPosition, curLeft, curCSSTop, curTop, curOffset, curCSSLeft, calculatePosition,
9882                position = jQuery.css(elem, "position"),
9883                curElem = jQuery(elem),
9884                props = {};
9885
9886            // Set position first, in-case top/left are set even on static elem
9887            if (position === "static") {
9888                elem.style.position = "relative";
9889            }
9890
9891            curOffset = curElem.offset();
9892            curCSSTop = jQuery.css(elem, "top");
9893            curCSSLeft = jQuery.css(elem, "left");
9894            calculatePosition = (position === "absolute" || position === "fixed") &&
9895                (curCSSTop + curCSSLeft).indexOf("auto") > -1;
9896
9897            // Need to be able to calculate position if either
9898            // top or left is auto and position is either absolute or fixed
9899            if (calculatePosition) {
9900                curPosition = curElem.position();
9901                curTop = curPosition.top;
9902                curLeft = curPosition.left;
9903
9904            } else {
9905                curTop = parseFloat(curCSSTop) || 0;
9906                curLeft = parseFloat(curCSSLeft) || 0;
9907            }
9908
9909            if (jQuery.isFunction(options)) {
9910
9911                // Use jQuery.extend here to allow modification of coordinates argument (gh-1848)
9912                options = options.call(elem, i, jQuery.extend({}, curOffset));
9913            }
9914
9915            if (options.top != null) {
9916                props.top = (options.top - curOffset.top) + curTop;
9917            }
9918            if (options.left != null) {
9919                props.left = (options.left - curOffset.left) + curLeft;
9920            }
9921
9922            if ("using" in options) {
9923                options.using.call(elem, props);
9924
9925            } else {
9926                curElem.css(props);
9927            }
9928        }
9929    };
9930
9931    jQuery.fn.extend({
9932        offset: function (options) {
9933
9934            // Preserve chaining for setter
9935            if (arguments.length) {
9936                return options === undefined ?
9937                    this :
9938                    this.each(function (i) {
9939                        jQuery.offset.setOffset(this, options, i);
9940                    });
9941            }
9942
9943            var doc, docElem, rect, win,
9944                elem = this[0];
9945
9946            if (!elem) {
9947                return;
9948            }
9949
9950            // Return zeros for disconnected and hidden (display: none) elements (gh-2310)
9951            // Support: IE <=11 only
9952            // Running getBoundingClientRect on a
9953            // disconnected node in IE throws an error
9954            if (!elem.getClientRects().length) {
9955                return {top: 0, left: 0};
9956            }
9957
9958            rect = elem.getBoundingClientRect();
9959
9960            doc = elem.ownerDocument;
9961            docElem = doc.documentElement;
9962            win = doc.defaultView;
9963
9964            return {
9965                top: rect.top + win.pageYOffset - docElem.clientTop,
9966                left: rect.left + win.pageXOffset - docElem.clientLeft
9967            };
9968        },
9969
9970        position: function () {
9971            if (!this[0]) {
9972                return;
9973            }
9974
9975            var offsetParent, offset,
9976                elem = this[0],
9977                parentOffset = {top: 0, left: 0};
9978
9979            // Fixed elements are offset from window (parentOffset = {top:0, left: 0},
9980            // because it is its only offset parent
9981            if (jQuery.css(elem, "position") === "fixed") {
9982
9983                // Assume getBoundingClientRect is there when computed position is fixed
9984                offset = elem.getBoundingClientRect();
9985
9986            } else {
9987
9988                // Get *real* offsetParent
9989                offsetParent = this.offsetParent();
9990
9991                // Get correct offsets
9992                offset = this.offset();
9993                if (!nodeName(offsetParent[0], "html")) {
9994                    parentOffset = offsetParent.offset();
9995                }
9996
9997                // Add offsetParent borders
9998                parentOffset = {
9999                    top: parentOffset.top + jQuery.css(offsetParent[0], "borderTopWidth", true),
10000                    left: parentOffset.left + jQuery.css(offsetParent[0], "borderLeftWidth", true)
10001                };
10002            }
10003
10004            // Subtract parent offsets and element margins
10005            return {
10006                top: offset.top - parentOffset.top - jQuery.css(elem, "marginTop", true),
10007                left: offset.left - parentOffset.left - jQuery.css(elem, "marginLeft", true)
10008            };
10009        },
10010
10011        // This method will return documentElement in the following cases:
10012        // 1) For the element inside the iframe without offsetParent, this method will return
10013        // 	documentElement of the parent window
10014        // 2) For the hidden or detached element
10015        // 3) For body or html element, i.e. in case of the html node - it will return itself
10016        //
10017        // but those exceptions were never presented as a real life use-cases
10018        // and might be considered as more preferable results.
10019        //
10020        // This logic, however, is not guaranteed and can change at any point in the future
10021        offsetParent: function () {
10022            return this.map(function () {
10023                var offsetParent = this.offsetParent;
10024
10025                while (offsetParent && jQuery.css(offsetParent, "position") === "static") {
10026                    offsetParent = offsetParent.offsetParent;
10027                }
10028
10029                return offsetParent || documentElement;
10030            });
10031        }
10032    });
vendor: 4,280 bytes, lines 10033-10132
10033
10034// Create scrollLeft and scrollTop methods
10035    jQuery.each({scrollLeft: "pageXOffset", scrollTop: "pageYOffset"}, function (method, prop) {
10036        var top = "pageYOffset" === prop;
10037
10038        jQuery.fn[method] = function (val) {
10039            return access(this, function (elem, method, val) {
10040
10041                // Coalesce documents and windows
10042                var win;
10043                if (jQuery.isWindow(elem)) {
10044                    win = elem;
10045                } else if (elem.nodeType === 9) {
10046                    win = elem.defaultView;
10047                }
10048
10049                if (val === undefined) {
10050                    return win ? win[prop] : elem[method];
10051                }
10052
10053                if (win) {
10054                    win.scrollTo(
10055                        !top ? val : win.pageXOffset,
10056                        top ? val : win.pageYOffset
10057                    );
10058
10059                } else {
10060                    elem[method] = val;
10061                }
10062            }, method, val, arguments.length);
10063        };
10064    });
10065
10066// Support: Safari <=7 - 9.1, Chrome <=37 - 49
10067// Add the top/left cssHooks using jQuery.fn.position
10068// Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084
10069// Blink bug: https://bugs.chromium.org/p/chromium/issues/detail?id=589347
10070// getComputedStyle returns percent when specified for top/left/bottom/right;
10071// rather than make the css module depend on the offset module, just check for it here
10072    jQuery.each(["top", "left"], function (i, prop) {
10073        jQuery.cssHooks[prop] = addGetHookIf(support.pixelPosition,
10074            function (elem, computed) {
10075                if (computed) {
10076                    computed = curCSS(elem, prop);
10077
10078                    // If curCSS returns percentage, fallback to offset
10079                    return rnumnonpx.test(computed) ?
10080                        jQuery(elem).position()[prop] + "px" :
10081                        computed;
10082                }
10083            }
10084        );
10085    });
10086
10087
10088// Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods
10089    jQuery.each({Height: "height", Width: "width"}, function (name, type) {
10090        jQuery.each({padding: "inner" + name, content: type, "": "outer" + name},
10091            function (defaultExtra, funcName) {
10092
10093                // Margin is only for outerHeight, outerWidth
10094                jQuery.fn[funcName] = function (margin, value) {
10095                    var chainable = arguments.length && (defaultExtra || typeof margin !== "boolean"),
10096                        extra = defaultExtra || (margin === true || value === true ? "margin" : "border");
10097
10098                    return access(this, function (elem, type, value) {
10099                        var doc;
10100
10101                        if (jQuery.isWindow(elem)) {
10102
10103                            // $( window ).outerWidth/Height return w/h including scrollbars (gh-1729)
10104                            return funcName.indexOf("outer") === 0 ?
10105                                elem["inner" + name] :
10106                                elem.document.documentElement["client" + name];
10107                        }
10108
10109                        // Get document width or height
10110                        if (elem.nodeType === 9) {
10111                            doc = elem.documentElement;
10112
10113                            // Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height],
10114                            // whichever is greatest
10115                            return Math.max(
10116                                elem.body["scroll" + name], doc["scroll" + name],
10117                                elem.body["offset" + name], doc["offset" + name],
10118                                doc["client" + name]
10119                            );
10120                        }
10121
10122                        return value === undefined ?
10123
10124                            // Get width or height on the element, requesting but not forcing parseFloat
10125                            jQuery.css(elem, type, extra) :
10126
10127                            // Set width or height on the element
10128                            jQuery.style(elem, type, value, extra);
10129                    }, type, chainable ? margin : undefined, chainable);
10130                };
10131            });
10132    });
10133
10134
10135    jQuery.fn.extend({
10136
10137        bind: function (types, data, fn) {
10138            return this.on(types, null, data, fn);
10139        },
10140        unbind: function (types, fn) {
10141            return this.off(types, null, fn);
10142        },
10143
10144        delegate: function (selector, types, data, fn) {
10145            return this.on(types, selector, data, fn);
10146        },
10147        undelegate: function (selector, types, fn) {
10148
10149            // ( namespace ) or ( selector, types [, fn] )
10150            return arguments.length === 1 ?
10151                this.off(selector, "**") :
10152                this.off(types, selector || "**", fn);
10153        }
10154    });
10155
10156    jQuery.holdReady = function (hold) {
10157        if (hold) {
10158            jQuery.readyWait++;
10159        } else {
10160            jQuery.ready(true);
10161        }
10162    };
10163    jQuery.isArray = Array.isArray;
10164    jQuery.parseJSON = JSON.parse;
10165    jQuery.nodeName = nodeName;
10166
10167
10168// Register as a named AMD module, since jQuery can be concatenated with other
10169// files that may use define, but not via a proper concatenation script that
10170// understands anonymous AMD modules. A named AMD is safest and most robust
10171// way to register. Lowercase jquery is used because AMD module names are
10172// derived from file names, and jQuery is normally delivered in a lowercase
10173// file name. Do this after creating the global so that if an AMD module wants
10174// to call noConflict to hide this version of jQuery, it will work.
10175
10176// Note that for maximum portability, libraries that are not jQuery should
10177// declare themselves as anonymous modules, and avoid setting a global if an
10178// AMD loader is present. jQuery is a special case. For more information, see
10179// https://github.com/jrburke/requirejs/wiki/Updating-existing-libraries#wiki-anon
10180
10181    if (typeof define === "function" && define.amd) {
10182        define("jquery", [], function () {
10183            return jQuery;
10184        });
10185    }
10186
10187
10188    var
10189
10190        // Map over jQuery in case of overwrite
10191        _jQuery = window.jQuery,
10192
10193        // Map over the $ in case of overwrite
10194        _$ = window.$;
10195
10196    jQuery.noConflict = function (deep) {
10197        if (window.$ === jQuery) {
10198            window.$ = _$;
10199        }
10200
10201        if (deep && window.jQuery === jQuery) {
10202            window.jQuery = _jQuery;
10203        }
10204
10205        return jQuery;
10206    };
10207
10208// Expose jQuery and $ identifiers, even in AMD
10209// (#7102#comment:10, https://github.com/jquery/jquery/pull/557)
10210// and CommonJS for browser emulators (#13566)
10211    if (!noGlobal) {
10212        window.jQuery = window.$ = jQuery;
10213    }
10214
10215
10216    return jQuery;
10217});
10218// ==================================================
10219// fancyBox v3.1.20
10220//
10221// Licensed GPLv3 for open source use
10222// or fancyBox Commercial License for commercial use
10223//
10224// http://fancyapps.com/fancybox/
10225// Copyright 2017 fancyApps
10226//
10227// ==================================================
10228;(function (window, document, $, undefined) {
10229    'use strict';
10230
10231    // If there's no jQuery, fancyBox can't work
10232    // =========================================
10233
10234    if (!$) {
10235        return;
10236    }
10237
10238    // Check if fancyBox is already initialized
10239    // ========================================
10240
10241    if ($.fn.fancybox) {
10242
10243        $.error('fancyBox already initialized');
10244
10245        return;
10246    }
10247
10248    // Private default settings
10249    // ========================
10250
10251    var defaults = {
10252
10253        // Enable infinite gallery navigation
10254        loop: false,
10255
10256        // Space around image, ignored if zoomed-in or viewport smaller than 800px
10257        margin: [44, 0],
10258
10259        // Horizontal space between slides
10260        gutter: 50,
10261
10262        // Enable keyboard navigation
10263        keyboard: true,
10264
10265        // Should display navigation arrows at the screen edges
10266        arrows: true,
10267
10268        // Should display infobar (counter and arrows at the top)
10269        infobar: false,
10270
10271        // Should display toolbar (buttons at the top)
10272        toolbar: true,
10273
10274        // What buttons should appear in the top right corner.
10275        // Buttons will be created using templates from `btnTpl` option
10276        // and they will be placed into toolbar (class="fancybox-toolbar"` element)
10277        buttons: [
10278            'slideShow',
10279            'fullScreen',
10280            'thumbs',
10281            'close'
10282        ],
10283
10284        // Detect "idle" time in seconds
10285        idleTime: 4,
10286
10287        // Should display buttons at top right corner of the content
10288        // If 'auto' - they will be created for content having type 'html', 'inline' or 'ajax'
10289        // Use template from `btnTpl.smallBtn` for customization
10290        smallBtn: 'auto',
10291
10292        // Disable right-click and use simple image protection for images
10293        protect: false,
10294
10295        // Shortcut to make content "modal" - disable keyboard navigtion, hide buttons, etc
10296        modal: false,
10297
10298        image: {
10299
10300            // Wait for images to load before displaying
10301            // Requires predefined image dimensions
10302            // If 'auto' - will zoom in thumbnail if 'width' and 'height' attributes are found
10303            preload: "auto",
10304
10305        },
10306
10307        ajax: {
10308
10309            // Object containing settings for ajax request
10310            settings: {
10311
10312                // This helps to indicate that request comes from the modal
10313                // Feel free to change naming
10314                data: {
10315                    fancybox: true
10316                }
10317            }
10318
10319        },
10320
10321        iframe: {
10322
10323            // Iframe template
10324            tpl: '<iframe id="fancybox-frame{rnd}" name="fancybox-frame{rnd}" class="fancybox-iframe" frameborder="0" vspace="0" hspace="0" webkitAllowFullScreen mozallowfullscreen allowFullScreen allowtransparency="true" src=""></iframe>',
10325
10326            // Preload iframe before displaying it
10327            // This allows to calculate iframe content width and height
10328            // (note: Due to "Same Origin Policy", you can't get cross domain data).
10329            preload: true,
10330
10331            // Custom CSS styling for iframe wrapping element
10332            // You can use this to set custom iframe dimensions
10333            css: {},
10334
10335            // Iframe tag attributes
10336            attr: {
10337                scrolling: 'auto'
10338            }
10339
10340        },
10341
10342        // Open/close animation type
10343        // Possible values:
10344        // false						- disable
10345        // "zoom"					- zoom images from/to thumbnail
10346        // "fade"
10347        // "zoom-in-out"
10348        //
10349        animationEffect: "zoom",
10350
10351        // Duration in ms for open/close animation
10352        animationDuration: 366,
10353
10354        // Should image change opacity while zooming
10355        // If opacity is 'auto', then opacity will be changed if image and thumbnail have different aspect ratios
10356        zoomOpacity: 'auto',
10357
10358        // Transition effect between slides
10359        //
10360        // Possible values:
10361        // false						- disable
10362        // "fade'
10363        // "slide'
10364        // "circular'
10365        // "tube'
10366        // "zoom-in-out'
10367        // "rotate'
10368        //
10369        transitionEffect: "fade",
10370
10371        // Duration in ms for transition animation
10372        transitionDuration: 366,
10373
10374        // Custom CSS class for slide element
10375        slideClass: '',
10376
10377        // Custom CSS class for layout
10378        baseClass: '',
10379
10380        // Base template for layout
10381        baseTpl:
10382            '<div class="fancybox-container" role="dialog" tabindex="-1">' +
10383            '<div class="fancybox-bg"></div>' +
10384            '<div class="fancybox-inner">' +
10385            '<div class="fancybox-infobar">' +
10386            '<button data-fancybox-prev title="{{PREV}}" class="fancybox-button fancybox-button--left"></button>' +
10387            '<div class="fancybox-infobar__body">' +
10388            '<span data-fancybox-index></span>&nbsp;/&nbsp;<span data-fancybox-count></span>' +
10389            '</div>' +
10390            '<button data-fancybox-next title="{{NEXT}}" class="fancybox-button fancybox-button--right"></button>' +
10391            '</div>' +
10392            '<div class="fancybox-toolbar">' +
10393            '{{BUTTONS}}' +
10394            '</div>' +
10395            '<div class="fancybox-navigation">' +
10396            '<button data-fancybox-prev title="{{PREV}}" class="fancybox-arrow fancybox-arrow--left" />' +
10397            '<button data-fancybox-next title="{{NEXT}}" class="fancybox-arrow fancybox-arrow--right" />' +
10398            '</div>' +
10399            '<div class="fancybox-stage"></div>' +
10400            '<div class="fancybox-caption-wrap">' +
10401            '<div class="fancybox-caption"></div>' +
10402            '</div>' +
10403            '</div>' +
10404            '</div>',
10405
10406        // Loading indicator template
10407        spinnerTpl: '<div class="fancybox-loading"></div>',
10408
10409        // Error message template
10410        errorTpl: '<div class="fancybox-error"><p>{{ERROR}}<p></div>',
10411
10412        btnTpl: {
10413            slideShow: '<button data-fancybox-play class="fancybox-button fancybox-button--play" title="{{PLAY_START}}"></button>',
10414            fullScreen: '<button data-fancybox-fullscreen class="fancybox-button fancybox-button--fullscreen" title="{{FULL_SCREEN}}"></button>',
10415            thumbs: '<button data-fancybox-thumbs class="fancybox-button fancybox-button--thumbs" title="{{THUMBS}}"></button>',
10416            close: '<button data-fancybox-close class="fancybox-button fancybox-button--close" title="{{CLOSE}}"></button>',
10417
10418            // This small close button will be appended to your html/inline/ajax content by default,
10419            // if "smallBtn" option is not set to false
10420            smallBtn: '<button data-fancybox-close class="fancybox-close-small" title="{{CLOSE}}"></button>'
10421        },
10422
10423        // Container is injected into this element
10424        parentEl: 'body',
10425
10426
10427        // Focus handling
10428        // ==============
10429
10430        // Try to focus on the first focusable element after opening
10431        autoFocus: true,
10432
10433        // Put focus back to active element after closing
10434        backFocus: true,
10435
10436        // Do not let user to focus on element outside modal content
10437        trapFocus: true,
10438
10439
10440        // Module specific options
10441        // =======================
10442
10443        fullScreen: {
10444            autoStart: false,
10445        },
10446
10447        touch: {
10448            vertical: true,	// Allow to drag content vertically
10449            momentum: true	// Continue movement after releasing mouse/touch when panning
10450        },
10451
10452        // Hash value when initializing manually,
10453        // set `false` to disable hash change
10454        hash: null,
10455
10456        // Customize or add new media types
10457        // Example:
10458        /*
10459			media : {
10460					youtube : {
10461							params : {
10462									autoplay : 0
10463							}
10464					}
10465			}
10466			*/
10467        media: {},
10468
10469        slideShow: {
10470            autoStart: false,
10471            speed: 4000
10472        },
10473
10474        thumbs: {
10475            autoStart: false,	// Display thumbnails on opening
10476            hideOnClose: true		// Hide thumbnail grid when closing animation starts
10477        },
10478
10479        // Callbacks
10480        //==========
10481
10482        // See Documentation/API/Events for more information
10483        // Example:
10484        /*
10485					afterShow: function( instance, current ) {
10486							console.info( 'Clicked element:' );
10487							console.info( current.opts.$orig );
10488					}
10489			*/
10490
10491        onInit: $.noop,	// When instance has been initialized
10492
10493        beforeLoad: $.noop,	// Before the content of a slide is being loaded
10494        afterLoad: $.noop,	// When the content of a slide is done loading
10495
10496        beforeShow: $.noop,	// Before open animation starts
10497        afterShow: $.noop,	// When content is done loading and animating
10498
10499        beforeClose: $.noop,	// Before the instance attempts to close. Return false to cancel the close.
10500        afterClose: $.noop,	// After instance has been closed
10501
10502        onActivate: $.noop,	// When instance is brought to front
10503        onDeactivate: $.noop,	// When other instance has been activated
10504
10505
10506        // Interaction
10507        // ===========
10508
10509        // Use options below to customize taken action when user clicks or double clicks on the fancyBox area,
10510        // each option can be string or method that returns value.
10511        //
10512        // Possible values:
10513        //   "close"           - close instance
10514        //   "next"            - move to next gallery item
10515        //   "nextOrClose"     - move to next gallery item or close if gallery has only one item
10516        //   "toggleControls"  - show/hide controls
10517        //   "zoom"            - zoom image (if loaded)
10518        //   false             - do nothing
10519
10520        // Clicked on the content
10521        clickContent: function (current, event) {
10522            return current.type === 'image' ? 'zoom' : false;
10523        },
10524
10525        // Clicked on the slide
10526        clickSlide: 'close',
10527
10528        // Clicked on the background (backdrop) element
10529        clickOutside: 'close',
10530
10531        // Same as previous two, but for double click
10532        dblclickContent: false,
10533        dblclickSlide: false,
10534        dblclickOutside: false,
10535
10536
10537        // Custom options when mobile device is detected
10538        // =============================================
10539
10540        mobile: {
10541            clickContent: function (current, event) {
10542                return current.type === 'image' ? 'toggleControls' : false;
10543            },
10544            clickSlide: function (current, event) {
10545                return current.type === 'image' ? 'toggleControls' : "close";
10546            },
10547            dblclickContent: function (current, event) {
10548                return current.type === 'image' ? 'zoom' : false;
10549            },
10550            dblclickSlide: function (current, event) {
10551                return current.type === 'image' ? 'zoom' : false;
10552            }
10553        },
10554
10555
10556        // Internationalization
10557        // ============
10558
10559        lang: 'en',
10560        i18n: {
10561            'en': {
10562                CLOSE: 'Close',
10563                NEXT: 'Next',
10564                PREV: 'Previous',
10565                ERROR: 'The requested content cannot be loaded. <br/> Please try again later.',
10566                PLAY_START: 'Start slideshow',
10567                PLAY_STOP: 'Pause slideshow',
10568                FULL_SCREEN: 'Full screen',
10569                THUMBS: 'Thumbnails'
10570            },
10571            'de': {
10572                CLOSE: 'Schliessen',
10573                NEXT: 'Weiter',
10574                PREV: 'Zurück',
10575                ERROR: 'Die angeforderten Daten konnten nicht geladen werden. <br/>
10575 Bitte versuchen Sie es später nochmal.',
10576                PLAY_START: 'Diaschau starten',
10577                PLAY_STOP: 'Diaschau beenden',
10578                FULL_SCREEN: 'Vollbild',
10579                THUMBS: 'Vorschaubilder'
10580            }
10581        }
10582
10583    };
10584
10585    // Few useful variables and methods
10586    // ================================
10587
10588    var $W = $(window);
10589    var $D = $(document);
10590
10591    var called = 0;
10592
10593
10594    // Check if an object is a jQuery object and not a native JavaScript object
10595    // ========================================================================
10596
10597    var isQuery = function (obj) {
10598        return obj && obj.hasOwnProperty && obj instanceof $;
10599    };
10600
10601
10602    // Handle multiple browsers for "requestAnimationFrame" and "cancelAnimationFrame"
10603    // ===============================================================================
10604
10605    var requestAFrame = (function () {
10606        return window.requestAnimationFrame ||
10607            window.webkitRequestAnimationFrame ||
10608            window.mozRequestAnimationFrame ||
10609            window.oRequestAnimationFrame ||
10610            // if all else fails, use setTimeout
10611            function (callback) {
10612                return window.setTimeout(callback, 1000 / 60);
10613            };
10614    })();
10615
10616
10617    // Detect the supported transition-end event property name
10618    // =======================================================
10619
10620    var transitionEnd = (function () {
10621        var t, el = document.createElement("fakeelement");
10622
10623        var transitions = {
10624            "transition": "transitionend",
10625            "OTransition": "oTransitionEnd",
10626            "MozTransition": "transitionend",
10627            "WebkitTransition": "webkitTransitionEnd"
10628        };
10629
10630        for (t in transitions) {
10631            if (el.style[t] !== undefined) {
10632                return transitions[t];
10633            }
10634        }
10635    })();
10636
10637
10638    // Force redraw on an element.
10639    // This helps in cases where the browser doesn't redraw an updated element properly.
10640    // =================================================================================
10641
10642    var forceRedraw = function ($el) {
10643        return ($el && $el.length && $el[0].offsetHeight);
10644    };
10645
10646
10647    // Class definition
10648    // ================
10649
10650    var FancyBox = function (content, opts, index) {
10651        var self = this;
10652
10653        self.opts = $.extend(true, {index: index}, defaults, opts || {});
10654
10655        // Exclude buttons option from deep merging
10656        if (opts && $.isArray(opts.buttons)) {
10657            self.opts.buttons = opts.buttons;
10658        }
10659
10660        self.id = self.opts.id || ++called;
10661        self.group = [];
10662
10663        self.currIndex = parseInt(self.opts.index, 10) || 0;
10664        self.prevIndex = null;
10665
10666        self.prevPos = null;
10667        self.currPos = 0;
10668
10669        self.firstRun = null;
10670
10671        // Create group elements from original item collection
10672        self.createGroup(content);
10673
10674        if (!self.group.length) {
10675            return;
10676        }
10677
10678        // Save last active element and current scroll position
10679        self.$lastFocus = $(document.activeElement).blur();
10680
10681        // Collection of gallery objects
10682        self.slides = {};
10683
10684        self.init(content);
10685
10686    };
10687
10688    $.extend(FancyBox.prototype, {
10689
10690        // Create DOM structure
10691        // ====================
10692
10693        init: function () {
10694            var self = this;
10695
10696            var testWidth, $container, buttonStr;
10697
10698            var firstItemOpts = self.group[self.currIndex].opts;
10699
10700            self.scrollTop = $D.scrollTop();
10701            self.scrollLeft = $D.scrollLeft();
10702
10703
10704            // Hide scrollbars
10705            // ===============
10706
10707            if (!$.fancybox.getInstance() && !$.fancybox.isMobile && $('body').css('overflow') !== 'hidden') {
10708                testWidth = $('body').width();
10709
10710                $('html').addClass('fancybox-enabled');
10711
10712                // Compare body width after applying "overflow: hidden"
10713                testWidth = $('body').width() - testWidth;
10714
10715                // If width has changed - compensate missing scrollbars by adding right margin
10716                if (testWidth > 1) {
10717                    $('head').append('<style id="fancybox-style-noscroll" type="text/css">.compensate-for-scrollbar, .fancybox-enabled body { margin-right: ' + testWidth + 'px; }</style>');
10718                }
10719            }
10720
10721
10722            // Build html markup and set references
10723            // ====================================
10724
10725            // Build html code for buttons and insert into main template
10726            buttonStr = '';
10727
10728            $.each(firstItemOpts.buttons, function (index, value) {
10729                buttonStr += (firstItemOpts.btnTpl[value] || '');
10730            });
10731
10732            // Create markup from base template, it will be initially hidden to
10733            // avoid unnecessary work like painting while initializing is not complete
10734            $container = $(self.translate(self, firstItemOpts.baseTpl.replace('\{\{BUTTONS\}\}', buttonStr)))
10735                .addClass('fancybox-is-hidden')
10736                .attr('id', 'fancybox-container-' + self.id)
10737                .addClass(firstItemOpts.baseClass)
10738                .data('FancyBox', self)
10739                .prependTo(firstItemOpts.parentEl);
10740
10741            // Create object holding references to jQuery wrapped nodes
10742            self.$refs = {
10743                container: $container
10744            };
10745
10746            ['bg', 'inner', 'infobar', 'toolbar', 'stage', 'caption'].forEach(function (item) {
10747                self.$refs[item] = $container.find('.fancybox-' + item);
10748            });
10749
10750            // Check for redundant elements
10751            if (!firstItemOpts.arrows || self.group.length < 2) {
10752                $container.find('.fancybox-navigation').remove();
10753            }
10754
10755            if (!firstItemOpts.infobar) {
10756                self.$refs.infobar.remove();
10757            }
10758
10759            if (!firstItemOpts.toolbar) {
10760                self.$refs.toolbar.remove();
10761            }
10762
10763            self.trigger('onInit');
10764
10765            // Bring to front and enable events
10766            self.activate();
10767
10768            // Build slides, load and reveal content
10769            self.jumpTo(self.currIndex);
10770        },
10771
10772
10773        // Simple i18n support - replaces object keys found in template
10774        // with corresponding values
10775        // ============================================================
10776
10777        translate: function (obj, str) {
10778            var arr = obj.opts.i18n[obj.opts.lang];
10779
10780            return str.replace(/\{\{(\w+)\}\}/g, function (match, n) {
10781                var value = arr[n];
10782
10783                if (value === undefined) {
10784                    return match;
10785                }
10786
10787                return value;
10788            });
10789        },
10790
10791        // Create array of gally item objects
10792        // Check if each object has valid type and content
10793        // ===============================================
10794
10795        createGroup: function (content) {
10796            var self = this;
10797            var items = $.makeArray(content);
10798
10799            $.each(items, function (i, item) {
10800                var obj = {},
10801                    opts = {},
10802                    data = [],
10803                    $item,
10804                    type,
10805                    src,
10806                    srcParts;
10807
10808                // Step 1 - Make sure we have an object
10809                // ====================================
10810
10811                if ($.isPlainObject(item)) {
10812
10813                    // We probably have manual usage here, something like
10814                    // $.fancybox.open( [ { src : "image.jpg", type : "image" } ] )
10815
10816                    obj = item;
10817                    opts = item.opts || item;
10818
10819                } else if ($.type(item) === 'object' && $(item).length) {
10820
10821                    // Here we propbably have jQuery collection returned by some selector
10822
10823                    $item = $(item);
10824                    data = $item.data();
10825
10826                    opts = 'options' in data ? data.options : {};
10827                    opts = $.type(opts) === 'object' ? opts : {};
10828
10829                    obj.src = 'src' in data ? data.src : (opts.src || $item.attr('href'));
10830
10831                    ['width', 'height', 'thumb', 'type', 'filter'].forEach(function (item) {
10832                        if (item in data) {
10833                            opts[item] = data[item];
10834                        }
10835                    });
10836
10837                    if ('srcset' in data) {
10838                        opts.image = {srcset: data.srcset};
10839                    }
10840
10841                    opts.$orig = $item;
10842
10843                    if (!obj.type && !obj.src) {
10844                        obj.type = 'inline';
10845                        obj.src = item;
10846                    }
10847
10848                } else {
10849
10850                    // Assume we have a simple html code, for example:
10851                    // $.fancybox.open( '<div><h1>Hi!</h1></div>' );
10852
10853                    obj = {
10854                        type: 'html',
10855                        src: item + ''
10856                    };
10857
10858                }
10859
10860                // Each gallery object has full collection of options
10861                obj.opts = $.extend(true, {}, self.opts, opts);
10862
10863                if ($.fancybox.isMobile) {
10864                    obj.opts = $.extend(true, {}, obj.opts, obj.opts.mobile);
10865                }
10866
10867
10868                // Step 2 - Make sure we have content type, if not - try to guess
10869                // ==============================================================
10870
10871                type = obj.type || obj.opts.type;
10872                src = obj.src || '';
10873
10874                if (!type && src) {
10875                    if (src.match(/(^data:image\/[a-z0-9+\/=]*,)|(\.(jp(e|g|eg)|gif|png|bmp|webp|svg|ico)((\?|#).*)?$)/i)) {
10876                        type = 'image';
10877
10878                    } else if (src.match(/\.(pdf)((\?|#).*)?$/i)) {
10879                        type = 'pdf';
10880
10881                    } else if (src.charAt(0) === '#') {
10882                        type = 'inline';
10883                    }
10884                }
10885
10886                obj.type = type;
10887
10888
10889                // Step 3 - Some adjustments
10890                // =========================
10891
10892                obj.index = self.group.length;
10893
10894                // Check if $orig and $thumb objects exist
10895                if (obj.opts.$orig && !obj.opts.$orig.length) {
10896                    delete obj.opts.$orig;
10897                }
10898
10899                if (!obj.opts.$thumb && obj.opts.$orig) {
10900                    obj.opts.$thumb = obj.opts.$orig.find('img:first');
10901                }
10902
10903                if (obj.opts.$thumb && !obj.opts.$thumb.length) {
10904                    delete obj.opts.$thumb;
10905                }
10906
10907                // Caption is a "special" option, it can be passed as a method
10908                if ($.type(obj.opts.caption) === 'function') {
10909                    obj.opts.caption = obj.opts.caption.apply(item, [self, obj]);
10910
10911                } else if ('caption' in data) {
10912                    obj.opts.caption = data.caption;
10913                }
10914
10915                // Make sure we have caption as a string
10916                obj.opts.caption = obj.opts.caption === undefined ? '' : obj.opts.caption + '';
10917
10918                // Check if url contains "filter" used to filter the content
10919                // Example: "ajax.html #something"
10920                if (type === 'ajax') {
10921                    srcParts = src.split(/\s+/, 2);
10922
10923                    if (srcParts.length > 1) {
10924                        obj.src = srcParts.shift();
10925
10926                        obj.opts.filter = srcParts.shift();
10927                    }
10928                }
10929
10930                if (obj.opts.smallBtn == 'auto') {
10931
10932                    if ($.inArray(type, ['html', 'inline', 'ajax']) > -1) {
10933                        obj.opts.toolbar = false;
10934                        obj.opts.smallBtn = true;
10935
10936                    } else {
10937                        obj.opts.smallBtn = false;
10938                    }
10939
10940                }
10941
10942                // If the type is "pdf", then simply load file into iframe
10943                if (type === 'pdf') {
10944                    obj.type = 'iframe';
10945
10946                    obj.opts.iframe.preload = false;
10947                }
10948
10949                // Hide all buttons and disable interactivity for modal items
10950                if (obj.opts.modal) {
10951
10952                    obj.opts = $.extend(true, obj.opts, {
10953                        // Remove buttons
10954                        infobar: 0,
10955                        toolbar: 0,
10956
10957                        smallBtn: 0,
10958
10959                        // Disable keyboard navigation
10960                        keyboard: 0,
10961
10962                        // Disable some modules
10963                        slideShow: 0,
10964                        fullScreen: 0,
10965                        thumbs: 0,
10966                        touch: 0,
10967
10968                        // Disable click event handlers
10969                        clickContent: false,
10970                        clickSlide: false,
10971                        clickOutside: false,
10972                        dblclickContent: false,
10973                        dblclickSlide: false,
10974                        dblclickOutside: false
10975                    });
10976
10977                }
10978
10979                // Step 4 - Add processed object to group
10980                // ======================================
10981
10982                self.group.push(obj);
10983
10984            });
10985
10986        },
10987
10988
10989        // Attach an event handler functions for:
10990        // - navigation buttons
10991        // - browser scrolling, resizing;
10992        // - focusing
10993        // - keyboard
10994        // - detect idle
10995        // ======================================
10996
10997        addEvents: function () {
10998            var self = this;
10999
11000            self.removeEvents();
11001
11002            // Make navigation elements clickable
11003            self.$refs.container.on('click.fb-close', '[data-fancybox-close]', function (e) {
11004                e.stopPropagation();
11005                e.preventDefault();
11006
11007                self.close(e);
11008
11009            }).on('click.fb-prev touchend.fb-prev', '[data-fancybox-prev]', function (e) {
11010                e.stopPropagation();
11011                e.preventDefault();
11012
11013                self.previous();
11014
11015            }).on('click.fb-next touchend.fb-next', '[data-fancybox-next]', function (e) {
11016                e.stopPropagation();
11017                e.preventDefault();
11018
11019                self.next();
11020
11021            });
11022
11023
11024            // Handle page scrolling and browser resizing
11025            $W.on('orientationchange.fb resize.fb', function (e) {
11026
11027                if (e && e.originalEvent && e.originalEvent.type === "resize") {
11028
11029                    requestAFrame(function () {
11030                        self.update();
11031                    });
11032
11033                } else {
11034
11035                    self.$refs.stage.hide();
11036
11037                    setTimeout(function () {
11038                        self.$refs.stage.show();
11039
11040                        self.update();
11041                    }, 500);
11042
11043                }
11044
11045            });
11046
11047            // Trap keyboard focus inside of the modal, so the user does not accidentally tab outside of the modal
11048            // (a.k.a. "escaping the modal")
11049            $D.on('focusin.fb', function (e) {
11050                var instance = $.fancybox ? $.fancybox.getInstance() : null;
11051
11052                if (instance.isClosing || !instance.current || !instance.current.opts.trapFocus || $(e.target).hasClass('fancybox-container') || $(e.target).is(document)) {
11053                    return;
11054                }
11055
11056                if (instance && $(e.target).css('position') !== 'fixed' && !instance.$refs.container.has(e.target).length) {
11057                    e.stopPropagation();
11058
11059                    instance.focus();
11060
11061                    // Sometimes page gets scrolled, set it back
11062                    $W.scrollTop(self.scrollTop).scrollLeft(self.scrollLeft);
11063                }
11064            });
11065
11066
11067            // Enable keyboard navigation
11068            $D.on('keydown.fb', function (e) {
11069                var current = self.current,
11070                    keycode = e.keyCode || e.which;
11071
11072                if (!current || !current.opts.keyboard) {
11073                    return;
11074                }
11075
11076                if ($(e.target).is('input') || $(e.target).is('textarea')) {
11077                    return;
11078                }
11079
11080                // Backspace and Esc keys
11081                if (keycode === 8 || keycode === 27) {
11082                    e.preventDefault();
11083
11084                    self.close(e);
11085
11086                    return;
11087                }
11088
11089                // Left arrow and Up arrow
11090                if (keycode === 37 || keycode === 38) {
11091                    e.preventDefault();
11092
11093                    self.previous();
11094
11095                    return;
11096                }
11097
11098                // Righ arrow and Down arrow
11099                if (keycode === 39 || keycode === 40) {
11100                    e.preventDefault();
11101
11102                    self.next();
11103
11104                    return;
11105                }
11106
11107                self.trigger('afterKeydown', e, keycode);
11108            });
11109
11110
11111            // Hide controls after some inactivity period
11112            if (self.group[self.currIndex].opts.idleTime) {
11113                self.idleSecondsCounter = 0;
11114
11115                $D.on('mousemove.fb-idle mouseenter.fb-idle mouseleave.fb-idle mousedown.fb-idle touchstart.fb-idle touchmove.fb-idle scroll.fb-idle keydown.fb-idle', function () {
11116                    self.idleSecondsCounter = 0;
11117
11118                    if (self.isIdle) {
11119                        self.showControls();
11120                    }
11121
11122                    self.isIdle = false;
11123                });
11124
11125                self.idleInterval = window.setInterval(function () {
11126
11127                    self.idleSecondsCounter++;
11128
11129                    if (self.idleSecondsCounter >= self.group[self.currIndex].opts.idleTime) {
11130                        self.isIdle = true;
11131                        self.idleSecondsCounter = 0;
11132
11133                        self.hideControls();
11134                    }
11135
11136                }, 1000);
11137            }
11138
11139        },
11140
11141
11142        // Remove events added by the core
11143        // ===============================
11144
11145        removeEvents: function () {
11146            var self = this;
11147
11148            $W.off('orientationchange.fb resize.fb');
11149            $D.off('focusin.fb keydown.fb .fb-idle');
11150
11151            this.$refs.container.off('.fb-close .fb-prev .fb-next');
11152
11153            if (self.idleInterval) {
11154                window.clearInterval(self.idleInterval);
11155
11156                self.idleInterval = null;
11157            }
11158        },
11159
11160
11161        // Change to previous gallery item
11162        // ===============================
11163
11164        previous: function (duration) {
11165            return this.jumpTo(this.currPos - 1, duration);
11166        },
11167
11168
11169        // Change to next gallery item
11170        // ===========================
11171
11172        next: function (duration) {
11173            return this.jumpTo(this.currPos + 1, duration);
11174        },
11175
11176
11177        // Switch to selected gallery item
11178        // ===============================
11179
11180        jumpTo: function (pos, duration, slide) {
11181            var self = this,
11182                firstRun,
11183                loop,
11184                current,
11185                previous,
11186                canvasWidth,
11187                currentPos,
11188                transitionProps;
11189
11190            var groupLen = self.group.length;
11191
11192            if (self.isSliding || self.isClosing || (self.isAnimating && self.firstRun)) {
11193                return;
11194            }
11195
11196            pos = parseInt(pos, 10);
11197            loop = self.current ? self.current.opts.loop : self.opts.loop;
11198
11199            if (!loop && (pos < 0 || pos >= groupLen)) {
11200                return false;
11201            }
11202
11203            firstRun = self.firstRun = (self.firstRun === null);
11204
11205            if (groupLen < 2 && !firstRun && !!self.isSliding) {
11206                return;
11207            }
11208
11209            previous = self.current;
11210
11211            self.prevIndex = self.currIndex;
11212            self.prevPos = self.currPos;
11213
11214            // Create slides
11215            current = self.createSlide(pos);
11216
11217            if (groupLen > 1) {
11218                if (loop || current.index > 0) {
11219                    self.createSlide(pos - 1);
11220                }
11221
11222                if (loop || current.index < groupLen - 1) {
11223                    self.createSlide(pos + 1);
11224                }
11225            }
11226
11227            self.current = current;
11228            self.currIndex = current.index;
11229            self.currPos = current.pos;
11230
11231            self.trigger('beforeShow', firstRun);
11232
11233            self.updateControls();
11234
11235            currentPos = $.fancybox.getTranslate(current.$slide);
11236
11237            current.isMoved = (currentPos.left !== 0 || currentPos.top !== 0) && !current.$slide.hasClass('fancybox-animated');
11238            current.forcedDuration = undefined;
11239
11240            if ($.isNumeric(duration)) {
11241                current.forcedDuration = duration;
11242            } else {
11243                duration = current.opts[firstRun ? 'animationDuration' : 'transitionDuration'];
11244            }
11245
11246            duration = parseInt(duration, 10);
11247
11248            // Fresh start - reveal container, current slide and start loading content
11249            if (firstRun) {
11250
11251                if (current.opts.animationEffect && duration) {
11252                    self.$refs.container.css('transition-duration', duration + 'ms');
11253                }
11254
11255                self.$refs.container.removeClass('fancybox-is-hidden');
11256
11257                forceRedraw(self.$refs.container);
11258
11259                self.$refs.container.addClass('fancybox-is-open');
11260
11261                // Make first slide visible (to display loading icon, if needed)
11262                current.$slide.addClass('fancybox-slide--current');
11263
11264                self.loadSlide(current);
11265
11266                self.preload();
11267
11268                return;
11269            }
11270
11271            // Clean up
11272            $.each(self.slides, function (index, slide) {
11273                $.fancybox.stop(slide.$slide);
11274            });
11275
11276            // Make current that slide is visible even if content is still loading
11277            current.$slide.removeClass('fancybox-slide--next fancybox-slide--previous').addClass('fancybox-slide--current');
11278
11279            // If slides have been dragged, animate them to correct position
11280            if (current.isMoved) {
11281                canvasWidth = Math.round(current.$slide.width());
11282
11283                $.each(self.slides, function (index, slide) {
11284                    var pos = slide.pos - current.pos;
11285
11286                    $.fancybox.animate(slide.$slide, {
11287                        top: 0,
11288                        left: (pos * canvasWidth) + (pos * slide.opts.gutter)
11289                    }, duration, function () {
11290
11291                        slide.$slide.removeAttr('style').removeClass('fancybox-slide--next fancybox-slide--previous');
11292
11293                        if (slide.pos === self.currPos) {
11294                            current.isMoved = false;
11295
11296                            self.complete();
11297                        }
11298                    });
11299                });
11300
11301            } else {
11302                self.$refs.stage.children().removeAttr('style');
11303            }
11304
11305            // Start transition that reveals current content
11306            // or wait when it will be loaded
11307
11308            if (current.isLoaded) {
11309                self.revealContent(current);
11310
11311            } else {
11312                self.loadSlide(current);
11313            }
11314
11315            self.preload();
11316
11317            if (previous.pos === current.pos) {
11318                return;
11319            }
11320
11321            // Handle previous slide
11322            // =====================
11323
11324            transitionProps = 'fancybox-slide--' + (previous.pos > current.pos ? 'next' : 'previous');
11325
11326            previous.$slide.removeClass('fancybox-slide--complete fancybox-slide--current fancybox-slide--next fancybox-slide--previous');
11327
11328            previous.isComplete = false;
11329
11330            if (!duration || (!current.isMoved && !current.opts.transitionEffect)) {
11331                return;
11332            }
11333
11334            if (current.isMoved) {
11335                previous.$slide.addClass(transitionProps);
11336
11337            } else {
11338
11339                transitionProps = 'fancybox-animated ' + transitionProps + ' fancybox-fx-' + current.opts.transitionEffect;
11340
11341                $.fancybox.animate(previous.$slide, transitionProps, duration, function () {
11342                    previous.$slide.removeClass(transitionProps).removeAttr('style');
11343                });
11344
11345            }
11346
11347        },
11348
11349
11350        // Create new "slide" element
11351        // These are gallery items	that are actually added to DOM
11352        // =======================================================
11353
11354        createSlide: function (pos) {
11355
11356            var self = this;
11357            var $slide;
11358            var index;
11359
11360            index = pos % self.group.length;
11361            index = index < 0 ? self.group.length + index : index;
11362
11363            if (!self.slides[pos] && self.group[index]) {
11364                $slide = $('<div class="fancybox-slide"></div>').appendTo(self.$refs.stage);
11365
11366                self.slides[pos] = $.extend(true, {}, self.group[index], {
11367                    pos: pos,
11368                    $slide: $slide,
11369                    isLoaded: false,
11370                });
11371
11372                self.updateSlide(self.slides[pos]);
11373            }
11374
11375            return self.slides[pos];
11376        },
11377
11378
11379        // Scale image to the actual size of the image
11380        // ===========================================
11381
11382        scaleToActual: function (x, y, duration) {
11383
11384            var self = this;
11385
11386            var current = self.current;
11387            var $what = current.$content;
11388
11389            var imgPos, posX, posY, scaleX, scaleY;
11390
11391            var canvasWidth = parseInt(current.$slide.width(), 10);
11392            var canvasHeight = parseInt(current.$slide.height(), 10);
11393
11394            var newImgWidth = current.width;
11395            var newImgHeight = current.height;
11396
11397            if (!(current.type == 'image' && !current.hasError) || !$what || self.isAnimating) {
11398                return;
11399            }
11400
11401            $.fancybox.stop($what);
11402
11403            self.isAnimating = true;
11404
11405            x = x === undefined ? canvasWidth * 0.5 : x;
11406            y = y === undefined ? canvasHeight * 0.5 : y;
11407
11408            imgPos = $.fancybox.getTranslate($what);
11409
11410            scaleX = newImgWidth / imgPos.width;
11411            scaleY = newImgHeight / imgPos.height;
11412
11413            // Get center position for original image
11414            posX = (canvasWidth * 0.5 - newImgWidth * 0.5);
11415            posY = (canvasHeight * 0.5 - newImgHeight * 0.5);
11416
11417            // Make sure image does not move away from edges
11418            if (newImgWidth > canvasWidth) {
11419                posX = imgPos.left * scaleX - ((x * scaleX) - x);
11420
11421                if (posX > 0) {
11422                    posX = 0;
11423                }
11424
11425                if (posX < canvasWidth - newImgWidth) {
11426                    posX = canvasWidth - newImgWidth;
11427                }
11428            }
11429
11430            if (newImgHeight > canvasHeight) {
11431                posY = imgPos.top * scaleY - ((y * scaleY) - y);
11432
11433                if (posY > 0) {
11434                    posY = 0;
11435                }
11436
11437                if (posY < canvasHeight - newImgHeight) {
11438                    posY = canvasHeight - newImgHeight;
11439                }
11440            }
11441
11442            self.updateCursor(newImgWidth, newImgHeight);
11443
11444            $.fancybox.animate($what, {
11445                top: posY,
11446                left: posX,
11447                scaleX: scaleX,
11448                scaleY: scaleY
11449            }, duration || 330, function () {
11450                self.isAnimating = false;
11451            });
11452
11453            // Stop slideshow
11454            if (self.SlideShow && self.SlideShow.isActive) {
11455                self.SlideShow.stop();
11456            }
11457        },
11458
11459
11460        // Scale image to fit inside parent element
11461        // ========================================
11462
11463        scaleToFit: function (duration) {
11464
11465            var self = this;
11466
11467            var current = self.current;
11468            var $what = current.$content;
11469            var end;
11470
11471            if (!(current.type == 'image' && !current.hasError) || !$what || self.isAnimating) {
11472                return;
11473            }
11474
11475            $.fancybox.stop($what);
11476
11477            self.isAnimating = true;
11478
11479            end = self.getFitPos(current);
11480
11481            self.updateCursor(end.width, end.height);
11482
11483            $.fancybox.animate($what, {
11484                top: end.top,
11485                left: end.left,
11486                scaleX: end.width / $what.width(),
11487                scaleY: end.height / $what.height()
11488            }, duration || 330, function () {
11489                self.isAnimating = false;
11490            });
11491
11492        },
11493
11494        // Calculate image size to fit inside viewport
11495        // ===========================================
11496
11497        getFitPos: function (slide) {
11498            var self = this;
11499            var $what = slide.$content;
11500
11501            var imgWidth = slide.width;
11502            var imgHeight = slide.height;
11503
11504            var margin = slide.opts.margin;
11505
11506            var canvasWidth, canvasHeight, minRatio, width, height;
11507
11508            if (!$what || !$what.length || (!imgWidth && !imgHeight)) {
11509                return false;
11510            }
11511
11512            // Convert "margin to CSS style: [ top, right, bottom, left ]
11513            if ($.type(margin) === "number") {
11514                margin = [margin, margin];
11515            }
11516
11517            if (margin.length == 2) {
11518                margin = [margin[0], margin[1], margin[0], margin[1]];
11519            }
11520
11521            if ($W.width() < 800) {
11522                margin = [0, 0, 0, 0];
11523            }
11524
11525            // We can not use $slide width here, because it can have different diemensions while in transiton
11526            canvasWidth = parseInt(self.$refs.stage.width(), 10) - (margin[1] + margin[3]);
11527            canvasHeight = parseInt(self.$refs.stage.height(), 10) - (margin[0] + margin[2]);
11528
11529            minRatio = Math.min(1, canvasWidth / imgWidth, canvasHeight / imgHeight);
11530
11531            width = Math.floor(minRatio * imgWidth);
11532            height = Math.floor(minRatio * imgHeight);
11533
11534            // Use floor rounding to make sure it really fits
11535            return {
11536                top: Math.floor((canvasHeight - height) * 0.5) + margin[0],
11537                left: Math.floor((canvasWidth - width) * 0.5) + margin[3],
11538                width: width,
11539                height: height
11540            };
11541
11542        },
11543
11544
11545        // Update position and content of all slides
11546        // =========================================
11547
11548        update: function () {
11549
11550            var self = this;
11551
11552            $.each(self.slides, function (key, slide) {
11553                self.updateSlide(slide);
11554            });
11555
11556        },
11557
11558
11559        // Update slide position and scale content to fit
11560        // ==============================================
11561
11562        updateSlide: function (slide) {
11563
11564            var self = this;
11565            var $what = slide.$content;
11566
11567            if ($what && (slide.width || slide.height)) {
11568                $.fancybox.stop($what);
11569
11570                $.fancybox.setTranslate($what, self.getFitPos(slide));
11571
11572                if (slide.pos === self.currPos) {
11573                    self.updateCursor();
11574                }
11575            }
11576
11577            slide.$slide.trigger('refresh');
11578
11579            self.trigger('onUpdate', slide);
11580
11581        },
11582
11583        // Update cursor style depending if content can be zoomed
11584        // ======================================================
11585
11586        updateCursor: function (nextWidth, nextHeight) {
11587
11588            var self = this;
11589            var isScaledDown;
11590
11591            var $container = self.$refs.container.removeClass('fancybox-is-zoomable fancybox-can-zoomIn fancybox-can-drag fancybox-can-zoomOut');
11592
11593            if (!self.current || self.isClosing) {
11594                return;
11595            }
11596
11597            if (self.isZoomable()) {
11598
11599                $container.addClass('fancybox-is-zoomable');
11600
11601                if (nextWidth !== undefined && nextHeight !== undefined) {
11602                    isScaledDown = nextWidth < self.current.width && nextHeight < self.current.height;
11603
11604                } else {
11605                    isScaledDown = self.isScaledDown();
11606                }
11607
11608                if (isScaledDown) {
11609
11610                    // If image is scaled down, then, obviously, it can be zoomed to full size
11611                    $container.addClass('fancybox-can-zoomIn');
11612
11613                } else {
11614
11615                    if (self.current.opts.touch) {
11616
11617                        // If image size ir largen than available available and touch module is not disable,
11618                        // then user can do panning
11619                        $container.addClass('fancybox-can-drag');
11620
11621                    } else {
11622                        $container.addClass('fancybox-can-zoomOut');
11623                    }
11624
11625                }
11626
11627            } else if (self.current.opts.touch) {
11628                $container.addClass('fancybox-can-drag');
11629            }
11630
11631        },
11632
11633
11634        // Check if current slide is zoomable
11635        // ==================================
11636
11637        isZoomable: function () {
11638
11639            var self = this;
11640
11641            var current = self.current;
11642            var fitPos;
11643
11644            if (!current || self.isClosing) {
11645                return;
11646            }
11647
11648            // Assume that slide is zoomable if
11649            // - image is loaded successfuly
11650            // - click action is "zoom"
11651            // - actual size of the image is smaller than available area
11652            if (current.type === 'image' && current.isLoaded && !current.hasError &&
11653                (current.opts.clickContent === 'zoom' || ($.isFunction(current.opts.clickContent) && current.opts.clickContent(current) === "zoom"))
11654            ) {
11655
11656                fitPos = self.getFitPos(current);
11657
11658                if (current.width > fitPos.width || current.height > fitPos.height) {
11659                    return true;
11660                }
11661
11662            }
11663
11664            return false;
11665
11666        },
11667
11668
11669        // Check if current image dimensions are smaller than actual
11670        // =========================================================
11671
11672        isScaledDown: function () {
11673
11674            var self = this;
11675
11676            var current = self.current;
11677            var $what = current.$content;
11678
11679            var rez = false;
11680
11681            if ($what) {
11682                rez = $.fancybox.getTranslate($what);
11683                rez = rez.width < current.width || rez.height < current.height;
11684            }
11685
11686            return rez;
11687
11688        },
11689
11690
11691        // Check if image dimensions exceed parent element
11692        // ===============================================
11693
11694        canPan: function () {
11695
11696            var self = this;
11697
11698            var current = self.current;
11699            var $what = current.$content;
11700
11701            var rez = false;
11702
11703            if ($what) {
11704                rez = self.getFitPos(current);
11705                rez = Math.abs($what.width() - rez.width) > 1 || Math.abs($what.height() - rez.height) > 1;
11706
11707            }
11708
11709            return rez;
11710
11711        },
11712
11713
11714        // Load content into the slide
11715        // ===========================
11716
11717        loadSlide: function (slide) {
11718
11719            var self = this, type, $slide;
11720            var ajaxLoad;
11721
11722            if (slide.isLoading) {
11723                return;
11724            }
11725
11726            if (slide.isLoaded) {
11727                return;
11728            }
11729
11730            slide.isLoading = true;
11731
11732            self.trigger('beforeLoad', slide);
11733
11734            type = slide.type;
11735            $slide = slide.$slide;
11736
11737            $slide
11738                .off('refresh')
11739                .trigger('onReset')
11740                .addClass('fancybox-slide--' + (type || 'unknown'))
11741                .addClass(slide.opts.slideClass);
11742
11743            // Create content depending on the type
11744
11745            switch (type) {
11746
11747                case 'image':
11748
11749                    self.setImage(slide);
11750
11751                    break;
11752
11753                case 'iframe':
11754
11755                    self.setIframe(slide);
11756
11757                    break;
11758
11759                case 'html':
11760
11761                    self.setContent(slide, slide.src || slide.content);
11762
11763                    break;
11764
11765                case 'inline':
11766
11767                    if ($(slide.src).length) {
11768                        self.setContent(slide, $(slide.src));
11769
11770                    } else {
11771                        self.setError(slide);
11772                    }
11773
11774                    break;
11775
11776                case 'ajax':
11777
11778                    self.showLoading(slide);
11779
11780                    ajaxLoad = $.ajax($.extend({}, slide.opts.ajax.settings, {
11781                        url: slide.src,
11782                        success: function (data, textStatus) {
11783
11784                            if (textStatus === 'success') {
11785                                self.setContent(slide, data);
11786                            }
11787
11788                        },
11789                        error: function (jqXHR, textStatus) {
11790
11791                            if (jqXHR && textStatus !== 'abort') {
11792                                self.setError(slide);
11793                            }
11794
11795                        }
11796                    }));
11797
11798                    $slide.one('onReset', function () {
11799                        ajaxLoad.abort();
11800                    });
11801
11802                    break;
11803
11804                default:
11805
11806                    self.setError(slide);
11807
11808                    break;
11809
11810            }
11811
11812            return true;
11813
11814        },
11815
11816
11817        // Use thumbnail image, if possible
11818        // ================================
11819
11820        setImage: function (slide) {
11821
11822            var self = this;
11823            var srcset = slide.opts.image.srcset;
11824
11825            var found, temp, pxRatio, windowWidth;
11826
11827            // If we have "srcset", then we need to find matching "src" value.
11828            // This is necessary, because when you set an src attribute, the browser will preload the image
11829            // before any javascript or even CSS is applied.
11830            if (srcset) {
11831                pxRatio = window.devicePixelRatio || 1;
11832                windowWidth = window.innerWidth * pxRatio;
11833
11834                temp = srcset.split(',').map(function (el) {
11835                    var ret = {};
11836
11837                    el.trim().split(/\s+/).forEach(function (el, i) {
11838                        var value = parseInt(el.substring(0, el.length - 1), 10);
11839
11840                        if (i === 0) {
11841                            return (ret.url = el);
11842                        }
11843
11844                        if (value) {
11845                            ret.value = value;
11846                            ret.postfix = el[el.length - 1];
11847                        }
11848
11849                    });
11850
11851                    return ret;
11852                });
11853
11854                // Sort by value
11855                temp.sort(function (a, b) {
11856                    return a.value - b.value;
11857                });
11858
11859                // Ok, now we have an array of all srcset values
11860                for (var j = 0; j < temp.length; j++) {
11861                    var el = temp[j];
11862
11863                    if ((el.postfix === 'w' && el.value >= windowWidth) || (el.postfix === 'x' && el.value >= pxRatio)) {
11864                        found = el;
11865                        break;
11866                    }
11867                }
11868
11869                // If not found, take the last one
11870                if (!found && temp.length) {
11871                    found = temp[temp.length - 1];
11872                }
11873
11874                if (found) {
11875                    slide.src = found.url;
11876
11877                    // If we have default width/height values, we can calculate height for matching source
11878                    if (slide.width && slide.height && found.postfix == 'w') {
11879                        slide.height = (slide.width / slide.height) * found.value;
11880                        slide.width = found.value;
11881                    }
11882                }
11883            }
11884
11885            // This will be wrapper containing both ghost and actual image
11886            slide.$content = $('<div class="fancybox-image-wrap"></div>')
11887                .addClass('fancybox-is-hidden')
11888                .appendTo(slide.$slide);
11889
11890
11891            // If we have a thumbnail, we can display it while actual image is loading
11892            // Users will not stare at black screen and actual image will appear gradually
11893            if (slide.opts.preload !== false && slide.opts.width && slide.opts.height && (slide.opts.thumb || slide.opts.$thumb)) {
11894
11895                slide.width = slide.opts.width;
11896                slide.height = slide.opts.height;
11897
11898                slide.$ghost = $('<img />')
11899                    .one('error', function () {
11900
11901                        $(this).remove();
11902
11903                        slide.$ghost = null;
11904
11905                        self.setBigImage(slide);
11906
11907                    })
11908                    .one('load', function () {
11909
11910                        self.afterLoad(slide);
11911
11912                        self.setBigImage(slide);
11913
11914                    })
11915                    .addClass('fancybox-image')
11916                    .appendTo(slide.$content)
11917                    .attr('src', slide.opts.thumb || slide.opts.$thumb.attr('src'));
11918
11919            } else {
11920
11921                self.setBigImage(slide);
11922
11923            }
11924
11925        },
11926
11927
11928        // Create full-size image
11929        // ======================
11930
11931        setBigImage: function (slide) {
11932            var self = this;
11933            var $img = $('<img />');
11934
11935            slide.$image = $img
11936                .one('error', function () {
11937
11938                    self.setError(slide);
11939
11940                })
11941                .one('load', function () {
11942
11943                    // Clear timeout that checks if loading icon needs to be displayed
11944                    clearTimeout(slide.timouts);
11945
11946                    slide.timouts = null;
11947
11948                    if (self.isClosing) {
11949                        return;
11950                    }
11951
11952                    slide.width = this.naturalWidth;
11953                    slide.height = this.naturalHeight;
11954
11955                    if (slide.opts.image.srcset) {
11956                        $img.attr('sizes', '100vw').attr('srcset', slide.opts.image.srcset);
11957                    }
11958
11959                    self.hideLoading(slide);
11960
11961                    if (slide.$ghost) {
11962
11963                        slide.timouts = setTimeout(function () {
11964                            slide.timouts = null;
11965
11966                            slide.$ghost.hide();
11967
11968                        }, Math.min(300, Math.max(1000, slide.height / 1600)));
11969
11970                    } else {
11971                        self.afterLoad(slide);
11972                    }
11973
11974                })
11975                .addClass('fancybox-image')
11976                .attr('src', slide.src)
11977                .appendTo(slide.$content);
11978
11979            if ($img[0].complete) {
11980                $img.trigger('load');
11981
11982            } else if ($img[0].error) {
11983                $img.trigger('error');
11984
11985            } else {
11986
11987                slide.timouts = setTimeout(function () {
11988                    if (!$img[0].complete && !slide.hasError) {
11989                        self.showLoading(slide);
11990                    }
11991
11992                }, 100);
11993
11994            }
11995
11996        },
11997
11998
11999        // Create iframe wrapper, iframe and bindings
12000        // ==========================================
12001
12002        setIframe: function (slide) {
12003            var self = this,
12004                opts = slide.opts.iframe,
12005                $slide = slide.$slide,
12006                $iframe;
12007
12008            slide.$content = $('<div class="fancybox-content' + (opts.preload ? ' fancybox-is-hidden' : '') + '"></div>')
12009                .css(opts.css)
12010                .appendTo($slide);
12011
12012            $iframe = $(opts.tpl.replace(/\{rnd\}/g, new Date().getTime()))
12013                .attr(opts.attr)
12014                .appendTo(slide.$content);
12015
12016            if (opts.preload) {
12017
12018                self.showLoading(slide);
12019
12020                // Unfortunately, it is not always possible to determine if iframe is successfully loaded
12021                // (due to browser security policy)
12022
12023                $iframe.on('load.fb error.fb', function (e) {
12024                    this.isReady = 1;
12025
12026                    slide.$slide.trigger('refresh');
12027
12028                    self.afterLoad(slide);
12029                });
12030
12031                // Recalculate iframe content size
12032                // ===============================
12033
12034                $slide.on('refresh.fb', function () {
12035                    var $wrap = slide.$content,
12036                        $contents,
12037                        $body,
12038                        scrollWidth,
12039                        frameWidth,
12040                        frameHeight;
12041
12042                    if ($iframe[0].isReady !== 1) {
12043                        return;
12044                    }
12045
12046                    // Check if content is accessible,
12047                    // it will fail if frame is not with the same origin
12048
12049                    try {
12050                        $contents = $iframe.contents();
12051                        $body = $contents.find('body');
12052
12053                    } catch (ignore) {
12054                    }
12055
12056                    // Calculate dimensions for the wrapper
12057                    if ($body && $body.length && !(opts.css.width !== undefined && opts.css.height !== undefined)) {
12058
12059                        scrollWidth = $iframe[0].contentWindow.document.documentElement.scrollWidth;
12060
12061                        frameWidth = Math.ceil($body.outerWidth(true) + ($wrap.width() - scrollWidth));
12062                        frameHeight = Math.ceil($body.outerHeight(true));
12063
12064                        // Resize wrapper to fit iframe content
12065                        $wrap.css({
12066                            'width': opts.css.width === undefined ? frameWidth + ($wrap.outerWidth() - $wrap.innerWidth()) : opts.css.width,
12067                            'height': opts.css.height === undefined ? frameHeight + ($wrap.outerHeight() - $wrap.innerHeight()) : opts.css.height
12068                        });
12069
12070                    }
12071
12072                    $wrap.removeClass('fancybox-is-hidden');
12073
12074                });
12075
12076            } else {
12077
12078                this.afterLoad(slide);
12079
12080            }
12081
12082            $iframe.attr('src', slide.src);
12083
12084            if (slide.opts.smallBtn === true) {
12085                slide.$content.prepend(self.translate(slide, slide.opts.btnTpl.smallBtn));
12086            }
12087
12088            // Remove iframe if closing or changing gallery item
12089            $slide.one('onReset', function () {
12090
12091                // This helps IE not to throw errors when closing
12092                try {
12093
12094                    $(this).find('iframe').hide().attr('src', '//about:blank');
12095
12096                } catch (ignore) {
12097                }
12098
12099                $(this).empty();
12100
12101                slide.isLoaded = false;
12102
12103            });
12104
12105        },
12106
12107
12108        // Wrap and append content to the slide
12109        // ======================================
12110
12111        setContent: function (slide, content) {
12112
12113            var self = this;
12114
12115            if (self.isClosing) {
12116                return;
12117            }
12118
12119            self.hideLoading(slide);
12120
12121            slide.$slide.empty();
12122
12123            if (isQuery(content) && content.parent().length) {
12124
12125                // If content is a jQuery object, then it will be moved to the slide.
12126                // The placeholder is created so we will know where to put it back.
12127                // If user is navigating gallery fast, then the content might be already inside fancyBox
12128                // =====================================================================================
12129
12130                // Make sure content is not already moved to fancyBox
12131                content.parent('.fancybox-slide--inline').trigger('onReset');
12132
12133                // Create temporary element marking original place of the content
12134                slide.$placeholder = $('<div></div>').hide().insertAfter(content);
12135
12136                // Make sure content is visible
12137                content.css('display', 'inline-block');
12138
12139            } else if (!slide.hasError) {
12140
12141                // If content is just a plain text, try to convert it to html
12142                if ($.type(content) === 'string') {
12143                    content = $('<div>').append($.trim(content)).contents();
12144
12145                    // If we have text node, then add wrapping element to make vertical alignment work
12146                    if (content[0].nodeType === 3) {
12147                        content = $('<div>').html(content);
12148                    }
12149                }
12150
12151                // If "filter" option is provided, then filter content
12152                if (slide.opts.filter) {
12153                    content = $('<div>').html(content).find(slide.opts.filter);
12154                }
12155
12156            }
12157
12158            slide.$slide.one('onReset', function () {
12159
12160                // Put content back
12161                if (slide.$placeholder) {
12162                    slide.$placeholder.after(content.hide()).remove();
12163
12164                    slide.$placeholder = null;
12165                }
12166
12167                // Remove custom close button
12168                if (slide.$smallBtn) {
12169                    slide.$smallBtn.remove();
12170
12171                    slide.$smallBtn = null;
12172                }
12173
12174                // Remove content and mark slide as not loaded
12175                if (!slide.hasError) {
12176                    $(this).empty();
12177
12178                    slide.isLoaded = false;
12179                }
12180
12181            });
12182
12183            slide.$content = $(content).appendTo(slide.$slide);
12184
12185            if (slide.opts.smallBtn && !slide.$smallBtn) {
12186                slide.$smallBtn = $(self.translate(slide, slide.opts.btnTpl.smallBtn)).appendTo(slide.$content);
12187            }
12188
12189            this.afterLoad(slide);
12190        },
12191
12192        // Display error message
12193        // =====================
12194
12195        setError: function (slide) {
12196
12197            slide.hasError = true;
12198
12199            slide.$slide.removeClass('fancybox-slide--' + slide.type);
12200
12201            this.setContent(slide, this.translate(slide, slide.opts.errorTpl));
12202
12203        },
12204
12205
12206        // Show loading icon inside the slide
12207        // ==================================
12208
12209        showLoading: function (slide) {
12210
12211            var self = this;
12212
12213            slide = slide || self.current;
12214
12215            if (slide && !slide.$spinner) {
12216                slide.$spinner = $(self.opts.spinnerTpl).appendTo(slide.$slide);
12217            }
12218
12219        },
12220
12221        // Remove loading icon from the slide
12222        // ==================================
12223
12224        hideLoading: function (slide) {
12225
12226            var self = this;
12227
12228            slide = slide || self.current;
12229
12230            if (slide && slide.$spinner) {
12231                slide.$spinner.remove();
12232
12233                delete slide.$spinner;
12234            }
12235
12236        },
12237
12238
12239        // Adjustments after slide content has been loaded
12240        // ===============================================
12241
12242        afterLoad: function (slide) {
12243
12244            var self = this;
12245
12246            if (self.isClosing) {
12247                return;
12248            }
12249
12250            slide.isLoading = false;
12251            slide.isLoaded = true;
12252
12253            self.trigger('afterLoad', slide);
12254
12255            self.hideLoading(slide);
12256
12257            if (slide.opts.protect && slide.$content && !slide.hasError) {
12258
12259                // Disable right click
12260                slide.$content.on('contextmenu.fb', function (e) {
12261                    if (e.button == 2) {
12262                        e.preventDefault();
12263                    }
12264
12265                    return true;
12266                });
12267
12268                // Add fake element on top of the image
12269                // This makes a bit harder for user to select image
12270                if (slide.type === 'image') {
12271                    $('<div class="fancybox-spaceball"></div>').appendTo(slide.$content);
12272                }
12273
12274            }
12275
12276            self.revealContent(slide);
12277
12278        },
12279
12280
12281        // Make content visible
12282        // This method is called right after content has been loaded or
12283        // user navigates gallery and transition should start
12284        // ============================================================
12285
12286        revealContent: function (slide) {
12287
12288            var self = this;
12289            var $slide = slide.$slide;
12290
12291            var effect, effectClassName, duration, opacity, end, start = false;
12292
12293            effect = slide.opts[self.firstRun ? 'animationEffect' : 'transitionEffect'];
12294            duration = slide.opts[self.firstRun ? 'animationDuration' : 'transitionDuration'];
12295
12296            duration = parseInt(slide.forcedDuration === undefined ? duration : slide.forcedDuration, 10);
12297
12298            if (slide.isMoved || slide.pos !== self.currPos || !duration) {
12299                effect = false;
12300            }
12301
12302            // Check if can zoom
12303            if (effect === 'zoom' && !(slide.pos === self.currPos && duration && slide.type === 'image' && !slide.hasError && (start = self.getThumbPos(slide)))) {
12304                effect = 'fade';
12305            }
12306
12307
12308            // Zoom animation
12309            // ==============
12310
12311            if (effect === 'zoom') {
12312                end = self.getFitPos(slide);
12313
12314                end.scaleX = Math.round((end.width / start.width) * 100) / 100;
12315                end.scaleY = Math.round((end.height / start.height) * 100) / 100;
12316
12317                delete end.width;
12318                delete end.height;
12319
12320                // Check if we need to animate opacity
12321                opacity = slide.opts.zoomOpacity;
12322
12323                if (opacity == 'auto') {
12324                    opacity = Math.abs(slide.width / slide.height - start.width / start.height) > 0.1;
12325                }
12326
12327                if (opacity) {
12328                    start.opacity = 0.1;
12329                    end.opacity = 1;
12330                }
12331
12332                // Draw image at start position
12333                $.fancybox.setTranslate(slide.$content.removeClass('fancybox-is-hidden'), start);
12334
12335                forceRedraw(slide.$content);
12336
12337                // Start animation
12338                $.fancybox.animate(slide.$content, end, duration, function () {
12339                    self.complete();
12340                });
12341
12342                return;
12343            }
12344
12345
12346            self.updateSlide(slide);
12347
12348
12349            // Simply show content
12350            // ===================
12351
12352            if (!effect) {
12353                forceRedraw($slide);
12354
12355                slide.$content.removeClass('fancybox-is-hidden');
12356
12357                if (slide.pos === self.currPos) {
12358                    self.complete();
12359                }
12360
12361                return;
12362            }
12363
12364            $.fancybox.stop($slide);
12365
12366            effectClassName = 'fancybox-animated fancybox-slide--' + (slide.pos > self.prevPos ? 'next' : 'previous') + ' fancybox-fx-' + effect;
12367
12368            $slide.removeAttr('style').removeClass('fancybox-slide--current fancybox-slide--next fancybox-slide--previous').addClass(effectClassName);
12369
12370            slide.$content.removeClass('fancybox-is-hidden');
12371
12372            //Force reflow for CSS3 transitions
12373            forceRedraw($slide);
12374
12375            $.fancybox.animate($slide, 'fancybox-slide--current', duration, function (e) {
12376                $slide.removeClass(effectClassName).removeAttr('style');
12377
12378                if (slide.pos === self.currPos) {
12379                    self.complete();
12380                }
12381
12382            }, true);
12383
12384        },
12385
12386
12387        // Check if we can and have to zoom from thumbnail
12388        //================================================
12389
12390        getThumbPos: function (slide) {
12391
12392            var self = this;
12393            var rez = false;
12394
12395            // Check if element is inside the viewport by at least 1 pixel
12396            var isElementVisible = function ($el) {
12397                var element = $el[0];
12398
12399                var elementRect = element.getBoundingClientRect();
12400                var parentRects = [];
12401
12402                var visibleInAllParents;
12403
12404                while (element.parentElement !== null) {
12405                    if ($(element.parentElement).css('overflow') === 'hidden' || $(element.parentElement).css('overflow') === 'auto') {
12406                        parentRects.push(element.parentElement.getBoundingClientRect());
12407                    }
12408
12409                    element = element.parentElement;
12410                }
12411
12412                visibleInAllParents = parentRects.every(function (parentRect) {
12413                    var visiblePixelX = Math.min(elementRect.right, parentRect.right) - Math.max(elementRect.left, parentRect.left);
12414                    var visiblePixelY = Math.min(elementRect.bottom, parentRect.bottom) - Math.max(elementRect.top, parentRect.top);
12415
12416                    return visiblePixelX > 0 && visiblePixelY > 0;
12417                });
12418
12419                return visibleInAllParents &&
12420                    elementRect.bottom > 0 && elementRect.right > 0 &&
12421                    elementRect.left < $(window).width() && elementRect.top < $(window).height();
12422            };
12423
12424            var $thumb = slide.opts.$thumb;
12425            var thumbPos = $thumb ? $thumb.offset() : 0;
12426            var slidePos;
12427
12428            if (thumbPos && $thumb[0].ownerDocument === document && isElementVisible($thumb)) {
12429                slidePos = self.$refs.stage.offset();
12430
12431                rez = {
12432                    top: thumbPos.top - slidePos.top + parseFloat($thumb.css("border-top-width") || 0),
12433                    left: thumbPos.left - slidePos.left + parseFloat($thumb.css("border-left-width") || 0),
12434                    width: $thumb.width(),
12435                    height: $thumb.height(),
12436                    scaleX: 1,
12437                    scaleY: 1
12438                };
12439            }
12440
12441            return rez;
12442        },
12443
12444
12445        // Final adjustments after current gallery item is moved to position
12446        // and it`s content is loaded
12447        // ==================================================================
12448
12449        complete: function () {
12450
12451            var self = this;
12452
12453            var current = self.current;
12454            var slides = {};
12455
12456            if (current.isMoved || !current.isLoaded || current.isComplete) {
12457                return;
12458            }
12459
12460            current.isComplete = true;
12461
12462            current.$slide.siblings().trigger('onReset');
12463
12464            // Trigger any CSS3 transiton inside the slide
12465            forceRedraw(current.$slide);
12466
12467            current.$slide.addClass('fancybox-slide--complete');
12468
12469            // Remove unnecessary slides
12470            $.each(self.slides, function (key, slide) {
12471                if (slide.pos >= self.currPos - 1 && slide.pos <= self.currPos + 1) {
12472                    slides[slide.pos] = slide;
12473
12474                } else if (slide) {
12475
12476                    $.fancybox.stop(slide.$slide);
12477
12478                    slide.$slide.unbind().remove();
12479                }
12480            });
12481
12482            self.slides = slides;
12483
12484            self.updateCursor();
12485
12486            self.trigger('afterShow');
12487
12488            // Try to focus on the first focusable element
12489            if ($(document.activeElement).is('[disabled]') || (current.opts.autoFocus && !(current.type == 'image' || current.type === 'iframe'))) {
12490                self.focus();
12491            }
12492
12493        },
12494
12495
12496        // Preload next and previous slides
12497        // ================================
12498
12499        preload: function () {
12500            var self = this;
12501            var next, prev;
12502
12503            if (self.group.length < 2) {
12504                return;
12505            }
12506
12507            next = self.slides[self.currPos + 1];
12508            prev = self.slides[self.currPos - 1];
12509
12510            if (next && next.type === 'image') {
12511                self.loadSlide(next);
12512            }
12513
12514            if (prev && prev.type === 'image') {
12515                self.loadSlide(prev);
12516            }
12517
12518        },
12519
12520
12521        // Try to find and focus on the first focusable element
12522        // ====================================================
12523
12524        focus: function () {
12525            var current = this.current;
12526            var $el;
12527
12528            if (this.isClosing) {
12529                return;
12530            }
12531
12532            // Skip for images and iframes
12533            $el = current && current.isComplete ? current.$slide.find('button,:input,[tabindex],a').filter(':not([disabled]):visible:first') : null;
12534            $el = $el && $el.length ? $el : this.$refs.container;
12535
12536            $el.focus();
12537        },
12538
12539
12540        // Activates current instance - brings container to the front and enables keyboard,
12541        // notifies other instances about deactivating
12542        // =================================================================================
12543
12544        activate: function () {
12545            var self = this;
12546
12547            // Deactivate all instances
12548            $('.fancybox-container').each(function () {
12549                var instance = $(this).data('FancyBox');
12550
12551                // Skip self and closing instances
12552                if (instance && instance.uid !== self.uid && !instance.isClosing) {
12553                    instance.trigger('onDeactivate');
12554                }
12555
12556            });
12557
12558            if (self.current) {
12559                if (self.$refs.container.index() > 0) {
12560                    self.$refs.container.prependTo(document.body);
12561                }
12562
12563                self.updateControls();
12564            }
12565
12566            self.trigger('onActivate');
12567
12568            self.addEvents();
12569
12570        },
12571
12572
12573        // Start closing procedure
12574        // This will start "zoom-out" animation if needed and clean everything up afterwards
12575        // =================================================================================
12576
12577        close: function (e, d) {
12578
12579            var self = this;
12580            var current = self.current;
12581
12582            var effect, duration;
12583            var $what, opacity, start, end;
12584
12585            var done = function () {
12586                self.cleanUp(e);
12587            };
12588
12589            if (self.isClosing) {
12590                return false;
12591            }
12592
12593            self.isClosing = true;
12594
12595            // If beforeClose callback prevents closing, make sure content is centered
12596            if (self.trigger('beforeClose', e) === false) {
12597                self.isClosing = false;
12598
12599                requestAFrame(function () {
12600                    self.update();
12601                });
12602
12603                return false;
12604            }
12605
12606            // Remove all events
12607            // If there are multiple instances, they will be set again by "activate" method
12608            self.removeEvents();
12609
12610            if (current.timouts) {
12611                clearTimeout(current.timouts);
12612            }
12613
12614            $what = current.$content;
12615            effect = current.opts.animationEffect;
12616            duration = $.isNumeric(d) ? d : (effect ? current.opts.animationDuration : 0);
12617
12618            // Remove other slides
12619            current.$slide.off(transitionEnd).removeClass('fancybox-slide--complete fancybox-slide--next fancybox-slide--previous fancybox-animated');
12620
12621            current.$slide.siblings().trigger('onReset').remove();
12622
12623            // Trigger animations
12624            if (duration) {
12625                self.$refs.container.removeClass('fancybox-is-open').addClass('fancybox-is-closing');
12626            }
12627
12628            // Clean up
12629            self.hideLoading(current);
12630
12631            self.hideControls();
12632
12633            self.updateCursor();
12634
12635            // Check if possible to zoom-out
12636            if (effect === 'zoom' && !(e !== true && $what && duration && current.type === 'image' && !current.hasError && (end = self.getThumbPos(current)))) {
12637                effect = 'fade';
12638            }
12639
12640            if (effect === 'zoom') {
12641                $.fancybox.stop($what);
12642
12643                start = $.fancybox.getTranslate($what);
12644
12645                start.width = start.width * start.scaleX;
12646                start.height = start.height * start.scaleY;
12647
12648                // Check if we need to animate opacity
12649                opacity = current.opts.zoomOpacity;
12650
12651                if (opacity == 'auto') {
12652                    opacity = Math.abs(current.width / current.height - end.width / end.height) > 0.1;
12653                }
12654
12655                if (opacity) {
12656                    end.opacity = 0;
12657                }
12658
12659                start.scaleX = start.width / end.width;
12660                start.scaleY = start.height / end.height;
12661
12662                start.width = end.width;
12663                start.height = end.height;
12664
12665                $.fancybox.setTranslate(current.$content, start);
12666
12667                $.fancybox.animate(current.$content, end, duration, done);
12668
12669                return true;
12670            }
12671
12672            if (effect && duration) {
12673
12674                // If skip animation
12675                if (e === true) {
12676                    setTimeout(done, duration);
12677
12678                } else {
12679                    $.fancybox.animate(current.$slide.removeClass('fancybox-slide--current'), 'fancybox-animated fancybox-slide--previous fancybox-fx-' + effect, duration, done);
12680                }
12681
12682            } else {
12683                done();
12684            }
12685
12686            return true;
12687        },
12688
12689
12690        // Final adjustments after removing the instance
12691        // =============================================
12692
12693        cleanUp: function (e) {
12694            var self = this,
12695                instance;
12696
12697            self.current.$slide.trigger('onReset');
12698
12699            self.$refs.container.empty().remove();
12700
12701            self.trigger('afterClose', e);
12702
12703            // Place back focus
12704            if (self.$lastFocus && !!!self.current.focusBack) {
12705                self.$lastFocus.focus();
12706            }
12707
12708            self.current = null;
12709
12710            // Check if there are other instances
12711            instance = $.fancybox.getInstance();
12712
12713            if (instance) {
12714                instance.activate();
12715
12716            } else {
12717
12718                $W.scrollTop(self.scrollTop).scrollLeft(self.scrollLeft);
12719
12720                $('html').removeClass('fancybox-enabled');
12721
12722                $('#fancybox-style-noscroll').remove();
12723            }
12724
12725        },
12726
12727
12728        // Call callback and trigger an event
12729        // ==================================
12730
12731        trigger: function (name, slide) {
12732            var args = Array.prototype.slice.call(arguments, 1),
12733                self = this,
12734                obj = slide && slide.opts ? slide : self.current,
12735                rez;
12736
12737            if (obj) {
12738                args.unshift(obj);
12739
12740            } else {
12741                obj = self;
12742            }
12743
12744            args.unshift(self);
12745
12746            if ($.isFunction(obj.opts[name])) {
12747                rez = obj.opts[name].apply(obj, args);
12748            }
12749
12750            if (rez === false) {
12751                return rez;
12752            }
12753
12754            if (name === 'afterClose') {
12755                $D.trigger(name + '.fb', args);
12756
12757            } else {
12758                self.$refs.container.trigger(name + '.fb', args);
12759            }
12760
12761        },
12762
12763
12764        // Update infobar values, navigation button states and reveal caption
12765        // ==================================================================
12766
12767        updateControls: function (force) {
12768
12769            var self = this;
12770
12771            var current = self.current;
12772            var index = current.index;
12773            var opts = current.opts;
12774            var caption = opts.caption;
12775            var $caption = self.$refs.caption;
12776
12777            // Recalculate content dimensions
12778            current.$slide.trigger('refresh');
12779
12780            self.$caption = caption && caption.length ? $caption.html(caption) : null;
12781
12782            if (!self.isHiddenControls) {
12783                self.showControls();
12784            }
12785
12786            // Update info and navigation elements
12787            $('[data-fancybox-count]').html(self.group.length);
12788            $('[data-fancybox-index]').html(index + 1);
12789
12790            $('[data-fancybox-prev]').prop('disabled', (!opts.loop && index <= 0));
12791            $('[data-fancybox-next]').prop('disabled', (!opts.loop && index >= self.group.length - 1));
12792
12793        },
12794
12795        // Hide toolbar and caption
12796        // ========================
12797
12798        hideControls: function () {
12799
12800            this.isHiddenControls = true;
12801
12802            this.$refs.container.removeClass('fancybox-show-infobar fancybox-show-toolbar fancybox-show-caption fancybox-show-nav');
12803
12804        },
12805
12806        showControls: function () {
12807
12808            var self = this;
12809            var opts = self.current ? self.current.opts : self.opts;
12810            var $container = self.$refs.container;
12811
12812            self.isHiddenControls = false;
12813            self.idleSecondsCounter = 0;
12814
12815            $container
12816                .toggleClass('fancybox-show-toolbar', !!(opts.toolbar && opts.buttons))
12817                .toggleClass('fancybox-show-infobar', !!(opts.infobar && self.group.length > 1))
12818                .toggleClass('fancybox-show-nav', !!(opts.arrows && self.group.length > 1))
12819                .toggleClass('fancybox-is-modal', !!opts.modal);
12820
12821            if (self.$caption) {
12822                $container.addClass('fancybox-show-caption ');
12823
12824            } else {
12825                $container.removeClass('fancybox-show-caption');
12826            }
12827
12828        },
12829
12830
12831        // Toggle toolbar and caption
12832        // ==========================
12833
12834        toggleControls: function () {
12835
12836            if (this.isHiddenControls) {
12837                this.showControls();
12838
12839            } else {
12840                this.hideControls();
12841            }
12842
12843        },
12844
12845
12846    });
12847
12848
12849    $.fancybox = {
12850
12851        version: "3.1.20",
12852        defaults: defaults,
12853
12854
12855        // Get current instance and execute a command.
12856        //
12857        // Examples of usage:
12858        //
12859        //   $instance = $.fancybox.getInstance();
12860        //   $.fancybox.getInstance().jumpTo( 1 );
12861        //   $.fancybox.getInstance( 'jumpTo', 1 );
12862        //   $.fancybox.getInstance( function() {
12863        //       console.info( this.currIndex );
12864        //   });
12865        // ======================================================
12866
12867        getInstance: function (command) {
12868            var instance = $('.fancybox-container:not(".fancybox-is-closing"):first').data('FancyBox');
12869            var args = Array.prototype.slice.call(arguments, 1);
12870
12871            if (instance instanceof FancyBox) {
12872
12873                if ($.type(command) === 'string') {
12874                    instance[command].apply(instance, args);
12875
12876                } else if ($.type(command) === 'function') {
12877                    command.apply(instance, args);
12878
12879                }
12880
12881                return instance;
12882            }
12883
12884            return false;
12885
12886        },
12887
12888
12889        // Create new instance
12890        // ===================
12891
12892        open: function (items, opts, index) {
12893            return new FancyBox(items, opts, index);
12894        },
12895
12896
12897        // Close current or all instances
12898        // ==============================
12899
12900        close: function (all) {
12901            var instance = this.getInstance();
12902
12903            if (instance) {
12904                instance.close();
12905
12906                // Try to find and close next instance
12907
12908                if (all === true) {
12909                    this.close();
12910                }
12911            }
12912
12913        },
12914
12915        // Close instances and unbind all events
12916        // ==============================
12917
12918        destroy: function () {
12919
12920            this.close(true);
12921
12922            $D.off('click.fb-start');
12923
12924        },
12925
12926
12927        // Try to detect mobile devices
12928        // ============================
12929
12930        isMobile: document.createTouch !== undefined && /Android|webOS|iPhone|iPad|iPod|BlackBerry/i.test(navigator.userAgent),
12931
12932
12933        // Detect if 'translate3d' support is available
12934        // ============================================
12935
12936        use3d: (function () {
12937            var div = document.createElement('div');
12938
12939            return window.getComputedStyle && window.getComputedStyle(div).getPropertyValue('transform') && !(document.documentMode && document.documentMode < 11);
12940        }()),
12941
12942
12943        // Helper function to get current visual state of an element
12944        // returns array[ top, left, horizontal-scale, vertical-scale, opacity ]
12945        // =====================================================================
12946
12947        getTranslate: function ($el) {
12948            var matrix;
12949
12950            if (!$el || !$el.length) {
12951                return false;
12952            }
12953
12954            matrix = $el.eq(0).css('transform');
12955
12956            if (matrix && matrix.indexOf('matrix') !== -1) {
12957                matrix = matrix.split('(')[1];
12958                matrix = matrix.split(')')[0];
12959                matrix = matrix.split(',');
12960            } else {
12961                matrix = [];
12962            }
12963
12964            if (matrix.length) {
12965
12966                // If IE
12967                if (matrix.length > 10) {
12968                    matrix = [matrix[13], matrix[12], matrix[0], matrix[5]];
12969
12970                } else {
12971                    matrix = [matrix[5], matrix[4], matrix[0], matrix[3]];
12972                }
12973
12974                matrix = matrix.map(parseFloat);
12975
12976            } else {
12977                matrix = [0, 0, 1, 1];
12978
12979                var transRegex = /\.*translate\((.*)px,(.*)px\)/i;
12980                var transRez = transRegex.exec($el.eq(0).attr('style'));
12981
12982                if (transRez) {
12983                    matrix[0] = parseFloat(transRez[2]);
12984                    matrix[1] = parseFloat(transRez[1]);
12985                }
12986            }
12987
12988            return {
12989                top: matrix[0],
12990                left: matrix[1],
12991                scaleX: matrix[2],
12992                scaleY: matrix[3],
12993                opacity: parseFloat($el.css('opacity')),
12994                width: $el.width(),
12995                height: $el.height()
12996            };
12997
12998        },
12999
13000
13001        // Shortcut for setting "translate3d" properties for element
13002        // Can set be used to set opacity, too
13003        // ========================================================
13004
13005        setTranslate: function ($el, props) {
13006            var str = '';
13007            var css = {};
13008
13009            if (!$el || !props) {
13010                return;
13011            }
13012
13013            if (props.left !== undefined || props.top !== undefined) {
13014                str = (props.left === undefined ? $el.position().left : props.left) + 'px, ' + (props.top === undefined ? $el.position().top : props.top) + 'px';
13015
13016                if (this.use3d) {
13017                    str = 'translate3d(' + str + ', 0px)';
13018
13019                } else {
13020                    str = 'translate(' + str + ')';
13021                }
13022            }
13023
13024            if (props.scaleX !== undefined && props.scaleY !== undefined) {
13025                str = (str.length ? str + ' ' : '') + 'scale(' + props.scaleX + ', ' + props.scaleY + ')';
13026            }
13027
13028            if (str.length) {
13029                css.transform = str;
13030            }
13031
13032            if (props.opacity !== undefined) {
13033                css.opacity = props.opacity;
13034            }
13035
13036            if (props.width !== undefined) {
13037                css.width = props.width;
13038            }
13039
13040            if (props.height !== undefined) {
13041                css.height = props.height;
13042            }
13043
13044            return $el.css(css);
13045        },
13046
13047
13048        // Simple CSS transition handler
13049        // =============================
13050
13051        animate: function ($el, to, duration, callback, leaveAnimationName) {
13052            var event = transitionEnd || 'transitionend';
13053
13054            if ($.isFunction(duration)) {
13055                callback = duration;
13056                duration = null;
13057            }
13058
13059            if (!$.isPlainObject(to)) {
13060                $el.removeAttr('style');
13061            }
13062
13063            $el.on(event, function (e) {
13064
13065                // Skip events from child elements and z-index change
13066                if (e && e.originalEvent && (!$el.is(e.originalEvent.target) || e.originalEvent.propertyName == 'z-index')) {
13067                    return;
13068                }
13069
13070                $el.off(event);
13071
13072                if ($.isPlainObject(to)) {
13073
13074                    if (to.scaleX !== undefined && to.scaleY !== undefined) {
13075                        $el.css('transition-duration', '0ms');
13076
13077                        to.width = $el.width() * to.scaleX;
13078                        to.height = $el.height() * to.scaleY;
13079
13080                        to.scaleX = 1;
13081                        to.scaleY = 1;
13082
13083                        $.fancybox.setTranslate($el, to);
13084                    }
13085
13086                } else if (leaveAnimationName !== true) {
13087                    $el.removeClass(to);
13088                }
13089
13090                if ($.isFunction(callback)) {
13091                    callback(e);
13092                }
13093
13094            });
13095
13096            if ($.isNumeric(duration)) {
13097                $el.css('transition-duration', duration + 'ms');
13098            }
13099
13100            if ($.isPlainObject(to)) {
13101                $.fancybox.setTranslate($el, to);
13102
13103            } else {
13104                $el.addClass(to);
13105            }
13106
13107            $el.data("timer", setTimeout(function () {
13108                $el.trigger('transitionend');
13109            }, duration + 16));
13110
13111        },
13112
13113        stop: function ($el) {
13114            clearTimeout($el.data("timer"));
13115
13116            $el.off(transitionEnd);
13117        }
13118
13119    };
13120
13121
13122    // Default click handler for "fancyboxed" links
13123    // ============================================
13124
13125    function _run(e) {
13126        var target = e.currentTarget,
13127            opts = e.data ? e.data.options : {},
13128            items = e.data ? e.data.items : [],
13129            value = $(target).attr('data-fancybox') || '',
13130            index = 0;
13131
13132        e.preventDefault();
13133        e.stopPropagation();
13134
13135        // Get all related items and find index for clicked one
13136        if (value) {
13137            items = items.length ? items.filter('[data-fancybox="' + value + '"]') : $('[data-fancybox="' + value + '"]');
13138            index = items.index(target);
13139
13140            // Sometimes current item can not be found
13141            // (for example, when slider clones items)
13142            if (index < 0) {
13143                index = 0;
13144            }
13145
13146        } else {
13147            items = [target];
13148        }
13149
13150        $.fancybox.open(items, opts, index);
13151    }
13152
13153
13154    // Create a jQuery plugin
13155    // ======================
13156
13157    $.fn.fancybox = function (options) {
13158        var selector;
13159
13160        options = options || {};
13161        selector = options.selector || false;
13162
13163        if (selector) {
13164
13165            $('body').off('click.fb-start', selector).on('click.fb-start', selector, {
13166                items: $(selector),
13167                options: options
13168            }, _run);
13169
13170        } else {
13171
13172            this.off('click.fb-start').on('click.fb-start', {
13173                items: this,
13174                options: options
13175            }, _run);
13176
13177        }
13178
13179        return this;
13180    };
13181
13182
13183    // Self initializing plugin
13184    // ========================
13185
13186    $D.on('click.fb-start', '[data-fancybox]', _run);
13187
13188}(window, document, window.jQuery));
13189
13190// ==========================================================================
13191//
13192// Media
13193// Adds additional media type support
13194//
13195// ==========================================================================
13196;(function ($) {
13197
13198    'use strict';
13199
13200// Formats matching url to final form
13201
13202    var format = function (url, rez, params) {
13203        if (!url) {
13204            return;
13205        }
13206
13207        params = params || '';
13208
13209        if ($.type(params) === "object") {
13210            params = $.param(params, true);
13211        }
13212
13213        $.each(rez, function (key, value) {
13214            url = url.replace('$' + key, value || '');
13215        });
13216
13217        if (params.length) {
13218            url += (url.indexOf('?') > 0 ? '&' : '?') + params;
13219        }
13220
13221        return url;
13222    };
13223
13224// Object containing properties for each media type
13225
13226    var defaults = {
13227        youtube: {
13228            matcher: /(youtube\.com|youtu\.be|youtube\-nocookie\.com)\/(watch\?(.*&)?v=|v\/|u\/|embed\/?)?(videoseries\?list=(.*)|[\w-]{11}|\?listType=(.*)&list=(.*))(.*)/i,
13229            params: {
13230                autoplay: 1,
13231                autohide: 1,
13232                fs: 1,
13233                rel: 0,
13234                hd: 1,
13235                wmode: 'transparent',
13236                enablejsapi: 1,
13237                html5: 1
13238            },
13239            paramPlace: 8,
13240            type: 'iframe',
13241            url: '//www.youtube.com/embed/$4',
13242            thumb: '//img.youtube.com/vi/$4/hqdefault.jpg'
13243        },
13244
13245        vimeo: {
13246            matcher: /^.+vimeo.com\/(.*\/)?([\d]+)(.*)?/,
13247            params: {
13248                autoplay: 1,
13249                hd: 1,
13250                show_title: 1,
13251                show_byline: 1,
13252                show_portrait: 0,
13253                fullscreen: 1,
13254                api: 1
13255            },
13256            paramPlace: 3,
13257            type: 'iframe',
13258            url: '//player.vimeo.com/video/$2'
13259        },
13260
13261        metacafe: {
13262            matcher: /metacafe.com\/watch\/(\d+)\/(.*)?/,
13263            type: 'iframe',
13264            url: '//www.metacafe.com/embed/$1/?ap=1'
13265        },
13266
13267        dailymotion: {
13268            matcher: /dailymotion.com\/video\/(.*)\/?(.*)/,
13269            params: {
13270                additionalInfos: 0,
13271                autoStart: 1
13272            },
13273            type: 'iframe',
13274            url: '//www.dailymotion.com/embed/video/$1'
13275        },
13276
13277        vine: {
13278            matcher: /vine.co\/v\/([a-zA-Z0-9\?\=\-]+)/,
13279            type: 'iframe',
13280            url: '//vine.co/v/$1/embed/simple'
13281        },
13282
13283        instagram: {
13284            matcher: /(instagr\.am|instagram\.com)\/p\/([a-zA-Z0-9_\-]+)\/?/i,
13285            type: 'image',
13286            url: '//$1/p/$2/media/?size=l'
13287        },
13288
13289        // Examples:
13290        // http://maps.google.com/?ll=48.857995,2.294297&spn=0.007666,0.021136&t=m&z=16
13291        // http://maps.google.com/?ll=48.857995,2.294297&spn=0.007666,0.021136&t=m&z=16
13292        // https://www.google.lv/maps/place/Googleplex/@37.4220041,-122.0833494,17z/data=!4m5!3m4!1s0x0:0x6c296c66619367e0!8m2!3d37.4219998!4d-122.0840572
13293        google_maps: {
13294            matcher: /(maps\.)?google\.([a-z]{2,3}(\.[a-z]{2})?)\/(((maps\/(place\/(.*)\/)?\@(.*),(\d+.?\d+?)z))|(\?ll=))(.*)?/i,
13295            type: 'iframe',
13296            url: function (rez) {
13297                return '//maps.google.' + rez[2] + '/?ll=' + (rez[9] ? rez[9] + '&z=' + Math.floor(rez[10]) + (rez[12] ? rez[12].replace(/^\//, "&") : '') : rez[12]) + '&output=' + (rez[12] && rez[12].indexOf('layer=c') > 0 ? 'svembed' : 'embed');
13298            }
13299        }
13300    };
13301
13302    $(document).on('onInit.fb', function (e, instance) {
13303
13304        $.each(instance.group, function (i, item) {
13305
13306            var url = item.src || '',
13307                type = false,
13308                media,
13309                thumb,
13310                rez,
13311                params,
13312                urlParams,
13313                o,
13314                provider;
13315
13316            // Skip items that already have content type
13317            if (item.type) {
13318                return;
13319            }
13320
13321            media = $.extend(true, {}, defaults, item.opts.media);
13322
13323            // Look for any matching media type
13324            $.each(media, function (n, el) {
13325                rez = url.match(el.matcher);
13326                o = {};
13327                provider = n;
13328
13329                if (!rez) {
13330                    return;
13331                }
13332
13333                type = el.type;
13334
13335                if (el.paramPlace && rez[el.paramPlace]) {
13336                    urlParams = rez[el.paramPlace];
13337
13338                    if (urlParams[0] == '?') {
13339                        urlParams = urlParams.substring(1);
13340                    }
13341
13342                    urlParams = urlParams.split('&');
13343
13344                    for (var m = 0; m < urlParams.length; ++m) {
13345                        var p = urlParams[m].split('=', 2);
13346
13347                        if (p.length == 2) {
13348                            o[p[0]] = decodeURIComponent(p[1].replace(/\+/g, " "));
13349                        }
13350                    }
13351                }
13352
13353                params = $.extend(true, {}, el.params, item.opts[n], o);
13354
13355                url = $.type(el.url) === "function" ? el.url.call(this, rez, params, item) : format(el.url, rez, params);
13356                thumb = $.type(el.thumb) === "function" ? el.thumb.call(this, rez, params, item) : format(el.thumb, rez);
13357
13358                if (provider === 'vimeo') {
13359                    url = url.replace('&%23', '#');
13360                }
13361
13362                return false;
13363            });
13364
13365            // If it is found, then change content type and update the url
13366
13367            if (type) {
13368                item.src = url;
13369                item.type = type;
13370
13371                if (!item.opts.thumb && !(item.opts.$thumb && item.opts.$thumb.length)) {
13372                    item.opts.thumb = thumb;
13373                }
13374
13375                if (type === 'iframe') {
13376                    $.extend(true, item.opts, {
13377                        iframe: {
13378                            preload: false,
13379                            attr: {
13380                                scrolling: "no"
13381                            }
13382                        }
13383                    });
13384
13385                    item.contentProvider = provider;
13386
13387                    item.opts.slideClass += ' fancybox-slide--' + (provider == 'google_maps' ? 'map' : 'video');
13388                }
13389
13390            } else {
13391
13392                // If no content type is found, then set it to `image` as fallback
13393                item.type = 'image';
13394            }
13395
13396        });
13397
13398    });
13399
13400}(window.jQuery));
13401
13402// ==========================================================================
13403//
13404// Guestures
13405// Adds touch guestures, handles click and tap events
13406//
13407// ==========================================================================
13408;(function (window, document, $) {
13409    'use strict';
13410
13411    var requestAFrame = (function () {
13412        return window.requestAnimationFrame ||
13413            window.webkitRequestAnimationFrame ||
13414            window.mozRequestAnimationFrame ||
13415            window.oRequestAnimationFrame ||
13416            // if all else fails, use setTimeout
13417            function (callback) {
13418                return window.setTimeout(callback, 1000 / 60);
13419            };
13420    })();
13421
13422
13423    var cancelAFrame = (function () {
13424        return window.cancelAnimationFrame ||
13425            window.webkitCancelAnimationFrame ||
13426            window.mozCancelAnimationFrame ||
13427            window.oCancelAnimationFrame ||
13428            function (id) {
13429                window.clearTimeout(id);
13430            };
13431    })();
13432
13433
13434    var pointers = function (e) {
13435        var result = [];
13436
13437        e = e.originalEvent || e || window.e;
13438        e = e.touches && e.touches.length ? e.touches : (e.changedTouches && e.changedTouches.length ? e.changedTouches : [e]);
13439
13440        for (var key in e) {
13441
13442            if (e[key].pageX) {
13443                result.push({x: e[key].pageX, y: e[key].pageY});
13444
13445            } else if (e[key].clientX) {
13446                result.push({x: e[key].clientX, y: e[key].clientY});
13447            }
13448        }
13449
13450        return result;
13451    };
13452
13453    var distance = function (point2, point1, what) {
13454        if (!point1 || !point2) {
13455            return 0;
13456        }
13457
13458        if (what === 'x') {
13459            return point2.x - point1.x;
13460
13461        } else if (what === 'y') {
13462            return point2.y - point1.y;
13463        }
13464
13465        return Math.sqrt(Math.pow(point2.x - point1.x, 2) + Math.pow(point2.y - point1.y, 2));
13466    };
13467
13468    var isClickable = function ($el) {
13469        if ($el.is('a,button,input,select,textarea') || $.isFunction($el.get(0).onclick)) {
13470            return true;
13471        }
13472
13473        // Check for attributes like data-fancybox-next or data-fancybox-close
13474        for (var i = 0, atts = $el[0].attributes, n = atts.length; i < n; i++) {
13475            if (atts[i].nodeName.substr(0, 14) === 'data-fancybox-') {
13476                return true;
13477            }
13478        }
13479
13480        return false;
13481    };
13482
13483    var hasScrollbars = function (el) {
13484        var overflowY = window.getComputedStyle(el)['overflow-y'];
13485        var overflowX = window.getComputedStyle(el)['overflow-x'];
13486
13487        var vertical = (overflowY === 'scroll' || overflowY === 'auto') && el.scrollHeight > el.clientHeight;
13488        var horizontal = (overflowX === 'scroll' || overflowX === 'auto') && el.scrollWidth > el.clientWidth;
13489
13490        return vertical || horizontal;
13491    };
13492
13493    var isScrollable = function ($el) {
13494        var rez = false;
13495
13496        while (true) {
13497            rez = hasScrollbars($el.get(0));
13498
13499            if (rez) {
13500                break;
13501            }
13502
13503            $el = $el.parent();
13504
13505            if (!$el.length || $el.hasClass('fancybox-stage') || $el.is('body')) {
13506                break;
13507            }
13508        }
13509
13510        return rez;
13511    };
13512
13513
13514    var Guestures = function (instance) {
13515        var self = this;
13516
13517        self.instance = instance;
13518
13519        self.$bg = instance.$refs.bg;
13520        self.$stage = instance.$refs.stage;
13521        self.$container = instance.$refs.container;
13522
13523        self.destroy();
13524
13525        self.$container.on('touchstart.fb.touch mousedown.fb.touch', $.proxy(self, 'ontouchstart'));
13526    };
13527
13528    Guestures.prototype.destroy = function () {
13529        this.$container.off('.fb.touch');
13530    };
13531
13532    Guestures.prototype.ontouchstart = function (e) {
13533        var self = this;
13534
13535        var $target = $(e.target);
13536        var instance = self.instance;
13537        var current = instance.current;
13538        var $content = current.$content;
13539
13540        var isTouchDevice = (e.type == 'touchstart');
13541
13542        // Do not respond to both events
13543        if (isTouchDevice) {
13544            self.$container.off('mousedown.fb.touch');
13545        }
13546
13547        // Ignore clicks while zooming or closing
13548        if (!current || self.instance.isAnimating || self.instance.isClosing) {
13549            e.stopPropagation();
13550            e.preventDefault();
13551
13552            return;
13553        }
13554
13555        // Ignore right click
13556        if (e.originalEvent && e.originalEvent.button == 2) {
13557            return;
13558        }
13559
13560        // Ignore taping on links, buttons, input elements
13561        if (!$target.length || isClickable($target) || isClickable($target.parent())) {
13562            return;
13563        }
13564
13565        // Ignore clicks on the scrollbar
13566        if (e.originalEvent.clientX > $target[0].clientWidth + $target.offset().left) {
13567            return;
13568        }
13569
13570        self.startPoints = pointers(e);
13571
13572        // Prevent zooming if already swiping
13573        if (!self.startPoints || (self.startPoints.length > 1 && instance.isSliding)) {
13574            return;
13575        }
13576
13577        self.$target = $target;
13578        self.$content = $content;
13579        self.canTap = true;
13580
13581        $(document).off('.fb.touch');
13582
13583        $(document).on(isTouchDevice ? 'touchend.fb.touch touchcancel.fb.touch' : 'mouseup.fb.touch mouseleave.fb.touch', $.proxy(self, "ontouchend"));
13584        $(document).on(isTouchDevice ? 'touchmove.fb.touch' : 'mousemove.fb.touch', $.proxy(self, "ontouchmove"));
13585
13586        e.stopPropagation();
13587
13588        if (!(instance.current.opts.touch || instance.canPan()) || !($target.is(self.$stage) || self.$stage.find($target).length)) {
13589
13590            // Prevent ghosting
13591            if ($target.is('img')) {
13592                e.preventDefault();
13593            }
13594
13595            return;
13596        }
13597
13598        if (!($.fancybox.isMobile && (isScrollable(self.$target) || isScrollable(self.$target.parent())))) {
13599            e.preventDefault();
13600        }
13601
13602        self.canvasWidth = Math.round(current.$slide[0].clientWidth);
13603        self.canvasHeight = Math.round(current.$slide[0].clientHeight);
13604
13605        self.startTime = new Date().getTime();
13606        self.distanceX = self.distanceY = self.distance = 0;
13607
13608        self.isPanning = false;
13609        self.isSwiping = false;
13610        self.isZooming = false;
13611
13612        self.sliderStartPos = self.sliderLastPos || {top: 0, left: 0};
13613        self.contentStartPos = $.fancybox.getTranslate(self.$content);
13614        self.contentLastPos = null;
13615
13616        if (self.startPoints.length === 1 && !self.isZooming) {
13617            self.canTap = !instance.isSliding;
13618
13619            if (current.type === 'image' && (self.contentStartPos.width > self.canvasWidth + 1 || self.contentStartPos.height > self.canvasHeight + 1)) {
13620
13621                $.fancybox.stop(self.$content);
13622
13623                self.$content.css('transition-duration', '0ms');
13624
13625                self.isPanning = true;
13626
13627            } else {
13628
13629                self.isSwiping = true;
13630            }
13631
13632            self.$container.addClass('fancybox-controls--isGrabbing');
13633        }
13634
13635        if (self.startPoints.length === 2 && !instance.isAnimating && !current.hasError && current.type === 'image' && (current.isLoaded || current.$ghost)) {
13636            self.isZooming = true;
13637
13638            self.isSwiping = false;
13639            self.isPanning = false;
13640
13641            $.fancybox.stop(self.$content);
13642
13643            self.$content.css('transition-duration', '0ms');
13644
13645            self.centerPointStartX = ((self.startPoints[0].x + self.startPoints[1].x) * 0.5) - $(window).scrollLeft();
13646            self.centerPointStartY = ((self.startPoints[0].y + self.startPoints[1].y) * 0.5) - $(window).scrollTop();
13647
13648            self.percentageOfImageAtPinchPointX = (self.centerPointStartX - self.contentStartPos.left) / self.contentStartPos.width;
13649            self.percentageOfImageAtPinchPointY = (self.centerPointStartY - self.contentStartPos.top) / self.contentStartPos.height;
13650
13651            self.startDistanceBetweenFingers = distance(self.startPoints[0], self.startPoints[1]);
13652        }
13653
13654    };
13655
13656    Guestures.prototype.ontouchmove = function (e) {
13657
13658        var self = this;
13659
13660        self.newPoints = pointers(e);
13661
13662        if ($.fancybox.isMobile && (isScrollable(self.$target) || isScrollable(self.$target.parent()))) {
13663            e.stopPropagation();
13664
13665            self.canTap = false;
13666
13667            return;
13668        }
13669
13670        if (!(self.instance.current.opts.touch || self.instance.canPan()) || !self.newPoints || !self.newPoints.length) {
13671            return;
13672        }
13673
13674        self.distanceX = distance(self.newPoints[0], self.startPoints[0], 'x');
13675        self.distanceY = distance(self.newPoints[0], self.startPoints[0], 'y');
13676
13677        self.distance = distance(self.newPoints[0], self.startPoints[0]);
13678
13679        // Skip false ontouchmove events (Chrome)
13680        if (self.distance > 0) {
13681
13682            if (!(self.$target.is(self.$stage) || self.$stage.find(self.$target).length)) {
13683                return;
13684            }
13685
13686            e.stopPropagation();
13687            e.preventDefault();
13688
13689            if (self.isSwiping) {
13690                self.onSwipe();
13691
13692            } else if (self.isPanning) {
13693                self.onPan();
13694
13695            } else if (self.isZooming) {
13696                self.onZoom();
13697            }
13698
13699        }
13700
13701    };
13702
13703    Guestures.prototype.onSwipe = function () {
13704
13705        var self = this;
13706
13707        var swiping = self.isSwiping;
13708        var left = self.sliderStartPos.left || 0;
13709        var angle;
13710
13711        if (swiping === true) {
13712
13713            if (Math.abs(self.distance) > 10) {
13714
13715                self.canTap = false;
13716
13717                if (self.instance.group.length < 2 && self.instance.opts.touch.vertical) {
13718                    self.isSwiping = 'y';
13719
13720                } else if (self.instance.isSliding || self.instance.opts.touch.vertical === false || (self.instance.opts.touch.vertical === 'auto' && $(window).width() > 800)) {
13721                    self.isSwiping = 'x';
13722
13723                } else {
13724                    angle = Math.abs(Math.atan2(self.distanceY, self.distanceX) * 180 / Math.PI);
13725
13726                    self.isSwiping = (angle > 45 && angle < 135) ? 'y' : 'x';
13727                }
13728
13729                self.instance.isSliding = self.isSwiping;
13730
13731                // Reset points to avoid jumping, because we dropped first swipes to calculate the angle
13732                self.startPoints = self.newPoints;
13733
13734                $.each(self.instance.slides, function (index, slide) {
13735                    $.fancybox.stop(slide.$slide);
13736
13737                    slide.$slide.css('transition-duration', '0ms');
13738
13739                    slide.inTransition = false;
13740
13741                    if (slide.pos === self.instance.current.pos) {
13742                        self.sliderStartPos.left = $.fancybox.getTranslate(slide.$slide).left;
13743                    }
13744                });
13745
13746                //self.instance.current.isMoved = true;
13747
13748                // Stop slideshow
13749                if (self.instance.SlideShow && self.instance.SlideShow.isActive) {
13750                    self.instance.SlideShow.stop();
13751                }
13752            }
13753
13754        } else {
13755
13756            if (swiping == 'x') {
13757
13758                // Sticky edges
13759                if (self.distanceX > 0 && (self.instance.group.length < 2 || (self.instance.current.index === 0 && !self.instance.current.opts.loop))) {
13760                    left = left + Math.pow(self.distanceX, 0.8);
13761
13762                } else if (self.distanceX < 0 && (self.instance.group.length < 2 || (self.instance.current.index === self.instance.group.length - 1 && !self.instance.current.opts.loop))) {
13763                    left = left - Math.pow(-self.distanceX, 0.8);
13764
13765                } else {
13766                    left = left + self.distanceX;
13767                }
13768
13769            }
13770
13771            self.sliderLastPos = {
13772                top: swiping == 'x' ? 0 : self.sliderStartPos.top + self.distanceY,
13773                left: left
13774            };
13775
13776            if (self.requestId) {
13777                cancelAFrame(self.requestId);
13778
13779                self.requestId = null;
13780            }
13781
13782            self.requestId = requestAFrame(function () {
13783
13784                if (self.sliderLastPos) {
13785                    $.each(self.instance.slides, function (index, slide) {
13786                        var pos = slide.pos - self.instance.currPos;
13787
13788                        $.fancybox.setTranslate(slide.$slide, {
13789                            top: self.sliderLastPos.top,
13790                            left: self.sliderLastPos.left + (pos * self.canvasWidth) + (pos * slide.opts.gutter)
13791                        });
13792                    });
13793
13794                    self.$container.addClass('fancybox-is-sliding');
13795                }
13796
13797            });
13798
13799        }
13800
13801    };
13802
13803    Guestures.prototype.onPan = function () {
13804
13805        var self = this;
13806
13807        var newOffsetX, newOffsetY, newPos;
13808
13809        self.canTap = false;
13810
13811        if (self.contentStartPos.width > self.canvasWidth) {
13812            newOffsetX = self.contentStartPos.left + self.distanceX;
13813
13814        } else {
13815            newOffsetX = self.contentStartPos.left;
13816        }
13817
13818        newOffsetY = self.contentStartPos.top + self.distanceY;
13819
13820        newPos = self.limitMovement(newOffsetX, newOffsetY, self.contentStartPos.width, self.contentStartPos.height);
13821
13822        newPos.scaleX = self.contentStartPos.scaleX;
13823        newPos.scaleY = self.contentStartPos.scaleY;
13824
13825        self.contentLastPos = newPos;
13826
13827        if (self.requestId) {
13828            cancelAFrame(self.requestId);
13829
13830            self.requestId = null;
13831        }
13832
13833        self.requestId = requestAFrame(function () {
13834            $.fancybox.setTranslate(self.$content, self.contentLastPos);
13835        });
13836    };
13837
13838// Make panning sticky to the edges
13839    Guestures.prototype.limitMovement = function (newOffsetX, newOffsetY, newWidth, newHeight) {
13840
13841        var self = this;
13842
13843        var minTranslateX, minTranslateY, maxTranslateX, maxTranslateY;
13844
13845        var canvasWidth = self.canvasWidth;
13846        var canvasHeight = self.canvasHeight;
13847
13848        var currentOffsetX = self.contentStartPos.left;
13849        var currentOffsetY = self.contentStartPos.top;
13850
13851        var distanceX = self.distanceX;
13852        var distanceY = self.distanceY;
13853
13854        // Slow down proportionally to traveled distance
13855
13856        minTranslateX = Math.max(0, canvasWidth * 0.5 - newWidth * 0.5);
13857        minTranslateY = Math.max(0, canvasHeight * 0.5 - newHeight * 0.5);
13858
13859        maxTranslateX = Math.min(canvasWidth - newWidth, canvasWidth * 0.5 - newWidth * 0.5);
13860        maxTranslateY = Math.min(canvasHeight - newHeight, canvasHeight * 0.5 - newHeight * 0.5);
13861
13862        if (newWidth > canvasWidth) {
13863
13864            // ->
13865            if (distanceX > 0 && newOffsetX > minTranslateX) {
13866                newOffsetX = minTranslateX - 1 + Math.pow(-minTranslateX + currentOffsetX + distanceX, 0.8) || 0;
13867            }
13868
13869            // 	<-
13870            if (distanceX < 0 && newOffsetX < maxTranslateX) {
13871                newOffsetX = maxTranslateX + 1 - Math.pow(maxTranslateX - currentOffsetX - distanceX, 0.8) || 0;
13872            }
13873
13874        }
13875
13876        if (newHeight > canvasHeight) {
13877
13878            // \/
13879            if (distanceY > 0 && newOffsetY > minTranslateY) {
13880                newOffsetY = minTranslateY - 1 + Math.pow(-minTranslateY + currentOffsetY + distanceY, 0.8) || 0;
13881            }
13882
13883            // /\
13884            if (distanceY < 0 && newOffsetY < maxTranslateY) {
13885                newOffsetY = maxTranslateY + 1 - Math.pow(maxTranslateY - currentOffsetY - distanceY, 0.8) || 0;
13886            }
13887
13888        }
13889
13890        return {
13891            top: newOffsetY,
13892            left: newOffsetX
13893        };
13894
13895    };
13896
13897
13898    Guestures.prototype.limitPosition = function (newOffsetX, newOffsetY, newWidth, newHeight) {
13899
13900        var self = this;
13901
13902        var canvasWidth = self.canvasWidth;
13903        var canvasHeight = self.canvasHeight;
13904
13905        if (newWidth > canvasWidth) {
13906            newOffsetX = newOffsetX > 0 ? 0 : newOffsetX;
13907            newOffsetX = newOffsetX < canvasWidth - newWidth ? canvasWidth - newWidth : newOffsetX;
13908
13909        } else {
13910
13911            // Center horizontally
13912            newOffsetX = Math.max(0, canvasWidth / 2 - newWidth / 2);
13913
13914        }
13915
13916        if (newHeight > canvasHeight) {
13917            newOffsetY = newOffsetY > 0 ? 0 : newOffsetY;
13918            newOffsetY = newOffsetY < canvasHeight - newHeight ? canvasHeight - newHeight : newOffsetY;
13919
13920        } else {
13921
13922            // Center vertically
13923            newOffsetY = Math.max(0, canvasHeight / 2 - newHeight / 2);
13924
13925        }
13926
13927        return {
13928            top: newOffsetY,
13929            left: newOffsetX
13930        };
13931
13932    };
13933
13934    Guestures.prototype.onZoom = function () {
13935
13936        var self = this;
13937
13938        // Calculate current distance between points to get pinch ratio and new width and height
13939
13940        var currentWidth = self.contentStartPos.width;
13941        var currentHeight = self.contentStartPos.height;
13942
13943        var currentOffsetX = self.contentStartPos.left;
13944        var currentOffsetY = self.contentStartPos.top;
13945
13946        var endDistanceBetweenFingers = distance(self.newPoints[0], self.newPoints[1]);
13947
13948        var pinchRatio = endDistanceBetweenFingers / self.startDistanceBetweenFingers;
13949
13950        var newWidth = Math.floor(currentWidth * pinchRatio);
13951        var newHeight = Math.floor(currentHeight * pinchRatio);
13952
13953        // This is the translation due to pinch-zooming
13954        var translateFromZoomingX = (currentWidth - newWidth) * self.percentageOfImageAtPinchPointX;
13955        var translateFromZoomingY = (currentHeight - newHeight) * self.percentageOfImageAtPinchPointY;
13956
13957        //Point between the two touches
13958
13959        var centerPointEndX = ((self.newPoints[0].x + self.newPoints[1].x) / 2) - $(window).scrollLeft();
13960        var centerPointEndY = ((self.newPoints[0].y + self.newPoints[1].y) / 2) - $(window).scrollTop();
13961
13962        // And this is the translation due to translation of the centerpoint
13963        // between the two fingers
13964
13965        var translateFromTranslatingX = centerPointEndX - self.centerPointStartX;
13966        var translateFromTranslatingY = centerPointEndY - self.centerPointStartY;
13967
13968        // The new offset is the old/current one plus the total translation
13969
13970        var newOffsetX = currentOffsetX + (translateFromZoomingX + translateFromTranslatingX);
13971        var newOffsetY = currentOffsetY + (translateFromZoomingY + translateFromTranslatingY);
13972
13973        var newPos = {
13974            top: newOffsetY,
13975            left: newOffsetX,
13976            scaleX: self.contentStartPos.scaleX * pinchRatio,
13977            scaleY: self.contentStartPos.scaleY * pinchRatio
13978        };
13979
13980        self.canTap = false;
13981
13982        self.newWidth = newWidth;
13983        self.newHeight = newHeight;
13984
13985        self.contentLastPos = newPos;
13986
13987        if (self.requestId) {
13988            cancelAFrame(self.requestId);
13989
13990            self.requestId = null;
13991        }
13992
13993        self.requestId = requestAFrame(function () {
13994            $.fancybox.setTranslate(self.$content, self.contentLastPos);
13995        });
13996
13997    };
13998
13999    Guestures.prototype.ontouchend = function (e) {
14000
14001        var self = this;
14002        var dMs = Math.max((new Date().getTime()) - self.startTime, 1);
14003
14004        var swiping = self.isSwiping;
14005        var panning = self.isPanning;
14006        var zooming = self.isZooming;
14007
14008        self.endPoints = pointers(e);
14009
14010        self.$container.removeClass('fancybox-controls--isGrabbing');
14011
14012        $(document).off('.fb.touch');
14013
14014        if (self.requestId) {
14015            cancelAFrame(self.requestId);
14016
14017            self.requestId = null;
14018        }
14019
14020        self.isSwiping = false;
14021        self.isPanning = false;
14022        self.isZooming = false;
14023
14024        if (self.canTap) {
14025            return self.onTap(e);
14026        }
14027
14028        self.speed = 366;
14029
14030        // Speed in px/ms
14031        self.velocityX = self.distanceX / dMs * 0.5;
14032        self.velocityY = self.distanceY / dMs * 0.5;
14033
14034        self.speedX = Math.max(self.speed * 0.5, Math.min(self.speed * 1.5, (1 / Math.abs(self.velocityX)) * self.speed));
14035
14036        if (panning) {
14037            self.endPanning();
14038
14039        } else if (zooming) {
14040            self.endZooming();
14041
14042        } else {
14043            self.endSwiping(swiping);
14044        }
14045
14046        return;
14047    };
14048
14049    Guestures.prototype.endSwiping = function (swiping) {
14050
14051        var self = this;
14052        var ret = false;
14053
14054        self.instance.isSliding = false;
14055        self.sliderLastPos = null;
14056
14057        // Close if swiped vertically / navigate if horizontally
14058        if (swiping == 'y' && Math.abs(self.distanceY) > 50) {
14059
14060            // Continue vertical movement
14061            $.fancybox.animate(self.instance.current.$slide, {
14062                top: self.sliderStartPos.top + self.distanceY + (self.velocityY * 150),
14063                opacity: 0
14064            }, 150);
14065
14066            ret = self.instance.close(true, 300);
14067
14068        } else if (swiping == 'x' && self.distanceX > 50 && self.instance.group.length > 1) {
14069            ret = self.instance.previous(self.speedX);
14070
14071        } else if (swiping == 'x' && self.distanceX < -50 && self.instance.group.length > 1) {
14072            ret = self.instance.next(self.speedX);
14073        }
14074
14075        if (ret === false && (swiping == 'x' || swiping == 'y')) {
14076            self.instance.jumpTo(self.instance.current.index, 150);
14077        }
14078
14079        self.$container.removeClass('fancybox-is-sliding');
14080
14081    };
14082
14083// Limit panning from edges
14084// ========================
14085
14086    Guestures.prototype.endPanning = function () {
14087
14088        var self = this;
14089        var newOffsetX, newOffsetY, newPos;
14090
14091        if (!self.contentLastPos) {
14092            return;
14093        }
14094
14095        if (self.instance.current.opts.touch.momentum === false) {
14096            newOffsetX = self.contentLastPos.left;
14097            newOffsetY = self.contentLastPos.top;
14098
14099        } else {
14100
14101            // Continue movement
14102            newOffsetX = self.contentLastPos.left + (self.velocityX * self.speed);
14103            newOffsetY = self.contentLastPos.top + (self.velocityY * self.speed);
14104        }
14105
14106        newPos = self.limitPosition(newOffsetX, newOffsetY, self.contentStartPos.width, self.contentStartPos.height);
14107
14108        newPos.width = self.contentStartPos.width;
14109        newPos.height = self.contentStartPos.height;
14110
14111        $.fancybox.animate(self.$content, newPos, 330);
14112    };
14113
14114
14115    Guestures.prototype.endZooming = function () {
14116
14117        var self = this;
14118
14119        var current = self.instance.current;
14120
14121        var newOffsetX, newOffsetY, newPos, reset;
14122
14123        var newWidth = self.newWidth;
14124        var newHeight = self.newHeight;
14125
14126        if (!self.contentLastPos) {
14127            return;
14128        }
14129
14130        newOffsetX = self.contentLastPos.left;
14131        newOffsetY = self.contentLastPos.top;
14132
14133        reset = {
14134            top: newOffsetY,
14135            left: newOffsetX,
14136            width: newWidth,
14137            height: newHeight,
14138            scaleX: 1,
14139            scaleY: 1
14140        };
14141
14142        // Reset scalex/scaleY values; this helps for perfomance and does not break animation
14143        $.fancybox.setTranslate(self.$content, reset);
14144
14145        if (newWidth < self.canvasWidth && newHeight < self.canvasHeight) {
14146            self.instance.scaleToFit(150);
14147
14148        } else if (newWidth > current.width || newHeight > current.height) {
14149            self.instance.scaleToActual(self.centerPointStartX, self.centerPointStartY, 150);
14150
14151        } else {
14152
14153            newPos = self.limitPosition(newOffsetX, newOffsetY, newWidth, newHeight);
14154
14155            // Switch from scale() to width/height or animation will not work correctly
14156            $.fancybox.setTranslate(self.content, $.fancybox.getTranslate(self.$content));
14157
14158            $.fancybox.animate(self.$content, newPos, 150);
14159        }
14160
14161    };
14162
14163    Guestures.prototype.onTap = function (e) {
14164        var self = this;
14165        var $target = $(e.target);
14166
14167        var instance = self.instance;
14168        var current = instance.current;
14169
14170        var endPoints = (e && pointers(e)) || self.startPoints;
14171
14172        var tapX = endPoints[0] ? endPoints[0].x - self.$stage.offset().left : 0;
14173        var tapY = endPoints[0] ? endPoints[0].y - self.$stage.offset().top : 0;
14174
14175        var where;
14176
14177        var process = function (prefix) {
14178
14179            var action = current.opts[prefix];
14180
14181            if ($.isFunction(action)) {
14182                action = action.apply(instance, [current, e]);
14183            }
14184
14185            if (!action) {
14186                return;
14187            }
14188
14189            switch (action) {
14190
14191                case "close" :
14192
14193                    instance.close(self.startEvent);
14194
14195                    break;
14196
14197                case "toggleControls" :
14198
14199                    instance.toggleControls(true);
14200
14201                    break;
14202
14203                case "next" :
14204
14205                    instance.next();
14206
14207                    break;
14208
14209                case "nextOrClose" :
14210
14211                    if (instance.group.length > 1) {
14212                        instance.next();
14213
14214                    } else {
14215                        instance.close(self.startEvent);
14216                    }
14217
14218                    break;
14219
14220                case "zoom" :
14221
14222                    if (current.type == 'image' && (current.isLoaded || current.$ghost)) {
14223
14224                        if (instance.canPan()) {
14225                            instance.scaleToFit();
14226
14227                        } else if (instance.isScaledDown()) {
14228                            instance.scaleToActual(tapX, tapY);
14229
14230                        } else if (instance.group.length < 2) {
14231                            instance.close(self.startEvent);
14232                        }
14233                    }
14234
14235                    break;
14236            }
14237
14238        };
14239
14240        // Ignore right click
14241        if (e.originalEvent && e.originalEvent.button == 2) {
14242            return;
14243        }
14244
14245        // Skip if current slide is not in the center
14246        if (instance.isSliding) {
14247            return;
14248        }
14249
14250        // Skip if clicked on the scrollbar
14251        if (tapX > $target[0].clientWidth + $target.offset().left) {
14252            return;
14253        }
14254
14255        // Check where is clicked
14256        if ($target.is('.fancybox-bg,.fancybox-inner,.fancybox-outer,.fancybox-container')) {
14257            where = 'Outside';
14258
14259        } else if ($target.is('.fancybox-slide')) {
14260            where = 'Slide';
14261
14262        } else if (instance.current.$content && instance.current.$content.has(e.target).length) {
14263            where = 'Content';
14264
14265        } else {
14266            return;
14267        }
14268
14269        // Check if this is a double tap
14270        if (self.tapped) {
14271
14272            // Stop previously created single tap
14273            clearTimeout(self.tapped);
14274            self.tapped = null;
14275
14276            // Skip if distance between taps is too big
14277            if (Math.abs(tapX - self.tapX) > 50 || Math.abs(tapY - self.tapY) > 50 || instance.isSliding) {
14278                return this;
14279            }
14280
14281            // OK, now we assume that this is a double-tap
14282            process('dblclick' + where);
14283
14284        } else {
14285
14286            // Single tap will be processed if user has not clicked second time within 300ms
14287            // or there is no need to wait for double-tap
14288            self.tapX = tapX;
14289            self.tapY = tapY;
14290
14291            if (current.opts['dblclick' + where] && current.opts['dblclick' + where] !== current.opts['click' + where]) {
14292                self.tapped = setTimeout(function () {
14293                    self.tapped = null;
14294
14295                    process('click' + where);
14296
14297                }, 300);
14298
14299            } else {
14300                process('click' + where);
14301            }
14302
14303        }
14304
14305        return this;
14306    };
14307
14308    $(document).on('onActivate.fb', function (e, instance) {
14309        if (instance && !instance.Guestures) {
14310            instance.Guestures = new Guestures(instance);
14311        }
14312    });
14313
14314    $(document).on('beforeClose.fb', function (e, instance) {
14315        if (instance && instance.Guestures) {
14316            instance.Guestures.destroy();
14317        }
14318    });
14319
14320
14321}(window, document, window.jQuery));
14322
14323// ==========================================================================
14324//
14325// SlideShow
14326// Enables slideshow functionality
14327//
14328// Example of usage:
14329// $.fancybox.getInstance().SlideShow.start()
14330//
14331// ==========================================================================
14332;(function (document, $) {
14333    'use strict';
14334
14335    var SlideShow = function (instance) {
14336        this.instance = instance;
14337        this.init();
14338    };
14339
14340    $.extend(SlideShow.prototype, {
14341        timer: null,
14342        isActive: false,
14343        $button: null,
14344        speed: 3000,
14345
14346        init: function () {
14347            var self = this;
14348
14349            self.$button = self.instance.$refs.toolbar.find('[data-fancybox-play]').on('click', function () {
14350                self.toggle();
14351            });
14352
14353            if (self.instance.group.length < 2 || !self.instance.group[self.instance.currIndex].opts.slideShow) {
14354                self.$button.hide();
14355            }
14356        },
14357
14358        set: function () {
14359            var self = this;
14360
14361            // Check if reached last element
14362            if (self.instance && self.instance.current && (self.instance.current.opts.loop || self.instance.currIndex < self.instance.group.length - 1)) {
14363                self.timer = setTimeout(function () {
14364                    self.instance.next();
14365
14366                }, self.instance.current.opts.slideShow.speed || self.speed);
14367
14368            } else {
14369                self.stop();
14370                self.instance.idleSecondsCounter = 0;
14371                self.instance.showControls();
14372            }
14373
14374        },
14375
14376        clear: function () {
14377            var self = this;
14378
14379            clearTimeout(self.timer);
14380
14381            self.timer = null;
14382        },
14383
14384        start: function () {
14385            var self = this;
14386            var current = self.instance.current;
14387
14388            if (self.instance && current && (current.opts.loop || current.index < self.instance.group.length - 1)) {
14389
14390                self.isActive = true;
14391
14392                self.$button
14393                    .attr('title', current.opts.i18n[current.opts.lang].PLAY_STOP)
14394                    .addClass('fancybox-button--pause');
14395
14396                if (current.isComplete) {
14397                    self.set();
14398                }
14399            }
14400        },
14401
14402        stop: function () {
14403            var self = this;
14404            var current = self.instance.current;
14405
14406            self.clear();
14407
14408            self.$button
14409                .attr('title', current.opts.i18n[current.opts.lang].PLAY_START)
14410                .removeClass('fancybox-button--pause');
14411
14412            self.isActive = false;
14413        },
14414
14415        toggle: function () {
14416            var self = this;
14417
14418            if (self.isActive) {
14419                self.stop();
14420
14421            } else {
14422                self.start();
14423            }
14424        }
14425
14426    });
14427
14428    $(document).on({
14429        'onInit.fb': function (e, instance) {
14430            if (instance && !instance.SlideShow) {
14431                instance.SlideShow = new SlideShow(instance);
14432            }
14433        },
14434
14435        'beforeShow.fb': function (e, instance, current, firstRun) {
14436            var SlideShow = instance && instance.SlideShow;
14437
14438            if (firstRun) {
14439
14440                if (SlideShow && current.opts.slideShow.autoStart) {
14441                    SlideShow.start();
14442                }
14443
14444            } else if (SlideShow && SlideShow.isActive) {
14445                SlideShow.clear();
14446            }
14447        },
14448
14449        'afterShow.fb': function (e, instance, current) {
14450            var SlideShow = instance && instance.SlideShow;
14451
14452            if (SlideShow && SlideShow.isActive) {
14453                SlideShow.set();
14454            }
14455        },
14456
14457        'afterKeydown.fb': function (e, instance, current, keypress, keycode) {
14458            var SlideShow = instance && instance.SlideShow;
14459
14460            // "P" or Spacebar
14461            if (SlideShow && current.opts.slideShow && (keycode === 80 || keycode === 32) && !$(document.activeElement).is('button,a,input')) {
14462                keypress.preventDefault();
14463
14464                SlideShow.toggle();
14465            }
14466        },
14467
14468        'beforeClose.fb onDeactivate.fb': function (e, instance) {
14469            var SlideShow = instance && instance.SlideShow;
14470
14471            if (SlideShow) {
14472                SlideShow.stop();
14473            }
14474        }
14475    });
14476
14477// Page Visibility API to pause slideshow when window is not active
14478    $(document).on("visibilitychange", function () {
14479        var instance = $.fancybox.getInstance();
14480        var SlideShow = instance && instance.SlideShow;
14481
14482        if (SlideShow && SlideShow.isActive) {
14483            if (document.hidden) {
14484                SlideShow.clear();
14485
14486            } else {
14487                SlideShow.set();
14488            }
14489        }
14490    });
14491
14492}(document, window.jQuery));
14493
14494// ==========================================================================
14495//
14496// FullScreen
14497// Adds fullscreen functionality
14498//
14499// ==========================================================================
14500;(function (document, $) {
14501    'use strict';
14502
14503// Collection of methods supported by user browser
14504    var fn = (function () {
14505
14506        var fnMap = [
14507            [
14508                'requestFullscreen',
14509                'exitFullscreen',
14510                'fullscreenElement',
14511                'fullscreenEnabled',
14512                'fullscreenchange',
14513                'fullscreenerror'
14514            ],
14515            // new WebKit
14516            [
14517                'webkitRequestFullscreen',
14518                'webkitExitFullscreen',
14519                'webkitFullscreenElement',
14520                'webkitFullscreenEnabled',
14521                'webkitfullscreenchange',
14522                'webkitfullscreenerror'
14523
14524            ],
14525            // old WebKit (Safari 5.1)
14526            [
14527                'webkitRequestFullScreen',
14528                'webkitCancelFullScreen',
14529                'webkitCurrentFullScreenElement',
14530                'webkitCancelFullScreen',
14531                'webkitfullscreenchange',
14532                'webkitfullscreenerror'
14533
14534            ],
14535            [
14536                'mozRequestFullScreen',
14537                'mozCancelFullScreen',
14538                'mozFullScreenElement',
14539                'mozFullScreenEnabled',
14540                'mozfullscreenchange',
14541                'mozfullscreenerror'
14542            ],
14543            [
14544                'msRequestFullscreen',
14545                'msExitFullscreen',
14546                'msFullscreenElement',
14547                'msFullscreenEnabled',
14548                'MSFullscreenChange',
14549                'MSFullscreenError'
14550            ]
14551        ];
14552
14553        var val;
14554        var ret = {};
14555        var i, j;
14556
14557        for (i = 0; i < fnMap.length; i++) {
14558            val = fnMap[i];
14559
14560            if (val && val[1] in document) {
14561                for (j = 0; j < val.length; j++) {
14562                    ret[fnMap[0][j]] = val[j];
14563                }
14564
14565                return ret;
14566            }
14567        }
14568
14569        return false;
14570    })();
14571
14572// If browser does not have Full Screen API, then simply unset default button template and stop
14573    if (!fn) {
14574        $.fancybox.defaults.btnTpl.fullScreen = false;
14575
14576        return;
14577    }
14578
14579    var FullScreen = {
14580        request: function (elem) {
14581
14582            elem = elem || document.documentElement;
14583
14584            elem[fn.requestFullscreen](elem.ALLOW_KEYBOARD_INPUT);
14585
14586        },
14587        exit: function () {
14588
14589            document[fn.exitFullscreen]();
14590
14591        },
14592        toggle: function (elem) {
14593
14594            elem = elem || document.documentElement;
14595
14596            if (this.isFullscreen()) {
14597                this.exit();
14598
14599            } else {
14600                this.request(elem);
14601            }
14602
14603        },
14604        isFullscreen: function () {
14605
14606            return Boolean(document[fn.fullscreenElement]);
14607
14608        },
14609        enabled: function () {
14610
14611            return Boolean(document[fn.fullscreenEnabled]);
14612
14613        }
14614    };
14615
14616    $(document).on({
14617        'onInit.fb': function (e, instance) {
14618            var $container;
14619
14620            var $button = instance.$refs.toolbar.find('[data-fancybox-fullscreen]');
14621
14622            if (instance && !instance.FullScreen && instance.group[instance.currIndex].opts.fullScreen) {
14623                $container = instance.$refs.container;
14624
14625                $container.on('click.fb-fullscreen', '[data-fancybox-fullscreen]', function (e) {
14626
14627                    e.stopPropagation();
14628                    e.preventDefault();
14629
14630                    FullScreen.toggle($container[0]);
14631
14632                });
14633
14634                if (instance.opts.fullScreen && instance.opts.fullScreen.autoStart === true) {
14635                    FullScreen.request($container[0]);
14636                }
14637
14638                // Expose API
14639                instance.FullScreen = FullScreen;
14640
14641            } else {
14642                $button.hide();
14643            }
14644
14645        },
14646
14647        'afterKeydown.fb': function (e, instance, current, keypress, keycode) {
14648
14649            // "P" or Spacebar
14650            if (instance && instance.FullScreen && keycode === 70) {
14651                keypress.preventDefault();
14652
14653                instance.FullScreen.toggle(instance.$refs.container[0]);
14654            }
14655
14656        },
14657
14658        'beforeClose.fb': function (instance) {
14659            if (instance && instance.FullScreen) {
14660                FullScreen.exit();
14661            }
14662        }
14663    });
14664
14665    $(document).on(fn.fullscreenchange, function () {
14666        var instance = $.fancybox.getInstance();
14667
14668        // If image is zooming, then force to stop and reposition properly
14669        if (instance.current && instance.current.type === 'image' && instance.isAnimating) {
14670            instance.current.$content.css('transition', 'none');
14671
14672            instance.isAnimating = false;
14673
14674            instance.update(true, true, 0);
14675        }
14676
14677    });
14678
14679}(document, window.jQuery));
14680
14681// ==========================================================================
14682//
14683// Thumbs
14684// Displays thumbnails in a grid
14685//
14686// ==========================================================================
14687;(function (document, $) {
14688    'use strict';
14689
14690    var FancyThumbs = function (instance) {
14691        this.instance = instance;
14692        this.init();
14693    };
14694
14695    $.extend(FancyThumbs.prototype, {
14696
14697        $button: null,
14698        $grid: null,
14699        $list: null,
14700        isVisible: false,
14701
14702        init: function () {
14703            var self = this;
14704
14705            var first = self.instance.group[0],
14706                second = self.instance.group[1];
14707
14708            self.$button = self.instance.$refs.toolbar.find('[data-fancybox-thumbs]');
14709
14710            if (self.instance.group.length > 1 && self.instance.group[self.instance.currIndex].opts.thumbs && (
14711                (first.type == 'image' || first.opts.thumb || first.opts.$thumb) &&
14712                (second.type == 'image' || second.opts.thumb || second.opts.$thumb)
14713            )) {
14714
14715                self.$button.on('click', function () {
14716                    self.toggle();
14717                });
14718
14719                self.isActive = true;
14720
14721            } else {
14722                self.$button.hide();
14723
14724                self.isActive = false;
14725            }
14726
14727        },
14728
14729        create: function () {
14730            var instance = this.instance,
14731                list,
14732                src;
14733
14734            this.$grid = $('<div class="fancybox-thumbs"></div>').appendTo(instance.$refs.container);
14735
14736            list = '<ul>';
14737
14738            $.each(instance.group, function (i, item) {
14739
14740                src = item.opts.thumb || (item.opts.$thumb ? item.opts.$thumb.attr('src') : null);
14741
14742                if (!src && item.type === 'image') {
14743                    src = item.src;
14744                }
14745
14746                if (src && src.length) {
14747                    list += '<li data-index="' + i + '"	tabindex="0" class="fancybox-thumbs-loading"><img data-src="' + src + '" /></li>';
14748                }
14749
14750            });
14751
14752            list += '</ul>';
14753
14754            this.$list = $(list).appendTo(this.$grid).on('click', 'li', function () {
14755                instance.jumpTo($(this).data('index'));
14756            });
14757
14758            this.$list.find('img').hide().one('load', function () {
14759
14760                var $parent = $(this).parent().removeClass('fancybox-thumbs-loading'),
14761                    thumbWidth = $parent.outerWidth(),
14762                    thumbHeight = $parent.outerHeight(),
14763                    width,
14764                    height,
14765                    widthRatio,
14766                    heightRatio;
14767
14768                width = this.naturalWidth || this.width;
14769                height = this.naturalHeight || this.height;
14770
14771                //Calculate thumbnail width/height and center it
14772
14773                widthRatio = width / thumbWidth;
14774                heightRatio = height / thumbHeight;
14775
14776                if (widthRatio >= 1 && heightRatio >= 1) {
14777                    if (widthRatio > heightRatio) {
14778                        width = width / heightRatio;
14779                        height = thumbHeight;
14780
14781                    } else {
14782                        width = thumbWidth;
14783                        height = height / widthRatio;
14784                    }
14785                }
14786
14787                $(this).css({
14788                    width: Math.floor(width),
14789                    height: Math.floor(height),
14790                    'margin-top': Math.min(0, Math.floor(thumbHeight * 0.3 - he
14790ight * 0.3)),
14791                    'margin-left': Math.min(0, Math.floor(thumbWidth * 0.5 - width * 0.5))
14792                }).show();
14793
14794            })
14795                .each(function () {
14796                    this.src = $(this).data('src');
14797                });
14798
14799        },
14800
14801        focus: function () {
14802
14803            if (this.instance.current) {
14804                this.$list
14805                    .children()
14806                    .removeClass('fancybox-thumbs-active')
14807                    .filter('[data-index="' + this.instance.current.index + '"]')
14808                    .addClass('fancybox-thumbs-active')
14809                    .focus();
14810            }
14811
14812        },
14813
14814        close: function () {
14815            this.$grid.hide();
14816        },
14817
14818        update: function () {
14819
14820            this.instance.$refs.container.toggleClass('fancybox-show-thumbs', this.isVisible);
14821
14822            if (this.isVisible) {
14823
14824                if (!this.$grid) {
14825                    this.create();
14826                }
14827
14828                this.instance.trigger('onThumbsShow');
14829
14830                this.focus();
14831
14832            } else if (this.$grid) {
14833                this.instance.trigger('onThumbsHide');
14834            }
14835
14836            // Update content position
14837            this.instance.update();
14838
14839        },
14840
14841        hide: function () {
14842            this.isVisible = false;
14843            this.update();
14844        },
14845
14846        show: function () {
14847            this.isVisible = true;
14848            this.update();
14849        },
14850
14851        toggle: function () {
14852            this.isVisible = !this.isVisible;
14853            this.update();
14854        }
14855
14856    });
14857
14858    $(document).on({
14859
14860        'onInit.fb': function (e, instance) {
14861            if (instance && !instance.Thumbs) {
14862                instance.Thumbs = new FancyThumbs(instance);
14863            }
14864        },
14865
14866        'beforeShow.fb': function (e, instance, item, firstRun) {
14867            var Thumbs = instance && instance.Thumbs;
14868
14869            if (!Thumbs || !Thumbs.isActive) {
14870                return;
14871            }
14872
14873            if (item.modal) {
14874                Thumbs.$button.hide();
14875
14876                Thumbs.hide();
14877
14878                return;
14879            }
14880
14881            if (firstRun && instance.opts.thumbs.autoStart === true) {
14882                Thumbs.show();
14883            }
14884
14885            if (Thumbs.isVisible) {
14886                Thumbs.focus();
14887            }
14888        },
14889
14890        'afterKeydown.fb': function (e, instance, current, keypress, keycode) {
14891            var Thumbs = instance && instance.Thumbs;
14892
14893            // "G"
14894            if (Thumbs && Thumbs.isActive && keycode === 71) {
14895                keypress.preventDefault();
14896
14897                Thumbs.toggle();
14898            }
14899        },
14900
14901        'beforeClose.fb': function (e, instance) {
14902            var Thumbs = instance && instance.Thumbs;
14903
14904            if (Thumbs && Thumbs.isVisible && instance.opts.thumbs.hideOnClose !== false) {
14905                Thumbs.close();
14906            }
14907        }
14908
14909    });
14910
14911}(document, window.jQuery));
14912
14913// ==========================================================================
14914//
14915// Hash
14916// Enables linking to each modal
14917//
14918// ==========================================================================
14919;(function (document, window, $) {
14920    'use strict';
14921
14922// Simple $.escapeSelector polyfill (for jQuery prior v3)
14923    if (!$.escapeSelector) {
14924        $.escapeSelector = function (sel) {
14925            var rcssescape = /([\0-\x1f\x7f]|^-?\d)|^-$|[^\x80-\uFFFF\w-]/g;
14926            var fcssescape = function (ch, asCodePoint) {
14927                if (asCodePoint) {
14928                    // U+0000 NULL becomes U+FFFD REPLACEMENT CHARACTER
14929                    if (ch === "\0") {
14930                        return "\uFFFD";
14931                    }
14932
14933                    // Control characters and (dependent upon position) numbers get escaped as code points
14934                    return ch.slice(0, -1) + "\\" + ch.charCodeAt(ch.length - 1).toString(16) + " ";
14935                }
14936
14937                // Other potentially-special ASCII characters get backslash-escaped
14938                return "\\" + ch;
14939            };
14940
14941            return (sel + "").replace(rcssescape, fcssescape);
14942        };
14943    }
14944
14945// Variable containing last hash value set by fancyBox
14946// It will be used to determine if fancyBox needs to close after hash change is detected
14947    var currentHash = null;
14948
14949// Throtlling the history change
14950    var timerID = null;
14951
14952// Get info about gallery name and current index from url
14953    function parseUrl() {
14954        var hash = window.location.hash.substr(1);
14955        var rez = hash.split('-');
14956        var index = rez.length > 1 && /^\+?\d+$/.test(rez[rez.length - 1]) ? parseInt(rez.pop(-1), 10) || 1 : 1;
14957        var gallery = rez.join('-');
14958
14959        // Index is starting from 1
14960        if (index < 1) {
14961            index = 1;
14962        }
14963
14964        return {
14965            hash: hash,
14966            index: index,
14967            gallery: gallery
14968        };
14969    }
14970
14971// Trigger click evnt on links to open new fancyBox instance
14972    function triggerFromUrl(url) {
14973        var $el;
14974
14975        if (url.gallery !== '') {
14976
14977            // If we can find element matching 'data-fancybox' atribute, then trigger click event for that ..
14978            $el = $("[data-fancybox='" + $.escapeSelector(url.gallery) + "']").eq(url.index - 1);
14979
14980            if ($el.length) {
14981                $el.trigger('click');
14982
14983            } else {
14984
14985                // .. if not, try finding element by ID
14986                $("#" + $.escapeSelector(url.gallery) + "").trigger('click');
14987
14988            }
14989
14990        }
14991    }
14992
14993// Get gallery name from current instance
14994    function getGallery(instance) {
14995        var opts;
14996
14997        if (!instance) {
14998            return false;
14999        }
15000
15001        opts = instance.current ? instance.current.opts : instance.opts;
15002
15003        return opts.$orig ? opts.$orig.data('fancybox') : (opts.hash || '');
15004    }
15005
15006// Star when DOM becomes ready
15007    $(function () {
15008
15009        // Small delay is used to allow other scripts to process "dom ready" event
15010        setTimeout(function () {
15011
15012            // Check if this module is not disabled
15013            if ($.fancybox.defaults.hash === false) {
15014                return;
15015            }
15016
15017            // Update hash when opening/closing fancyBox
15018            $(document).on({
15019                'onInit.fb': function (e, instance) {
15020                    var url, gallery;
15021
15022                    if (instance.group[instance.currIndex].opts.hash === false) {
15023                        return;
15024                    }
15025
15026                    url = parseUrl();
15027                    gallery = getGallery(instance);
15028
15029                    // Make sure gallery start index matches index from hash
15030                    if (gallery && url.gallery && gallery == url.gallery) {
15031                        instance.currIndex = url.index - 1;
15032                    }
15033
15034                },
15035
15036                'beforeShow.fb': function (e, instance, current, firstRun) {
15037                    var gallery;
15038
15039                    if (current.opts.hash === false) {
15040                        return;
15041                    }
15042
15043                    gallery = getGallery(instance);
15044
15045                    // Update window hash
15046                    if (gallery && gallery !== '') {
15047
15048                        if (window.location.hash.indexOf(gallery) < 0) {
15049                            instance.opts.origHash = window.location.hash;
15050                        }
15051
15052                        currentHash = gallery + (instance.group.length > 1 ? '-' + (current.index + 1) : '');
15053
15054                        if ('replaceState' in window.history) {
15055                            if (timerID) {
15056                                clearTimeout(timerID);
15057                            }
15058
15059                            timerID = setTimeout(function () {
15060                                window.history[firstRun ? 'pushState' : 'replaceState']({}, document.title, window.location.pathname + window.location.search + '#' + currentHash);
15061
15062                                timerID = null;
15063
15064                            }, 300);
15065
15066                        } else {
15067                            window.location.hash = currentHash;
15068                        }
15069
15070                    }
15071
15072                },
15073
15074                'beforeClose.fb': function (e, instance, current) {
15075                    var gallery, origHash;
15076
15077                    if (timerID) {
15078                        clearTimeout(timerID);
15079                    }
15080
15081                    if (current.opts.hash === false) {
15082                        return;
15083                    }
15084
15085                    gallery = getGallery(instance);
15086                    origHash = instance && instance.opts.origHash ? instance.opts.origHash : '';
15087
15088                    // Remove hash from location bar
15089                    if (gallery && gallery !== '') {
15090
15091                        if ('replaceState' in history) {
15092                            window.history.replaceState({}, document.title, window.location.pathname + window.location.search + origHash);
15093
15094                        } else {
15095                            window.location.hash = origHash;
15096
15097                            // Keep original scroll position
15098                            $(window).scrollTop(instance.scrollTop).scrollLeft(instance.scrollLeft);
15099                        }
15100                    }
15101
15102                    currentHash = null;
15103                }
15104            });
15105
15106            // Check if need to close after url has changed
15107            $(window).on('hashchange.fb', function () {
15108                var url = parseUrl();
15109
15110                if ($.fancybox.getInstance()) {
15111                    if (currentHash && currentHash !== url.gallery + '-' + url.index && !(url.index === 1 && currentHash == url.gallery)) {
15112                        currentHash = null;
15113
15114                        $.fancybox.close();
15115                    }
15116
15117                } else if (url.gallery !== '') {
15118                    triggerFromUrl(url);
15119                }
15120            });
15121
15122            // If navigating away from current page
15123            $(window).one('unload.fb popstate.fb', function () {
15124                $.fancybox.getInstance('close', true, 0);
15125            });
15126
15127            // Check current hash and trigger click event on matching element to start fancyBox, if needed
15128            triggerFromUrl(parseUrl());
15129
15130        }, 50);
15131
15132    });
vendor: 11,894 bytes, lines 15133-15467
15133
15134
15135}(document, window, window.jQuery));
15136
15137/*! jQuery UI - v1.12.1 - 2017-06-21
15138* http://jqueryui.com
15139* Includes: widget.js, position.js, keycode.js, unique-id.js, widgets/autocomplete.js, widgets/menu.js
15140* Copyright jQuery Foundation and other contributors; Licensed MIT */
15141
15142(function (factory) {
15143    if (typeof define === "function" && define.amd) {
15144
15145        // AMD. Register as an anonymous module.
15146        define(["jquery"], factory);
15147    } else {
15148
15149        // Browser globals
15150        factory(jQuery);
15151    }
15152}(function ($) {
15153
15154    $.ui = $.ui || {};
15155
15156    var version = $.ui.version = "1.12.1";
15157
15158
15159    /*!
15160* jQuery UI Widget 1.12.1
15161* http://jqueryui.com
15162*
15163* Copyright jQuery Foundation and other contributors
15164* Released under the MIT license.
15165* http://jquery.org/license
15166*/
15167
15168//>>label: Widget
15169//>>group: Core
15170//>>description: Provides a factory for creating stateful widgets with a common API.
15171//>>docs: http://api.jqueryui.com/jQuery.widget/
15172//>>demos: http://jqueryui.com/widget/
15173
15174
15175    var widgetUuid = 0;
15176    var widgetSlice = Array.prototype.slice;
15177
15178    $.cleanData = (function (orig) {
15179        return function (elems) {
15180            var events, elem, i;
15181            for (i = 0; (elem = elems[i]) != null; i++) {
15182                try {
15183
15184                    // Only trigger remove when necessary to save time
15185                    events = $._data(elem, "events");
15186                    if (events && events.remove) {
15187                        $(elem).triggerHandler("remove");
15188                    }
15189
15190                    // Http://bugs.jquery.com/ticket/8235
15191                } catch (e) {
15192                }
15193            }
15194            orig(elems);
15195        };
15196    })($.cleanData);
15197
15198    $.widget = function (name, base, prototype) {
15199        var existingConstructor, constructor, basePrototype;
15200
15201// ProxiedPrototype allows the provided prototype to remain unmodified
15202// so that it can be used as a mixin for multiple widgets (#8876)
15203        var proxiedPrototype = {};
15204
15205        var namespace = name.split(".")[0];
15206        name = name.split(".")[1];
15207        var fullName = namespace + "-" + name;
15208
15209        if (!prototype) {
15210            prototype = base;
15211            base = $.Widget;
15212        }
15213
15214        if ($.isArray(prototype)) {
15215            prototype = $.extend.apply(null, [{}].concat(prototype));
15216        }
15217
15218// Create selector for plugin
15219        $.expr[":"][fullName.toLowerCase()] = function (elem) {
15220            return !!$.data(elem, fullName);
15221        };
15222
15223        $[namespace] = $[namespace] || {};
15224        existingConstructor = $[namespace][name];
15225        constructor = $[namespace][name] = function (options, element) {
15226
15227            // Allow instantiation without "new" keyword
15228            if (!this._createWidget) {
15229                return new constructor(options, element);
15230            }
15231
15232            // Allow instantiation without initializing for simple inheritance
15233            // must use "new" keyword (the code above always passes args)
15234            if (arguments.length) {
15235                this._createWidget(options, element);
15236            }
15237        };
15238
15239// Extend with the existing constructor to carry over any static properties
15240        $.extend(constructor, existingConstructor, {
15241            version: prototype.version,
15242
15243            // Copy the object used to create the prototype in case we need to
15244            // redefine the widget later
15245            _proto: $.extend({}, prototype),
15246
15247            // Track widgets that inherit from this widget in case this widget is
15248            // redefined after a widget inherits from it
15249            _childConstructors: []
15250        });
15251
15252        basePrototype = new base();
15253
15254// We need to make the options hash a property directly on the new instance
15255// otherwise we'll modify the options hash on the prototype that we're
15256// inheriting from
15257        basePrototype.options = $.widget.extend({}, basePrototype.options);
15258        $.each(prototype, function (prop, value) {
15259            if (!$.isFunction(value)) {
15260                proxiedPrototype[prop] = value;
15261                return;
15262            }
15263            proxiedPrototype[prop] = (function () {
15264                function _super() {
15265                    return base.prototype[prop].apply(this, arguments);
15266                }
15267
15268                function _superApply(args) {
15269                    return base.prototype[prop].apply(this, args);
15270                }
15271
15272                return function () {
15273                    var __super = this._super;
15274                    var __superApply = this._superApply;
15275                    var returnValue;
15276
15277                    this._super = _super;
15278                    this._superApply = _superApply;
15279
15280                    returnValue = value.apply(this, arguments);
15281
15282                    this._super = __super;
15283                    this._superApply = __superApply;
15284
15285                    return returnValue;
15286                };
15287            })();
15288        });
15289        constructor.prototype = $.widget.extend(basePrototype, {
15290
15291            // TODO: remove support for widgetEventPrefix
15292            // always use the name + a colon as the prefix, e.g., draggable:start
15293            // don't prefix for widgets that aren't DOM-based
15294            widgetEventPrefix: existingConstructor ? (basePrototype.widgetEventPrefix || name) : name
15295        }, proxiedPrototype, {
15296            constructor: constructor,
15297            namespace: namespace,
15298            widgetName: name,
15299            widgetFullName: fullName
15300        });
15301
15302// If this widget is being redefined then we need to find all widgets that
15303// are inheriting from it and redefine all of them so that they inherit from
15304// the new version of this widget. We're essentially trying to replace one
15305// level in the prototype chain.
15306        if (existingConstructor) {
15307            $.each(existingConstructor._childConstructors, function (i, child) {
15308                var childPrototype = child.prototype;
15309
15310                // Redefine the child widget using the same prototype that was
15311                // originally used, but inherit from the new version of the base
15312                $.widget(childPrototype.namespace + "." + childPrototype.widgetName, constructor,
15313                    child._proto);
15314            });
15315
15316            // Remove the list of existing child constructors from the old constructor
15317            // so the old child constructors can be garbage collected
15318            delete existingConstructor._childConstructors;
15319        } else {
15320            base._childConstructors.push(constructor);
15321        }
15322
15323        $.widget.bridge(name, constructor);
15324
15325        return constructor;
15326    };
15327
15328    $.widget.extend = function (target) {
15329        var input = widgetSlice.call(arguments, 1);
15330        var inputIndex = 0;
15331        var inputLength = input.length;
15332        var key;
15333        var value;
15334
15335        for (; inputIndex < inputLength; inputIndex++) {
15336            for (key in input[inputIndex]) {
15337                value = input[inputIndex][key];
15338                if (input[inputIndex].hasOwnProperty(key) && value !== undefined) {
15339
15340                    // Clone objects
15341                    if ($.isPlainObject(value)) {
15342                        target[key] = $.isPlainObject(target[key]) ?
15343                            $.widget.extend({}, target[key], value) :
15344
15345                            // Don't extend strings, arrays, etc. with objects
15346                            $.widget.extend({}, value);
15347
15348                        // Copy everything else by reference
15349                    } else {
15350                        target[key] = value;
15351                    }
15352                }
15353            }
15354        }
15355        return target;
15356    };
15357
15358    $.widget.bridge = function (name, object) {
15359        var fullName = object.prototype.widgetFullName || name;
15360        $.fn[name] = function (options) {
15361            var isMethodCall = typeof options === "string";
15362            var args = widgetSlice.call(arguments, 1);
15363            var returnValue = this;
15364
15365            if (isMethodCall) {
15366
15367                // If this is an empty collection, we need to have the instance method
15368                // return undefined instead of the jQuery instance
15369                if (!this.length && options === "instance") {
15370                    returnValue = undefined;
15371                } else {
15372                    this.each(function () {
15373                        var methodValue;
15374                        var instance = $.data(this, fullName);
15375
15376                        if (options === "instance") {
15377                            returnValue = instance;
15378                            return false;
15379                        }
15380
15381                        if (!instance) {
15382                            return $.error("cannot call methods on " + name +
15383                                " prior to initialization; " +
15384                                "attempted to call method '" + options + "'");
15385                        }
15386
15387                        if (!$.isFunction(instance[options]) || options.charAt(0) === "_") {
15388                            return $.error("no such method '" + options + "' for " + name +
15389                                " widget instance");
15390                        }
15391
15392                        methodValue = instance[options].apply(instance, args);
15393
15394                        if (methodValue !== instance && methodValue !== undefined) {
15395                            returnValue = methodValue && methodValue.jquery ?
15396                                returnValue.pushStack(methodValue.get()) :
15397                                methodValue;
15398                            return false;
15399                        }
15400                    });
15401                }
15402            } else {
15403
15404                // Allow multiple hashes to be passed on init
15405                if (args.length) {
15406                    options = $.widget.extend.apply(null, [options].concat(args));
15407                }
15408
15409                this.each(function () {
15410                    var instance = $.data(this, fullName);
15411                    if (instance) {
15412                        instance.option(options || {});
15413                        if (instance._init) {
15414                            instance._init();
15415                        }
15416                    } else {
15417                        $.data(this, fullName, new object(options, this));
15418                    }
15419                });
15420            }
15421
15422            return returnValue;
15423        };
15424    };
15425
15426    $.Widget = function ( /* options, element */) {
15427    };
15428    $.Widget._childConstructors = [];
15429
15430    $.Widget.prototype = {
15431        widgetName: "widget",
15432        widgetEventPrefix: "",
15433        defaultElement: "<div>",
15434
15435        options: {
15436            classes: {},
15437            disabled: false,
15438
15439            // Callbacks
15440            create: null
15441        },
15442
15443        _createWidget: function (options, element) {
15444            element = $(element || this.defaultElement || this)[0];
15445            this.element = $(element);
15446            this.uuid = widgetUuid++;
15447            this.eventNamespace = "." + this.widgetName + this.uuid;
15448
15449            this.bindings = $();
15450            this.hoverable = $();
15451            this.focusable = $();
15452            this.classesElementLookup = {};
15453
15454            if (element !== this) {
15455                $.data(element, this.widgetFullName, this);
15456                this._on(true, this.element, {
15457                    remove: function (event) {
15458                        if (event.target === element) {
15459                            this.destroy();
15460                        }
15461                    }
15462                });
15463                this.document = $(element.style ?
15464
15465                    // Element within the document
15466                    element.ownerDocument :
15467
vendor: 4,217 bytes, lines 15468-15602
15468                    // Element is window or document
15469                    element.document || element);
15470                this.window = $(this.document[0].defaultView || this.document[0].parentWindow);
15471            }
15472
15473            this.options = $.widget.extend({},
15474                this.options,
15475                this._getCreateOptions(),
15476                options);
15477
15478            this._create();
15479
15480            if (this.options.disabled) {
15481                this._setOptionDisabled(this.options.disabled);
15482            }
15483
15484            this._trigger("create", null, this._getCreateEventData());
15485            this._init();
15486        },
15487
15488        _getCreateOptions: function () {
15489            return {};
15490        },
15491
15492        _getCreateEventData: $.noop,
15493
15494        _create: $.noop,
15495
15496        _init: $.noop,
15497
15498        destroy: function () {
15499            var that = this;
15500
15501            this._destroy();
15502            $.each(this.classesElementLookup, function (key, value) {
15503                that._removeClass(value, key);
15504            });
15505
15506            // We can probably remove the unbind calls in 2.0
15507            // all event bindings should go through this._on()
15508            this.element
15509                .off(this.eventNamespace)
15510                .removeData(this.widgetFullName);
15511            this.widget()
15512                .off(this.eventNamespace)
15513                .removeAttr("aria-disabled");
15514
15515            // Clean up events and states
15516            this.bindings.off(this.eventNamespace);
15517        },
15518
15519        _destroy: $.noop,
15520
15521        widget: function () {
15522            return this.element;
15523        },
15524
15525        option: function (key, value) {
15526            var options = key;
15527            var parts;
15528            var curOption;
15529            var i;
15530
15531            if (arguments.length === 0) {
15532
15533                // Don't return a reference to the internal hash
15534                return $.widget.extend({}, this.options);
15535            }
15536
15537            if (typeof key === "string") {
15538
15539                // Handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } }
15540                options = {};
15541                parts = key.split(".");
15542                key = parts.shift();
15543                if (parts.length) {
15544                    curOption = options[key] = $.widget.extend({}, this.options[key]);
15545                    for (i = 0; i < parts.length - 1; i++) {
15546                        curOption[parts[i]] = curOption[parts[i]] || {};
15547                        curOption = curOption[parts[i]];
15548                    }
15549                    key = parts.pop();
15550                    if (arguments.length === 1) {
15551                        return curOption[key] === undefined ? null : curOption[key];
15552                    }
15553                    curOption[key] = value;
15554                } else {
15555                    if (arguments.length === 1) {
15556                        return this.options[key] === undefined ? null : this.options[key];
15557                    }
15558                    options[key] = value;
15559                }
15560            }
15561
15562            this._setOptions(options);
15563
15564            return this;
15565        },
15566
15567        _setOptions: function (options) {
15568            var key;
15569
15570            for (key in options) {
15571                this._setOption(key, options[key]);
15572            }
15573
15574            return this;
15575        },
15576
15577        _setOption: function (key, value) {
15578            if (key === "classes") {
15579                this._setOptionClasses(value);
15580            }
15581
15582            this.options[key] = value;
15583
15584            if (key === "disabled") {
15585                this._setOptionDisabled(value);
15586            }
15587
15588            return this;
15589        },
15590
15591        _setOptionClasses: function (value) {
15592            var classKey, elements, currentElements;
15593
15594            for (classKey in value) {
15595                currentElements = this.classesElementLookup[classKey];
15596                if (value[classKey] === this.options.classes[classKey] ||
15597                    !currentElements ||
15598                    !currentElements.length) {
15599                    continue;
15600                }
15601
15602                // We are doing this to create a new jQuery object because the _removeClass() call
vendor: 10,798 bytes, lines 15603-15879
15603                // on the next line is going to destroy the reference to the current elements being
15604                // tracked. We need to save a copy of this collection so that we can add the new classes
15605                // below.
15606                elements = $(currentElements.get());
15607                this._removeClass(currentElements, classKey);
15608
15609                // We don't use _addClass() here, because that uses this.options.classes
15610                // for generating the string of classes. We want to use the value passed in from
15611                // _setOption(), this is the new value of the classes option which was passed to
15612                // _setOption(). We pass this value directly to _classes().
15613                elements.addClass(this._classes({
15614                    element: elements,
15615                    keys: classKey,
15616                    classes: value,
15617                    add: true
15618                }));
15619            }
15620        },
15621
15622        _setOptionDisabled: function (value) {
15623            this._toggleClass(this.widget(), this.widgetFullName + "-disabled", null, !!value);
15624
15625            // If the widget is becoming disabled, then nothing is interactive
15626            if (value) {
15627                this._removeClass(this.hoverable, null, "ui-state-hover");
15628                this._removeClass(this.focusable, null, "ui-state-focus");
15629            }
15630        },
15631
15632        enable: function () {
15633            return this._setOptions({disabled: false});
15634        },
15635
15636        disable: function () {
15637            return this._setOptions({disabled: true});
15638        },
15639
15640        _classes: function (options) {
15641            var full = [];
15642            var that = this;
15643
15644            options = $.extend({
15645                element: this.element,
15646                classes: this.options.classes || {}
15647            }, options);
15648
15649            function processClassString(classes, checkOption) {
15650                var current, i;
15651                for (i = 0; i < classes.length; i++) {
15652                    current = that.classesElementLookup[classes[i]] || $();
15653                    if (options.add) {
15654                        current = $($.unique(current.get().concat(options.element.get())));
15655                    } else {
15656                        current = $(current.not(options.element).get());
15657                    }
15658                    that.classesElementLookup[classes[i]] = current;
15659                    full.push(classes[i]);
15660                    if (checkOption && options.classes[classes[i]]) {
15661                        full.push(options.classes[classes[i]]);
15662                    }
15663                }
15664            }
15665
15666            this._on(options.element, {
15667                "remove": "_untrackClassesElement"
15668            });
15669
15670            if (options.keys) {
15671                processClassString(options.keys.match(/\S+/g) || [], true);
15672            }
15673            if (options.extra) {
15674                processClassString(options.extra.match(/\S+/g) || []);
15675            }
15676
15677            return full.join(" ");
15678        },
15679
15680        _untrackClassesElement: function (event) {
15681            var that = this;
15682            $.each(that.classesElementLookup, function (key, value) {
15683                if ($.inArray(event.target, value) !== -1) {
15684                    that.classesElementLookup[key] = $(value.not(event.target).get());
15685                }
15686            });
15687        },
15688
15689        _removeClass: function (element, keys, extra) {
15690            return this._toggleClass(element, keys, extra, false);
15691        },
15692
15693        _addClass: function (element, keys, extra) {
15694            return this._toggleClass(element, keys, extra, true);
15695        },
15696
15697        _toggleClass: function (element, keys, extra, add) {
15698            add = (typeof add === "boolean") ? add : extra;
15699            var shift = (typeof element === "string" || element === null),
15700                options = {
15701                    extra: shift ? keys : extra,
15702                    keys: shift ? element : keys,
15703                    element: shift ? this.element : element,
15704                    add: add
15705                };
15706            options.element.toggleClass(this._classes(options), add);
15707            return this;
15708        },
15709
15710        _on: function (suppressDisabledCheck, element, handlers) {
15711            var delegateElement;
15712            var instance = this;
15713
15714            // No suppressDisabledCheck flag, shuffle arguments
15715            if (typeof suppressDisabledCheck !== "boolean") {
15716                handlers = element;
15717                element = suppressDisabledCheck;
15718                suppressDisabledCheck = false;
15719            }
15720
15721            // No element argument, shuffle and use this.element
15722            if (!handlers) {
15723                handlers = element;
15724                element = this.element;
15725                delegateElement = this.widget();
15726            } else {
15727                element = delegateElement = $(element);
15728                this.bindings = this.bindings.add(element);
15729            }
15730
15731            $.each(handlers, function (event, handler) {
15732                function handlerProxy() {
15733
15734                    // Allow widgets to customize the disabled handling
15735                    // - disabled as an array instead of boolean
15736                    // - disabled class as method for disabling individual parts
15737                    if (!suppressDisabledCheck &&
15738                        (instance.options.disabled === true ||
15739                            $(this).hasClass("ui-state-disabled"))) {
15740                        return;
15741                    }
15742                    return (typeof handler === "string" ? instance[handler] : handler)
15743                        .apply(instance, arguments);
15744                }
15745
15746                // Copy the guid so direct unbinding works
15747                if (typeof handler !== "string") {
15748                    handlerProxy.guid = handler.guid =
15749                        handler.guid || handlerProxy.guid || $.guid++;
15750                }
15751
15752                var match = event.match(/^([\w:-]*)\s*(.*)$/);
15753                var eventName = match[1] + instance.eventNamespace;
15754                var selector = match[2];
15755
15756                if (selector) {
15757                    delegateElement.on(eventName, selector, handlerProxy);
15758                } else {
15759                    element.on(eventName, handlerProxy);
15760                }
15761            });
15762        },
15763
15764        _off: function (element, eventName) {
15765            eventName = (eventName || "").split(" ").join(this.eventNamespace + " ") +
15766                this.eventNamespace;
15767            element.off(eventName).off(eventName);
15768
15769            // Clear the stack to avoid memory leaks (#10056)
15770            this.bindings = $(this.bindings.not(element).get());
15771            this.focusable = $(this.focusable.not(element).get());
15772            this.hoverable = $(this.hoverable.not(element).get());
15773        },
15774
15775        _delay: function (handler, delay) {
15776            function handlerProxy() {
15777                return (typeof handler === "string" ? instance[handler] : handler)
15778                    .apply(instance, arguments);
15779            }
15780
15781            var instance = this;
15782            return setTimeout(handlerProxy, delay || 0);
15783        },
15784
15785        _hoverable: function (element) {
15786            this.hoverable = this.hoverable.add(element);
15787            this._on(element, {
15788                mouseenter: function (event) {
15789                    this._addClass($(event.currentTarget), null, "ui-state-hover");
15790                },
15791                mouseleave: function (event) {
15792                    this._removeClass($(event.currentTarget), null, "ui-state-hover");
15793                }
15794            });
15795        },
15796
15797        _focusable: function (element) {
15798            this.focusable = this.focusable.add(element);
15799            this._on(element, {
15800                focusin: function (event) {
15801                    this._addClass($(event.currentTarget), null, "ui-state-focus");
15802                },
15803                focusout: function (event) {
15804                    this._removeClass($(event.currentTarget), null, "ui-state-focus");
15805                }
15806            });
15807        },
15808
15809        _trigger: function (type, event, data) {
15810            var prop, orig;
15811            var callback = this.options[type];
15812
15813            data = data || {};
15814            event = $.Event(event);
15815            event.type = (type === this.widgetEventPrefix ?
15816                type :
15817                this.widgetEventPrefix + type).toLowerCase();
15818
15819            // The original event may come from any element
15820            // so we need to reset the target on the new event
15821            event.target = this.element[0];
15822
15823            // Copy original event properties over to the new event
15824            orig = event.originalEvent;
15825            if (orig) {
15826                for (prop in orig) {
15827                    if (!(prop in event)) {
15828                        event[prop] = orig[prop];
15829                    }
15830                }
15831            }
15832
15833            this.element.trigger(event, data);
15834            return !($.isFunction(callback) &&
15835                callback.apply(this.element[0], [event].concat(data)) === false ||
15836                event.isDefaultPrevented());
15837        }
15838    };
15839
15840    $.each({show: "fadeIn", hide: "fadeOut"}, function (method, defaultEffect) {
15841        $.Widget.prototype["_" + method] = function (element, options, callback) {
15842            if (typeof options === "string") {
15843                options = {effect: options};
15844            }
15845
15846            var hasOptions;
15847            var effectName = !options ?
15848                method :
15849                options === true || typeof options === "number" ?
15850                    defaultEffect :
15851                    options.effect || defaultEffect;
15852
15853            options = options || {};
15854            if (typeof options === "number") {
15855                options = {duration: options};
15856            }
15857
15858            hasOptions = !$.isEmptyObject(options);
15859            options.complete = callback;
15860
15861            if (options.delay) {
15862                element.delay(options.delay);
15863            }
15864
15865            if (hasOptions && $.effects && $.effects.effect[effectName]) {
15866                element[method](options);
15867            } else if (effectName !== method && element[effectName]) {
15868                element[effectName](options.duration, options.easing, callback);
15869            } else {
15870                element.queue(function (next) {
15871                    $(this)[method]();
15872                    if (callback) {
15873                        callback.call(element[0]);
15874                    }
15875                    next();
15876                });
15877            }
15878        };
15879    });
vendor: 7,229 bytes, lines 15880-16070
15880
15881    var widget = $.widget;
15882
15883
15884    /*!
15885* jQuery UI Position 1.12.1
15886* http://jqueryui.com
15887*
15888* Copyright jQuery Foundation and other contributors
15889* Released under the MIT license.
15890* http://jquery.org/license
15891*
15892* http://api.jqueryui.com/position/
15893*/
15894
15895//>>label: Position
15896//>>group: Core
15897//>>description: Positions elements relative to other elements.
15898//>>docs: http://api.jqueryui.com/position/
15899//>>demos: http://jqueryui.com/position/
15900
15901
15902    (function () {
15903        var cachedScrollbarWidth,
15904            max = Math.max,
15905            abs = Math.abs,
15906            rhorizontal = /left|center|right/,
15907            rvertical = /top|center|bottom/,
15908            roffset = /[\+\-]\d+(\.[\d]+)?%?/,
15909            rposition = /^\w+/,
15910            rpercent = /%$/,
15911            _position = $.fn.position;
15912
15913        function getOffsets(offsets, width, height) {
15914            return [
15915                parseFloat(offsets[0]) * (rpercent.test(offsets[0]) ? width / 100 : 1),
15916                parseFloat(offsets[1]) * (rpercent.test(offsets[1]) ? height / 100 : 1)
15917            ];
15918        }
15919
15920        function parseCss(element, property) {
15921            return parseInt($.css(element, property), 10) || 0;
15922        }
15923
15924        function getDimensions(elem) {
15925            var raw = elem[0];
15926            if (raw.nodeType === 9) {
15927                return {
15928                    width: elem.width(),
15929                    height: elem.height(),
15930                    offset: {top: 0, left: 0}
15931                };
15932            }
15933            if ($.isWindow(raw)) {
15934                return {
15935                    width: elem.width(),
15936                    height: elem.height(),
15937                    offset: {top: elem.scrollTop(), left: elem.scrollLeft()}
15938                };
15939            }
15940            if (raw.preventDefault) {
15941                return {
15942                    width: 0,
15943                    height: 0,
15944                    offset: {top: raw.pageY, left: raw.pageX}
15945                };
15946            }
15947            return {
15948                width: elem.outerWidth(),
15949                height: elem.outerHeight(),
15950                offset: elem.offset()
15951            };
15952        }
15953
15954        $.position = {
15955            scrollbarWidth: function () {
15956                if (cachedScrollbarWidth !== undefined) {
15957                    return cachedScrollbarWidth;
15958                }
15959                var w1, w2,
15960                    div = $("<div " +
15961                        "style='display:block;position:absolute;width:50px;height:50px;overflow:hidden;'>" +
15962                        "<div style='height:100px;width:auto;'></div></div>"),
15963                    innerDiv = div.children()[0];
15964
15965                $("body").append(div);
15966                w1 = innerDiv.offsetWidth;
15967                div.css("overflow", "scroll");
15968
15969                w2 = innerDiv.offsetWidth;
15970
15971                if (w1 === w2) {
15972                    w2 = div[0].clientWidth;
15973                }
15974
15975                div.remove();
15976
15977                return (cachedScrollbarWidth = w1 - w2);
15978            },
15979            getScrollInfo: function (within) {
15980                var overflowX = within.isWindow || within.isDocument ? "" :
15981                        within.element.css("overflow-x"),
15982                    overflowY = within.isWindow || within.isDocument ? "" :
15983                        within.element.css("overflow-y"),
15984                    hasOverflowX = overflowX === "scroll" ||
15985                        (overflowX === "auto" && within.width < within.element[0].scrollWidth),
15986                    hasOverflowY = overflowY === "scroll" ||
15987                        (overflowY === "auto" && within.height < within.element[0].scrollHeight);
15988                return {
15989                    width: hasOverflowY ? $.position.scrollbarWidth() : 0,
15990                    height: hasOverflowX ? $.position.scrollbarWidth() : 0
15991                };
15992            },
15993            getWithinInfo: function (element) {
15994                var withinElement = $(element || window),
15995                    isWindow = $.isWindow(withinElement[0]),
15996                    isDocument = !!withinElement[0] && withinElement[0].nodeType === 9,
15997                    hasOffset = !isWindow && !isDocument;
15998                return {
15999                    element: withinElement,
16000                    isWindow: isWindow,
16001                    isDocument: isDocument,
16002                    offset: hasOffset ? $(element).offset() : {left: 0, top: 0},
16003                    scrollLeft: withinElement.scrollLeft(),
16004                    scrollTop: withinElement.scrollTop(),
16005                    width: withinElement.outerWidth(),
16006                    height: withinElement.outerHeight()
16007                };
16008            }
16009        };
16010
16011        $.fn.position = function (options) {
16012            if (!options || !options.of) {
16013                return _position.apply(this, arguments);
16014            }
16015
16016// Make a copy, we don't want to modify arguments
16017            options = $.extend({}, options);
16018
16019            var atOffset, targetWidth, targetHeight, targetOffset, basePosition, dimensions,
16020                target = $(options.of),
16021                within = $.position.getWithinInfo(options.within),
16022                scrollInfo = $.position.getScrollInfo(within),
16023                collision = (options.collision || "flip").split(" "),
16024                offsets = {};
16025
16026            dimensions = getDimensions(target);
16027            if (target[0].preventDefault) {
16028
16029                // Force left top to allow flipping
16030                options.at = "left top";
16031            }
16032            targetWidth = dimensions.width;
16033            targetHeight = dimensions.height;
16034            targetOffset = dimensions.offset;
16035
16036// Clone to reuse original targetOffset later
16037            basePosition = $.extend({}, targetOffset);
16038
16039// Force my and at to have valid horizontal and vertical positions
16040// if a value is missing or invalid, it will be converted to center
16041            $.each(["my", "at"], function () {
16042                var pos = (options[this] || "").split(" "),
16043                    horizontalOffset,
16044                    verticalOffset;
16045
16046                if (pos.length === 1) {
16047                    pos = rhorizontal.test(pos[0]) ?
16048                        pos.concat(["center"]) :
16049                        rvertical.test(pos[0]) ?
16050                            ["center"].concat(pos) :
16051                            ["center", "center"];
16052                }
16053                pos[0] = rhorizontal.test(pos[0]) ? pos[0] : "center";
16054                pos[1] = rvertical.test(pos[1]) ? pos[1] : "center";
16055
16056                // Calculate offsets
16057                horizontalOffset = roffset.exec(pos[0]);
16058                verticalOffset = roffset.exec(pos[1]);
16059                offsets[this] = [
16060                    horizontalOffset ? horizontalOffset[0] : 0,
16061                    verticalOffset ? verticalOffset[0] : 0
16062                ];
16063
16064                // Reduce to just the positions without the offsets
16065                options[this] = [
16066                    rposition.exec(pos[0])[0],
16067                    rposition.exec(pos[1])[0]
16068                ];
16069            });
16070
vendor: 14,711 bytes, lines 16071-16372
16071// Normalize collision option
16072            if (collision.length === 1) {
16073                collision[1] = collision[0];
16074            }
16075
16076            if (options.at[0] === "right") {
16077                basePosition.left += targetWidth;
16078            } else if (options.at[0] === "center") {
16079                basePosition.left += targetWidth / 2;
16080            }
16081
16082            if (options.at[1] === "bottom") {
16083                basePosition.top += targetHeight;
16084            } else if (options.at[1] === "center") {
16085                basePosition.top += targetHeight / 2;
16086            }
16087
16088            atOffset = getOffsets(offsets.at, targetWidth, targetHeight);
16089            basePosition.left += atOffset[0];
16090            basePosition.top += atOffset[1];
16091
16092            return this.each(function () {
16093                var collisionPosition, using,
16094                    elem = $(this),
16095                    elemWidth = elem.outerWidth(),
16096                    elemHeight = elem.outerHeight(),
16097                    marginLeft = parseCss(this, "marginLeft"),
16098                    marginTop = parseCss(this, "marginTop"),
16099                    collisionWidth = elemWidth + marginLeft + parseCss(this, "marginRight") +
16100                        scrollInfo.width,
16101                    collisionHeight = elemHeight + marginTop + parseCss(this, "marginBottom") +
16102                        scrollInfo.height,
16103                    position = $.extend({}, basePosition),
16104                    myOffset = getOffsets(offsets.my, elem.outerWidth(), elem.outerHeight());
16105
16106                if (options.my[0] === "right") {
16107                    position.left -= elemWidth;
16108                } else if (options.my[0] === "center") {
16109                    position.left -= elemWidth / 2;
16110                }
16111
16112                if (options.my[1] === "bottom") {
16113                    position.top -= elemHeight;
16114                } else if (options.my[1] === "center") {
16115                    position.top -= elemHeight / 2;
16116                }
16117
16118                position.left += myOffset[0];
16119                position.top += myOffset[1];
16120
16121                collisionPosition = {
16122                    marginLeft: marginLeft,
16123                    marginTop: marginTop
16124                };
16125
16126                $.each(["left", "top"], function (i, dir) {
16127                    if ($.ui.position[collision[i]]) {
16128                        $.ui.position[collision[i]][dir](position, {
16129                            targetWidth: targetWidth,
16130                            targetHeight: targetHeight,
16131                            elemWidth: elemWidth,
16132                            elemHeight: elemHeight,
16133                            collisionPosition: collisionPosition,
16134                            collisionWidth: collisionWidth,
16135                            collisionHeight: collisionHeight,
16136                            offset: [atOffset[0] + myOffset[0], atOffset [1] + myOffset[1]],
16137                            my: options.my,
16138                            at: options.at,
16139                            within: within,
16140                            elem: elem
16141                        });
16142                    }
16143                });
16144
16145                if (options.using) {
16146
16147                    // Adds feedback as second argument to using callback, if present
16148                    using = function (props) {
16149                        var left = targetOffset.left - position.left,
16150                            right = left + targetWidth - elemWidth,
16151                            top = targetOffset.top - position.top,
16152                            bottom = top + targetHeight - elemHeight,
16153                            feedback = {
16154                                target: {
16155                                    element: target,
16156                                    left: targetOffset.left,
16157                                    top: targetOffset.top,
16158                                    width: targetWidth,
16159                                    height: targetHeight
16160                                },
16161                                element: {
16162                                    element: elem,
16163                                    left: position.left,
16164                                    top: position.top,
16165                                    width: elemWidth,
16166                                    height: elemHeight
16167                                },
16168                                horizontal: right < 0 ? "left" : left > 0 ? "right" : "center",
16169                                vertical: bottom < 0 ? "top" : top > 0 ? "bottom" : "middle"
16170                            };
16171                        if (targetWidth < elemWidth && abs(left + right) < targetWidth) {
16172                            feedback.horizontal = "center";
16173                        }
16174                        if (targetHeight < elemHeight && abs(top + bottom) < targetHeight) {
16175                            feedback.vertical = "middle";
16176                        }
16177                        if (max(abs(left), abs(right)) > max(abs(top), abs(bottom))) {
16178                            feedback.important = "horizontal";
16179                        } else {
16180                            feedback.important = "vertical";
16181                        }
16182                        options.using.call(this, props, feedback);
16183                    };
16184                }
16185
16186                elem.offset($.extend(position, {using: using}));
16187            });
16188        };
16189
16190        $.ui.position = {
16191            fit: {
16192                left: function (position, data) {
16193                    var within = data.within,
16194                        withinOffset = within.isWindow ? within.scrollLeft : within.offset.left,
16195                        outerWidth = within.width,
16196                        collisionPosLeft = position.left - data.collisionPosition.marginLeft,
16197                        overLeft = withinOffset - collisionPosLeft,
16198                        overRight = collisionPosLeft + data.collisionWidth - outerWidth - withinOffset,
16199                        newOverRight;
16200
16201                    // Element is wider than within
16202                    if (data.collisionWidth > outerWidth) {
16203
16204                        // Element is initially over the left side of within
16205                        if (overLeft > 0 && overRight <= 0) {
16206                            newOverRight = position.left + overLeft + data.collisionWidth - outerWidth -
16207                                withinOffset;
16208                            position.left += overLeft - newOverRight;
16209
16210                            // Element is initially over right side of within
16211                        } else if (overRight > 0 && overLeft <= 0) {
16212                            position.left = withinOffset;
16213
16214                            // Element is initially over both left and right sides of within
16215                        } else {
16216                            if (overLeft > overRight) {
16217                                position.left = withinOffset + outerWidth - data.collisionWidth;
16218                            } else {
16219                                position.left = withinOffset;
16220                            }
16221                        }
16222
16223                        // Too far left -> align with left edge
16224                    } else if (overLeft > 0) {
16225                        position.left += overLeft;
16226
16227                        // Too far right -> align with right edge
16228                    } else if (overRight > 0) {
16229                        position.left -= overRight;
16230
16231                        // Adjust based on position and margin
16232                    } else {
16233                        position.left = max(position.left - collisionPosLeft, position.left);
16234                    }
16235                },
16236                top: function (position, data) {
16237                    var within = data.within,
16238                        withinOffset = within.isWindow ? within.scrollTop : within.offset.top,
16239                        outerHeight = data.within.height,
16240                        collisionPosTop = position.top - data.collisionPosition.marginTop,
16241                        overTop = withinOffset - collisionPosTop,
16242                        overBottom = collisionPosTop + data.collisionHeight - outerHeight - withinOffset,
16243                        newOverBottom;
16244
16245                    // Element is taller than within
16246                    if (data.collisionHeight > outerHeight) {
16247
16248                        // Element is initially over the top of within
16249                        if (overTop > 0 && overBottom <= 0) {
16250                            newOverBottom = position.top + overTop + data.collisionHeight - outerHeight -
16251                                withinOffset;
16252                            position.top += overTop - newOverBottom;
16253
16254                            // Element is initially over bottom of within
16255                        } else if (overBottom > 0 && overTop <= 0) {
16256                            position.top = withinOffset;
16257
16258                            // Element is initially over both top and bottom of within
16259                        } else {
16260                            if (overTop > overBottom) {
16261                                position.top = withinOffset + outerHeight - data.collisionHeight;
16262                            } else {
16263                                position.top = withinOffset;
16264                            }
16265                        }
16266
16267                        // Too far up -> align with top
16268                    } else if (overTop > 0) {
16269                        position.top += overTop;
16270
16271                        // Too far down -> align with bottom edge
16272                    } else if (overBottom > 0) {
16273                        position.top -= overBottom;
16274
16275                        // Adjust based on position and margin
16276                    } else {
16277                        position.top = max(position.top - collisionPosTop, position.top);
16278                    }
16279                }
16280            },
16281            flip: {
16282                left: function (position, data) {
16283                    var within = data.within,
16284                        withinOffset = within.offset.left + within.scrollLeft,
16285                        outerWidth = within.width,
16286                        offsetLeft = within.isWindow ? within.scrollLeft : within.offset.left,
16287                        collisionPosLeft = position.left - data.collisionPosition.marginLeft,
16288                        overLeft = collisionPosLeft - offsetLeft,
16289                        overRight = collisionPosLeft + data.collisionWidth - outerWidth - offsetLeft,
16290                        myOffset = data.my[0] === "left" ?
16291                            -data.elemWidth :
16292                            data.my[0] === "right" ?
16293                                data.elemWidth :
16294                                0,
16295                        atOffset = data.at[0] === "left" ?
16296                            data.targetWidth :
16297                            data.at[0] === "right" ?
16298                                -data.targetWidth :
16299                                0,
16300                        offset = -2 * data.offset[0],
16301                        newOverRight,
16302                        newOverLeft;
16303
16304                    if (overLeft < 0) {
16305                        newOverRight = position.left + myOffset + atOffset + offset + data.collisionWidth -
16306                            outerWidth - withinOffset;
16307                        if (newOverRight < 0 || newOverRight < abs(overLeft)) {
16308                            position.left += myOffset + atOffset + offset;
16309                        }
16310                    } else if (overRight > 0) {
16311                        newOverLeft = position.left - data.collisionPosition.marginLeft + myOffset +
16312                            atOffset + offset - offsetLeft;
16313                        if (newOverLeft > 0 || abs(newOverLeft) < overRight) {
16314                            position.left += myOffset + atOffset + offset;
16315                        }
16316                    }
16317                },
16318                top: function (position, data) {
16319                    var within = data.within,
16320                        withinOffset = within.offset.top + within.scrollTop,
16321                        outerHeight = within.height,
16322                        offsetTop = within.isWindow ? within.scrollTop : within.offset.top,
16323                        collisionPosTop = position.top - data.collisionPosition.marginTop,
16324                        overTop = collisionPosTop - offsetTop,
16325                        overBottom = collisionPosTop + data.collisionHeight - outerHeight - offsetTop,
16326                        top = data.my[1] === "top",
16327                        myOffset = top ?
16328                            -data.elemHeight :
16329                            data.my[1] === "bottom" ?
16330                                data.elemHeight :
16331                                0,
16332                        atOffset = data.at[1] === "top" ?
16333                            data.targetHeight :
16334                            data.at[1] === "bottom" ?
16335                                -data.targetHeight :
16336                                0,
16337                        offset = -2 * data.offset[1],
16338                        newOverTop,
16339                        newOverBottom;
16340                    if (overTop < 0) {
16341                        newOverBottom = position.top + myOffset + atOffset + offset + data.collisionHeight -
16342                            outerHeight - withinOffset;
16343                        if (newOverBottom < 0 || newOverBottom < abs(overTop)) {
16344                            position.top += myOffset + atOffset + offset;
16345                        }
16346                    } else if (overBottom > 0) {
16347                        newOverTop = position.top - data.collisionPosition.marginTop + myOffset + atOffset +
16348                            offset - offsetTop;
16349                        if (newOverTop > 0 || abs(newOverTop) < overBottom) {
16350                            position.top += myOffset + atOffset + offset;
16351                        }
16352                    }
16353                }
16354            },
16355            flipfit: {
16356                left: function () {
16357                    $.ui.position.flip.left.apply(this, arguments);
16358                    $.ui.position.fit.left.apply(this, arguments);
16359                },
16360                top: function () {
16361                    $.ui.position.flip.top.apply(this, arguments);
16362                    $.ui.position.fit.top.apply(this, arguments);
16363                }
16364            }
16365        };
16366
16367    })();
16368
16369    var position = $.ui.position;
16370
16371
16372    /*!
vendor: 7,979 bytes, lines 16373-16613
16373* jQuery UI Keycode 1.12.1
16374* http://jqueryui.com
16375*
16376* Copyright jQuery Foundation and other contributors
16377* Released under the MIT license.
16378* http://jquery.org/license
16379*/
16380
16381//>>label: Keycode
16382//>>group: Core
16383//>>description: Provide keycodes as keynames
16384//>>docs: http://api.jqueryui.com/jQuery.ui.keyCode/
16385
16386
16387    var keycode = $.ui.keyCode = {
16388        BACKSPACE: 8,
16389        COMMA: 188,
16390        DELETE: 46,
16391        DOWN: 40,
16392        END: 35,
16393        ENTER: 13,
16394        ESCAPE: 27,
16395        HOME: 36,
16396        LEFT: 37,
16397        PAGE_DOWN: 34,
16398        PAGE_UP: 33,
16399        PERIOD: 190,
16400        RIGHT: 39,
16401        SPACE: 32,
16402        TAB: 9,
16403        UP: 38
16404    };
16405
16406
16407    /*!
16408* jQuery UI Unique ID 1.12.1
16409* http://jqueryui.com
16410*
16411* Copyright jQuery Foundation and other contributors
16412* Released under the MIT license.
16413* http://jquery.org/license
16414*/
16415
16416//>>label: uniqueId
16417//>>group: Core
16418//>>description: Functions to generate and remove uniqueId's
16419//>>docs: http://api.jqueryui.com/uniqueId/
16420
16421
16422    var uniqueId = $.fn.extend({
16423        uniqueId: (function () {
16424            var uuid = 0;
16425
16426            return function () {
16427                return this.each(function () {
16428                    if (!this.id) {
16429                        this.id = "ui-id-" + (++uuid);
16430                    }
16431                });
16432            };
16433        })(),
16434
16435        removeUniqueId: function () {
16436            return this.each(function () {
16437                if (/^ui-id-\d+$/.test(this.id)) {
16438                    $(this).removeAttr("id");
16439                }
16440            });
16441        }
16442    });
16443
16444
16445    var safeActiveElement = $.ui.safeActiveElement = function (document) {
16446        var activeElement;
16447
16448// Support: IE 9 only
16449// IE9 throws an "Unspecified error" accessing document.activeElement from an <iframe>
16450        try {
16451            activeElement = document.activeElement;
16452        } catch (error) {
16453            activeElement = document.body;
16454        }
16455
16456// Support: IE 9 - 11 only
16457// IE may return null instead of an element
16458// Interestingly, this only seems to occur when NOT in an iframe
16459        if (!activeElement) {
16460            activeElement = document.body;
16461        }
16462
16463// Support: IE 11 only
16464// IE11 returns a seemingly empty object in some cases when accessing
16465// document.activeElement from an <iframe>
16466        if (!activeElement.nodeName) {
16467            activeElement = document.body;
16468        }
16469
16470        return activeElement;
16471    };
16472
16473
16474    /*!
16475* jQuery UI Menu 1.12.1
16476* http://jqueryui.com
16477*
16478* Copyright jQuery Foundation and other contributors
16479* Released under the MIT license.
16480* http://jquery.org/license
16481*/
16482
16483//>>label: Menu
16484//>>group: Widgets
16485//>>description: Creates nestable menus.
16486//>>docs: http://api.jqueryui.com/menu/
16487//>>demos: http://jqueryui.com/menu/
16488//>>css.structure: ../../themes/base/core.css
16489//>>css.structure: ../../themes/base/menu.css
16490//>>css.theme: ../../themes/base/theme.css
16491
16492
16493    var widgetsMenu = $.widget("ui.menu", {
16494        version: "1.12.1",
16495        defaultElement: "<ul>",
16496        delay: 300,
16497        options: {
16498            icons: {
16499                submenu: "ui-icon-caret-1-e"
16500            },
16501            items: "> *",
16502            menus: "ul",
16503            position: {
16504                my: "left top",
16505                at: "right top"
16506            },
16507            role: "menu",
16508
16509            // Callbacks
16510            blur: null,
16511            focus: null,
16512            select: null
16513        },
16514
16515        _create: function () {
16516            this.activeMenu = this.element;
16517
16518            // Flag used to prevent firing of the click handler
16519            // as the event bubbles up through nested menus
16520            this.mouseHandled = false;
16521            this.element
16522                .uniqueId()
16523                .attr({
16524                    role: this.options.role,
16525                    tabIndex: 0
16526                });
16527
16528            this._addClass("ui-menu", "ui-widget ui-widget-content");
16529            this._on({
16530
16531                // Prevent focus from sticking to links inside menu after clicking
16532                // them (focus should always stay on UL during navigation).
16533                "mousedown .ui-menu-item": function (event) {
16534                    event.preventDefault();
16535                },
16536                "click .ui-menu-item": function (event) {
16537                    var target = $(event.target);
16538                    var active = $($.ui.safeActiveElement(this.document[0]));
16539                    if (!this.mouseHandled && target.not(".ui-state-disabled").length) {
16540                        this.select(event);
16541
16542                        // Only set the mouseHandled flag if the event will bubble, see #9469.
16543                        if (!event.isPropagationStopped()) {
16544                            this.mouseHandled = true;
16545                        }
16546
16547                        // Open submenu on click
16548                        if (target.has(".ui-menu").length) {
16549                            this.expand(event);
16550                        } else if (!this.element.is(":focus") &&
16551                            active.closest(".ui-menu").length) {
16552
16553                            // Redirect focus to the menu
16554                            this.element.trigger("focus", [true]);
16555
16556                            // If the active item is on the top level, let it stay active.
16557                            // Otherwise, blur the active item since it is no longer visible.
16558                            if (this.active && this.active.parents(".ui-menu").length === 1) {
16559                                clearTimeout(this.timer);
16560                            }
16561                        }
16562                    }
16563                },
16564                "mouseenter .ui-menu-item": function (event) {
16565
16566                    // Ignore mouse events while typeahead is active, see #10458.
16567                    // Prevents focusing the wrong item when typeahead causes a scroll while the mouse
16568                    // is over an item in the menu
16569                    if (this.previousFilter) {
16570                        return;
16571                    }
16572
16573                    var actualTarget = $(event.target).closest(".ui-menu-item"),
16574                        target = $(event.currentTarget);
16575
16576                    // Ignore bubbled events on parent items, see #11641
16577                    if (actualTarget[0] !== target[0]) {
16578                        return;
16579                    }
16580
16581                    // Remove ui-state-active class from siblings of the newly focused menu item
16582                    // to avoid a jump caused by adjacent elements both having a class with a border
16583                    this._removeClass(target.siblings().children(".ui-state-active"),
16584                        null, "ui-state-active");
16585                    this.focus(event, target);
16586                },
16587                mouseleave: "collapseAll",
16588                "mouseleave .ui-menu": "collapseAll",
16589                focus: function (event, keepActiveItem) {
16590
16591                    // If there's already an active item, keep it active
16592                    // If not, activate the first item
16593                    var item = this.active || this.element.find(this.options.items).eq(0);
16594
16595                    if (!keepActiveItem) {
16596                        this.focus(event, item);
16597                    }
16598                },
16599                blur: function (event) {
16600                    this._delay(function () {
16601                        var notContained = !$.contains(
16602                            this.element[0],
16603                            $.ui.safeActiveElement(this.document[0])
16604                        );
16605                        if (notContained) {
16606                            this.collapseAll(event);
16607                        }
16608                    });
16609                },
16610                keydown: "_keydown"
16611            });
16612
16613            this.refresh();
vendor: 6,354 bytes, lines 16614-16777
16614
16615            // Clicks outside of a menu collapse any open menus
16616            this._on(this.document, {
16617                click: function (event) {
16618                    if (this._closeOnDocumentClick(event)) {
16619                        this.collapseAll(event);
16620                    }
16621
16622                    // Reset the mouseHandled flag
16623                    this.mouseHandled = false;
16624                }
16625            });
16626        },
16627
16628        _destroy: function () {
16629            var items = this.element.find(".ui-menu-item")
16630                    .removeAttr("role aria-disabled"),
16631                submenus = items.children(".ui-menu-item-wrapper")
16632                    .removeUniqueId()
16633                    .removeAttr("tabIndex role aria-haspopup");
16634
16635            // Destroy (sub)menus
16636            this.element
16637                .removeAttr("aria-activedescendant")
16638                .find(".ui-menu").addBack()
16639                .removeAttr("role aria-labelledby aria-expanded aria-hidden aria-disabled " +
16640                    "tabIndex")
16641                .removeUniqueId()
16642                .show();
16643
16644            submenus.children().each(function () {
16645                var elem = $(this);
16646                if (elem.data("ui-menu-submenu-caret")) {
16647                    elem.remove();
16648                }
16649            });
16650        },
16651
16652        _keydown: function (event) {
16653            var match, prev, character, skip,
16654                preventDefault = true;
16655
16656            switch (event.keyCode) {
16657                case $.ui.keyCode.PAGE_UP:
16658                    this.previousPage(event);
16659                    break;
16660                case $.ui.keyCode.PAGE_DOWN:
16661                    this.nextPage(event);
16662                    break;
16663                case $.ui.keyCode.HOME:
16664                    this._move("first", "first", event);
16665                    break;
16666                case $.ui.keyCode.END:
16667                    this._move("last", "last", event);
16668                    break;
16669                case $.ui.keyCode.UP:
16670                    this.previous(event);
16671                    break;
16672                case $.ui.keyCode.DOWN:
16673                    this.next(event);
16674                    break;
16675                case $.ui.keyCode.LEFT:
16676                    this.collapse(event);
16677                    break;
16678                case $.ui.keyCode.RIGHT:
16679                    if (this.active && !this.active.is(".ui-state-disabled")) {
16680                        this.expand(event);
16681                    }
16682                    break;
16683                case $.ui.keyCode.ENTER:
16684                case $.ui.keyCode.SPACE:
16685                    this._activate(event);
16686                    break;
16687                case $.ui.keyCode.ESCAPE:
16688                    this.collapse(event);
16689                    break;
16690                default:
16691                    preventDefault = false;
16692                    prev = this.previousFilter || "";
16693                    skip = false;
16694
16695                    // Support number pad values
16696                    character = event.keyCode >= 96 && event.keyCode <= 105 ?
16697                        (event.keyCode - 96).toString() : String.fromCharCode(event.keyCode);
16698
16699                    clearTimeout(this.filterTimer);
16700
16701                    if (character === prev) {
16702                        skip = true;
16703                    } else {
16704                        character = prev + character;
16705                    }
16706
16707                    match = this._filterMenuItems(character);
16708                    match = skip && match.index(this.active.next()) !== -1 ?
16709                        this.active.nextAll(".ui-menu-item") :
16710                        match;
16711
16712                    // If no matches on the current filter, reset to the last character pressed
16713                    // to move down the menu to the first item that starts with that character
16714                    if (!match.length) {
16715                        character = String.fromCharCode(event.keyCode);
16716                        match = this._filterMenuItems(character);
16717                    }
16718
16719                    if (match.length) {
16720                        this.focus(event, match);
16721                        this.previousFilter = character;
16722                        this.filterTimer = this._delay(function () {
16723                            delete this.previousFilter;
16724                        }, 1000);
16725                    } else {
16726                        delete this.previousFilter;
16727                    }
16728            }
16729
16730            if (preventDefault) {
16731                event.preventDefault();
16732            }
16733        },
16734
16735        _activate: function (event) {
16736            if (this.active && !this.active.is(".ui-state-disabled")) {
16737                if (this.active.children("[aria-haspopup='true']").length) {
16738                    this.expand(event);
16739                } else {
16740                    this.select(event);
16741                }
16742            }
16743        },
16744
16745        refresh: function () {
16746            var menus, items, newSubmenus, newItems, newWrappers,
16747                that = this,
16748                icon = this.options.icons.submenu,
16749                submenus = this.element.find(this.options.menus);
16750
16751            this._toggleClass("ui-menu-icons", null, !!this.element.find(".ui-icon").length);
16752
16753            // Initialize nested menus
16754            newSubmenus = submenus.filter(":not(.ui-menu)")
16755                .hide()
16756                .attr({
16757                    role: this.options.role,
16758                    "aria-hidden": "true",
16759                    "aria-expanded": "false"
16760                })
16761                .each(function () {
16762                    var menu = $(this),
16763                        item = menu.prev(),
16764                        submenuCaret = $("<span>").data("ui-menu-submenu-caret", true);
16765
16766                    that._addClass(submenuCaret, "ui-menu-icon", "ui-icon " + icon);
16767                    item
16768                        .attr("aria-haspopup", "true")
16769                        .prepend(submenuCaret);
16770                    menu.attr("aria-labelledby", item.attr("id"));
16771                });
16772
16773            this._addClass(newSubmenus, "ui-menu", "ui-widget ui-widget-content ui-front");
16774
16775            menus = submenus.add(this.element);
16776            items = menus.find(this.options.items);
16777
vendor: 6,066 bytes, lines 16778-16941
16778            // Initialize menu-items containing spaces and/or dashes only as dividers
16779            items.not(".ui-menu-item").each(function () {
16780                var item = $(this);
16781                if (that._isDivider(item)) {
16782                    that._addClass(item, "ui-menu-divider", "ui-widget-content");
16783                }
16784            });
16785
16786            // Don't refresh list items that are already adapted
16787            newItems = items.not(".ui-menu-item, .ui-menu-divider");
16788            newWrappers = newItems.children()
16789                .not(".ui-menu")
16790                .uniqueId()
16791                .attr({
16792                    tabIndex: -1,
16793                    role: this._itemRole()
16794                });
16795            this._addClass(newItems, "ui-menu-item")
16796                ._addClass(newWrappers, "ui-menu-item-wrapper");
16797
16798            // Add aria-disabled attribute to any disabled menu item
16799            items.filter(".ui-state-disabled").attr("aria-disabled", "true");
16800
16801            // If the active item has been removed, blur the menu
16802            if (this.active && !$.contains(this.element[0], this.active[0])) {
16803                this.blur();
16804            }
16805        },
16806
16807        _itemRole: function () {
16808            return {
16809                menu: "menuitem",
16810                listbox: "option"
16811            }[this.options.role];
16812        },
16813
16814        _setOption: function (key, value) {
16815            if (key === "icons") {
16816                var icons = this.element.find(".ui-menu-icon");
16817                this._removeClass(icons, null, this.options.icons.submenu)
16818                    ._addClass(icons, null, value.submenu);
16819            }
16820            this._super(key, value);
16821        },
16822
16823        _setOptionDisabled: function (value) {
16824            this._super(value);
16825
16826            this.element.attr("aria-disabled", String(value));
16827            this._toggleClass(null, "ui-state-disabled", !!value);
16828        },
16829
16830        focus: function (event, item) {
16831            var nested, focused, activeParent;
16832            this.blur(event, event && event.type === "focus");
16833
16834            this._scrollIntoView(item);
16835
16836            this.active = item.first();
16837
16838            focused = this.active.children(".ui-menu-item-wrapper");
16839            this._addClass(focused, null, "ui-state-active");
16840
16841            // Only update aria-activedescendant if there's a role
16842            // otherwise we assume focus is managed elsewhere
16843            if (this.options.role) {
16844                this.element.attr("aria-activedescendant", focused.attr("id"));
16845            }
16846
16847            // Highlight active parent menu item, if any
16848            activeParent = this.active
16849                .parent()
16850                .closest(".ui-menu-item")
16851                .children(".ui-menu-item-wrapper");
16852            this._addClass(activeParent, null, "ui-state-active");
16853
16854            if (event && event.type === "keydown") {
16855                this._close();
16856            } else {
16857                this.timer = this._delay(function () {
16858                    this._close();
16859                }, this.delay);
16860            }
16861
16862            nested = item.children(".ui-menu");
16863            if (nested.length && event && (/^mouse/.test(event.type))) {
16864                this._startOpening(nested);
16865            }
16866            this.activeMenu = item.parent();
16867
16868            this._trigger("focus", event, {item: item});
16869        },
16870
16871        _scrollIntoView: function (item) {
16872            var borderTop, paddingTop, offset, scroll, elementHeight, itemHeight;
16873            if (this._hasScroll()) {
16874                borderTop = parseFloat($.css(this.activeMenu[0], "borderTopWidth")) || 0;
16875                paddingTop = parseFloat($.css(this.activeMenu[0], "paddingTop")) || 0;
16876                offset = item.offset().top - this.activeMenu.offset().top - borderTop - paddingTop;
16877                scroll = this.activeMenu.scrollTop();
16878                elementHeight = this.activeMenu.height();
16879                itemHeight = item.outerHeight();
16880
16881                if (offset < 0) {
16882                    this.activeMenu.scrollTop(scroll + offset);
16883                } else if (offset + itemHeight > elementHeight) {
16884                    this.activeMenu.scrollTop(scroll + offset - elementHeight + itemHeight);
16885                }
16886            }
16887        },
16888
16889        blur: function (event, fromFocus) {
16890            if (!fromFocus) {
16891                clearTimeout(this.timer);
16892            }
16893
16894            if (!this.active) {
16895                return;
16896            }
16897
16898            this._removeClass(this.active.children(".ui-menu-item-wrapper"),
16899                null, "ui-state-active");
16900
16901            this._trigger("blur", event, {item: this.active});
16902            this.active = null;
16903        },
16904
16905        _startOpening: function (submenu) {
16906            clearTimeout(this.timer);
16907
16908            // Don't open if already open fixes a Firefox bug that caused a .5 pixel
16909            // shift in the submenu position when mousing over the caret icon
16910            if (submenu.attr("aria-hidden") !== "true") {
16911                return;
16912            }
16913
16914            this.timer = this._delay(function () {
16915                this._close();
16916                this._open(submenu);
16917            }, this.delay);
16918        },
16919
16920        _open: function (submenu) {
16921            var position = $.extend({
16922                of: this.active
16923            }, this.options.position);
16924
16925            clearTimeout(this.timer);
16926            this.element.find(".ui-menu").not(submenu.parents(".ui-menu"))
16927                .hide()
16928                .attr("aria-hidden", "true");
16929
16930            submenu
16931                .show()
16932                .removeAttr("aria-hidden")
16933                .attr("aria-expanded", "true")
16934                .position(position);
16935        },
16936
16937        collapseAll: function (event, all) {
16938            clearTimeout(this.timer);
16939            this.timer = this._delay(function () {
16940
16941                // If we were passed an event, look for the submenu that c
vendor: 18,847 bytes, lines 16941-17414
16941ontains the event
16942                var currentMenu = all ? this.element :
16943                    $(event && event.target).closest(this.element.find(".ui-menu"));
16944
16945                // If we found no valid submenu ancestor, use the main menu to close all
16946                // sub menus anyway
16947                if (!currentMenu.length) {
16948                    currentMenu = this.element;
16949                }
16950
16951                this._close(currentMenu);
16952
16953                this.blur(event);
16954
16955                // Work around active item staying active after menu is blurred
16956                this._removeClass(currentMenu.find(".ui-state-active"), null, "ui-state-active");
16957
16958                this.activeMenu = currentMenu;
16959            }, this.delay);
16960        },
16961
16962        // With no arguments, closes the currently active menu - if nothing is active
16963        // it closes all menus.  If passed an argument, it will search for menus BELOW
16964        _close: function (startMenu) {
16965            if (!startMenu) {
16966                startMenu = this.active ? this.active.parent() : this.element;
16967            }
16968
16969            startMenu.find(".ui-menu")
16970                .hide()
16971                .attr("aria-hidden", "true")
16972                .attr("aria-expanded", "false");
16973        },
16974
16975        _closeOnDocumentClick: function (event) {
16976            return !$(event.target).closest(".ui-menu").length;
16977        },
16978
16979        _isDivider: function (item) {
16980
16981            // Match hyphen, em dash, en dash
16982            return !/[^\-\u2014\u2013\s]/.test(item.text());
16983        },
16984
16985        collapse: function (event) {
16986            var newItem = this.active &&
16987                this.active.parent().closest(".ui-menu-item", this.element);
16988            if (newItem && newItem.length) {
16989                this._close();
16990                this.focus(event, newItem);
16991            }
16992        },
16993
16994        expand: function (event) {
16995            var newItem = this.active &&
16996                this.active
16997                    .children(".ui-menu ")
16998                    .find(this.options.items)
16999                    .first();
17000
17001            if (newItem && newItem.length) {
17002                this._open(newItem.parent());
17003
17004                // Delay so Firefox will not hide activedescendant change in expanding submenu from AT
17005                this._delay(function () {
17006                    this.focus(event, newItem);
17007                });
17008            }
17009        },
17010
17011        next: function (event) {
17012            this._move("next", "first", event);
17013        },
17014
17015        previous: function (event) {
17016            this._move("prev", "last", event);
17017        },
17018
17019        isFirstItem: function () {
17020            return this.active && !this.active.prevAll(".ui-menu-item").length;
17021        },
17022
17023        isLastItem: function () {
17024            return this.active && !this.active.nextAll(".ui-menu-item").length;
17025        },
17026
17027        _move: function (direction, filter, event) {
17028            var next;
17029            if (this.active) {
17030                if (direction === "first" || direction === "last") {
17031                    next = this.active
17032                        [direction === "first" ? "prevAll" : "nextAll"](".ui-menu-item")
17033                        .eq(-1);
17034                } else {
17035                    next = this.active
17036                        [direction + "All"](".ui-menu-item")
17037                        .eq(0);
17038                }
17039            }
17040            if (!next || !next.length || !this.active) {
17041                next = this.activeMenu.find(this.options.items)[filter]();
17042            }
17043
17044            this.focus(event, next);
17045        },
17046
17047        nextPage: function (event) {
17048            var item, base, height;
17049
17050            if (!this.active) {
17051                this.next(event);
17052                return;
17053            }
17054            if (this.isLastItem()) {
17055                return;
17056            }
17057            if (this._hasScroll()) {
17058                base = this.active.offset().top;
17059                height = this.element.height();
17060                this.active.nextAll(".ui-menu-item").each(function () {
17061                    item = $(this);
17062                    return item.offset().top - base - height < 0;
17063                });
17064
17065                this.focus(event, item);
17066            } else {
17067                this.focus(event, this.activeMenu.find(this.options.items)
17068                    [!this.active ? "first" : "last"]());
17069            }
17070        },
17071
17072        previousPage: function (event) {
17073            var item, base, height;
17074            if (!this.active) {
17075                this.next(event);
17076                return;
17077            }
17078            if (this.isFirstItem()) {
17079                return;
17080            }
17081            if (this._hasScroll()) {
17082                base = this.active.offset().top;
17083                height = this.element.height();
17084                this.active.prevAll(".ui-menu-item").each(function () {
17085                    item = $(this);
17086                    return item.offset().top - base + height > 0;
17087                });
17088
17089                this.focus(event, item);
17090            } else {
17091                this.focus(event, this.activeMenu.find(this.options.items).first());
17092            }
17093        },
17094
17095        _hasScroll: function () {
17096            return this.element.outerHeight() < this.element.prop("scrollHeight");
17097        },
17098
17099        select: function (event) {
17100
17101            // TODO: It should never be possible to not have an active item at this
17102            // point, but the tests don't trigger mouseenter before click.
17103            this.active = this.active || $(event.target).closest(".ui-menu-item");
17104            var ui = {item: this.active};
17105            if (!this.active.has(".ui-menu").length) {
17106                this.collapseAll(event, true);
17107            }
17108            this._trigger("select", event, ui);
17109        },
17110
17111        _filterMenuItems: function (character) {
17112            var escapedCharacter = character.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&"),
17113                regex = new RegExp("^" + escapedCharacter, "i");
17114
17115            return this.activeMenu
17116                .find(this.options.items)
17117
17118                // Only match on items, not dividers or other content (#10571)
17119                .filter(".ui-menu-item")
17120                .filter(function () {
17121                    return regex.test(
17122                        $.trim($(this).children(".ui-menu-item-wrapper").text()));
17123                });
17124        }
17125    });
17126
17127
17128    /*!
17129* jQuery UI Autocomplete 1.12.1
17130* http://jqueryui.com
17131*
17132* Copyright jQuery Foundation and other contributors
17133* Released under the MIT license.
17134* http://jquery.org/license
17135*/
17136
17137//>>label: Autocomplete
17138//>>group: Widgets
17139//>>description: Lists suggested words as the user is typing.
17140//>>docs: http://api.jqueryui.com/autocomplete/
17141//>>demos: http://jqueryui.com/autocomplete/
17142//>>css.structure: ../../themes/base/core.css
17143//>>css.structure: ../../themes/base/autocomplete.css
17144//>>css.theme: ../../themes/base/theme.css
17145
17146
17147    $.widget("ui.autocomplete", {
17148        version: "1.12.1",
17149        defaultElement: "<input>",
17150        options: {
17151            appendTo: null,
17152            autoFocus: false,
17153            delay: 300,
17154            minLength: 1,
17155            position: {
17156                my: "left top",
17157                at: "left bottom",
17158                collision: "none"
17159            },
17160            source: null,
17161
17162            // Callbacks
17163            change: null,
17164            close: null,
17165            focus: null,
17166            open: null,
17167            response: null,
17168            search: null,
17169            select: null
17170        },
17171
17172        requestIndex: 0,
17173        pending: 0,
17174
17175        _create: function () {
17176
17177            // Some browsers only repeat keydown events, not keypress events,
17178            // so we use the suppressKeyPress flag to determine if we've already
17179            // handled the keydown event. #7269
17180            // Unfortunately the code for & in keypress is the same as the up arrow,
17181            // so we use the suppressKeyPressRepeat flag to avoid handling keypress
17182            // events when we know the keydown event was used to modify the
17183            // search term. #7799
17184            var suppressKeyPress, suppressKeyPressRepeat, suppressInput,
17185                nodeName = this.element[0].nodeName.toLowerCase(),
17186                isTextarea = nodeName === "textarea",
17187                isInput = nodeName === "input";
17188
17189            // Textareas are always multi-line
17190            // Inputs are always single-line, even if inside a contentEditable element
17191            // IE also treats inputs as contentEditable
17192            // All other element types are determined by whether or not they're contentEditable
17193            this.isMultiLine = isTextarea || !isInput && this._isContentEditable(this.element);
17194
17195            this.valueMethod = this.element[isTextarea || isInput ? "val" : "text"];
17196            this.isNewMenu = true;
17197
17198            this._addClass("ui-autocomplete-input");
17199            this.element.attr("autocomplete", "off");
17200
17201            this._on(this.element, {
17202                keydown: function (event) {
17203                    if (this.element.prop("readOnly")) {
17204                        suppressKeyPress = true;
17205                        suppressInput = true;
17206                        suppressKeyPressRepeat = true;
17207                        return;
17208                    }
17209
17210                    suppressKeyPress = false;
17211                    suppressInput = false;
17212                    suppressKeyPressRepeat = false;
17213                    var keyCode = $.ui.keyCode;
17214                    switch (event.keyCode) {
17215                        case keyCode.PAGE_UP:
17216                            suppressKeyPress = true;
17217                            this._move("previousPage", event);
17218                            break;
17219                        case keyCode.PAGE_DOWN:
17220                            suppressKeyPress = true;
17221                            this._move("nextPage", event);
17222                            break;
17223                        case keyCode.UP:
17224                            suppressKeyPress = true;
17225                            this._keyEvent("previous", event);
17226                            break;
17227                        case keyCode.DOWN:
17228                            suppressKeyPress = true;
17229                            this._keyEvent("next", event);
17230                            break;
17231                        case keyCode.ENTER:
17232
17233                            // when menu is open and has focus
17234                            if (this.menu.active) {
17235
17236                                // #6055 - Opera still allows the keypress to occur
17237                                // which causes forms to submit
17238                                suppressKeyPress = true;
17239                                event.preventDefault();
17240                                this.menu.select(event);
17241                            }
17242                            break;
17243                        case keyCode.TAB:
17244                            if (this.menu.active) {
17245                                this.menu.select(event);
17246                            }
17247                            break;
17248                        case keyCode.ESCAPE:
17249                            if (this.menu.element.is(":visible")) {
17250                                if (!this.isMultiLine) {
17251                                    this._value(this.term);
17252                                }
17253                                this.close(event);
17254
17255                                // Different browsers have different default behavior for escape
17256                                // Single press can mean undo or clear
17257                                // Double press in IE means clear the whole form
17258                                event.preventDefault();
17259                            }
17260                            break;
17261                        default:
17262                            suppressKeyPressRepeat = true;
17263
17264                            // search timeout should be triggered before the input value is changed
17265                            this._searchTimeout(event);
17266                            break;
17267                    }
17268                },
17269                keypress: function (event) {
17270                    if (suppressKeyPress) {
17271                        suppressKeyPress = false;
17272                        if (!this.isMultiLine || this.menu.element.is(":visible")) {
17273                            event.preventDefault();
17274                        }
17275                        return;
17276                    }
17277                    if (suppressKeyPressRepeat) {
17278                        return;
17279                    }
17280
17281                    // Replicate some key handlers to allow them to repeat in Firefox and Opera
17282                    var keyCode = $.ui.keyCode;
17283                    switch (event.keyCode) {
17284                        case keyCode.PAGE_UP:
17285                            this._move("previousPage", event);
17286                            break;
17287                        case keyCode.PAGE_DOWN:
17288                            this._move("nextPage", event);
17289                            break;
17290                        case keyCode.UP:
17291                            this._keyEvent("previous", event);
17292                            break;
17293                        case keyCode.DOWN:
17294                            this._keyEvent("next", event);
17295                            break;
17296                    }
17297                },
17298                input: function (event) {
17299                    if (suppressInput) {
17300                        suppressInput = false;
17301                        event.preventDefault();
17302                        return;
17303                    }
17304                    this._searchTimeout(event);
17305                },
17306                focus: function () {
17307                    this.selectedItem = null;
17308                    this.previous = this._value();
17309                },
17310                blur: function (event) {
17311                    if (this.cancelBlur) {
17312                        delete this.cancelBlur;
17313                        return;
17314                    }
17315
17316                    clearTimeout(this.searching);
17317                    this.close(event);
17318                    this._change(event);
17319                }
17320            });
17321
17322            this._initSource();
17323            this.menu = $("<ul>")
17324                .appendTo(this._appendTo())
17325                .menu({
17326
17327                    // disable ARIA support, the live region takes care of that
17328                    role: null
17329                })
17330                .hide()
17331                .menu("instance");
17332
17333            this._addClass(this.menu.element, "ui-autocomplete", "ui-front");
17334            this._on(this.menu.element, {
17335                mousedown: function (event) {
17336
17337                    // prevent moving focus out of the text field
17338                    event.preventDefault();
17339
17340                    // IE doesn't prevent moving focus even with event.preventDefault()
17341                    // so we set a flag to know when we should ignore the blur event
17342                    this.cancelBlur = true;
17343                    this._delay(function () {
17344                        delete this.cancelBlur;
17345
17346                        // Support: IE 8 only
17347                        // Right clicking a menu item or selecting text from the menu items will
17348                        // result in focus moving out of the input. However, we've already received
17349                        // and ignored the blur event because of the cancelBlur flag set above. So
17350                        // we restore focus to ensure that the menu closes properly based on the user's
17351                        // next actions.
17352                        if (this.element[0] !== $.ui.safeActiveElement(this.document[0])) {
17353                            this.element.trigger("focus");
17354                        }
17355                    });
17356                },
17357                menufocus: function (event, ui) {
17358                    var label, item;
17359
17360                    // support: Firefox
17361                    // Prevent accidental activation of menu items in Firefox (#7024 #9118)
17362                    if (this.isNewMenu) {
17363                        this.isNewMenu = false;
17364                        if (event.originalEvent && /^mouse/.test(event.originalEvent.type)) {
17365                            this.menu.blur();
17366
17367                            this.document.one("mousemove", function () {
17368                                $(event.target).trigger(event.originalEvent);
17369                            });
17370
17371                            return;
17372                        }
17373                    }
17374
17375                    item = ui.item.data("ui-autocomplete-item");
17376                    if (false !== this._trigger("focus", event, {item: item})) {
17377
17378                        // use value to match what will end up in the input, if it was a key event
17379                        if (event.originalEvent && /^key/.test(event.originalEvent.type)) {
17380                            this._value(item.value);
17381                        }
17382                    }
17383
17384                    // Announce the value in the liveRegion
17385                    label = ui.item.attr("aria-label") || item.value;
17386                    if (label && $.trim(label).length) {
17387                        this.liveRegion.children().hide();
17388                        $("<div>").text(label).appendTo(this.liveRegion);
17389                    }
17390                },
17391                menuselect: function (event, ui) {
17392                    var item = ui.item.data("ui-autocomplete-item"),
17393                        previous = this.previous;
17394
17395                    // Only trigger when focus was lost (click on menu)
17396                    if (this.element[0] !== $.ui.safeActiveElement(this.document[0])) {
17397                        this.element.trigger("focus");
17398                        this.previous = previous;
17399
17400                        // #6109 - IE triggers two focus events and the second
17401                        // is asynchronous, so we need to reset the previous
17402                        // term synchronously and asynchronously :-(
17403                        this._delay(function () {
17404                            this.previous = previous;
17405                            this.selectedItem = item;
17406                        });
17407                    }
17408
17409                    if (false !== this._trigger("select", event, {item: item})) {
17410                        this._value(item.value);
17411                    }
17412
17413                    // reset the term after the select event
17414                    // this allows custom select handling to work properly
vendor: 4,534 bytes, lines 17415-17542
17415                    this.term = this._value();
17416
17417                    this.close(event);
17418                    this.selectedItem = item;
17419                }
17420            });
17421
17422            this.liveRegion = $("<div>", {
17423                role: "status",
17424                "aria-live": "assertive",
17425                "aria-relevant": "additions"
17426            })
17427                .appendTo(this.document[0].body);
17428
17429            this._addClass(this.liveRegion, null, "ui-helper-hidden-accessible");
17430
17431            // Turning off autocomplete prevents the browser from remembering the
17432            // value when navigating through history, so we re-enable autocomplete
17433            // if the page is unloaded before the widget is destroyed. #7790
17434            this._on(this.window, {
17435                beforeunload: function () {
17436                    this.element.removeAttr("autocomplete");
17437                }
17438            });
17439        },
17440
17441        _destroy: function () {
17442            clearTimeout(this.searching);
17443            this.element.removeAttr("autocomplete");
17444            this.menu.element.remove();
17445            this.liveRegion.remove();
17446        },
17447
17448        _setOption: function (key, value) {
17449            this._super(key, value);
17450            if (key === "source") {
17451                this._initSource();
17452            }
17453            if (key === "appendTo") {
17454                this.menu.element.appendTo(this._appendTo());
17455            }
17456            if (key === "disabled" && value && this.xhr) {
17457                this.xhr.abort();
17458            }
17459        },
17460
17461        _isEventTargetInWidget: function (event) {
17462            var menuElement = this.menu.element[0];
17463
17464            return event.target === this.element[0] ||
17465                event.target === menuElement ||
17466                $.contains(menuElement, event.target);
17467        },
17468
17469        _closeOnClickOutside: function (event) {
17470            if (!this._isEventTargetInWidget(event)) {
17471                this.close();
17472            }
17473        },
17474
17475        _appendTo: function () {
17476            var element = this.options.appendTo;
17477
17478            if (element) {
17479                element = element.jquery || element.nodeType ?
17480                    $(element) :
17481                    this.document.find(element).eq(0);
17482            }
17483
17484            if (!element || !element[0]) {
17485                element = this.element.closest(".ui-front, dialog");
17486            }
17487
17488            if (!element.length) {
17489                element = this.document[0].body;
17490            }
17491
17492            return element;
17493        },
17494
17495        _initSource: function () {
17496            var array, url,
17497                that = this;
17498            if ($.isArray(this.options.source)) {
17499                array = this.options.source;
17500                this.source = function (request, response) {
17501                    response($.ui.autocomplete.filter(array, request.term));
17502                };
17503            } else if (typeof this.options.source === "string") {
17504                url = this.options.source;
17505                this.source = function (request, response) {
17506                    if (that.xhr) {
17507                        that.xhr.abort();
17508                    }
17509                    that.xhr = $.ajax({
17510                        url: url,
17511                        data: request,
17512                        dataType: "json",
17513                        success: function (data) {
17514                            response(data);
17515                        },
17516                        error: function () {
17517                            response([]);
17518                        }
17519                    });
17520                };
17521            } else {
17522                this.source = this.options.source;
17523            }
17524        },
17525
17526        _searchTimeout: function (event) {
17527            clearTimeout(this.searching);
17528            this.searching = this._delay(function () {
17529
17530                // Search if the value has changed, or if the user retypes the same value (see #7434)
17531                var equalValues = this.term === this._value(),
17532                    menuVisible = this.menu.element.is(":visible"),
17533                    modifierKey = event.altKey || event.ctrlKey || event.metaKey || event.shiftKey;
17534
17535                if (!equalValues || (equalValues && !menuVisible && !modifierKey)) {
17536                    this.selectedItem = null;
17537                    this.search(null, event);
17538                }
17539            }, this.options.delay);
17540        },
17541
17542        search: function (value, event) {
vendor: 6,418 bytes, lines 17543-17743
17543            value = value != null ? value : this._value();
17544
17545            // Always save the actual value, not the one passed as an argument
17546            this.term = this._value();
17547
17548            if (value.length < this.options.minLength) {
17549                return this.close(event);
17550            }
17551
17552            if (this._trigger("search", event) === false) {
17553                return;
17554            }
17555
17556            return this._search(value);
17557        },
17558
17559        _search: function (value) {
17560            this.pending++;
17561            this._addClass("ui-autocomplete-loading");
17562            this.cancelSearch = false;
17563
17564            this.source({term: value}, this._response());
17565        },
17566
17567        _response: function () {
17568            var index = ++this.requestIndex;
17569
17570            return $.proxy(function (content) {
17571                if (index === this.requestIndex) {
17572                    this.__response(content);
17573                }
17574
17575                this.pending--;
17576                if (!this.pending) {
17577                    this._removeClass("ui-autocomplete-loading");
17578                }
17579            }, this);
17580        },
17581
17582        __response: function (content) {
17583            if (content) {
17584                content = this._normalize(content);
17585            }
17586            this._trigger("response", null, {content: content});
17587            if (!this.options.disabled && content && content.length && !this.cancelSearch) {
17588                this._suggest(content);
17589                this._trigger("open");
17590            } else {
17591
17592                // use ._close() instead of .close() so we don't cancel future searches
17593                this._close();
17594            }
17595        },
17596
17597        close: function (event) {
17598            this.cancelSearch = true;
17599            this._close(event);
17600        },
17601
17602        _close: function (event) {
17603
17604            // Remove the handler that closes the menu on outside clicks
17605            this._off(this.document, "mousedown");
17606
17607            if (this.menu.element.is(":visible")) {
17608                this.menu.element.hide();
17609                this.menu.blur();
17610                this.isNewMenu = true;
17611                this._trigger("close", event);
17612            }
17613        },
17614
17615        _change: function (event) {
17616            if (this.previous !== this._value()) {
17617                this._trigger("change", event, {item: this.selectedItem});
17618            }
17619        },
17620
17621        _normalize: function (items) {
17622
17623            // assume all items have the right format when the first item is complete
17624            if (items.length && items[0].label && items[0].value) {
17625                return items;
17626            }
17627            return $.map(items, function (item) {
17628                if (typeof item === "string") {
17629                    return {
17630                        label: item,
17631                        value: item
17632                    };
17633                }
17634                return $.extend({}, item, {
17635                    label: item.label || item.value,
17636                    value: item.value || item.label
17637                });
17638            });
17639        },
17640
17641        _suggest: function (items) {
17642            var ul = this.menu.element.empty();
17643            this._renderMenu(ul, items);
17644            this.isNewMenu = true;
17645            this.menu.refresh();
17646
17647            // Size and position menu
17648            ul.show();
17649            this._resizeMenu();
17650            ul.position($.extend({
17651                of: this.element
17652            }, this.options.position));
17653
17654            if (this.options.autoFocus) {
17655                this.menu.next();
17656            }
17657
17658            // Listen for interactions outside of the widget (#6642)
17659            this._on(this.document, {
17660                mousedown: "_closeOnClickOutside"
17661            });
17662        },
17663
17664        _resizeMenu: function () {
17665            var ul = this.menu.element;
17666            ul.outerWidth(Math.max(
17667                // Firefox wraps long text (possibly a rounding bug)
17668                // so we add 1px to avoid the wrapping (#7513)
17669                ul.width("").outerWidth() + 1,
17670                this.element.outerWidth()
17671            ));
17672        },
17673
17674        _renderMenu: function (ul, items) {
17675            var that = this;
17676            $.each(items, function (index, item) {
17677                that._renderItemData(ul, item);
17678            });
17679        },
17680
17681        _renderItemData: function (ul, item) {
17682            return this._renderItem(ul, item).data("ui-autocomplete-item", item);
17683        },
17684
17685        _renderItem: function (ul, item) {
17686            return $("<li>")
17687                .append($("<div>").text(item.label))
17688                .appendTo(ul);
17689        },
17690
17691        _move: function (direction, event) {
17692            if (!this.menu.element.is(":visible")) {
17693                this.search(null, event);
17694                return;
17695            }
17696            if (this.menu.isFirstItem() && /^previous/.test(direction) ||
17697                this.menu.isLastItem() && /^next/.test(direction)) {
17698
17699                if (!this.isMultiLine) {
17700                    this._value(this.term);
17701                }
17702
17703                this.menu.blur();
17704                return;
17705            }
17706            this.menu[direction](event);
17707        },
17708
17709        widget: function () {
17710            return this.menu.element;
17711        },
17712
17713        _value: function () {
17714            return this.valueMethod.apply(this.element, arguments);
17715        },
17716
17717        _keyEvent: function (keyEvent, event) {
17718            if (!this.isMultiLine || this.menu.element.is(":visible")) {
17719                this._move(keyEvent, event);
17720
17721                // Prevents moving cursor to beginning/end of the text field in some browsers
17722                event.preventDefault();
17723            }
17724        },
17725
17726// Support: Chrome <=50
17727// We should be able to just use this.element.prop( "isContentEditable" )
17728// but hidden elements always report false in Chrome.
17729// https://code.google.com/p/chromium/issues/detail?id=313082
17730        _isContentEditable: function (element) {
17731            if (!element.length) {
17732                return false;
17733            }
17734
17735            var editable = element.prop("contentEditable");
17736
17737            if (editable === "inherit") {
17738                return this._isContentEditable(element.parent());
17739            }
17740
17741            return editable === "true";
17742        }
17743    });
17744
17745    $.extend($.ui.autocomplete, {
17746        escapeRegex: function (value) {
17747            return value.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&");
17748        },
17749        filter: function (array, term) {
17750            var matcher = new RegExp($.ui.autocomplete.escapeRegex(term), "i");
17751            return $.grep(array, function (value) {
17752                return matcher.test(value.label || value.value || value);
17753            });
17754        }
17755    });
17756
17757// Live region extension, adding a `messages` option
17758// NOTE: This is an experimental API. We are still investigating
17759// a full solution for string manipulation and internationalization.
17760    $.widget("ui.autocomplete", $.ui.autocomplete, {
17761        options: {
17762            messages: {
17763                noResults: "No search results.",
17764                results: function (amount) {
17765                    return amount + (amount > 1 ? " results are" : " result is") +
17766                        " available, use up and down arrow keys to navigate.";
17767                }
17768            }
17769        },
17770
17771        __response: function (content) {
17772            var message;
17773            this._superApply(arguments);
17774            if (this.options.disabled || this.cancelSearch) {
17775                return;
17776            }
17777            if (content && content.length) {
17778                message = this.options.messages.results(content.length);
17779            } else {
17780                message = this.options.messages.noResults;
17781            }
17782            this.liveRegion.children().hide();
17783            $("<div>").text(message).appendTo(this.liveRegion);
17784        }
17785    });
17786
17787    var widgetsAutocomplete = $.ui.autocomplete;
17788
17789
17790}));
17791/*
17792     _ _      _       _
17793 ___| (_) ___| | __  (_)___
17794/ __| | |/ __| |/ /  | / __|
17795\__ \ | | (__|   < _ | \__ \
17796|___/_|_|\___|_|\_(_)/ |___/
17797								|__/
17798
17799Version: 1.6.0
17800Author: Ken Wheeler
17801Website: http://kenwheeler.github.io
17802	Docs: http://kenwheeler.github.io/slick
17803	Repo: http://github.com/kenwheeler/slick
17804Issues: http://github.com/kenwheeler/slick/issues
17805
17806*/
17807/* global window, document, define, jQuery, setInterval, clearInterval */
17808(function (factory) {
17809    'use strict';
17810    if (typeof define === 'function' && define.amd) {
17811        define(['jquery'], factory);
17812    } else if (typeof exports !== 'undefined') {
17813        module.exports = factory(require('jquery'));
17814    } else {
17815        factory(jQuery);
17816    }
17817
17818}(function ($) {
17819    'use strict';
17820    var Slick = window.Slick || {};
17821
17822    Slick = (function () {
17823
17824        var instanceUid = 0;
17825
17826        function Slick(element, settings) {
17827
17828            var _ = this, dataSettings;
17829
17830            _.defaults = {
17831                accessibility: true,
17832                adaptiveHeight: false,
17833                appendArrows: $(element),
17834                appendDots: $(element),
17835                arrows: true,
17836                asNavFor: null,
17837                prevArrow: '<button type="button" data-role="none" class="slick-prev" aria-label="Previous" tabindex="0" role="button">Previous</button>',
17838                nextArrow: '<button type="button" data-role="none" class="slick-next" aria-label="Next" tabindex="0" role="button">Next</button>',
17839                autoplay: false,
17840                autoplaySpeed: 3000,
17841                centerMode: false,
17842                centerPadding: '50px',
17843                cssEase: 'ease',
17844                customPaging: function (slider, i) {
17845                    return $('<button type="button" data-role="none" role="button" tabindex="0" />').text(i + 1);
17846                },
17847                dots: false,
17848                dotsClass: 'slick-dots',
17849                draggable: true,
17850                easing: 'linear',
17851                edgeFriction: 0.35,
17852                fade: false,
17853                focusOnSelect: false,
17854                infinite: true,
17855                initialSlide: 0,
17856                lazyLoad: 'ondemand',
17857                mobileFirst: false,
17858                pauseOnHover: true,
17859                pauseOnFocus: true,
17860                pauseOnDotsHover: false,
17861                respondTo: 'window',
17862                responsive: null,
17863                rows: 1,
17864                rtl: false,
17865                slide: '',
17866                slidesPerRow: 1,
17867                slidesToShow: 1,
17868                slidesToScroll: 1,
17869                speed: 500,
17870                swipe: true,
17871                swipeToSlide: false,
17872                touchMove: true,
17873                touchThreshold: 5,
17874                useCSS: true,
17875                useTransform: true,
17876                variableWidth: false,
17877                vertical: false,
17878                verticalSwiping: false,
17879                waitForAnimate: true,
17880                zIndex: 1000
17881            };
17882
17883            _.initials = {
17884                animating: false,
17885                dragging: false,
17886                autoPlayTimer: null,
17887                currentDirection: 0,
17888                currentLeft: null,
17889                currentSlide: 0,
17890                direction: 1,
17891                $dots: null,
17892                listWidth: null,
17893                listHeight: null,
17894                loadIndex: 0,
17895                $nextArrow: null,
17896                $prevArrow: null,
17897                slideCount: null,
17898                slideWidth: null,
17899                $slideTrack: null,
17900                $slides: null,
17901                sliding: false,
17902                slideOffset: 0,
17903                swipeLeft: null,
17904                $list: null,
17905                touchObject: {},
17906                transformsEnabled: false,
vendor: 80,620 bytes, lines 17907-20579
17907                unslicked: false
17908            };
17909
17910            $.extend(_, _.initials);
17911
17912            _.activeBreakpoint = null;
17913            _.animType = null;
17914            _.animProp = null;
17915            _.breakpoints = [];
17916            _.breakpointSettings = [];
17917            _.cssTransitions = false;
17918            _.focussed = false;
17919            _.interrupted = false;
17920            _.hidden = 'hidden';
17921            _.paused = true;
17922            _.positionProp = null;
17923            _.respondTo = null;
17924            _.rowCount = 1;
17925            _.shouldClick = true;
17926            _.$slider = $(element);
17927            _.$slidesCache = null;
17928            _.transformType = null;
17929            _.transitionType = null;
17930            _.visibilityChange = 'visibilitychange';
17931            _.windowWidth = 0;
17932            _.windowTimer = null;
17933
17934            dataSettings = $(element).data('slick') || {};
17935
17936            _.options = $.extend({}, _.defaults, settings, dataSettings);
17937
17938            _.currentSlide = _.options.initialSlide;
17939
17940            _.originalSettings = _.options;
17941
17942            if (typeof document.mozHidden !== 'undefined') {
17943                _.hidden = 'mozHidden';
17944                _.visibilityChange = 'mozvisibilitychange';
17945            } else if (typeof document.webkitHidden !== 'undefined') {
17946                _.hidden = 'webkitHidden';
17947                _.visibilityChange = 'webkitvisibilitychange';
17948            }
17949
17950            _.autoPlay = $.proxy(_.autoPlay, _);
17951            _.autoPlayClear = $.proxy(_.autoPlayClear, _);
17952            _.autoPlayIterator = $.proxy(_.autoPlayIterator, _);
17953            _.changeSlide = $.proxy(_.changeSlide, _);
17954            _.clickHandler = $.proxy(_.clickHandler, _);
17955            _.selectHandler = $.proxy(_.selectHandler, _);
17956            _.setPosition = $.proxy(_.setPosition, _);
17957            _.swipeHandler = $.proxy(_.swipeHandler, _);
17958            _.dragHandler = $.proxy(_.dragHandler, _);
17959            _.keyHandler = $.proxy(_.keyHandler, _);
17960
17961            _.instanceUid = instanceUid++;
17962
17963            // A simple way to check for HTML strings
17964            // Strict HTML recognition (must start with <)
17965            // Extracted from jQuery v1.11 source
17966            _.htmlExpr = /^(?:\s*(<[\w\W]+>)[^>]*)$/;
17967
17968
17969            _.registerBreakpoints();
17970            _.init(true);
17971
17972        }
17973
17974        return Slick;
17975
17976    }());
17977
17978    Slick.prototype.activateADA = function () {
17979        var _ = this;
17980
17981        _.$slideTrack.find('.slick-active').attr({
17982            'aria-hidden': 'false'
17983        }).find('a, input, button, select').attr({
17984            'tabindex': '0'
17985        });
17986
17987    };
17988
17989    Slick.prototype.addSlide = Slick.prototype.slickAdd = function (markup, index, addBefore) {
17990
17991        var _ = this;
17992
17993        if (typeof (index) === 'boolean') {
17994            addBefore = index;
17995            index = null;
17996        } else if (index < 0 || (index >= _.slideCount)) {
17997            return false;
17998        }
17999
18000        _.unload();
18001
18002        if (typeof (index) === 'number') {
18003            if (index === 0 && _.$slides.length === 0) {
18004                $(markup).appendTo(_.$slideTrack);
18005            } else if (addBefore) {
18006                $(markup).insertBefore(_.$slides.eq(index));
18007            } else {
18008                $(markup).insertAfter(_.$slides.eq(index));
18009            }
18010        } else {
18011            if (addBefore === true) {
18012                $(markup).prependTo(_.$slideTrack);
18013            } else {
18014                $(markup).appendTo(_.$slideTrack);
18015            }
18016        }
18017
18018        _.$slides = _.$slideTrack.children(this.options.slide);
18019
18020        _.$slideTrack.children(this.options.slide).detach();
18021
18022        _.$slideTrack.append(_.$slides);
18023
18024        _.$slides.each(function (index, element) {
18025            $(element).attr('data-slick-index', index);
18026        });
18027
18028        _.$slidesCache = _.$slides;
18029
18030        _.reinit();
18031
18032    };
18033
18034    Slick.prototype.animateHeight = function () {
18035        var _ = this;
18036        if (_.options.slidesToShow === 1 && _.options.adaptiveHeight === true && _.options.vertical === false) {
18037            var targetHeight = _.$slides.eq(_.currentSlide).outerHeight(true);
18038            _.$list.animate({
18039                height: targetHeight
18040            }, _.options.speed);
18041        }
18042    };
18043
18044    Slick.prototype.animateSlide = function (targetLeft, callback) {
18045
18046        var animProps = {},
18047            _ = this;
18048
18049        _.animateHeight();
18050
18051        if (_.options.rtl === true && _.options.vertical === false) {
18052            targetLeft = -targetLeft;
18053        }
18054        if (_.transformsEnabled === false) {
18055            if (_.options.vertical === false) {
18056                _.$slideTrack.animate({
18057                    left: targetLeft
18058                }, _.options.speed, _.options.easing, callback);
18059            } else {
18060                _.$slideTrack.animate({
18061                    top: targetLeft
18062                }, _.options.speed, _.options.easing, callback);
18063            }
18064
18065        } else {
18066
18067            if (_.cssTransitions === false) {
18068                if (_.options.rtl === true) {
18069                    _.currentLeft = -(_.currentLeft);
18070                }
18071                $({
18072                    animStart: _.currentLeft
18073                }).animate({
18074                    animStart: targetLeft
18075                }, {
18076                    duration: _.options.speed,
18077                    easing: _.options.easing,
18078                    step: function (now) {
18079                        now = Math.ceil(now);
18080                        if (_.options.vertical === false) {
18081                            animProps[_.animType] = 'translate(' +
18082                                now + 'px, 0px)';
18083                            _.$slideTrack.css(animProps);
18084                        } else {
18085                            animProps[_.animType] = 'translate(0px,' +
18086                                now + 'px)';
18087                            _.$slideTrack.css(animProps);
18088                        }
18089                    },
18090                    complete: function () {
18091                        if (callback) {
18092                            callback.call();
18093                        }
18094                    }
18095                });
18096
18097            } else {
18098
18099                _.applyTransition();
18100                targetLeft = Math.ceil(targetLeft);
18101
18102                if (_.options.vertical === false) {
18103                    animProps[_.animType] = 'translate3d(' + targetLeft + 'px, 0px, 0px)';
18104                } else {
18105                    animProps[_.animType] = 'translate3d(0px,' + targetLeft + 'px, 0px)';
18106                }
18107                _.$slideTrack.css(animProps);
18108
18109                if (callback) {
18110                    setTimeout(function () {
18111
18112                        _.disableTransition();
18113
18114                        callback.call();
18115                    }, _.options.speed);
18116                }
18117
18118            }
18119
18120        }
18121
18122    };
18123
18124    Slick.prototype.getNavTarget = function () {
18125
18126        var _ = this,
18127            asNavFor = _.options.asNavFor;
18128
18129        if (asNavFor && asNavFor !== null) {
18130            asNavFor = $(asNavFor).not(_.$slider);
18131        }
18132
18133        return asNavFor;
18134
18135    };
18136
18137    Slick.prototype.asNavFor = function (index) {
18138
18139        var _ = this,
18140            asNavFor = _.getNavTarget();
18141
18142        if (asNavFor !== null && typeof asNavFor === 'object') {
18143            asNavFor.each(function () {
18144                var target = $(this).slick('getSlick');
18145                if (!target.unslicked) {
18146                    target.slideHandler(index, true);
18147                }
18148            });
18149        }
18150
18151    };
18152
18153    Slick.prototype.applyTransition = function (slide) {
18154
18155        var _ = this,
18156            transition = {};
18157
18158        if (_.options.fade === false) {
18159            transition[_.transitionType] = _.transformType + ' ' + _.options.speed + 'ms ' + _.options.cssEase;
18160        } else {
18161            transition[_.transitionType] = 'opacity ' + _.options.speed + 'ms ' + _.options.cssEase;
18162        }
18163
18164        if (_.options.fade === false) {
18165            _.$slideTrack.css(transition);
18166        } else {
18167            _.$slides.eq(slide).css(transition);
18168        }
18169
18170    };
18171
18172    Slick.prototype.autoPlay = function () {
18173
18174        var _ = this;
18175
18176        _.autoPlayClear();
18177
18178        if (_.slideCount > _.options.slidesToShow) {
18179            _.autoPlayTimer = setInterval(_.autoPlayIterator, _.options.autoplaySpeed);
18180        }
18181
18182    };
18183
18184    Slick.prototype.autoPlayClear = function () {
18185
18186        var _ = this;
18187
18188        if (_.autoPlayTimer) {
18189            clearInterval(_.autoPlayTimer);
18190        }
18191
18192    };
18193
18194    Slick.prototype.autoPlayIterator = function () {
18195
18196        var _ = this,
18197            slideTo = _.currentSlide + _.options.slidesToScroll;
18198
18199        if (!_.paused && !_.interrupted && !_.focussed) {
18200
18201            if (_.options.infinite === false) {
18202
18203                if (_.direction === 1 && (_.currentSlide + 1) === (_.slideCount - 1)) {
18204                    _.direction = 0;
18205                } else if (_.direction === 0) {
18206
18207                    slideTo = _.currentSlide - _.options.slidesToScroll;
18208
18209                    if (_.currentSlide - 1 === 0) {
18210                        _.direction = 1;
18211                    }
18212
18213                }
18214
18215            }
18216
18217            _.slideHandler(slideTo);
18218
18219        }
18220
18221    };
18222
18223    Slick.prototype.buildArrows = function () {
18224
18225        var _ = this;
18226
18227        if (_.options.arrows === true) {
18228
18229            _.$prevArrow = $(_.options.prevArrow).addClass('slick-arrow');
18230            _.$nextArrow = $(_.options.nextArrow).addClass('slick-arrow');
18231
18232            if (_.slideCount > _.options.slidesToShow) {
18233
18234                _.$prevArrow.removeClass('slick-hidden').removeAttr('aria-hidden tabindex');
18235                _.$nextArrow.removeClass('slick-hidden').removeAttr('aria-hidden tabindex');
18236
18237                if (_.htmlExpr.test(_.options.prevArrow)) {
18238                    _.$prevArrow.prependTo(_.options.appendArrows);
18239                }
18240
18241                if (_.htmlExpr.test(_.options.nextArrow)) {
18242                    _.$nextArrow.appendTo(_.options.appendArrows);
18243                }
18244
18245                if (_.options.infinite !== true) {
18246                    _.$prevArrow
18247                        .addClass('slick-disabled')
18248                        .attr('aria-disabled', 'true');
18249                }
18250
18251            } else {
18252
18253                _.$prevArrow.add(_.$nextArrow)
18254
18255                    .addClass('slick-hidden')
18256                    .attr({
18257                        'aria-disabled': 'true',
18258                        'tabindex': '-1'
18259                    });
18260
18261            }
18262
18263        }
18264
18265    };
18266
18267    Slick.prototype.buildDots = function () {
18268
18269        var _ = this,
18270            i, dot;
18271
18272        if (_.options.dots === true && _.slideCount > _.options.slidesToShow) {
18273
18274            _.$slider.addClass('slick-dotted');
18275
18276            dot = $('<ul />').addClass(_.options.dotsClass);
18277
18278            for (i = 0; i <= _.getDotCount(); i += 1) {
18279                dot.append($('<li />').append(_.options.customPaging.call(this, _, i)));
18280            }
18281
18282            _.$dots = dot.appendTo(_.options.appendDots);
18283
18284            _.$dots.find('li').first().addClass('slick-active').attr('aria-hidden', 'false');
18285
18286        }
18287
18288    };
18289
18290    Slick.prototype.buildOut = function () {
18291
18292        var _ = this;
18293
18294        _.$slides =
18295            _.$slider
18296                .children(_.options.slide + ':not(.slick-cloned)')
18297                .addClass('slick-slide');
18298
18299        _.slideCount = _.$slides.length;
18300
18301        _.$slides.each(function (index, element) {
18302            $(element)
18303                .attr('data-slick-index', index)
18304                .data('originalStyling', $(element).attr('style') || '');
18305        });
18306
18307        _.$slider.addClass('slick-slider');
18308
18309        _.$slideTrack = (_.slideCount === 0) ?
18310            $('<div class="slick-track"/>').appendTo(_.$slider) :
18311            _.$slides.wrapAll('<div class="slick-track"/>').parent();
18312
18313        _.$list = _.$slideTrack.wrap(
18314            '<div aria-live="polite" class="slick-list"/>').parent();
18315        _.$slideTrack.css('opacity', 0);
18316
18317        if (_.options.centerMode === true || _.options.swipeToSlide === true) {
18318            _.options.slidesToScroll = 1;
18319        }
18320
18321        $('img[data-lazy]', _.$slider).not('[src]').addClass('slick-loading');
18322
18323        _.setupInfinite();
18324
18325        _.buildArrows();
18326
18327        _.buildDots();
18328
18329        _.updateDots();
18330
18331
18332        _.setSlideClasses(typeof _.currentSlide === 'number' ? _.currentSlide : 0);
18333
18334        if (_.options.draggable === true) {
18335            _.$list.addClass('draggable');
18336        }
18337
18338    };
18339
18340    Slick.prototype.buildRows = function () {
18341
18342        var _ = this, a, b, c, newSlides, numOfSlides, originalSlides, slidesPerSection;
18343
18344        newSlides = document.createDocumentFragment();
18345        originalSlides = _.$slider.children();
18346
18347        if (_.options.rows > 1) {
18348
18349            slidesPerSection = _.options.slidesPerRow * _.options.rows;
18350            numOfSlides = Math.ceil(
18351                originalSlides.length / slidesPerSection
18352            );
18353
18354            for (a = 0; a < numOfSlides; a++) {
18355                var slide = document.createElement('div');
18356                for (b = 0; b < _.options.rows; b++) {
18357                    var row = document.createElement('div');
18358                    for (c = 0; c < _.options.slidesPerRow; c++) {
18359                        var target = (a * slidesPerSection + ((b * _.options.slidesPerRow) + c));
18360                        if (originalSlides.get(target)) {
18361                            row.appendChild(originalSlides.get(target));
18362                        }
18363                    }
18364                    slide.appendChild(row);
18365                }
18366                newSlides.appendChild(slide);
18367            }
18368
18369            _.$slider.empty().append(newSlides);
18370            _.$slider.children().children().children()
18371                .css({
18372                    'width': (100 / _.options.slidesPerRow) + '%',
18373                    'display': 'inline-block'
18374                });
18375
18376        }
18377
18378    };
18379
18380    Slick.prototype.checkResponsive = function (initial, forceUpdate) {
18381
18382        var _ = this,
18383            breakpoint, targetBreakpoint, respondToWidth, triggerBreakpoint = false;
18384        var sliderWidth = _.$slider.width();
18385        var windowWidth = window.innerWidth || $(window).width();
18386
18387        if (_.respondTo === 'window') {
18388            respondToWidth = windowWidth;
18389        } else if (_.respondTo === 'slider') {
18390            respondToWidth = sliderWidth;
18391        } else if (_.respondTo === 'min') {
18392            respondToWidth = Math.min(windowWidth, sliderWidth);
18393        }
18394
18395        if (_.options.responsive &&
18396            _.options.responsive.length &&
18397            _.options.responsive !== null) {
18398
18399            targetBreakpoint = null;
18400
18401            for (breakpoint in _.breakpoints) {
18402                if (_.breakpoints.hasOwnProperty(breakpoint)) {
18403                    if (_.originalSettings.mobileFirst === false) {
18404                        if (respondToWidth < _.breakpoints[breakpoint]) {
18405                            targetBreakpoint = _.breakpoints[breakpoint];
18406                        }
18407                    } else {
18408                        if (respondToWidth > _.breakpoints[breakpoint]) {
18409                            targetBreakpoint = _.breakpoints[breakpoint];
18410                        }
18411                    }
18412                }
18413            }
18414
18415            if (targetBreakpoint !== null) {
18416                if (_.activeBreakpoint !== null) {
18417                    if (targetBreakpoint !== _.activeBreakpoint || forceUpdate) {
18418                        _.activeBreakpoint =
18419                            targetBreakpoint;
18420                        if (_.breakpointSettings[targetBreakpoint] === 'unslick') {
18421                            _.unslick(targetBreakpoint);
18422                        } else {
18423                            _.options = $.extend({}, _.originalSettings,
18424                                _.breakpointSettings[
18425                                    targetBreakpoint]);
18426                            if (initial === true) {
18427                                _.currentSlide = _.options.initialSlide;
18428                            }
18429                            _.refresh(initial);
18430                        }
18431                        triggerBreakpoint = targetBreakpoint;
18432                    }
18433                } else {
18434                    _.activeBreakpoint = targetBreakpoint;
18435                    if (_.breakpointSettings[targetBreakpoint] === 'unslick') {
18436                        _.unslick(targetBreakpoint);
18437                    } else {
18438                        _.options = $.extend({}, _.originalSettings,
18439                            _.breakpointSettings[
18440                                targetBreakpoint]);
18441                        if (initial === true) {
18442                            _.currentSlide = _.options.initialSlide;
18443                        }
18444                        _.refresh(initial);
18445                    }
18446                    triggerBreakpoint = targetBreakpoint;
18447                }
18448            } else {
18449                if (_.activeBreakpoint !== null) {
18450                    _.activeBreakpoint = null;
18451                    _.options = _.originalSettings;
18452                    if (initial === true) {
18453                        _.currentSlide = _.options.initialSlide;
18454                    }
18455                    _.refresh(initial);
18456                    triggerBreakpoint = targetBreakpoint;
18457                }
18458            }
18459
18460            // only trigger breakpoints during an actual break. not on initialize.
18461            if (!initial && triggerBreakpoint !== false) {
18462                _.$slider.trigger('breakpoint', [_, triggerBreakpoint]);
18463            }
18464        }
18465
18466    };
18467
18468    Slick.prototype.changeSlide = function (event, dontAnimate) {
18469
18470        var _ = this,
18471            $target = $(event.currentTarget),
18472            indexOffset, slideOffset, unevenOffset;
18473
18474        // If target is a link, prevent default action.
18475        if ($target.is('a')) {
18476            event.preventDefault();
18477        }
18478
18479        // If target is not the <li> element (ie: a child), find the <li>.
18480        if (!$target.is('li')) {
18481            $target = $target.closest('li');
18482        }
18483
18484        unevenOffset = (_.slideCount % _.options.slidesToScroll !== 0);
18485        indexOffset = unevenOffset ? 0 : (_.slideCount - _.currentSlide) % _.options.slidesToScroll;
18486
18487        switch (event.data.message) {
18488
18489            case 'previous':
18490                slideOffset = indexOffset === 0 ? _.options.slidesToScroll : _.options.slidesToShow - indexOffset;
18491                if (_.slideCount > _.options.slidesToShow) {
18492                    _.slideHandler(_.currentSlide - slideOffset, false, dontAnimate);
18493                }
18494                break;
18495
18496            case 'next':
18497                slideOffset = indexOffset === 0 ? _.options.slidesToScroll : indexOffset;
18498                if (_.slideCount > _.options.slidesToShow) {
18499                    _.slideHandler(_.currentSlide + slideOffset, false, dontAnimate);
18500                }
18501                break;
18502
18503            case 'index':
18504                var index = event.data.index === 0 ? 0 :
18505                    event.data.index || $target.index() * _.options.slidesToScroll;
18506
18507                _.slideHandler(_.checkNavigable(index), false, dontAnimate);
18508                $target.children().trigger('focus');
18509                break;
18510
18511            default:
18512                return;
18513        }
18514
18515    };
18516
18517    Slick.prototype.checkNavigable = function (index) {
18518
18519        var _ = this,
18520            navigables, prevNavigable;
18521
18522        navigables = _.getNavigableIndexes();
18523        prevNavigable = 0;
18524        if (index > navigables[navigables.length - 1]) {
18525            index = navigables[navigables.length - 1];
18526        } else {
18527            for (var n in navigables) {
18528                if (index < navigables[n]) {
18529                    index = prevNavigable;
18530                    break;
18531                }
18532                prevNavigable = navigables[n];
18533            }
18534        }
18535
18536        return index;
18537    };
18538
18539    Slick.prototype.cleanUpEvents = function () {
18540
18541        var _ = this;
18542
18543        if (_.options.dots && _.$dots !== null) {
18544
18545            $('li', _.$dots)
18546                .off('click.slick', _.changeSlide)
18547                .off('mouseenter.slick', $.proxy(_.interrupt, _, true))
18548                .off('mouseleave.slick', $.proxy(_.interrupt, _, false));
18549
18550        }
18551
18552        _.$slider.off('focus.slick blur.slick');
18553
18554        if (_.options.arrows === true && _.slideCount > _.options.slidesToShow) {
18555            _.$prevArrow && _.$prevArrow.off('click.slick', _.changeSlide);
18556            _.$nextArrow && _.$nextArrow.off('click.slick', _.changeSlide);
18557        }
18558
18559        _.$list.off('touchstart.slick mousedown.slick', _.swipeHandler);
18560        _.$list.off('touchmove.slick mousemove.slick', _.swipeHandler);
18561        _.$list.off('touchend.slick mouseup.slick', _.swipeHandler);
18562        _.$list.off('touchcancel.slick mouseleave.slick', _.swipeHandler);
18563
18564        _.$list.off('click.slick', _.clickHandler);
18565
18566        $(document).off(_.visibilityChange, _.visibility);
18567
18568        _.cleanUpSlideEvents();
18569
18570        if (_.options.accessibility === true) {
18571            _.$list.off('keydown.slick', _.keyHandler);
18572        }
18573
18574        if (_.options.focusOnSelect === true) {
18575            $(_.$slideTrack).children().off('click.slick', _.selectHandler);
18576        }
18577
18578        $(window).off('orientationchange.slick.slick-' + _.instanceUid, _.orientationChange);
18579
18580        $(window).off('resize.slick.slick-' + _.instanceUid, _.resize);
18581
18582        $('[draggable!=true]', _.$slideTrack).off('dragstart', _.preventDefault);
18583
18584        $(window).off('load.slick.slick-' + _.instanceUid, _.setPosition);
18585        $(document).off('ready.slick.slick-' + _.instanceUid, _.setPosition);
18586
18587    };
18588
18589    Slick.prototype.cleanUpSlideEvents = function () {
18590
18591        var _ = this;
18592
18593        _.$list.off('mouseenter.slick', $.proxy(_.interrupt, _, true));
18594        _.$list.off('mouseleave.slick', $.proxy(_.interrupt, _, false));
18595
18596    };
18597
18598    Slick.prototype.cleanUpRows = function () {
18599
18600        var _ = this, originalSlides;
18601
18602        if (_.options.rows > 1) {
18603            originalSlides = _.$slides.children().children();
18604            originalSlides.removeAttr('style');
18605            _.$slider.empty().append(originalSlides);
18606        }
18607
18608    };
18609
18610    Slick.prototype.clickHandler = function (event) {
18611
18612        var _ = this;
18613
18614        if (_.shouldClick === false) {
18615            event.stopImmediatePropagation();
18616            event.stopPropagation();
18617            event.preventDefault();
18618        }
18619
18620    };
18621
18622    Slick.prototype.destroy = function (refresh) {
18623
18624        var _ = this;
18625
18626        _.autoPlayClear();
18627
18628        _.touchObject = {};
18629
18630        _.cleanUpEvents();
18631
18632        $('.slick-cloned', _.$slider).detach();
18633
18634        if (_.$dots) {
18635            _.$dots.remove();
18636        }
18637
18638
18639        if (_.$prevArrow && _.$prevArrow.length) {
18640
18641            _.$prevArrow
18642                .removeClass('slick-disabled slick-arrow slick-hidden')
18643                .removeAttr('aria-hidden aria-disabled tabindex')
18644                .css('display', '');
18645
18646            if (_.htmlExpr.test(_.options.prevArrow)) {
18647                _.$prevArrow.remove();
18648            }
18649        }
18650
18651        if (_.$nextArrow && _.$nextArrow.length) {
18652
18653            _.$nextArrow
18654                .removeClass('slick-disabled slick-arrow slick-hidden')
18655                .removeAttr('aria-hidden aria-disabled tabindex')
18656                .css('display', '');
18657
18658            if (_.htmlExpr.test(_.options.nextArrow)) {
18659                _.$nextArrow.remove();
18660            }
18661
18662        }
18663
18664
18665        if (_.$slides) {
18666
18667            _.$slides
18668                .removeClass('slick-slide slick-active slick-center slick-visible slick-current')
18669                .removeAttr('aria-hidden')
18670                .removeAttr('data-slick-index')
18671                .each(function () {
18672                    $(this).attr('style', $(this).data('originalStyling'));
18673                });
18674
18675            _.$slideTrack.children(this.options.slide).detach();
18676
18677            _.$slideTrack.detach();
18678
18679            _.$list.detach();
18680
18681            _.$slider.append(_.$slides);
18682        }
18683
18684        _.cleanUpRows();
18685
18686        _.$slider.removeClass('slick-slider');
18687        _.$slider.removeClass('slick-initialized');
18688        _.$slider.removeClass('slick-dotted');
18689
18690        _.unslicked = true;
18691
18692        if (!refresh) {
18693            _.$slider.trigger('destroy', [_]);
18694        }
18695
18696    };
18697
18698    Slick.prototype.disableTransition = function (slide) {
18699
18700        var _ = this,
18701            transition = {};
18702
18703        transition[_.transitionType] = '';
18704
18705        if (_.options.fade === false) {
18706            _.$slideTrack.css(transition);
18707        } else {
18708            _.$slides.eq(slide).css(transition);
18709        }
18710
18711    };
18712
18713    Slick.prototype.fadeSlide = function (slideIndex, callback) {
18714
18715        var _ = this;
18716
18717        if (_.cssTransitions === false) {
18718
18719            _.$slides.eq(slideIndex).css({
18720                zIndex: _.options.zIndex
18721            });
18722
18723            _.$slides.eq(slideIndex).animate({
18724                opacity: 1
18725            }, _.options.speed, _.options.easing, callback);
18726
18727        } else {
18728
18729            _.applyTransition(slideIndex);
18730
18731            _.$slides.eq(slideIndex).css({
18732                opacity: 1,
18733                zIndex: _.options.zIndex
18734            });
18735
18736            if (callback) {
18737                setTimeout(function () {
18738
18739                    _.disableTransition(slideIndex);
18740
18741                    callback.call();
18742                }, _.options.speed);
18743            }
18744
18745        }
18746
18747    };
18748
18749    Slick.prototype.fadeSlideOut = function (slideIndex) {
18750
18751        var _ = this;
18752
18753        if (_.cssTransitions === false) {
18754
18755            _.$slides.eq(slideIndex).animate({
18756                opacity: 0,
18757                zIndex: _.options.zIndex - 2
18758            }, _.options.speed, _.options.easing);
18759
18760        } else {
18761
18762            _.applyTransition(slideIndex);
18763
18764            _.$slides.eq(slideIndex).css({
18765                opacity: 0,
18766                zIndex: _.options.zIndex - 2
18767            });
18768
18769        }
18770
18771    };
18772
18773    Slick.prototype.filterSlides = Slick.prototype.slickFilter = function (filter) {
18774
18775        var _ = this;
18776
18777        if (filter !== null) {
18778
18779            _.$slidesCache = _.$slides;
18780
18781            _.unload();
18782
18783            _.$slideTrack.children(this.options.slide).detach();
18784
18785            _.$slidesCache.filter(filter).appendTo(_.$slideTrack);
18786
18787            _.reinit();
18788
18789        }
18790
18791    };
18792
18793    Slick.prototype.focusHandler = function () {
18794
18795        var _ = this;
18796
18797        _.$slider
18798            .off('focus.slick blur.slick')
18799            .on('focus.slick blur.slick',
18800                '*:not(.slick-arrow)', function (event) {
18801
18802                    event.stopImmediatePropagation();
18803                    var $sf = $(this);
18804
18805                    setTimeout(function () {
18806
18807                        if (_.options.pauseOnFocus) {
18808                            _.focussed = $sf.is(':focus');
18809                            _.autoPlay();
18810                        }
18811
18812                    }, 0);
18813
18814                });
18815    };
18816
18817    Slick.prototype.getCurrent = Slick.prototype.slickCurrentSlide = function () {
18818
18819        var _ = this;
18820        return _.currentSlide;
18821
18822    };
18823
18824    Slick.prototype.getDotCount = function () {
18825
18826        var _ = this;
18827
18828        var breakPoint = 0;
18829        var counter = 0;
18830        var pagerQty = 0;
18831
18832        if (_.options.infinite === true) {
18833            while (breakPoint < _.slideCount) {
18834                ++pagerQty;
18835                breakPoint = counter + _.options.slidesToScroll;
18836                counter += _.options.slidesToScroll <= _.options.slidesToShow ? _.options.slidesToScroll : _.options.slidesToShow;
18837            }
18838        } else if (_.options.centerMode === true) {
18839            pagerQty = _.slideCount;
18840        } else if (!_.options.asNavFor) {
18841            pagerQty = 1 + Math.ceil((_.slideCount - _.options.slidesToShow) / _.options.slidesToScroll);
18842        } else {
18843            while (breakPoint < _.slideCount) {
18844                ++pagerQty;
18845                breakPoint = counter + _.options.slidesToScroll;
18846                counter += _.options.slidesToScroll <= _.options.slidesToShow ? _.options.slidesToScroll : _.options.slidesToShow;
18847            }
18848        }
18849
18850        return pagerQty - 1;
18851
18852    };
18853
18854    Slick.prototype.getLeft = function (slideIndex) {
18855
18856        var _ = this,
18857            targetLeft,
18858            verticalHeight,
18859            verticalOffset = 0,
18860            targetSlide;
18861
18862        _.slideOffset = 0;
18863        verticalHeight = _.$slides.first().outerHeight(true);
18864
18865        if (_.options.infinite === true) {
18866            if (_.slideCount > _.options.slidesToShow) {
18867                _.slideOffset = (_.slideWidth * _.options.slidesToShow) * -1;
18868                verticalOffset = (verticalHeight * _.options.slidesToShow) * -1;
18869            }
18870            if (_.slideCount % _.options.slidesToScroll !== 0) {
18871                if (slideIndex + _.options.slidesToScroll > _.slideCount && _.slideCount > _.options.slidesToShow) {
18872                    if (slideIndex > _.slideCount) {
18873                        _.slideOffset = ((_.options.slidesToShow - (slideIndex - _.slideCount)) * _.slideWidth) * -1;
18874                        verticalOffset = ((_.options.slidesToShow - (slideIndex - _.slideCount)) * verticalHeight) * -1;
18875                    } else {
18876                        _.slideOffset = ((_.slideCount % _.options.slidesToScroll) * _.slideWidth) * -1;
18877                        verticalOffset = ((_.slideCount % _.options.slidesToScroll) * verticalHeight) * -1;
18878                    }
18879                }
18880            }
18881        } else {
18882            if (slideIndex + _.options.slidesToShow > _.slideCount) {
18883                _.slideOffset = ((slideIndex + _.options.slidesToShow) - _.slideCount) * _.slideWidth;
18884                verticalOffset = ((slideIndex + _.options.slidesToShow) - _.slideCount) * verticalHeight;
18885            }
18886        }
18887
18888        if (_.slideCount <= _.options.slidesToShow) {
18889            _.slideOffset = 0;
18890            verticalOffset = 0;
18891        }
18892
18893        if (_.options.centerMode === true && _.options.infinite === true) {
18894            _.slideOffset += _.slideWidth * Math.floor(_.options.slidesToShow / 2) - _.slideWidth;
18895        } else if (_.options.centerMode === true) {
18896            _.slideOffset = 0;
18897            _.slideOffset += _.slideWidth * Math.floor(_.options.slidesToShow / 2);
18898        }
18899
18900        if (_.options.vertical === false) {
18901            targetLeft = ((slideIndex * _.slideWidth) * -1) + _.slideOffset;
18902        } else {
18903            targetLeft = ((slideIndex * verticalHeight) * -1) + verticalOffset;
18904        }
18905
18906        if (_.options.variableWidth === true) {
18907
18908            if (_.slideCount <= _.options.slidesToShow || _.options.infinite === false) {
18909                targetSlide = _.$slideTrack.children('.slick-slide').eq(slideIndex);
18910            } else {
18911                targetSlide = _.$slideTrack.children('.slick-slide').eq(slideIndex + _.options.slidesToShow);
18912            }
18913
18914            if (_.options.rtl === true) {
18915                if (targetSlide[0]) {
18916                    targetLeft = (_.$slideTrack.width() - targetSlide[0].offsetLeft - targetSlide.width()) * -1;
18917                } else {
18918                    targetLeft = 0;
18919                }
18920            } else {
18921                targetLeft = targetSlide[0] ? targetSlide[0].offsetLeft * -1 : 0;
18922            }
18923
18924            if (_.options.centerMode === true) {
18925                if (_.slideCount <= _.options.slidesToShow || _.options.infinite === false) {
18926                    targetSlide = _.$slideTrack.children('.slick-slide').eq(slideIndex);
18927                } else {
18928                    targetSlide = _.$slideTrack.children('.slick-slide').eq(slideIndex + _.options.slidesToShow + 1);
18929                }
18930
18931                if (_.options.rtl === true) {
18932                    if (targetSlide[0]) {
18933                        targetLeft = (_.$slideTrack.width() - targetSlide[0].offsetLeft - targetSlide.width()) * -1;
18934                    } else {
18935                        targetLeft = 0;
18936                    }
18937                } else {
18938                    targetLeft = targetSlide[0] ? targetSlide[0].offsetLeft * -1 : 0;
18939                }
18940
18941                targetLeft += (_.$list.width() - targetSlide.outerWidth()) / 2;
18942            }
18943        }
18944
18945        return targetLeft;
18946
18947    };
18948
18949    Slick.prototype.getOption = Slick.prototype.slickGetOption = function (option) {
18950
18951        var _ = this;
18952
18953        return _.options[option];
18954
18955    };
18956
18957    Slick.prototype.getNavigableIndexes = function () {
18958
18959        var _ = this,
18960            breakPoint = 0,
18961            counter = 0,
18962            indexes = [],
18963            max;
18964
18965        if (_.options.infinite === false) {
18966            max = _.slideCount;
18967        } else {
18968            breakPoint = _.options.slidesToScroll * -1;
18969            counter = _.options.slidesToScroll * -1;
18970            max = _.slideCount * 2;
18971        }
18972
18973        while (breakPoint < max) {
18974            indexes.push(breakPoint);
18975            breakPoint = counter + _.options.slidesToScroll;
18976            counter += _.options.slidesToScroll <= _.options.slidesToShow ? _.options.slidesToScroll : _.options.slidesToShow;
18977        }
18978
18979        return indexes;
18980
18981    };
18982
18983    Slick.prototype.getSlick = function () {
18984
18985        return this;
18986
18987    };
18988
18989    Slick.prototype.getSlideCount = function () {
18990
18991        var _ = this,
18992            slidesTraversed, swipedSlide, centerOffset;
18993
18994        centerOffset = _.options.centerMode === true ? _.slideWidth * Math.floor(_.options.slidesToShow / 2) : 0;
18995
18996        if (_.options.swipeToSlide === true) {
18997            _.$slideTrack.find('.slick-slide').each(function (index, slide) {
18998                if (slide.offsetLeft - centerOffset + ($(slide).outerWidth() / 2) > (_.swipeLeft * -1)) {
18999                    swipedSlide = slide;
19000                    return false;
19001                }
19002            });
19003
19004            slidesTraversed = Math.abs($(swipedSlide).attr('data-slick-index') - _.currentSlide) || 1;
19005
19006            return slidesTraversed;
19007
19008        } else {
19009            return _.options.slidesToScroll;
19010        }
19011
19012    };
19013
19014    Slick.prototype.goTo = Slick.prototype.slickGoTo = function (slide, dontAnimate) {
19015
19016        var _ = this;
19017
19018        _.changeSlide({
19019            data: {
19020                message: 'index',
19021                index: parseInt(slide)
19022            }
19023        }, dontAnimate);
19024
19025    };
19026
19027    Slick.prototype.init = function (creation) {
19028
19029        var _ = this;
19030
19031        if (!$(_.$slider).hasClass('slick-initialized')) {
19032
19033            $(_.$slider).addClass('slick-initialized');
19034
19035            _.buildRows();
19036            _.buildOut();
19037            _.setProps();
19038            _.startLoad();
19039            _.loadSlider();
19040            _.initializeEvents();
19041            _.updateArrows();
19042            _.updateDots();
19043            _.checkResponsive(true);
19044            _.focusHandler();
19045
19046        }
19047
19048        if (creation) {
19049            _.$slider.trigger('init', [_]);
19050        }
19051
19052        if (_.options.accessibility === true) {
19053            _.initADA();
19054        }
19055
19056        if (_.options.autoplay) {
19057
19058            _.paused = false;
19059            _.autoPlay();
19060
19061        }
19062
19063    };
19064
19065    Slick.prototype.initADA = function () {
19066        var _ = this;
19067        _.$slides.add(_.$slideTrack.find('.slick-cloned')).attr({
19068            'aria-hidden': 'true',
19069            'tabindex': '-1'
19070        }).find('a, input, button, select').attr({
19071            'tabindex': '-1'
19072        });
19073
19074        _.$slideTrack.attr('role', 'listbox');
19075
19076        _.$slides.not(_.$slideTrack.find('.slick-cloned')).each(function (i) {
19077            $(this).attr({
19078                'role': 'option',
19079                'aria-describedby': 'slick-slide' + _.instanceUid + i + ''
19080            });
19081        });
19082
19083        if (_.$dots !== null) {
19084            _.$dots.attr('role', 'tablist').find('li').each(function (i) {
19085                $(this).attr({
19086                    'role': 'presentation',
19087                    'aria-selected': 'false',
19088                    'aria-controls': 'navigation' + _.instanceUid + i + '',
19089                    'id': 'slick-slide' + _.instanceUid + i + ''
19090                });
19091            })
19092                .first().attr('aria-selected', 'true').end()
19093                .find('button').attr('role', 'button').end()
19094                .closest('div').attr('role', 'toolbar');
19095        }
19096        _.activateADA();
19097
19098    };
19099
19100    Slick.prototype.initArrowEvents = function () {
19101
19102        var _ = this;
19103
19104        if (_.options.arrows === true && _.slideCount > _.options.slidesToShow) {
19105            _.$prevArrow
19106                .off('click.slick')
19107                .on('click.slick', {
19108                    message: 'previous'
19109                }, _.changeSlide);
19110            _.$nextArrow
19111                .off('click.slick')
19112                .on('click.slick', {
19113                    message: 'next'
19114                }, _.changeSlide);
19115        }
19116
19117    };
19118
19119    Slick.prototype.initDotEvents = function () {
19120
19121        var _ = this;
19122
19123        if (_.options.dots === true && _.slideCount > _.options.slidesToShow) {
19124            $('li', _.$dots).on('click.slick', {
19125                message: 'index'
19126            }, _.changeSlide);
19127        }
19128
19129        if (_.options.dots === true && _.options.pauseOnDotsHover === true) {
19130
19131            $('li', _.$dots)
19132                .on('mouseenter.slick', $.proxy(_.interrupt, _, true))
19133                .on('mouseleave.slick', $.proxy(_.interrupt, _, false));
19134
19135        }
19136
19137    };
19138
19139    Slick.prototype.initSlideEvents = function () {
19140
19141        var _ = this;
19142
19143        if (_.options.pauseOnHover) {
19144
19145            _.$list.on('mouseenter.slick', $.proxy(_.interrupt, _, true));
19146            _.$list.on('mouseleave.slick', $.proxy(_.interrupt, _, false));
19147
19148        }
19149
19150    };
19151
19152    Slick.prototype.initializeEvents = function () {
19153
19154        var _ = this;
19155
19156        _.initArrowEvents();
19157
19158        _.initDotEvents();
19159        _.initSlideEvents();
19160
19161        _.$list.on('touchstart.slick mousedown.slick', {
19162            action: 'start'
19163        }, _.swipeHandler);
19164        _.$list.on('touchmove.slick mousemove.slick', {
19165            action: 'move'
19166        }, _.swipeHandler);
19167        _.$list.on('touchend.slick mouseup.slick', {
19168            action: 'end'
19169        }, _.swipeHandler);
19170        _.$list.on('touchcancel.slick mouseleave.slick', {
19171            action: 'end'
19172        }, _.swipeHandler);
19173
19174        _.$list.on('click.slick', _.clickHandler);
19175
19176        $(document).on(_.visibilityChange, $.proxy(_.visibility, _));
19177
19178        if (_.options.accessibility === true) {
19179            _.$list.on('keydown.slick', _.keyHandler);
19180        }
19181
19182        if (_.options.focusOnSelect === true) {
19183            $(_.$slideTrack).children().on('click.slick', _.selectHandler);
19184        }
19185
19186        $(window).on('orientationchange.slick.slick-' + _.instanceUid, $.proxy(_.orientationChange, _));
19187
19188        $(window).on('resize.slick.slick-' + _.instanceUid, $.proxy(_.resize, _));
19189
19190        $('[draggable!=true]', _.$slideTrack).on('dragstart', _.preventDefault);
19191
19192        $(window).on('load.slick.slick-' + _.instanceUid, _.setPosition);
19193        $(document).on('ready.slick.slick-' + _.instanceUid, _.setPosition);
19194
19195    };
19196
19197    Slick.prototype.initUI = function () {
19198
19199        var _ = this;
19200
19201        if (_.options.arrows === true && _.slideCount > _.options.slidesToShow) {
19202
19203            _.$prevArrow.show();
19204            _.$nextArrow.show();
19205
19206        }
19207
19208        if (_.options.dots === true && _.slideCount > _.options.slidesToShow) {
19209
19210            _.$dots.show();
19211
19212        }
19213
19214    };
19215
19216    Slick.prototype.keyHandler = function (event) {
19217
19218        var _ = this;
19219        //Dont slide if the cursor is inside the form fields and arrow keys are pressed
19220        if (!event.target.tagName.match('TEXTAREA|INPUT|SELECT')) {
19221            if (event.keyCode === 37 && _.options.accessibility === true) {
19222                _.changeSlide({
19223                    data: {
19224                        message: _.options.rtl === true ? 'next' : 'previous'
19225                    }
19226                });
19227            } else if (event.keyCode === 39 && _.options.accessibility === true) {
19228                _.changeSlide({
19229                    data: {
19230                        message: _.options.rtl === true ? 'previous' : 'next'
19231                    }
19232                });
19233            }
19234        }
19235
19236    };
19237
19238    Slick.prototype.lazyLoad = function () {
19239
19240        var _ = this,
19241            loadRange, cloneRange, rangeStart, rangeEnd;
19242
19243        function loadImages(imagesScope) {
19244
19245            $('img[data-lazy]', imagesScope).each(function () {
19246
19247                var image = $(this),
19248                    imageSource = $(this).attr('data-lazy'),
19249                    imageToLoad = document.createElement('img');
19250
19251                imageToLoad.onload = function () {
19252
19253                    image
19254                        .animate({opacity: 0}, 100, function () {
19255                            image
19256                                .attr('src', imageSource)
19257                                .animate({opacity: 1}, 200, function () {
19258                                    image
19259                                        .removeAttr('data-lazy')
19260                                        .removeClass('slick-loading');
19261                                });
19262                            _.$slider.trigger('lazyLoaded', [_, image, imageSource]);
19263                        });
19264
19265                };
19266
19267                imageToLoad.onerror = function () {
19268
19269                    image
19270                        .removeAttr('data-lazy')
19271                        .removeClass('slick-loading')
19272                        .addClass('slick-lazyload-error');
19273
19274                    _.$slider.trigger('lazyLoadError', [_, image, imageSource]);
19275
19276                };
19277
19278                imageToLoad.src = imageSource;
19279
19280            });
19281
19282        }
19283
19284        if (_.options.centerMode === true) {
19285            if (_.options.infinite === true) {
19286                rangeStart = _.currentSlide + (_.options.slidesToShow / 2 + 1);
19287                rangeEnd = rangeStart + _.options.slidesToShow + 2;
19288            } else {
19289                rangeStart = Math.max(0, _.currentSlide - (_.options.slidesToShow / 2 + 1));
19290                rangeEnd = 2 + (_.options.slidesToShow / 2 + 1) + _.currentSlide;
19291            }
19292        } else {
19293            rangeStart = _.options.infinite ? _.options.slidesToShow + _.currentSlide : _.currentSlide;
19294            rangeEnd = Math.ceil(rangeStart + _.options.slidesToShow);
19295            if (_.options.fade === true) {
19296                if (rangeStart > 0) rangeStart--;
19297                if (rangeEnd <= _.slideCount) rangeEnd++;
19298            }
19299        }
19300
19301        loadRange = _.$slider.find('.slick-slide').slice(rangeStart, rangeEnd);
19302        loadImages(loadRange);
19303
19304        if (_.slideCount <= _.options.slidesToShow) {
19305            cloneRange = _.$slider.find('.slick-slide');
19306            loadImages(cloneRange);
19307        } else if (_.currentSlide >= _.slideCount - _.options.slidesToShow) {
19308            cloneRange = _.$slider.find('.slick-cloned').slice(0, _.options.slidesToShow);
19309            loadImages(cloneRange);
19310        } else if (_.currentSlide === 0) {
19311            cloneRange = _.$slider.find('.slick-cloned').slice(_.options.slidesToShow * -1);
19312            loadImages(cloneRange);
19313        }
19314
19315    };
19316
19317    Slick.prototype.loadSlider = function () {
19318
19319        var _ = this;
19320
19321        _.setPosition();
19322
19323        _.$slideTrack.css({
19324            opacity: 1
19325        });
19326
19327        _.$slider.removeClass('slick-loading');
19328
19329        _.initUI();
19330
19331        if (_.options.lazyLoad === 'progressive') {
19332            _.progressiveLazyLoad();
19333        }
19334
19335    };
19336
19337    Slick.prototype.next = Slick.prototype.slickNext = function () {
19338
19339        var _ = this;
19340
19341        _.changeSlide({
19342            data: {
19343                message: 'next'
19344            }
19345        });
19346
19347    };
19348
19349    Slick.prototype.orientationChange = function () {
19350
19351        var _ = this;
19352
19353        _.checkResponsive();
19354        _.setPosition();
19355
19356    };
19357
19358    Slick.prototype.pause = Slick.prototype.slickPause = function () {
19359
19360        var _ = this;
19361
19362        _.autoPlayClear();
19363        _.paused = true;
19364
19365    };
19366
19367    Slick.prototype.play = Slick.prototype.slickPlay = function () {
19368
19369        var _ = this;
19370
19371        _.autoPlay();
19372        _.options.autoplay = true;
19373        _.paused = false;
19374        _.focussed = false;
19375        _.interrupted = false;
19376
19377    };
19378
19379    Slick.prototype.postSlide = function (index) {
19380
19381        var _ = this;
19382
19383        if (!_.unslicked) {
19384
19385            _.$slider.trigger('afterChange', [_, index]);
19386
19387            _.animating = false;
19388
19389            _.setPosition();
19390
19391            _.swipeLeft = null;
19392
19393            if (_.options.autoplay) {
19394                _.autoPlay();
19395            }
19396
19397            if (_.options.accessibility === true) {
19398                _.initADA();
19399            }
19400
19401        }
19402
19403    };
19404
19405    Slick.prototype.prev = Slick.prototype.slickPrev = function () {
19406
19407        var _ = this;
19408
19409        _.changeSlide({
19410            data: {
19411                message: 'previous'
19412            }
19413        });
19414
19415    };
19416
19417    Slick.prototype.preventDefault = function (event) {
19418
19419        event.preventDefault();
19420
19421    };
19422
19423    Slick.prototype.progressiveLazyLoad = function (tryCount) {
19424
19425        tryCount = tryCount || 1;
19426
19427        var _ = this,
19428            $imgsToLoad = $('img[data-lazy]', _.$slider),
19429            image,
19430            imageSource,
19431            imageToLoad;
19432
19433        if ($imgsToLoad.length) {
19434
19435            image = $imgsToLoad.first();
19436            imageSource = image.attr('data-lazy');
19437            imageToLoad = document.createElement('img');
19438
19439            imageToLoad.onload = function () {
19440
19441                image
19442                    .attr('src', imageSource)
19443                    .removeAttr('data-lazy')
19444                    .removeClass('slick-loading');
19445
19446                if (_.options.adaptiveHeight === true) {
19447                    _.setPosition();
19448                }
19449
19450                _.$slider.trigger('lazyLoaded', [_, image, imageSource]);
19451                _.progressiveLazyLoad();
19452
19453            };
19454
19455            imageToLoad.onerror = function () {
19456
19457                if (tryCount < 3) {
19458
19459                    /**
19460                     * try to load the image 3 times,
19461                     * leave a slight delay so we don't get
19462                     * servers blocking the request.
19463                     */
19464                    setTimeout(function () {
19465                        _.progressiveLazyLoad(tryCount + 1);
19466                    }, 500);
19467
19468                } else {
19469
19470                    image
19471                        .removeAttr('data-lazy')
19472                        .removeClass('slick-loading')
19473                        .addClass('slick-lazyload-error');
19474
19475                    _.$slider.trigger('lazyLoadError', [_, image, imageSource]);
19476
19477                    _.progressiveLazyLoad();
19478
19479                }
19480
19481            };
19482
19483            imageToLoad.src = imageSource;
19484
19485        } else {
19486
19487            _.$slider.trigger('allImagesLoaded', [_]);
19488
19489        }
19490
19491    };
19492
19493    Slick.prototype.refresh = function (initializing) {
19494
19495        var _ = this, currentSlide, lastVisibleIndex;
19496
19497        lastVisibleIndex = _.slideCount - _.options.slidesToShow;
19498
19499        // in non-infinite sliders, we don't want to go past the
19500        // last visible index.
19501        if (!_.options.infinite && (_.currentSlide > lastVisibleIndex)) {
19502            _.currentSlide = lastVisibleIndex;
19503        }
19504
19505        // if less slides than to show, go to start.
19506        if (_.slideCount <= _.options.slidesToShow) {
19507            _.currentSlide = 0;
19508
19509        }
19510
19511        currentSlide = _.currentSlide;
19512
19513        _.destroy(true);
19514
19515        $.extend(_, _.initials, {currentSlide: currentSlide});
19516
19517        _.init();
19518
19519        if (!initializing) {
19520
19521            _.changeSlide({
19522                data: {
19523                    message: 'index',
19524                    index: currentSlide
19525                }
19526            }, false);
19527
19528        }
19529
19530    };
19531
19532    Slick.prototype.registerBreakpoints = function () {
19533
19534        var _ = this, breakpoint, currentBreakpoint, l,
19535            responsiveSettings = _.options.responsive || null;
19536
19537        if ($.type(responsiveSettings) === 'array' && responsiveSettings.length) {
19538
19539            _.respondTo = _.options.respondTo || 'window';
19540
19541            for (breakpoint in responsiveSettings) {
19542
19543                l = _.breakpoints.length - 1;
19544                currentBreakpoint = responsiveSettings[breakpoint].breakpoint;
19545
19546                if (responsiveSettings.hasOwnProperty(breakpoint)) {
19547
19548                    // loop through the breakpoints and cut out any existing
19549                    // ones with the same breakpoint number, we don't want dupes.
19550                    while (l >= 0) {
19551                        if (_.breakpoints[l] && _.breakpoints[l] === currentBreakpoint) {
19552                            _.breakpoints.splice(l, 1);
19553                        }
19554                        l--;
19555                    }
19556
19557                    _.breakpoints.push(currentBreakpoint);
19558                    _.breakpointSettings[currentBreakpoint] = responsiveSettings[breakpoint].settings;
19559
19560                }
19561
19562            }
19563
19564            _.breakpoints.sort(function (a, b) {
19565                return (_.options.mobileFirst) ? a - b : b - a;
19566            });
19567
19568        }
19569
19570    };
19571
19572    Slick.prototype.reinit = function () {
19573
19574        var _ = this;
19575
19576        _.$slides =
19577            _.$slideTrack
19578                .children(_.options.slide)
19579                .addClass('slick-slide');
19580
19581        _.slideCount = _.$slides.length;
19582
19583        if (_.currentSlide >= _.slideCount && _.currentSlide !== 0) {
19584            _.currentSlide = _.currentSlide - _.options.slidesToScroll;
19585        }
19586
19587        if (_.slideCount <= _.options.slidesToShow) {
19588            _.currentSlide = 0;
19589        }
19590
19591        _.registerBreakpoints();
19592
19593        _.setProps();
19594        _.setupInfinite();
19595        _.buildArrows();
19596        _.updateArrows();
19597        _.initArrowEvents();
19598        _.buildDots();
19599        _.updateDots();
19600        _.initDotEvents();
19601        _.cleanUpSlideEvents();
19602        _.initSlideEvents();
19603
19604        _.checkResponsive(false, true);
19605
19606        if (_.options.focusOnSelect === true) {
19607            $(_.$slideTrack).children().on('click.slick', _.selectHandler);
19608        }
19609
19610        _.setSlideClasses(typeof _.currentSlide === 'number' ? _.currentSlide : 0);
19611
19612        _.setPosition();
19613        _.focusHandler();
19614
19615        _.paused = !_.options.autoplay;
19616        _.autoPlay();
19617
19618        _.$slider.trigger('reInit', [_]);
19619
19620    };
19621
19622    Slick.prototype.resize = function () {
19623
19624        var _ = this;
19625
19626        if ($(window).width() !== _.windowWidth) {
19627            clearTimeout(_.windowDelay);
19628            _.windowDelay = window.setTimeout(function () {
19629                _.windowWidth = $(window).width();
19630                _.checkResponsive();
19631                if (!_.unslicked) {
19632                    _.setPosition();
19633                }
19634            }, 50);
19635        }
19636    };
19637
19638    Slick.prototype.removeSlide = Slick.prototype.slickRemove = function (index, removeBefore, removeAll) {
19639
19640        var _ = this;
19641
19642        if (typeof (index) === 'boolean') {
19643            removeBefore = index;
19644            index = removeBefore === true ? 0 : _.slideCount - 1;
19645        } else {
19646            index = removeBefore === true ? --index : index;
19647        }
19648
19649        if (_.slideCount < 1 || index < 0 || index > _.slideCount - 1) {
19650            return false;
19651        }
19652
19653        _.unload();
19654
19655        if (removeAll === true) {
19656            _.$slideTrack.children().remove();
19657        } else {
19658            _.$slideTrack.children(this.options.slide).eq(index).remove();
19659        }
19660
19661        _.$slides = _.$slideTrack.children(this.options.slide);
19662
19663        _.$slideTrack.children(this.options.slide).detach();
19664
19665        _.$slideTrack.append(_.$slides);
19666
19667        _.$slidesCache = _.$slides;
19668
19669        _.reinit();
19670
19671    };
19672
19673    Slick.prototype.setCSS = function (position) {
19674
19675        var _ = this,
19676            positionProps = {},
19677            x, y;
19678
19679        if (_.options.rtl === true) {
19680            position = -position;
19681        }
19682        x = _.positionProp == 'left' ? Math.ceil(position) + 'px' : '0px';
19683        y = _.positionProp == 'top' ? Math.ceil(position) + 'px' : '0px';
19684
19685        positionProps[_.positionProp] = position;
19686
19687        if (_.transformsEnabled === false) {
19688            _.$slideTrack.css(positionProps);
19689        } else {
19690            positionProps = {};
19691            if (_.cssTransitions === false) {
19692                positionProps[_.animType] = 'translate(' + x + ', ' + y + ')';
19693                _.$slideTrack.css(positionProps);
19694            } else {
19695                positionProps[_.animType] = 'translate3d(' + x + ', ' + y + ', 0px)';
19696                _.$slideTrack.css(positionProps);
19697            }
19698        }
19699
19700    };
19701
19702    Slick.prototype.setDimensions = function () {
19703
19704        var _ = this;
19705
19706        if (_.options.vertical === false) {
19707            if (_.options.centerMode === true) {
19708                _.$list.css({
19709                    padding: ('0px ' + _.options.centerPadding)
19710                });
19711            }
19712        } else {
19713            _.$list.height(_.$slides.first().outerHeight(true) * _.options.slidesToShow);
19714            if (_.options.centerMode === true) {
19715                _.$list.css({
19716                    padding: (_.options.centerPadding + ' 0px')
19717                });
19718            }
19719        }
19720
19721        _.listWidth = _.$list.width();
19722        _.listHeight = _.$list.height();
19723
19724
19725        if (_.options.vertical === false && _.options.variableWidth === false) {
19726            _.slideWidth = Math.ceil(_.listWidth / _.options.slidesToShow);
19727            _.$slideTrack.width(Math.ceil((_.slideWidth * _.$slideTrack.children('.slick-slide').length)));
19728
19729        } else if (_.options.variableWidth === true) {
19730            _.$slideTrack.width(5000 * _.slideCount);
19731        } else {
19732            _.slideWidth = Math.ceil(_.listWidth);
19733            _.$slideTrack.height(Math.ceil((_.$slides.first().outerHeight(true) * _.$slideTrack.children('.slick-slide').length)));
19734        }
19735
19736        var offset = _.$slides.first().outerWidth(true) - _.$slides.first().width();
19737        if (_.options.variableWidth === false) _.$slideTrack.children('.slick-slide').width(_.slideWidth - offset);
19738
19739    };
19740
19741    Slick.prototype.setFade = function () {
19742
19743        var _ = this,
19744            targetLeft;
19745
19746        _.$slides.each(function (index, element) {
19747            targetLeft = (_.slideWidth * index) * -1;
19748            if (_.options.rtl === true) {
19749                $(element).css({
19750                    position: 'relative',
19751                    right: targetLeft,
19752                    top: 0,
19753                    zIndex: _.options.zIndex - 2,
19754                    opacity: 0
19755                });
19756            } else {
19757                $(element).css({
19758                    position: 'relative',
19759                    left: targetLeft,
19760                    top: 0,
19761                    zIndex: _.options.zIndex - 2,
19762                    opacity: 0
19763                });
19764            }
19765        });
19766
19767        _.$slides.eq(_.currentSlide).css({
19768            zIndex: _.options.zIndex - 1,
19769            opacity: 1
19770        });
19771
19772    };
19773
19774    Slick.prototype.setHeight = function () {
19775
19776        var _ = this;
19777
19778        if (_.options.slidesToShow === 1 && _.options.adaptiveHeight === true && _.options.vertical === false) {
19779            var targetHeight = _.$slides.eq(_.currentSlide).outerHeight(true);
19780            _.$list.css('height', targetHeight);
19781        }
19782
19783    };
19784
19785    Slick.prototype.setOption =
19786        Slick.prototype.slickSetOption = function () {
19787
19788            /**
19789             * accepts arguments in format of:
19790             *
19791             *  - for changing a single option's value:
19792             *     .slick("setOption", option, value, refresh )
19793             *
19794             *  - for changing a set of responsive options:
19795             *     .slick("setOption", 'responsive', [{}, ...], refresh )
19796             *
19797             *  - for updating multiple values at once (not responsive)
19798             *     .slick("setOption", { 'option': value, ... }, refresh )
19799             */
19800
19801            var _ = this, l, item, option, value, refresh = false, type;
19802
19803            if ($.type(arguments[0]) === 'object') {
19804
19805                option = arguments[0];
19806                refresh = arguments[1];
19807                type = 'multiple';
19808
19809            } else if ($.type(arguments[0]) === 'string') {
19810
19811                option = arguments[0];
19812                value = arguments[1];
19813                refresh = arguments[2];
19814
19815                if (arguments[0] === 'responsive' && $.type(arguments[1]) === 'array') {
19816
19817                    type = 'responsive';
19818
19819                } else if (typeof arguments[1] !== 'undefined') {
19820
19821                    type = 'single';
19822
19823                }
19824
19825            }
19826
19827            if (type === 'single') {
19828
19829                _.options[option] = value;
19830
19831
19832            } else if (type === 'multiple') {
19833
19834                $.each(option, function (opt, val) {
19835
19836                    _.options[opt] = val;
19837
19838                });
19839
19840
19841            } else if (type === 'responsive') {
19842
19843                for (item in value) {
19844
19845                    if ($.type(_.options.responsive) !== 'array') {
19846
19847                        _.options.responsive = [value[item]];
19848
19849                    } else {
19850
19851                        l = _.options.responsive.length - 1;
19852
19853                        // loop through the responsive object and splice out duplicates.
19854                        while (l >= 0) {
19855
19856                            if (_.options.responsive[l].breakpoint === value[item].breakpoint) {
19857
19858                                _.options.responsive.splice(l, 1);
19859
19860                            }
19861
19862                            l--;
19863
19864                        }
19865
19866                        _.options.responsive.push(value[item]);
19867
19868                    }
19869
19870                }
19871
19872            }
19873
19874            if (refresh) {
19875
19876                _.unload();
19877                _.reinit();
19878
19879            }
19880
19881        };
19882
19883    Slick.prototype.setPosition = function () {
19884
19885        var _ = this;
19886
19887        _.setDimensions();
19888
19889        _.setHeight();
19890
19891        if (_.options.fade === false) {
19892            _.setCSS(_.getLeft(_.currentSlide));
19893        } else {
19894            _.setFade();
19895        }
19896
19897        _.$slider.trigger('setPosition', [_]);
19898
19899    };
19900
19901    Slick.prototype.setProps = function () {
19902
19903        var _ = this,
19904            bodyStyle = document.body.style;
19905
19906        _.positionProp = _.options.vertical === true ? 'top' : 'left';
19907
19908        if (_.positionProp === 'top') {
19909            _.$slider.addClass('slick-vertical');
19910        } else {
19911            _.$slider.removeClass('slick-vertical');
19912        }
19913
19914        if (bodyStyle.WebkitTransition !== undefined ||
19915            bodyStyle.MozTransition !== undefined ||
19916            bodyStyle.msTransition !== undefined) {
19917            if (_.options.useCSS === true) {
19918                _.cssTransitions = true;
19919            }
19920        }
19921
19922        if (_.options.fade) {
19923            if (typeof _.options.zIndex === 'number') {
19924                if (_.options.zIndex < 3) {
19925                    _.options.zIndex = 3;
19926                }
19927            } else {
19928                _.options.zIndex = _.defaults.zIndex;
19929            }
19930        }
19931
19932        if (bodyStyle.OTransform !== undefined) {
19933            _.animType = 'OTransform';
19934            _.transformType = '-o-transform';
19935            _.transitionType = 'OTransition';
19936            if (bodyStyle.perspectiveProperty === undefined && bodyStyle.webkitPerspective === undefined) _.animType = false;
19937        }
19938        if (bodyStyle.MozTransform !== undefined) {
19939            _.animType = 'MozTransform';
19940            _.transformType = '-moz-transform';
19941            _.transitionType = 'MozTransition';
19942            if (bodyStyle.perspectiveProperty === undefined && bodyStyle.MozPerspective === undefined) _.animType = false;
19943        }
19944        if (bodyStyle.webkitTransform !== undefined) {
19945            _.animType = 'webkitTransform';
19946            _.transformType = '-webkit-transform';
19947            _.transitionType = 'webkitTransition';
19948            if (bodyStyle.perspectiveProperty === undefined && bodyStyle.webkitPerspective === undefined) _.animType = false;
19949        }
19950        if (bodyStyle.msTransform !== undefined) {
19951            _.animType = 'msTransform';
19952            _.transformType = '-ms-transform';
19953            _.transitionType = 'msTransition';
19954            if (bodyStyle.msTransform === undefined) _.animType = false;
19955        }
19956        if (bodyStyle.transform !== undefined && _.animType !== false) {
19957            _.animType = 'transform';
19958            _.transformType = 'transform';
19959            _.transitionType = 'transition';
19960        }
19961        _.transformsEnabled = _.options.useTransform && (_.animType !== null && _.animType !== false);
19962    };
19963
19964
19965    Slick.prototype.setSlideClasses = function (index) {
19966
19967        var _ = this,
19968            centerOffset, allSlides, indexOffset, remainder;
19969
19970        allSlides = _.$slider
19971            .find('.slick-slide')
19972            .removeClass('slick-active slick-center slick-current')
19973            .attr('aria-hidden', 'true');
19974
19975        _.$slides
19976            .eq(index)
19977            .addClass('slick-current');
19978
19979        if (_.options.centerMode === true) {
19980
19981            centerOffset = Math.floor(_.options.slidesToShow / 2);
19982
19983            if (_.options.infinite === true) {
19984
19985                if (index >= centerOffset && index <= (_.slideCount - 1) - centerOffset) {
19986
19987                    _.$slides
19988                        .slice(index - centerOffset, index + centerOffset + 1)
19989                        .addClass('slick-active')
19990                        .attr('aria-hidden', 'false');
19991
19992                } else {
19993
19994                    indexOffset = _.options.slidesToShow + index;
19995                    allSlides
19996                        .slice(indexOffset - centerOffset + 1, indexOffset + centerOffset + 2)
19997                        .addClass('slick-active')
19998                        .attr('aria-hidden', 'false');
19999
20000                }
20001
20002                if (index === 0) {
20003
20004                    allSlides
20005                        .eq(allSlides.length - 1 - _.options.slidesToShow)
20006                        .addClass('slick-center');
20007
20008                } else if (index === _.slideCount - 1) {
20009
20010                    allSlides
20011                        .eq(_.options.slidesToShow)
20012                        .addClass('slick-center');
20013
20014                }
20015
20016            }
20017
20018            _.$slides
20019                .eq(index)
20020                .addClass('slick-center');
20021
20022        } else {
20023
20024            if (index >= 0 && index <= (_.slideCount - _.options.slidesToShow)) {
20025
20026                _.$slides
20027                    .slice(index, index + _.options.slidesToShow)
20028                    .addClass('slick-active')
20029                    .attr('aria-hidden', 'false');
20030
20031            } else if (allSlides.length <= _.options.slidesToShow) {
20032
20033                allSlides
20034                    .addClass('slick-active')
20035                    .attr('aria-hidden', 'false');
20036
20037            } else {
20038
20039                remainder = _.slideCount % _.options.slidesToShow;
20040                indexOffset = _.options.infinite === true ? _.options.slidesToShow + index : index;
20041
20042                if (_.options.slidesToShow == _.options.slidesToScroll && (_.slideCount - index) < _.options.slidesToShow) {
20043
20044                    allSlides
20045                        .slice(indexOffset - (_.options.slidesToShow - remainder), indexOffset + remainder)
20046                        .addClass('slick-active')
20047                        .attr('aria-hidden', 'false');
20048
20049                } else {
20050
20051                    allSlides
20052                        .slice(indexOffset, indexOffset + _.options.slidesToShow)
20053                        .addClass('slick-active')
20054                        .attr('aria-hidden', 'false');
20055
20056                }
20057
20058            }
20059
20060        }
20061
20062        if (_.options.lazyLoad === 'ondemand') {
20063            _.lazyLoad();
20064        }
20065
20066    };
20067
20068    Slick.prototype.setupInfinite = function () {
20069
20070        var _ = this,
20071            i, slideIndex, infiniteCount;
20072
20073        if (_.options.fade === true) {
20074            _.options.centerMode = false;
20075        }
20076
20077        if (_.options.infinite === true && _.options.fade === false) {
20078
20079            slideIndex = null;
20080
20081            if (_.slideCount > _.options.slidesToShow) {
20082
20083                if (_.options.centerMode === true) {
20084                    infiniteCount = _.options.slidesToShow + 1;
20085                } else {
20086                    infiniteCount = _.options.slidesToShow;
20087                }
20088
20089                for (i = _.slideCount; i > (_.slideCount -
20090                    infiniteCount); i -= 1) {
20091                    slideIndex = i - 1;
20092                    $(_.$slides[slideIndex]).clone(true).attr('id', '')
20093                        .attr('data-slick-index', slideIndex - _.slideCount)
20094                        .prependTo(_.$slideTrack).addClass('slick-cloned');
20095                }
20096                for (i = 0; i < infiniteCount; i += 1) {
20097                    slideIndex = i;
20098                    $(_.$slides[slideIndex]).clone(true).attr('id', '')
20099                        .attr('data-slick-index', slideIndex + _.slideCount)
20100                        .appendTo(_.$slideTrack).addClass('slick-cloned');
20101                }
20102                _.$slideTrack.find('.slick-cloned').find('[id]').each(function () {
20103                    $(this).attr('id', '');
20104                });
20105
20106            }
20107
20108        }
20109
20110    };
20111
20112    Slick.prototype.interrupt = function (toggle) {
20113
20114        var _ = this;
20115
20116        if (!toggle) {
20117            _.autoPlay();
20118        }
20119        _.interrupted = toggle;
20120
20121    };
20122
20123    Slick.prototype.selectHandler = function (event) {
20124
20125        var _ = this;
20126
20127        var targetElement =
20128            $(event.target).is('.slick-slide') ?
20129                $(event.target) :
20130                $(event.target).parents('.slick-slide');
20131
20132        var index = parseInt(targetElement.attr('data-slick-index'));
20133
20134        if (!index) index = 0;
20135
20136        if (_.slideCount <= _.options.slidesToShow) {
20137
20138            _.setSlideClasses(index);
20139            _.asNavFor(index);
20140            return;
20141
20142        }
20143
20144        _.slideHandler(index);
20145
20146    };
20147
20148    Slick.prototype.slideHandler = function (index, sync, dontAnimate) {
20149
20150        var targetSlide, animSlide, oldSlide, slideLeft, targetLeft = null,
20151            _ = this, navTarget;
20152
20153        sync = sync || false;
20154
20155        if (_.animating === true && _.options.waitForAnimate === true) {
20156            return;
20157        }
20158
20159        if (_.options.fade === true && _.currentSlide === index) {
20160            return;
20161        }
20162
20163        if (_.slideCount <= _.options.slidesToShow) {
20164            return;
20165        }
20166
20167        if (sync === false) {
20168            _.asNavFor(index);
20169        }
20170
20171        targetSlide = index;
20172        targetLeft = _.getLeft(targetSlide);
20173        slideLeft = _.getLeft(_.currentSlide);
20174
20175        _.currentLeft = _.swipeLeft === null ? slideLeft : _.swipeLeft;
20176
20177        if (_.options.infinite === false && _.options.centerMode === false && (index < 0 || index > _.getDotCount() * _.options.slidesToScroll)) {
20178            if (_.options.fade === false) {
20179                targetSlide = _.currentSlide;
20180                if (dontAnimate !== true) {
20181                    _.animateSlide(slideLeft, function () {
20182                        _.postSlide(targetSlide);
20183                    });
20184                } else {
20185                    _.postSlide(targetSlide);
20186                }
20187            }
20188            return;
20189        } else if (_.options.infinite === false && _.options.centerMode === true && (index < 0 || index > (_.slideCount - _.options.slidesToScroll))) {
20190            if (_.options.fade === false) {
20191                targetSlide = _.currentSlide;
20192                if (dontAnimate !== true) {
20193                    _.animateSlide(slideLeft, function () {
20194                        _.postSlide(targetSlide);
20195                    });
20196                } else {
20197                    _.postSlide(targetSlide);
20198                }
20199            }
20200            return;
20201        }
20202
20203        if (_.options.autoplay) {
20204            clearInterval(_.autoPlayTimer);
20205        }
20206
20207        if (targetSlide < 0) {
20208            if (_.slideCount % _.options.slidesToScroll !== 0) {
20209                animSlide = _.slideCount - (_.slideCount % _.options.slidesToScroll);
20210            } else {
20211                animSlide = _.slideCount + targetSlide;
20212            }
20213        } else if (targetSlide >= _.slideCount) {
20214            if (_.slideCount % _.options.slidesToScroll !== 0) {
20215                animSlide = 0;
20216            } else {
20217                animSlide = targetSlide - _.slideCount;
20218            }
20219        } else {
20220            animSlide = targetSlide;
20221        }
20222
20223        _.animating = true;
20224
20225        _.$slider.trigger('beforeChange', [_, _.currentSlide, animSlide]);
20226
20227        oldSlide = _.currentSlide;
20228        _.currentSlide = animSlide;
20229
20230        _.setSlideClasses(_.currentSlide);
20231
20232        if (_.options.asNavFor) {
20233
20234            navTarget = _.getNavTarget();
20235            navTarget = navTarget.slick('getSlick');
20236
20237            if (navTarget.slideCount <= navTarget.options.slidesToShow) {
20238                navTarget.setSlideClasses(_.currentSlide);
20239            }
20240
20241        }
20242
20243        _.updateDots();
20244        _.updateArrows();
20245
20246        if (_.options.fade === true) {
20247            if (dontAnimate !== true) {
20248
20249                _.fadeSlideOut(oldSlide);
20250
20251                _.fadeSlide(animSlide, function () {
20252                    _.postSlide(animSlide);
20253                });
20254
20255            } else {
20256                _.postSlide(animSlide);
20257            }
20258            _.animateHeight();
20259            return;
20260        }
20261
20262        if (dontAnimate !== true) {
20263            _.animateSlide(targetLeft, function () {
20264                _.postSlide(animSlide);
20265            });
20266        } else {
20267            _.postSlide(animSlide);
20268        }
20269
20270    };
20271
20272    Slick.prototype.startLoad = function () {
20273
20274        var _ = this;
20275
20276        if (_.options.arrows === true && _.slideCount > _.options.slidesToShow) {
20277
20278            _.$prevArrow.hide();
20279            _.$nextArrow.hide();
20280
20281        }
20282
20283        if (_.options.dots === true && _.slideCount > _.options.slidesToShow) {
20284
20285            _.$dots.hide();
20286
20287        }
20288
20289        _.$slider.addClass('slick-loading');
20290
20291    };
20292
20293    Slick.prototype.swipeDirection = function () {
20294
20295        var xDist, yDist, r, swipeAngle, _ = this;
20296
20297        xDist = _.touchObject.startX - _.touchObject.curX;
20298        yDist = _.touchObject.startY - _.touchObject.curY;
20299        r = Math.atan2(yDist, xDist);
20300
20301        swipeAngle = Math.round(r * 180 / Math.PI);
20302        if (swipeAngle < 0) {
20303            swipeAngle = 360 - Math.abs(swipeAngle);
20304        }
20305
20306        if ((swipeAngle <= 45) && (swipeAngle >= 0)) {
20307            return (_.options.rtl === false ? 'left' : 'right');
20308        }
20309        if ((swipeAngle <= 360) && (swipeAngle >= 315)) {
20310            return (_.options.rtl === false ? 'left' : 'right');
20311        }
20312        if ((swipeAngle >= 135) && (swipeAngle <= 225)) {
20313            return (_.options.rtl === false ? 'right' : 'left');
20314        }
20315        if (_.options.verticalSwiping === true) {
20316            if ((swipeAngle >= 35) && (swipeAngle <= 135)) {
20317                return 'down';
20318            } else {
20319                return 'up';
20320            }
20321        }
20322
20323        return 'vertical';
20324
20325    };
20326
20327    Slick.prototype.swipeEnd = function (event) {
20328
20329        var _ = this,
20330            slideCount,
20331            direction;
20332
20333        _.dragging = false;
20334        _.interrupted = false;
20335        _.shouldClick = (_.touchObject.swipeLength > 10) ? false : true;
20336
20337        if (_.touchObject.curX === undefined) {
20338            return false;
20339        }
20340
20341        if (_.touchObject.edgeHit === true) {
20342            _.$slider.trigger('edge', [_, _.swipeDirection()]);
20343        }
20344
20345        if (_.touchObject.swipeLength >= _.touchObject.minSwipe) {
20346
20347            direction = _.swipeDirection();
20348
20349            switch (direction) {
20350
20351                case 'left':
20352                case 'down':
20353
20354                    slideCount =
20355                        _.options.swipeToSlide ?
20356                            _.checkNavigable(_.currentSlide + _.getSlideCount()) :
20357                            _.currentSlide + _.getSlideCount();
20358
20359                    _.currentDirection = 0;
20360
20361                    break;
20362
20363                case 'right':
20364                case 'up':
20365
20366                    slideCount =
20367                        _.options.swipeToSlide ?
20368                            _.checkNavigable(_.currentSlide - _.getSlideCount()) :
20369                            _.currentSlide - _.getSlideCount();
20370
20371                    _.currentDirection = 1;
20372
20373                    break;
20374
20375                default:
20376
20377
20378            }
20379
20380            if (direction != 'vertical') {
20381
20382                _.slideHandler(slideCount);
20383                _.touchObject = {};
20384                _.$slider.trigger('swipe', [_, direction]);
20385
20386            }
20387
20388        } else {
20389
20390            if (_.touchObject.startX !== _.touchObject.curX) {
20391
20392                _.slideHandler(_.currentSlide);
20393                _.touchObject = {};
20394
20395            }
20396
20397        }
20398
20399    };
20400
20401    Slick.prototype.swipeHandler = function (event) {
20402
20403        var _ = this;
20404
20405        if ((_.options.swipe === false) || ('ontouchend' in document && _.options.swipe === false)) {
20406            return;
20407        } else if (_.options.draggable === false && event.type.indexOf('mouse') !== -1) {
20408            return;
20409        }
20410
20411        _.touchObject.fingerCount = event.originalEvent && event.originalEvent.touches !== undefined ?
20412            event.originalEvent.touches.length : 1;
20413
20414        _.touchObject.minSwipe = _.listWidth / _.options
20415            .touchThreshold;
20416
20417        if (_.options.verticalSwiping === true) {
20418            _.touchObject.minSwipe = _.listHeight / _.options
20419                .touchThreshold;
20420        }
20421
20422        switch (event.data.action) {
20423
20424            case 'start':
20425                _.swipeStart(event);
20426                break;
20427
20428            case 'move':
20429                _.swipeMove(event);
20430                break;
20431
20432            case 'end':
20433                _.swipeEnd(event);
20434                break;
20435
20436        }
20437
20438    };
20439
20440    Slick.prototype.swipeMove = function (event) {
20441
20442        var _ = this,
20443            edgeWasHit = false,
20444            curLeft, swipeDirection, swipeLength, positionOffset, touches;
20445
20446        touches = event.originalEvent !== undefined ? event.originalEvent.touches : null;
20447
20448        if (!_.dragging || touches && touches.length !== 1) {
20449            return false;
20450        }
20451
20452        curLeft = _.getLeft(_.currentSlide);
20453
20454        _.touchObject.curX = touches !== undefined ? touches[0].pageX : event.clientX;
20455        _.touchObject.curY = touches !== undefined ? touches[0].pageY : event.clientY;
20456
20457        _.touchObject.swipeLength = Math.round(Math.sqrt(
20458            Math.pow(_.touchObject.curX - _.touchObject.startX, 2)));
20459
20460        if (_.options.verticalSwiping === true) {
20461            _.touchObject.swipeLength = Math.round(Math.sqrt(
20462                Math.pow(_.touchObject.curY - _.touchObject.startY, 2)));
20463        }
20464
20465        swipeDirection = _.swipeDirection();
20466
20467        if (swipeDirection === 'vertical') {
20468            return;
20469        }
20470
20471        if (event.originalEvent !== undefined && _.touchObject.swipeLength > 4) {
20472            event.preventDefault();
20473        }
20474
20475        positionOffset = (_.options.rtl === false ? 1 : -1) * (_.touchObject.curX > _.touchObject.startX ? 1 : -1);
20476        if (_.options.verticalSwiping === true) {
20477            positionOffset = _.touchObject.curY > _.touchObject.startY ? 1 : -1;
20478        }
20479
20480
20481        swipeLength = _.touchObject.swipeLength;
20482
20483        _.touchObject.edgeHit = false;
20484
20485        if (_.options.infinite === false) {
20486            if ((_.currentSlide === 0 && swipeDirection === 'right') || (_.currentSlide >= _.getDotCount() && swipeDirection === 'left')) {
20487                swipeLength = _.touchObject.swipeLength * _.options.edgeFriction;
20488                _.touchObject.edgeHit = true;
20489            }
20490        }
20491
20492        if (_.options.vertical === false) {
20493            _.swipeLeft = curLeft + swipeLength * positionOffset;
20494        } else {
20495            _.swipeLeft = curLeft + (swipeLength * (_.$list.height() / _.listWidth)) * positionOffset;
20496        }
20497        if (_.options.verticalSwiping === true) {
20498            _.swipeLeft = curLeft + swipeLength * positionOffset;
20499        }
20500
20501        if (_.options.fade === true || _.options.touchMove === false) {
20502            return false;
20503        }
20504
20505        if (_.animating === true) {
20506            _.swipeLeft = null;
20507            return false;
20508        }
20509
20510        _.setCSS(_.swipeLeft);
20511
20512    };
20513
20514    Slick.prototype.swipeStart = function (event) {
20515
20516        var _ = this,
20517            touches;
20518
20519        _.interrupted = true;
20520
20521        if (_.touchObject.fingerCount !== 1 || _.slideCount <= _.options.slidesToShow) {
20522            _.touchObject = {};
20523            return false;
20524        }
20525
20526        if (event.originalEvent !== undefined && event.originalEvent.touches !== undefined) {
20527            touches = event.originalEvent.touches[0];
20528        }
20529
20530        _.touchObject.startX = _.touchObject.curX = touches !== undefined ? touches.pageX : event.clientX;
20531        _.touchObject.startY = _.touchObject.curY = touches !== undefined ? touches.pageY : event.clientY;
20532
20533        _.dragging = true;
20534
20535    };
20536
20537    Slick.prototype.unfilterSlides = Slick.prototype.slickUnfilter = function () {
20538
20539        var _ = this;
20540
20541        if (_.$slidesCache !== null) {
20542
20543            _.unload();
20544
20545            _.$slideTrack.children(this.options.slide).detach();
20546
20547            _.$slidesCache.appendTo(_.$slideTrack);
20548
20549            _.reinit();
20550
20551        }
20552
20553    };
20554
20555    Slick.prototype.unload = function () {
20556
20557        var _ = this;
20558
20559        $('.slick-cloned', _.$slider).remove();
20560
20561        if (_.$dots) {
20562            _.$dots.remove();
20563        }
20564
20565        if (_.$prevArrow && _.htmlExpr.test(_.options.prevArrow)) {
20566            _.$prevArrow.remove();
20567        }
20568
20569        if (_.$nextArrow && _.htmlExpr.test(_.options.nextArrow)) {
20570            _.$nextArrow.remove();
20571        }
20572
20573        _.$slides
20574            .removeClass('slick-slide slick-active slick-visible slick-current')
20575            .attr('aria-hidden', 'true')
20576            .css('width', '');
20577
20578    };
20579
20580    Slick.prototype.unslick = function (fromBreakpoint) {
20581
20582        var _ = this;
20583        _.$slider.trigger('unslick', [_, fromBreakpoint]);
20584        _.destroy();
20585
20586    };
20587
20588    Slick.prototype.updateArrows = function () {
20589
20590        var _ = this,
20591            centerOffset;
20592
20593        centerOffset = Math.floor(_.options.slidesToShow / 2);
20594
20595        if (_.options.arrows === true &&
20596            _.slideCount > _.options.slidesToShow &&
20597            !_.options.infinite) {
20598
20599            _.$prevArrow.removeClass('slick-disabled').attr('aria-disabled', 'false');
20600            _.$nextArrow.removeClass('slick-disabled').attr('aria-disabled', 'false');
20601
20602            if (_.currentSlide === 0) {
20603
20604                _.$prevArrow.addClass('slick-disabled').attr('aria-disabled', 'true');
20605                _.$nextArrow.removeClass('slick-disabled').attr('aria-disabled', 'false');
20606
20607            } else if (_.currentSlide >= _.slideCount - _.options.slidesToShow && _.options.centerMode === false) {
20608
20609                _.$nextArrow.addClass('slick-disabled').attr('aria-disabled', 'true');
20610                _.$prevArrow.removeClass('slick-disabled').attr('aria-disabled', 'false');
20611
20612            } else if (_.currentSlide >= _.slideCount - 1 && _.options.centerMode === true) {
20613
20614                _.$nextArrow.addClass('slick-disabled').attr('aria-disabled', 'true');
20615                _.$prevArrow.removeClass('slick-disabled').attr('aria-disabled', 'false');
20616
20617            }
20618
20619        }
20620
20621    };
20622
20623    Slick.prototype.updateDots = function () {
20624
20625        var _ = this;
20626
20627        if (_.$dots !== null) {
20628
20629            _.$dots
20630                .find('li')
20631                .removeClass('slick-active')
20632                .attr('aria-hidden', 'true');
20633
20634            _.$dots
20635                .find('li')
20636                .eq(Math.floor(_.currentSlide / _.options.slidesToScroll))
20637                .addClass('slick-active')
20638                .attr('aria-hidden', 'false');
20639
20640        }
20641
20642    };
20643
20644    Slick.prototype.visibility = function () {
20645
20646        var _ = this;
20647
20648        if (_.options.autoplay) {
20649
20650            if (document[_.hidden]) {
20651
20652                _.interrupted = true;
20653
20654            } else {
20655
20656                _.interrupted = false;
20657
20658            }
20659
20660        }
20661
20662    };
20663
20664    $.fn.slick = function () {
20665        var _ = this,
20666            opt = arguments[0],
20667            args = Array.prototype.slice.call(arguments, 1),
20668            l = _.length,
20669            i,
20670            ret;
20671        for (i = 0; i < l; i++) {
20672            if (typeof opt == 'object' || typeof opt == 'undefined')
20673                _[i].slick = new Slick(_[i], opt);
20674            else
20675                ret = _[i].slick[opt].apply(_[i].slick, args);
20676            if (typeof ret != 'undefined') return ret;
20677        }
20678        return _;
20679    };
20680
20681}));
20682
20683var openHotplug = function () {
20684    var element = $(this).parents('.toggle-container');
20685    //element.find(element.data('toggle')).slideToggle();
20686    element.toggleClass('active');
20687}
20688/* Hotplug on right side */
20689$(document).ready(function () {
20690    $('.toggle-hover').on('mouseenter mouseleave', openHotplug);
20691    $('.toggle-button').on('click', openHotplug);
20692});
20693
20694/* Normal toggle Buttons */
20695$(document).ready(function () {
20696    $('.toggle-div-button').on('click', function (e) {
20697        $(this).toggleClass('active');
20698        $($(this).data('toggle')).slideToggle();
20699        if (!$(this).hasClass('no-anchor')) {
20700            $(window).scrollTop($($(this).data('toggle')).position().top);
20701        }
20702        e.preventDefault();
20703    });
20704});
20705
20706/* Phone toggle Button */
20707$(document).ready(function () {
20708    $('.toggle-phone-button').on('click', function (e) {
20709        $(this).parents('.phone-button').toggleClass('active');
20710        $('body').toggleClass('noscroll');
20711        $($(this).data('toggle')).slideToggle();
20712        $(window).scrollTop($($(this).data('toggle')).position().top);
20713        e.preventDefault();
20714    });
20715});
20716
20717/* Responsive Menu toggling */
20718$(document).ready(function () {
20719    /* Top-Menu */
20720    $('ul.list-top > li.menu-item > a').on('click', function (e) {
20721        if ($(window).width() < 993) {
20722            if ($(
20723                this).next('ul.sub-menu').length > 0) {
20724                e.preventDefault();
20725            }
20726            $(this).parent().siblings().removeClass('active');
20727            $(this).parent().toggleClass('active');
20728            $(this).parent().siblings().not('active').children('ul.sub-menu').hide();
20729            $(this).next('ul.sub-menu').slideToggle();
20730        }
20731    });
20732
20733    /* Bottom-Menu */
20734    $('#footer-navigation ul.main > li > a').on('click', function (e) {
20735        if ($(window).width() < 993) {
20736            if ($(this).next('ul').length > 0) {
20737                e.preventDefault();
20738            }
20739            $(this).parent().siblings().removeClass('active');
20740            $(this).parent().toggleClass('active');
20741            $(this).parent().siblings().not('active').children('ul').hide();
20742            $(this).next('ul').slideToggle();
20743        }
20744    });
20745
20746    /* Top-Menu inset close button */
20747    if ($(window).width() < 993) {
20748        var closeli = $(document.createElement('li'))
20749            .addClass('close')
20750            .html('<i class="fa fa-times" aria-hidden="true"></i>')
20751            .click(function () {
20752                $('#top-nav').slideUp();
20753            });
20754        $('#top-nav .list-top').prepend(closeli);
20755    }
20756
20757    /* Rearrange Contact-Container */
20758    if ($(window).width() < 768) {
20759        var container = $('#mega-menu-contact');
20760        container.detach();
20761        container.addClass('scrollable');
20762        container.insertAfter($('.phone-button'));
20763    }
20764    if ($(window).width() < 768) {
20765        var scrollTop = 0;
20766        if ($('.info-button').length) {
20767            $(window).scroll(function () {
20768                /* Check scroll Direction */
20769                var ScrollDifference = $(window).scrollTop() - scrollTop;
20770                scrollTop = $(window).scrollTop();
20771
20772                if (ScrollDifference < 0) {
20773                    var y = $('.info-button').offset().top;
20774                    var ry = $('.right-menu').offset().top;
20775                    if (y < ry - 50) {
20776                        $('.info-button').css({'opacity': 1});
20777                    }
20778                } else {
20779                    var y = $('.info-button').offset().top;
20780                    var ry = $('.right-menu').offset().top
20781                    if (y > ry - 50) {
20782                        $('.info-button').css({'opacity': 0});
20783                    }
20784                }
20785            });
20786        }
20787    }
20788
20789    if ($(window).width() < 993) {
20790        $('#sidebar-nav-title').on('click', function (e) {
20791            e.preventDefault();
20792            if (!$('body').hasClass('no-left-menu')) {
20793                $('#sidebar-navigation').slideToggle();
20794                $('#sidebar-nav-title').toggleClass('active');
20795            }
20796        });
20797    }
20798
20799    if ($(window).width() < 993) {
20800        var container = $('.left-menu');
20801        container.detach();
20802        $('#logobar').append(container);
20803    }
20804
20805    $(document).on('click', 'a.smoothscroll', function (event) {
20806        event.preventDefault();
20807        $('html, body').animate({
20808            scrollTop: $($.attr(this, 'href')).offset().top
20809        }, 500);
20810    });
20811    /* Search bar UI autocomplete */
20812    jQuery('#search-bar-desktop').autocomplete({
20813        contentType: 'application/json; charset=utf-8',
20814        source: function (request, response) {
20815            $.post('/index.php?eID=na5108ajaxsearch', {sWord: request.term}, function (data) {
20816                var obj = jQuery.parseJSON(data);
20817                var ui = [];
20818                $.each(obj, function (i, k) {
20819                    var p = 0;
20820                    var p_title = 0;
20821                    var permalink = 0;
20822                    if (k.hasOwnProperty('data_page_id')) {
20823                        p = k.data_page_id;
20824                    }
20825                    if (k.hasOwnProperty('item_title')) {
20826                        p_title = k.item_title;
20827                    }
20828                    if (k.hasOwnProperty('page_permalink')) {
20829                        permalink = k.page_permalink;
20830                    }
20831                    ui.push({
20832                        'label': k.baseword,
20833                        'value': k.baseword,
20834                        'page_id': p,
20835                        'page_title': p_title,
20836                        'permalink': permalink
20837                    });
20838
20839                });
20840                response(ui);
20841            });
20842        },
20843        minLength: 3,
20844        select: function (event, ui) {
20845            if (ui.item.page_id != 0) {
20846                window.location.href = ui.item.permalink;
20847            } else {
20848                $('#search-bar-desktop').val(ui.item.label);
20849                $('#header-search').submit();
20850            }
20851        }
20852    }).autocomplete("instance")._renderItem = function (ul, item) {
20853        var obj = $("<li></li>");
20854        var outer = $('<div></div>');
20855        var html = item.label;
20856        var inner = $('<span></span>');
20857        var small = $('<span></span>');
20858        outer.addClass('ui-menu-item-wrapper');
20859        if (item.page_id != 0) {
20860            // inner.addClass('direct-link');
20861            small.addClass('small')
20862                .html('Seite: ' + item.page_title);
20863        } else {
20864            small.addClass('small')
20865                .html('alle Suchergebnisse');
20866        }
20867        inner.html(html);
20868        inner.appendTo(outer);
20869        if (small.html() != '') {
20870            small.appendTo(outer);
20871        }
20872        outer.appendTo(obj);
20873        obj.appendTo(ul);
20874        return obj;
20875    };
20876
20877    $('[href$=".jpg"],[href$=".gif"],[href$=".png"],[href$=".JPG"],[href$=".jpeg"]').attr('data-fancybox', 'gallery').fancybox();
20878
20879    /*$('#main-content .csc-textpic-imagewrap').each(function() { //.csc-textpic-imagecolumn
20880			if( $(this).width() > $('#main-content').width() ) {
20881					$(this).addClass('size-down');
20882			}
20883	});*/
20884});
20885
20886$(window).on('load', function () {
20887    $('.full-picture').find('img').each(function () {
20888        var imgClass = (this.width / this.height > 1) ? 'wide' : 'tall';
20889        $(this).addClass(imgClass);
20890    })
20891});
20892$(document).ready(function () {
20893    var total = $('.fena-slider img').length,
20894        rand = Math.floor(Math.random() * total);
20895
20896    $('.fena-slider').slick({
20897        accessibility: false,
20898        autoplay: true,
20899        autoplaySpeed: 15000,
20900        arrows: false,
20901        fade: true,
20902        initialSlide: rand
20903    });
20904
20905    $('.image-slider, .csc-textpic-imagewrap[data-csc-cols="1"] .csc-textpic-center-inner').slick({
20906        arrows: true,
20907        adaptiveHeight: true,
20908        dots: true,
20909        responsive: [
20910            {
20911                breakpoint: 768,
20912                settings: {
20913                    arrows: false,
20914                }
20915            },
20916        ]
20917    });
20918});
20919
20920$(document).ready(function () {
20921    /* Global Vars */
20922    var titleLinks = [];
20923    var showTitle = false;
20924    var titleText = false;
20925    var titleToggle = false;
20926    var scrollTop = 0;
20927
20928    $('.scrolling-header').find('a').click(function (e) {
20929        e.preventDefault();
20930        if ($(this).attr('data-target') != undefined) {
20931            $('.scrolling-header').removeClass('active');
20932            $('.target-groups-content').prev('a').removeClass('active');
20933            $('.target-groups-content').slideUp();
20934            $(window).scrollTop($('.target-groups-content').prev('a').offset().top);
20935            showTitle = false;
20936            titleLinks = [];
20937        }
20938    });
20939
20940    /* Tab Navigation using location.hash */
20941    $('.tab-list').each(function () {
20942        var $active, $content, $links = $(this).find('a');
20943
20944        $active = $($links.filter('[href="' + location.hash + '"]')[0] || $links[0]);
20945        $active.addClass('active');
20946
20947        $content = $('.' + $active[0].hash.substr(1, $active[0].hash.length));
20948        $content.addClass('active');
20949
20950        $links.not($active).each(function () {
20951            $('.' + this.hash.substr(1, this.hash.length)).hide();
20952        });
20953
20954        $(this).on('click', 'a', function (e) {
20955            $active.removeClass('active');
20956            $content.removeClass('active');
20957            $content.hide();
20958
20959            $active = $(this);
20960            $content = $('.' + this.hash.substr(1, this.hash.length));
20961
20962            $active.addClass('active');
20963            $content.show();
20964            $content.addClass('active');
20965
20966            e.preventDefault();
20967        });
20968    });
20969
20970    /* Tab Navigation using data-target Attribute */
20971    $('.target-list').each(function () {
20972        var $active, $content, $links = $(this).find('a');
20973
20974        if (typeof ($active) != 'undefined') {
20975            $active = $($links.filter('[data-target="' + $active.attr('data-target') + '"]')[0]);
20976        } else {
20977            $active = $($links[0]);
20978        }
20979
20980        if ($(window).width() > 992) {
20981            $active.addClass('active');
20982        }
20983
20984        $content = $('.' + $($active).attr('data-target'));
20985
20986        $links.not($active).each(function () {
20987            $('.' + $(this).attr('data-target')).hide();
20988        });
20989
20990        $(this).on('click', 'a', function (e) {
20991            $content.hide();
20992            $content = $('.' + $(this).attr('data-target'));
20993            if ($(window).width() <= 992 && $(this).hasClass('active')) {
20994                $('.target-groups-content').hide();
20995                $('.phone-button').removeClass('visible');
20996                $('.scrolling-header').removeClass('active');
20997                $content.hide();
20998                $('#mega-menu-header').hide();
20999                $active.removeClass('active');
21000                showTitle = false;
21001                titleLinks = [];
21002            } else {
21003                $active.removeClass('active');
21004                $active = $(this);
21005                if ($(window).width() <= 992) {
21006                    $(window).scrollTop($(this).offset().top - $('#logobar').outerHeight() - 10);
21007                    $container = $('.target-groups-content');
21008                    $container2 = $('#mega-menu-header');
21009                    $container.detach();
21010                    $container2.detach();
21011                    $container.insertAfter($active);
21012                    $container2.insertAfter($active);
21013                    $container.slideDown();
21014                    $container2.slideDown();
21015                    $('.phone-button').addClass('visible');
21016                }
21017                $active.addClass('active');
21018                $content.show();
21019            }
21020            e.preventDefault();
21021        });
21022    });
21023
21024    /* Front-Page Menu-Scrolling, Desktop only */
21025    if ($(window).width() > 992) {
21026        /* Set Initial Containerheight */
21027        $('#menu-container-wrap').height($('#menu-container').outerHeight());
21028        $('#menu-container').addClass("absolute");
21029
21030        $(window).scroll(function () {
21031            /* Check scroll Direction */
21032            var ScrollDifference = $(window).scrollTop() - scrollTop;
21033            scrollTop = $(window).scrollTop();
21034
21035            if (ScrollDifference < 0) {
21036                $('#menu-container')
21037                    .css('top', 0)
21038                    .addClass("fixed")
21039                    .removeClass("absolute")
21040                    .data('toppos', scrollTop);
21041            } else {
21042                var top = $('#menu-container').data('toppos');
21043                $('#menu-container')
21044                    .css('top', top)
21045                    .removeClass("fixed")
21046                    .addClass("absolute");
21047            }
21048        });
21049    }
21050
21051    /* Front-Page headlines scrolling, responsive only */
21052    if ($(window).width() <= 992) {
21053        /* Set Initial Containerheight */
21054        $('#logobar-wrap').height($('#logobar').outerHeight());
21055        $('#logobar').addClass("absolute");
21056
21057        $(window).scroll(function () {
21058            /* Check scroll Direction */
21059            var ScrollDifference = $(window).scrollTop() - scrollTop;
21060            scrollTop = $(window).scrollTop();
21061
21062            if (ScrollDifference < 0) {
21063                $('#logobar')
21064                    .css('top', 0)
21065                    .addClass("fixed")
21066                    .removeClass("absolute")
21067                    .data('toppos', scrollTop);
21068            } else {
21069                var top = $('#logobar').data('toppos');
21070                $('#logobar')
21071                    .css('top', top)
21072                    .removeClass("fixed")
21073                    .addClass("absolute");
21074            }
21075
21076            titleLinks = $('.front-page').find('#target-groups div.active .target-list li a.active');
21077
21078            if (titleLinks.length > 0) {
21079                titleLinks.each(function () {
21080                    if (($(this).offset().top + $(this).outerHeight()) < $(window).scrollTop()) {
21081                        showTitle = true;
21082                        titleText = $(this).text();
21083                        titleToggle = $(this).attr('data-target');
21084                    }
21085
21086                    if ($(this).offset().top >= $(window).scrollTop()) {
21087                        showTitle = false;
21088                    }
21089
21090                    var bottom = $(this).parent().offset().top + $(this).parent().outerHeight() - $('.scrolling-header').outerHeight();
21091
21092                    if (bottom < $(window).scrollTop()) {
21093                        showTitle = false;
21094                    }
21095
21096                });
21097            }
21098
21099            if (showTitle) {
21100                $('.scrolling-header').addClass('active');
21101                $('.scrolling-header').find('a').html(titleText);
21102                $('.scrolling-header').find('a').attr('data-target', titleToggle);
21103            } else {
21104                $('.scrolling-header').removeClass('active');
21105            }
21106        });
21107    }
21108});
21109
21110
21111function traverseTree(obj, id) {
21112    if (jQuery.inArray(id, obj.identifier) !== -1 && obj.identifier.length > 0) {
21113        return obj;
21114    }
21115    var result, p;
21116    for (p in obj) {
21117        if (obj.hasOwnProperty(p) && typeof obj[p] === 'object') {
21118            result = traverseTree(obj[p], id);
21119            if (result) {
21120                return result;
21121            }
21122        }
21123    }
21124    return result;
21125}
21126
21127$(document).ready(function () {
21128    /* This is to fill with Data */
21129    $('#TRIGGER').children().each(function () {
21130        var id = $(this).attr('id');
21131        var search = '#' + $(this).attr('id');
21132        var obj = traverseTree(Campus, search);
21133        // console.log(search);
21134        // console.log(obj.name);
21135
21136        var label = $(document.createElement('div'))
21137            .addClass("map-label")
21138            // .html('<p><strong>'+obj.name+'</strong></p><p>' + obj.short_description + '</p>')
21139            // .html('<p><strong>'+obj.name+'</strong></p>')
21140            .html('<p><strong>' + obj.name + '</strong></p><div>' + obj.description + '</div>')
21141            .attr('id', id + '-label');
21142        $('.label-list').append(label);
21143
21144        $('.poi-list').append(createPOI(id, obj));
21145
21146        if (obj.description && obj.description.length > 0) {
21147            var desc = $(document.createElement('div'))
21148                .addClass("map-description")
21149                // .html('<h3>'+obj.name+'</h3><h4>'+ obj.short_description +'</h4><p>' + obj.description + '</p>')
21150                // .html('<h3>'+ obj.short_description +' <small>('+obj.name+')</small></h3><p>' + obj.description + '</p>')
21151                .html('<h3>' + obj.name + '</h3><div>' + obj.description + '</div>')
21152                .attr('id', id + '-description');
21153
21154            $('.description-list').append(desc);
21155        }
21156    });
21157
21158    $('.floorplan-overlay').each(function () {
21159        var $house = $(this).data('house');
21160        var ul = $(document.createElement('ul')).addClass('floorList');
21161        $('#' + $house + '-building').parent().append(ul);
21162        $(this).find('.floor').each(function () {
21163            var search = '#' + $(this).attr('id');
21164            var obj = traverseTree(Campus, search);
21165            var li = createPOI($(this).attr('id'), obj);
21166            $(li).attr('data-target', $(this).attr('id'));
21167            $(ul).append(li);
21168
21169            var ulr = $(document.createElement('ul')).addClass('roomList');
21170            $('#' + $(this).attr('id') + '-' + obj.type).parent().append(ulr);
21171            $(this).find('#TRIGGER').children().each(function () {
21172                var search = '#' + $(this).attr('id');
21173                var obj = traverseTree(Campus, search);
21174                if (typeof obj !== 'undefined') {
21175                    $(ulr).append(createPOI($(this).attr('id'), obj));
21176
21177                    var label = $(document.createElement('div'))
21178                        .addClass("map-label")
21179                        .html('<p><strong>' + obj.name + '</strong></p><p>' + obj.short_description + '</p>')
21180                        .attr('id', $(this).attr('id') + '-label');
21181                    $('.label-list').append(label);
21182                }
21183            });
21184        });
21185    });
21186
21187    /* This is functionality */
21188    /* Triggers on Area-Overview */
21189    $('.playground #TRIGGER').children().hover(
21190        function (e) {
21191            var c = '#' + $(this).attr('id') + '-label';
21192            var l = '#' + $(this).attr('id') + '-building';
21193            $(l).addClass('active');
21194            $(c).stop().fadeIn('fast');
21195            if (e.pageX > ($(window).width() * .5)) {
21196                l = e.pageX - ($(c).width() + 10);
21197            }
21198            $(c).offset({left: l, top: e.pageY + 10});
21199        },
21200        function (e) {
21201            var c = '#' + $(this).attr('id') + '-label';
21202            var l = '#' + $(this).attr('id') + '-house-item';
21203            $(l).removeClass('active');
21204            $(c).stop().fadeOut('fast');
21205        }
21206    );
21207
21208    $('.playground #TRIGGER').children().mousemove(function (e) {
21209        var c = '#' + $(this).attr('id') + '-label';
21210        var l = e.pageX + 10;
21211        if (e.pageX > ($(window).width() * .5)) {
21212            l = e.pageX - ($(c).width() + 10);
21213        }
21214        $(c).offset({left: l, top: e.pageY + 10});
21215    });
21216
21217    $('.playground #TRIGGER').children().click(function (e) {
21218        $('#' + $(this).attr('id') + '-building').click();
21219    });
21220
21221    /* Triggers on Floorplan */
21222    $('.floor #TRIGGER').children().hover(
21223        function (e) {
21224            var c = '#' + $(this).attr('id') + '-label';
21225            var l = '#' + $(this).attr('id') + '-building';
21226            $(l).addClass('active');
21227            $(c).stop().fadeIn('fast');
21228            var l = e.pageX + 10;
21229            if (e.pageX > ($(window).width() * .5)) {
21230                l = e.pageX - ($(c).width() + 10);
21231            }
21232            $(c).offset({left: l, top: e.pageY + 10});
21233        },
21234        function (e) {
21235            var c = '#' + $(this).attr('id') + '-label';
21236            var l = '#' + $(this).attr('id') + '-house-item';
21237            $(l).removeClass('active');
21238            $(c).stop().fadeOut('fast');
21239        }
21240    );
21241
21242    $('.floor #TRIGGER').children().mousemove(function (e) {
21243        var c = '#' + $(this).attr('id') + '-label';
21244        var l = e.pageX + 10;
21245        if (e.pageX > ($(window).width() * .5)) {
21246            l = e.pageX - ($(c).width() + 10);
21247        }
21248        $(c).offset({left: l, top: e.pageY + 10});
21249    });
21250
21251    $('.floor #TRIGGER').children().click(function (e) {
21252        $('#' + $(this).attr('id') + '-building').click();
21253    });
21254
21255    $('.poi-list li a').hover(
21256        function (e) {
21257            var c = $(this).data('target');
21258            $(c).addClass('lp-active');
21259        },
21260        function (e) {
21261            var c = $(this).data('target');
21262            $(c).removeClass('lp-active');
21263        }
21264    );
21265
21266    /* $('.roomList li').hover(
21267			function(e) {
21268					// getHouseName is deleted
21269					var c = '#' + getHouseName($(this).attr('id'));
21270					$(c).addClass('active');
21271			},
21272			function(e) {
21273					// getHouseName is deleted
21274					var c = '#' + getHouseName($(this).attr('id'));
21275					$(c).removeClass('active');
21276			}
21277	);
21278
21279	$('.roomList li').click( function() {
21280			var o = '#' + $(this).parents('li').data('scroll-to');
21281			var y = $(o).offset().top - $('.floorplan-overlay').offset().top;
21282			$('.floorplan-overlay').animate({ scrollTop:y },200);
21283			$('.floorplan-overlay .room-list').animate({ top:y },200);
21284			showDescription($(this).data('hover-target'));
21285	});
21286*/
21287
21288
21289    $('.poi-list li a').click(function (e) {
21290        e.preventDefault();
21291        showDescription($(this).data('target'));
21292        if ($(this).parent().hasClass('building')) {
21293            if ($(this).next('ul.floorList').length > 0) {
21294                if (!$(this).parent().hasClass('floor-visible')) {
21295                    $(this).next('ul.floorList').find('li.floor').last().children('a').toggleClass('expanded');
21296                }
21297                $(this).next('ul.floorList').toggleClass('active');
21298                scrollIntoCenter($(this).next('ul.floorList').find('li.floor').last().data('target'));
21299                $('.building').hide();
21300                $('.map-description').hide();
21301                $(this).parents('.building').show().addClass('floor-visible');
21302                $(this).next('ul.floorList').find('.roomList').hide();
21303                $(this).next('ul.floorList').find('.roomList').last().show();
21304            } else {
21305                $('ul.floorList').removeClass('active');
21306                $('.house-item').show();
21307            }
21308        }
21309        if ($(this).parent().hasClass('floor')) {
21310            e.stopPropagation();
21311            e.preventDefault();
21312            scrollIntoCenter($(this).parent('.floor').data('target'));
21313            $('.floor a').removeClass('expanded');
21314            $(this).addClass('expanded');
21315            $('.roomList').hide();
21316            $(this).siblings('.roomList').show();
21317        }
21318        if ($(this).parent().hasClass('room')) {
21319            e.stopPropagation();
21320            e.preventDefault();
21321            scrollIntoCenter(
21322                $(this).parents('.floor').data('target')
21323            );
21324        }
21325    });
21326
21327    function showDescription(id) {
21328        var c = id + '-description';
21329        var f = id + '-floorplan';
21330        $('.map-description').hide();
21331        $(c).stop().show();
21332        if ($(f).length > 0) {
21333            $('body').addClass('floorplan-active');
21334            $(f).stop().slideDown();
21335            $('.description-list').slideUp();
21336            $('.close-floorplan').addClass('active');
21337        }
21338    }
21339
21340    function scrollIntoCenter(id) {
21341        var y = $('#' + id).position().top + $('.floorplan-overlay').scrollTop();
21342        $('.floorplan-overlay').animate({scrollTop: y}, 200);
21343    }
21344
21345    /* UNUSED, uses createPOI */
21346
21347    /* function addRoom(parent,roomList) {
21348			for(var i = 0; i < roomList.length; i++) {
21349					var id = roomList[i].id;
21350					// var li = createPOI(id,id,'room-item','-room-item');
21351					$(parent).append(li);
21352			}
21353	}
21354
21355	function addFloor(parent,obj) {
21356			var li = createPOI(obj.identifier[0],obj);
21357			$(parent).append(li);
21358	} */
21359
21360    function createPOI(id, obj) {
21361        var uuid = obj.name.replace(/\W/g, '_');
21362        var poi = $(document.createElement('li')).addClass(obj.type);
21363        var a = $(document.createElement('a'))
21364            .attr('href', '#')
21365            .attr('id', id + '-' + obj.type)
21366            .data('target', '#' + id)
21367            .html(obj.name);
21368        poi.append(a);
21369        // poi.attr('id',id+'-'+obj.type)
21370        return poi;
21371    }
21372
21373    $('.close-floorplan').click(function () {
21374        $('body').removeClass('floorplan-active');
21375        $(this).removeClass('active');
21376        $('ul.floorList').removeClass('active');
21377        $('li.floor a').removeClass('expanded');
21378        if ($(window).width() > 768) {
21379            $('.building').show();
21380        } else {
21381            $('.building').hide();
21382        }
21383        $('.floorplan-overlay').slideUp();
21384        $('.description-list').slideDown();
21385    });
21386
21387});
21388
21389/* ========================================================================
21390* Bootstrap: transition.js v3.3.7
21391* http://getbootstrap.com/javascript/#transitions
21392* ========================================================================
21393* Copyright 2011-2016 Twitter, Inc.
21394* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
21395* ======================================================================== */
21396
21397
21398+function ($) {
21399    'use strict';
21400
vendor: 8,943 bytes, lines 21401-21678
21401// CSS TRANSITION SUPPORT (Shoutout: http://www.modernizr.com/)
21402// ============================================================
21403
21404    function transitionEnd() {
21405        var el = document.createElement('bootstrap')
21406
21407        var transEndEventNames = {
21408            WebkitTransition: 'webkitTransitionEnd',
21409            MozTransition: 'transitionend',
21410            OTransition: 'oTransitionEnd otransitionend',
21411            transition: 'transitionend'
21412        }
21413
21414        for (var name in transEndEventNames) {
21415            if (el.style[name] !== undefined) {
21416                return {end: transEndEventNames[name]}
21417            }
21418        }
21419
21420        return false // explicit for ie8 (	._.)
21421    }
21422
21423// http://blog.alexmaccaw.com/css-transitions
21424    $.fn.emulateTransitionEnd = function (duration) {
21425        var called = false
21426        var $el = this
21427        $(this).one('bsTransitionEnd', function () {
21428            called = true
21429        })
21430        var callback = function () {
21431            if (!called) $($el).trigger($.support.transition.end)
21432        }
21433        setTimeout(callback, duration)
21434        return this
21435    }
21436
21437    $(function () {
21438        $.support.transition = transitionEnd()
21439
21440        if (!$.support.transition) return
21441
21442        $.event.special.bsTransitionEnd = {
21443            bindType: $.support.transition.end,
21444            delegateType: $.support.transition.end,
21445            handle: function (e) {
21446                if ($(e.target).is(this)) return e.handleObj.handler.apply(this, arguments)
21447            }
21448        }
21449    })
21450
21451}(jQuery);
21452
21453/* ========================================================================
21454* Bootstrap: collapse.js v3.3.7
21455* http://getbootstrap.com/javascript/#collapse
21456* ========================================================================
21457* Copyright 2011-2016 Twitter, Inc.
21458* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
21459* ======================================================================== */
21460
21461/* jshint latedef: false */
21462
21463+function ($) {
21464    'use strict';
21465
21466// COLLAPSE PUBLIC CLASS DEFINITION
21467// ================================
21468
21469    var Collapse = function (element, options) {
21470        this.$element = $(element)
21471        this.options = $.extend({}, Collapse.DEFAULTS, options)
21472        this.$trigger = $('[data-toggle="collapse"][href="#' + element.id + '"],' +
21473            '[data-toggle="collapse"][data-target="#' + element.id + '"]')
21474        this.transitioning = null
21475
21476        if (this.options.parent) {
21477            this.$parent = this.getParent()
21478        } else {
21479            this.addAriaAndCollapsedClass(this.$element, this.$trigger)
21480        }
21481
21482        if (this.options.toggle) this.toggle()
21483    }
21484
21485    Collapse.VERSION = '3.3.7'
21486
21487    Collapse.TRANSITION_DURATION = 350
21488
21489    Collapse.DEFAULTS = {
21490        toggle: true
21491    }
21492
21493    Collapse.prototype.dimension = function () {
21494        var hasWidth = this.$element.hasClass('width')
21495        return hasWidth ? 'width' : 'height'
21496    }
21497
21498    Collapse.prototype.show = function () {
21499        if (this.transitioning || this.$element.hasClass('in')) return
21500
21501        var activesData
21502        var actives = this.$parent && this.$parent.children('.panel').children('.in, .collapsing')
21503
21504        if (actives && actives.length) {
21505            activesData = actives.data('bs.collapse')
21506            if (activesData && activesData.transitioning) return
21507        }
21508
21509        var startEvent = $.Event('show.bs.collapse')
21510        this.$element.trigger(startEvent)
21511        if (startEvent.isDefaultPrevented()) return
21512
21513        if (actives && actives.length) {
21514            Plugin.call(actives, 'hide')
21515            activesData || actives.data('bs.collapse', null)
21516        }
21517
21518        var dimension = this.dimension()
21519
21520        this.$element
21521            .removeClass('collapse')
21522            .addClass('collapsing')[dimension](0)
21523            .attr('aria-expanded', true)
21524
21525        this.$trigger
21526            .removeClass('collapsed')
21527            .attr('aria-expanded', true)
21528
21529        this.transitioning = 1
21530
21531        var complete = function () {
21532            this.$element
21533                .removeClass('collapsing')
21534                .addClass('collapse in')[dimension]('')
21535            this.transitioning = 0
21536            this.$element
21537                .trigger('shown.bs.collapse')
21538        }
21539
21540        if (!$.support.transition) return complete.call(this)
21541
21542        var scrollSize = $.camelCase(['scroll', dimension].join('-'))
21543
21544        this.$element
21545            .one('bsTransitionEnd', $.proxy(complete, this))
21546            .emulateTransitionEnd(Collapse.TRANSITION_DURATION)[dimension](this.$element[0][scrollSize])
21547    }
21548
21549    Collapse.prototype.hide = function () {
21550        if (this.transitioning || !this.$element.hasClass('in')) return
21551
21552        var startEvent = $.Event('hide.bs.collapse')
21553        this.$element.trigger(startEvent)
21554        if (startEvent.isDefaultPrevented()) return
21555
21556        var dimension = this.dimension()
21557
21558        this.$element[dimension](this.$element[dimension]())[0].offsetHeight
21559
21560        this.$element
21561            .addClass('collapsing')
21562            .removeClass('collapse in')
21563            .attr('aria-expanded', false)
21564
21565        this.$trigger
21566            .addClass('collapsed')
21567            .attr('aria-expanded', false)
21568
21569        this.transitioning = 1
21570
21571        var complete = function () {
21572            this.transitioning = 0
21573            this.$element
21574                .removeClass('collapsing')
21575                .addClass('collapse')
21576                .trigger('hidden.bs.collapse')
21577        }
21578
21579        if (!$.support.transition) return complete.call(this)
21580
21581        this.$element
21582            [dimension](0)
21583            .one('bsTransitionEnd', $.proxy(complete, this))
21584            .emulateTransitionEnd(Collapse.TRANSITION_DURATION)
21585    }
21586
21587    Collapse.prototype.toggle = function () {
21588        this[this.$element.hasClass('in') ? 'hide' : 'show']()
21589    }
21590
21591    Collapse.prototype.getParent = function () {
21592        return $(this.options.parent)
21593            .find('[data-toggle="collapse"][data-parent="' + this.options.parent + '"]')
21594            .each($.proxy(function (i, element) {
21595                var $element = $(element)
21596                this.addAriaAndCollapsedClass(getTargetFromTrigger($element), $element)
21597            }, this))
21598            .end()
21599    }
21600
21601    Collapse.prototype.addAriaAndCollapsedClass = function ($element, $trigger) {
21602        var isOpen = $element.hasClass('in')
21603
21604        $element.attr('aria-expanded', isOpen)
21605        $trigger
21606            .toggleClass('collapsed', !isOpen)
21607            .attr('aria-expanded', isOpen)
21608    }
21609
21610    function getTargetFromTrigger($trigger) {
21611        var href
21612        var target = $trigger.attr('data-target')
21613            || (href = $trigger.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '') // strip for ie7
21614
21615        return $(target)
21616    }
21617
21618
21619// COLLAPSE PLUGIN DEFINITION
21620// ==========================
21621
21622    function Plugin(option) {
21623        return this.each(function () {
21624            var $this = $(this)
21625            var data = $this.data('bs.collapse')
21626            var options = $.extend({}, Collapse.DEFAULTS, $this.data(), typeof option == 'object' && option)
21627
21628            if (!data && options.toggle && /show|hide/.test(option)) options.toggle = false
21629            if (!data) $this.data('bs.collapse', (data = new Collapse(this, options)))
21630            if (typeof option == 'string') data[option]()
21631        })
21632    }
21633
21634    var old = $.fn.collapse
21635
21636    $.fn.collapse = Plugin
21637    $.fn.collapse.Constructor = Collapse
21638
21639
21640// COLLAPSE NO CONFLICT
21641// ====================
21642
21643    $.fn.collapse.noConflict = function () {
21644        $.fn.collapse = old
21645        return this
21646    }
21647
21648
21649// COLLAPSE DATA-API
21650// =================
21651
21652    $(document).on('click.bs.collapse.data-api', '[data-toggle="collapse"]', function (e) {
21653        var $this = $(this)
21654
21655        if (!$this.attr('data-target')) e.preventDefault()
21656
21657        var $target = getTargetFromTrigger($this)
21658        var data = $target.data('bs.collapse')
21659        var option = data ? 'toggle' : $this.data()
21660
21661        Plugin.call($target, option)
21662    })
21663
21664}(jQuery);
21665
21666jQuery(document).ready(function () {
21667
21668// iframe wrapper
21669    if (jQuery('.iframe-wrapper-info').length > 0 && jQuery.inArray('functionality', CookieScript.instance.currentState().categories) > -1) {
21670        jQuery('.iframe-wrapper-info').hide();
21671    }
21672    window.addEventListener('CookieScriptAccept', function (e) {
21673        if (jQuery('.iframe-wrapper-info').length > 0 && jQuery.inArray('functionality', e.detail.categories) > -1) {
21674            jQuery('.iframe-wrapper-info').hide();
21675        } else if (jQuery('.iframe-wrapper-info').length > 0) {
21676            jQuery('.iframe-wrapper-info').show();
21677        }
21678    });
21679
21680
21681// scroll to content on collapse
21682    $(document).on('shown.bs.collapse', function (event) {
21683        // event.target.scrollIntoView();
21684        var offset = $(event.target).offset().top;
21685        // $('html, body').animate({ scrollTop: offset }, 500, function(){ window.location.hash = $hash; });
21686        $('html, body').animate({scrollTop: offset - 50}, 500);
21687    });
21688
21689})

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.